Move Calendar to its own view

This commit is contained in:
Vyn 2025-06-17 17:03:07 +02:00
parent a03e71890c
commit d26f2f5a9f
Signed by: vyn
GPG key ID: E1B2BE34E7A971E7
19 changed files with 407 additions and 137 deletions

2
.gitmodules vendored
View file

@ -6,7 +6,7 @@
url = https://github.com/slint-ui/slint
[submodule "external/selenite"]
path = external/selenite
url = https://codeberg.org/vyn/selenite.git
url = https://code.evalyte.net/desktop/selenite.git
[submodule "external/evalyte-cpp-common"]
path = external/evalyte-cpp-common
url = https://codeberg.org/vyn/evalyte-cpp-common.git

View file

@ -34,6 +34,7 @@ add_executable(mirai
src/windows/AddSourceWindow/AddSourceWindow.cpp
src/windows/SettingsWindow/SettingsWindow.cpp
src/windows/EditSourceWindow/EditSourceWindow.cpp
src/windows/EditEventWindow/EditEventWindow.cpp
src/SeleniteSetup.cpp
src/shared/Utils.cpp
)

2
external/selenite vendored

@ -1 +1 @@
Subproject commit 9cba85a21aa6c2eee6101dd38252249283816327
Subproject commit c653e851118c893678762d1aeeac3b995a60b9d4

2
external/slint vendored

@ -1 +1 @@
Subproject commit ca66a6af4a4e9c4c78ff889ba447bcb460d07c91
Subproject commit 37fb91fafced9e117597a9a1825a641a8c3ea541

View file

@ -3,6 +3,8 @@ import { VCheckBox, VButton, VActionButton, Svg, VTag, VPopupIconMenu, VText, Pa
import { Utils } from "../shared/Utils.slint";
export struct CalendarDayEvent {
sourceId: int,
id: int,
title: string,
startsAt: Time,
endsAt: Time
@ -28,7 +30,12 @@ export component Calendar inherits Rectangle {
private property <length> available-day-space: self.height - header-height;
private property <length> day-start-y: header-height;
private property <length> hour-spacing: available-day-space / 24;
background: Palette.pane;
private property <int> contextMenuEventSourceId: -1;
callback delete-event-request(source-id: int, event-id: int);
HorizontalLayout {
Rectangle {
@ -58,6 +65,7 @@ export component Calendar inherits Rectangle {
}
Rectangle {
min-width: 400px;
//background: green;
HorizontalLayout {
for day[day-index] in root.days: Rectangle {
@ -113,6 +121,40 @@ export component Calendar inherits Rectangle {
}
}
}
eventActionsPopup := VPopupIconMenu {
//VActionButton {
//icon-svg: Svg.pen;
//icon-colorize: Colors.grey;
//icon-size: 1.5rem;
//border-radius: 0;
//clicked => {
//taskEdit.show({
//title: title,
//date: date
//});
//}
//}
VActionButton {
icon-svg: Svg.trash;
icon-colorize: Colors.pink;
icon-size: 1.5rem;
border-radius: 0;
clicked => {
delete-event-request(event.sourceId, event.id);
}
}
}
ta := TouchArea {
pointer-event(e) => {
if (e.button == PointerEventButton.right && e.kind == PointerEventKind.up) {
debug(ta.mouse-x, " ", ta.mouse-y);
eventActionsPopup.show(ta.mouse-x, ta.mouse-y);
}
}
}
}
}
}

View file

@ -8,38 +8,18 @@ export struct CreateTaskData {
date: Date
}
export struct CreateEventData {
sourceId: int,
title: string,
date: Date,
startsAt: Time,
endsAt: Time
}
export component CreateTaskOrEvent inherits Rectangle {
in property <[string]> sources;
private property <int> task-or-event: 1;
callback create-task(CreateTaskData);
callback create-event(CreateEventData);
function accepted() {
if (task-or-event == 1) {
root.create-task({
sourceId: AppWindowModels.get-source-id-from-name(sourceInput.current-value),
title: newTaskTitleInput.text,
date: taskDateInput.date
})
} else {
root.create-event({
sourceId: AppWindowModels.get-source-id-from-name(sourceInput.current-value),
title: newTaskTitleInput.text,
date: taskDateInput.date,
startsAt: eventStartTimeInput.time,
endsAt: eventEndTimeInput.time
})
}
root.create-task({
sourceId: AppWindowModels.get-source-id-from-name(sourceInput.current-value),
title: newTaskTitleInput.text,
date: taskDateInput.date
});
newTaskTitleInput.edit-text("");
}
@ -75,13 +55,6 @@ export component CreateTaskOrEvent inherits Rectangle {
HorizontalLayout {
alignment: start;
spacing: 8px;
VerticalLayout {
alignment: end;
VButton {
text: task-or-event == 1 ? "Task" : "Event";
clicked => { task-or-event = task-or-event == 1 ? 0 : 1 }
}
}
VText { text: "for"; vertical-alignment: bottom;}
VerticalLayout {
alignment: end;
@ -94,22 +67,6 @@ export component CreateTaskOrEvent inherits Rectangle {
taskDateInput := VDatePicker {
enabled: true;
}
Rectangle {
min-width: 0;
max-width: task-or-event == 0 ? 9999px : 0px;
opacity: task-or-event == 0 ? 1 : 0;
clip: true;
animate max-width, opacity {
duration: 250ms;
}
HorizontalLayout {
spacing: 4px;
VText { text: "between"; vertical-alignment: bottom; }
eventStartTimeInput := VTimePicker { }
VText { text: "and"; vertical-alignment: bottom; }
eventEndTimeInput := VTimePicker { }
}
}
VButton {
text: "Create";
icon-svg: Svg.correct;

View file

@ -4,7 +4,8 @@ import { AppWindow } from "windows/AppWindow/AppWindow.slint";
import { SettingsWindow } from "windows/SettingsWindow/SettingsWindow.slint";
import { AddSourceWindow } from "windows/AddSourceWindow//AddSourceWindow.slint";
import { EditSourceWindow } from "windows/EditSourceWindow/EditSourceWindow.slint";
import { EditEventWindow } from "windows/EditEventWindow/EditEventWindow.slint";
import { Utils } from "shared/Utils.slint";
import { Palette } from "@selenite";
export { Utils, Palette, AppWindow, AppWindowModels, AppWindowActions, SettingsWindow, AddSourceWindow, EditSourceWindow }
export { Utils, Palette, AppWindow, AppWindowModels, AppWindowActions, SettingsWindow, AddSourceWindow, EditSourceWindow, EditEventWindow }

View file

@ -13,7 +13,6 @@ export component AddSourceWindow inherits Window {
min-height: 100px;
max-height: 4000px; // needed, otherwise the window wants to fit the content (on Swaywm)
min-width: 400px;
default-font-size: 16px;
background: Palette.background;
in-out property <string> default-source-path;

View file

@ -18,7 +18,6 @@ export struct SaveTaskData {
}
export struct NewEventParams {
sourceId: int,
title: string,
date: Date,
startsAt: Time,
@ -39,6 +38,13 @@ struct OpenNewTaskFormParams {
eventId: int,
}
export struct CreateEventParams {
title: string,
date: Date,
startsAt: Time,
endsAt: Time
}
export global AppWindowActions {
callback task-clicked(int, int);
callback source-clicked(int);
@ -52,10 +58,11 @@ export global AppWindowActions {
callback open-edit-event-form(int, int);
callback toggle-show-completed-tasks();
callback delete-task-clicked(int, int);
callback delete-event-clicked(int, int);
callback open-add-event-window();
callback create-task(NewTaskData);
callback save-task(SaveTaskData);
callback create-event(NewEventParams);
callback save-event(SaveEventParams);
callback create-event(CreateEventParams);
callback delete-event(sourceId: int, eventId: int);
}

View file

@ -34,15 +34,15 @@
AppWindow::AppWindow(mirai::Mirai *miraiInstance)
: miraiInstance_(miraiInstance), addSourceWindow_(miraiInstance),
editSourceWindow_(miraiInstance), settingsWindow_(miraiInstance), view_(miraiInstance)
editSourceWindow_(miraiInstance), settingsWindow_(miraiInstance),
editEventWindow_(miraiInstance), view_(miraiInstance)
{
sources_ = std::make_shared<slint::VectorModel<ui::Source>>();
days_ = std::make_shared<slint::VectorModel<ui::Day>>();
calendar_ = std::make_shared<slint::VectorModel<ui::CalendarDay>>();
unscheduledTasks_ = std::make_shared<slint::VectorModel<ui::TaskData>>();
auto sourcesNames = std::make_shared<slint::MapModel<ui::Source, slint::SharedString>>(
sources_,
[&](const ui::Source &a) {
sources_, [&](const ui::Source &a) {
return a.name;
}
);
@ -125,6 +125,9 @@ void AppWindow::setupCallbacks()
assert(source);
editSourceWindow_.open(source);
});
actions().on_open_add_event_window([&]() {
editEventWindow_.open();
});
actions().on_task_clicked([&](int sourceId, int taskId) {
auto source = miraiInstance_->getSourceById(sourceId);
@ -217,7 +220,7 @@ void AppWindow::setupCallbacks()
reloadTasks();
});
actions().on_delete_event_clicked([&](int sourceId, int eventId) {
actions().on_delete_event([&](int sourceId, int eventId) {
auto source = miraiInstance_->getSourceById(sourceId);
assert(source);
auto event = source->getEventById(eventId);
@ -228,10 +231,12 @@ void AppWindow::setupCallbacks()
reloadTasks();
});
actions().on_create_event([&](ui::NewEventParams newEventParams) {
actions().on_create_event([&](ui::CreateEventParams newEventParams) {
std::println("okkk");
const ui::Date &date = newEventParams.date;
const std::string dateStr = SlintDateToStdString(date);
auto source = miraiInstance_->getSourceById(newEventParams.sourceId);
const auto sourceId = models().get_default_source_index();
auto source = miraiInstance_->getSourceById(sourceId == -1 ? 0 : sourceId);
source->createEvent({
.title = std::string(newEventParams.title),
@ -244,23 +249,23 @@ void AppWindow::setupCallbacks()
reloadTasks();
});
actions().on_save_event([&](ui::SaveEventParams newEventParams) {
const ui::Date &date = newEventParams.date;
const std::string dateStr = SlintDateToStdString(date);
auto source = miraiInstance_->getSourceById(newEventParams.sourceId);
assert(source);
auto event = source->getEventById(newEventParams.id);
assert(event);
event->setTitle(std::string(newEventParams.title));
event->setStartTime(SlintTimeToMiraiTime(newEventParams.startsAt));
event->setEndTime(SlintTimeToMiraiTime(newEventParams.endsAt));
/*actions().on_save_event([&](ui::SaveEventParams newEventParams) {*/
/*const ui::Date &date = newEventParams.date;*/
/*const std::string dateStr = SlintDateToStdString(date);*/
/*auto source = miraiInstance_->getSourceById(newEventParams.sourceId);*/
/*assert(source);*/
/*auto event = source->getEventById(newEventParams.id);*/
/*assert(event);*/
/*event->setTitle(std::string(newEventParams.title));*/
/*event->setStartTime(SlintTimeToMiraiTime(newEventParams.startsAt));*/
/*event->setEndTime(SlintTimeToMiraiTime(newEventParams.endsAt));*/
// TODO we can't change the date of the event for now.
/*// TODO we can't change the date of the event for now.*/
miraiInstance_->save();
view_.update();
reloadTasks();
});
/*miraiInstance_->save();*/
/*view_.update();*/
/*reloadTasks();*/
/*});*/
}
std::shared_ptr<slint::VectorModel<slint::SharedString>>
@ -291,14 +296,16 @@ void AppWindow::reloadTasks()
std::chrono::sys_days(todayDate.toStdChrono())
)
.count();
slintDays->push_back(ui::Day{
.date = MiraiDateToSlintDate(currentDate),
.events = slintEvents,
.tasks = slintDayTasks,
.isLate = currentDate < todayDate,
.isToday = currentDate == todayDate,
.relativeDaysDiff = static_cast<int>(relativeDaysDiff)
});
slintDays->push_back(
ui::Day{
.date = MiraiDateToSlintDate(currentDate),
.events = slintEvents,
.tasks = slintDayTasks,
.isLate = currentDate < todayDate,
.isToday = currentDate == todayDate,
.relativeDaysDiff = static_cast<int>(relativeDaysDiff)
}
);
// Day's tasks
const std::vector<mirai::Task> tasksForDate = view_.getTasksForDate(currentDate);
for (int taskIndex = 0; taskIndex < tasksForDate.size(); ++taskIndex) {
@ -317,14 +324,16 @@ void AppWindow::reloadTasks()
for (int eventIndex = 0; eventIndex < eventsForDate.size(); ++eventIndex) {
auto &currentEvent = eventsForDate.at(eventIndex);
auto slintTasks = std::make_shared<slint::VectorModel<ui::TaskData>>();
slintEvents->push_back(ui::Event{
.sourceId = currentEvent.sourceId(),
.id = currentEvent.id(),
.title = slint::SharedString(currentEvent.title()),
.startsAt = MiraiTimeToSlintTime(currentEvent.startsAt()),
.endsAt = MiraiTimeToSlintTime(currentEvent.endsAt()),
.tasks = slintTasks,
});
slintEvents->push_back(
ui::Event{
.sourceId = currentEvent.sourceId(),
.id = currentEvent.id(),
.title = slint::SharedString(currentEvent.title()),
.startsAt = MiraiTimeToSlintTime(currentEvent.startsAt()),
.endsAt = MiraiTimeToSlintTime(currentEvent.endsAt()),
.tasks = slintTasks,
}
);
auto eventTasks = currentEvent.queryTasks();
for (int taskIndex = 0; taskIndex < eventTasks.size(); ++taskIndex) {
auto &task = eventTasks.at(taskIndex);
@ -370,25 +379,29 @@ void AppWindow::reloadTasks()
std::chrono::sys_days(todayDate.toStdChrono())
)
.count();
if (relativeDaysDiff < 0 || relativeDaysDiff >= 3) {
if (relativeDaysDiff < 0 || relativeDaysDiff >= 7) {
continue;
}
const std::vector<mirai::Event> eventsForDate = view_.getEventsForDate(currentDate);
for (int eventIndex = 0; eventIndex < eventsForDate.size(); ++eventIndex) {
auto &currentEvent = eventsForDate.at(eventIndex);
slintEvents->push_back(ui::CalendarDayEvent{
.title = slint::SharedString(currentEvent.title()),
.startsAt = MiraiTimeToSlintTime(currentEvent.startsAt()),
.endsAt = MiraiTimeToSlintTime(currentEvent.endsAt()),
});
slintEvents->push_back(
ui::CalendarDayEvent{
.sourceId = currentEvent.sourceId(),
.id = currentEvent.id(),
.title = slint::SharedString(currentEvent.title()),
.startsAt = MiraiTimeToSlintTime(currentEvent.startsAt()),
.endsAt = MiraiTimeToSlintTime(currentEvent.endsAt()),
}
);
}
auto calendarDay = ui::CalendarDay{
.events = slintEvents,
.date = MiraiDateToSlintDate(currentDate),
.header =
slint::SharedString(capitalize(formatDateRelative(MiraiDateToSlintDate(currentDate))
))
.header = slint::SharedString(
capitalize(formatDateRelative(MiraiDateToSlintDate(currentDate)))
)
};
calendar_->push_back(calendarDay);
}

View file

@ -7,6 +7,7 @@
#pragma once
#include "../AddSourceWindow/AddSourceWindow.h"
#include "../EditEventWindow/EditEventWindow.h"
#include "../EditSourceWindow/EditSourceWindow.h"
#include "../SettingsWindow/SettingsWindow.h"
#include "mirai-core/Mirai.h"
@ -40,6 +41,7 @@ class AppWindow
SettingsWindow settingsWindow_;
AddSourceWindow addSourceWindow_;
EditSourceWindow editSourceWindow_;
EditEventWindow editEventWindow_;
mirai::Mirai *miraiInstance_;
mirai::View view_;

View file

@ -6,21 +6,46 @@ import { SettingsWindow } from "../SettingsWindow/SettingsWindow.slint";
import { AddSourceWindow } from "../AddSourceWindow//AddSourceWindow.slint";
import { EditSourceWindow } from "../EditSourceWindow/EditSourceWindow.slint";
import { Palette } from "@selenite";
import { CalendarView } from "views/CalendarView.slint";
import { VButton } from "../../../external/selenite/components/Button.slint";
export component AppWindow inherits Window {
title: "Mirai";
min-height: 100px;
max-height: 4000px; // needed, otherwise the window wants to fit the content (on Swaywm)
default-font-size: 16px;
background: Palette.pane;
private property<bool> show-tasks: false;
HorizontalLayout {
SideBar {}
MainView {
horizontal-stretch: 1;
VerticalLayout {
HorizontalLayout {
padding: 16px;
alignment: LayoutAlignment.stretch;
spacing: 8px;
VButton {
text: "Calendar";
clicked => { show-tasks = false }
}
VButton {
text: "Tasks";
clicked => { show-tasks = true }
}
}
SideBar {}
}
VerticalLayout {
if show-tasks : MainView {
horizontal-stretch: 1;
}
if !show-tasks : CalendarView {
horizontal-stretch: 1;
}
}
}
}
export { AppWindowModels, Palette, SettingsWindow, AddSourceWindow, EditSourceWindow } // Export to make it visible to the C++ backend

View file

@ -0,0 +1,90 @@
import { AppWindowModels, TaskData } from "../Models.slint";
import { AppWindowActions, NewTaskData, SaveTaskData } from "../Actions.slint";
import { Button, VerticalBox, CheckBox, ScrollView, ComboBox } from "std-widgets.slint";
import { TaskLine } from "../../../components/TaskLine.slint";
import { EventGroup } from "../../../components/EventGroup.slint";
import { Calendar } from "../../../components/Calendar.slint";
import { VPopupIconMenu, VDatePicker, VTimePicker, VCheckBox, VButton, VTag, VText, VTextInput, Svg, Palette } from "@selenite";
import { CreateTaskOrEvent } from "../../../components/CreateTaskOrEvent.slint";
import { Utils } from "../../../shared/Utils.slint";
import { VActionButton } from "../../../../external/selenite/components/index.slint";
export component CalendarView inherits Rectangle {
background: Palette.background;
private property<string> icon-visible: Svg.visible;
private property<string> icon-not-visible: Svg.not-visible;
private property<bool> completed-tasks-visible: false;
createEventPopup := PopupWindow {
x: parent.width / 2 - 200px;
y: parent.height / 2 - 300px;
close-policy: close-on-click-outside;
background := Rectangle {
height: 100%;
width: 100%;
background: Palette.background1;
border-color: Palette.popup-border;
border-width: 1px;
border-radius: 4px;
}
VerticalLayout {
padding: 16px;
spacing: 8px;
titleInput := VTextInput {
label: "title";
}
VText { text: "on"; vertical-alignment: bottom;}
dateInput := VDatePicker {
enabled: true;
}
HorizontalLayout {
spacing: 4px;
VText { text: "between"; vertical-alignment: bottom; }
startTimeInput := VTimePicker { }
VText { text: "and"; vertical-alignment: bottom; }
endTimeInput := VTimePicker { }
}
VButton {
text: "Create";
clicked => {
debug("clicked OK");
debug(createEventPopup.width);
debug(createEventPopup.height);
AppWindowActions.create-event({
title: titleInput.text,
date: dateInput.date,
startsAt: startTimeInput.time,
endsAt: endTimeInput.time
});
debug("Event sent");
createEventPopup.close();
}
}
}
}
VerticalLayout {
HorizontalLayout {
alignment: start;
padding: 16px;
VButton {
text: "New event";
icon-svg: Svg.plus;
icon-colorize: greenyellow;
clicked => {
createEventPopup.show();
}
}
}
Calendar {
delete-event-request(source-id, event-id) => { debug("DEELTE", source-id);AppWindowActions.delete-event(source-id, event-id) }
init => { debug("cal len", AppWindowModels.calendar.length) }
days: AppWindowModels.calendar;
current-date: Utils.current-date;
current-time: Utils.current-time;
}
}
}

View file

@ -52,16 +52,6 @@ export component MainView inherits Rectangle {
date: data.date
})
}
create-event(data) => {
AppWindowActions.create-event({
sourceId: data.sourceId,
title: data.title,
date: data.date,
startsAt: data.startsAt,
endsAt: data.endsAt,
});
}
}
Flickable {
@ -125,17 +115,17 @@ export component MainView inherits Rectangle {
AppWindowActions.task-clicked(event.sourceId, taskId);
}
delete => {
AppWindowActions.delete-event-clicked(event.sourceId, event.id)
//AppWindowActions.delete-event-clicked(event.sourceId, event.id)
}
edit(data) => {
AppWindowActions.save-event({
sourceId: event.sourceId,
id: event.id,
title: data.title,
//date: event.date,
startsAt: event.startsAt,
endsAt: event.endsAt,
});
//AppWindowActions.save-event({
//sourceId: event.sourceId,
//id: event.id,
//title: data.title,
////date: event.date,
//startsAt: event.startsAt,
//endsAt: event.endsAt,
//});
}
}
}
@ -214,12 +204,6 @@ export component MainView inherits Rectangle {
}
}
}
Calendar {
init => { debug("cal len", AppWindowModels.calendar.length) }
days: AppWindowModels.calendar;
current-date: Utils.current-date;
current-time: Utils.current-time;
}
}
}

View file

@ -0,0 +1,50 @@
/*
* Mirai. Copyright (C) 2024 Vyn
* This file is licensed under version 3 of the GNU General Public License (GPL-3.0-only)
* The license can be found in the LICENSE file or at https://www.gnu.org/licenses/gpl-3.0.txt
*/
#include "EditEventWindow.h"
#include "../../SeleniteSetup.h"
#include "evalyte-cpp-common/evalyte.h"
#include "mirai-core/DataProvider.h"
#include "mirai-core/MarkdownDataProvider.h"
#include "mirai-core/Mirai.h"
#include "slint.h"
#include "slint_string.h"
#include <bits/chrono.h>
#include <cassert>
#include <cstdio>
#include <cstdlib>
#include <ctime>
#include <memory>
#include <optional>
#include <print>
#include <string>
EditEventWindow::EditEventWindow(mirai::Mirai *miraiInstance) : miraiInstance_(miraiInstance)
{
const auto palettePath = std::string(getenv("HOME")) + "/.config/evalyte/theme.json";
const auto palette = selenite::parseJson(palettePath);
if (palette.has_value()) {
setSelenitePalette(window_->global<ui::Palette>(), palette.value());
}
setupCallbacks();
}
void EditEventWindow::setupCallbacks()
{
}
void EditEventWindow::open()
{
window_->show();
}
void EditEventWindow::close()
{
window_->hide();
}

View file

@ -0,0 +1,33 @@
/*
* Mirai. Copyright (C) 2024 Vyn
* This file is licensed under version 3 of the GNU General Public License (GPL-3.0-only)
* The license can be found in the LICENSE file or at https://www.gnu.org/licenses/gpl-3.0.txt
*/
#pragma once
#include "mirai-core/Mirai.h"
#include "slint.h"
#include "ui.h"
class EditEventWindow
{
public:
EditEventWindow(mirai::Mirai *mirai);
void open();
void close();
auto getHandle()
{
return this->window_;
}
private:
void setupCallbacks();
std::shared_ptr<slint::VectorModel<ui::Source>> sources_;
slint::ComponentHandle<ui::EditEventWindow> window_ = ui::EditEventWindow::create();
mirai::Mirai *miraiInstance_;
};

View file

@ -0,0 +1,68 @@
import { AppWindowModels } from "../AppWindow/Models.slint";
import { Button, VerticalBox, CheckBox } from "std-widgets.slint";
import { VText, VTextInput, Palette } from "@selenite";
import { VButton } from "../../../external/selenite/components/index.slint";
import { Date, Time, Button, VerticalBox, CheckBox, ScrollView, ComboBox } from "std-widgets.slint";
import { VDatePicker } from "../../../external/selenite/components/DatePicker.slint";
import { VTimePicker } from "../../../external/selenite/components/TimePicker.slint";
export struct CreateEventParams {
title: string,
date: Date,
startsAt: Time,
endsAt: Time
}
export component EditEventWindow inherits Window {
title: "Mirai - Event";
min-height: 100px;
max-height: 500px; // needed, otherwise the window wants to fit the content (on Swaywm)
max-width: 500px; // needed, otherwise the window wants to fit the content (on Swaywm)
background: Palette.background;
in-out property <int> sourceId;
callback create-event(CreateEventParams);
callback delete-event(int);
VerticalLayout {
padding: 16px;
spacing: 8px;
titleInput := VTextInput {
label: "title";
}
VText { text: "on"; vertical-alignment: bottom;}
dateInput := VDatePicker {
enabled: true;
}
HorizontalLayout {
spacing: 4px;
VText { text: "between"; vertical-alignment: bottom; }
startTimeInput := VTimePicker { }
VText { text: "and"; vertical-alignment: bottom; }
endTimeInput := VTimePicker { }
}
VButton {
text: "Create";
clicked => {
debug("clicked");
root.create-event({
title: titleInput.text,
date: dateInput.date,
startsAt: startTimeInput.time,
endsAt: endTimeInput.time
})
}
}
VButton {
text: "Delete";
background-color: Palette.red;
double-clicked => {
//root.delete-event(root.id)
}
}
}
}
export { AppWindowModels, Palette } // Export to make it visible to the C++ backend

View file

@ -16,7 +16,6 @@ export component EditSourceWindow inherits Window {
min-height: 100px;
max-height: 4000px; // needed, otherwise the window wants to fit the content (on Swaywm)
min-width: 400px;
default-font-size: 16px;
background: Palette.background;
callback modify-source(ModifySourceParam);

View file

@ -7,7 +7,6 @@ export component SettingsWindow inherits Window {
title: "Mirai - Settings";
min-height: 100px;
max-height: 4000px; // needed, otherwise the window wants to fit the content (on Swaywm)
default-font-size: 16px;
background: Palette.background;
VerticalLayout {