mirror of
https://codeberg.org/vyn/mirai.git
synced 2025-07-02 01:13:19 +00:00
Move Calendar to its own view
This commit is contained in:
parent
a03e71890c
commit
d26f2f5a9f
19 changed files with 407 additions and 137 deletions
2
.gitmodules
vendored
2
.gitmodules
vendored
|
@ -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
|
||||
|
|
|
@ -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
2
external/selenite
vendored
|
@ -1 +1 @@
|
|||
Subproject commit 9cba85a21aa6c2eee6101dd38252249283816327
|
||||
Subproject commit c653e851118c893678762d1aeeac3b995a60b9d4
|
2
external/slint
vendored
2
external/slint
vendored
|
@ -1 +1 @@
|
|||
Subproject commit ca66a6af4a4e9c4c78ff889ba447bcb460d07c91
|
||||
Subproject commit 37fb91fafced9e117597a9a1825a641a8c3ea541
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 }
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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 ¤tEvent = 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 ¤tEvent = 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);
|
||||
}
|
||||
|
|
|
@ -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_;
|
||||
|
|
|
@ -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
|
||||
|
|
90
src/windows/AppWindow/views/CalendarView.slint
Normal file
90
src/windows/AppWindow/views/CalendarView.slint
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
50
src/windows/EditEventWindow/EditEventWindow.cpp
Normal file
50
src/windows/EditEventWindow/EditEventWindow.cpp
Normal 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();
|
||||
}
|
33
src/windows/EditEventWindow/EditEventWindow.h
Normal file
33
src/windows/EditEventWindow/EditEventWindow.h
Normal 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_;
|
||||
};
|
68
src/windows/EditEventWindow/EditEventWindow.slint
Normal file
68
src/windows/EditEventWindow/EditEventWindow.slint
Normal 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
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue