mirai/src/components/Calendar.slint

157 lines
4.2 KiB
Text
Raw Normal View History

2024-10-29 15:02:46 +01:00
import { ScrollView, Date, Time } from "std-widgets.slint";
import { VCheckBox, VButton, VActionButton, Svg, VTag, VPopupIconMenu, VText, Palette } from "@selenite";
import { Utils } from "../shared/Utils.slint";
2025-06-29 20:07:11 +02:00
import { AppModels, CalendarViewDate, CalendarDateDisplayFormat } from "../shared/Models.slint";
2024-10-29 15:02:46 +01:00
export component Calendar inherits Rectangle {
2025-06-29 20:07:11 +02:00
in property<[CalendarViewDate]> days;
2024-10-29 15:02:46 +01:00
in property <CalendarDateDisplayFormat> format;
in property <Date> current-date;
in property <Time> current-time;
2024-10-29 15:02:46 +01:00
private property <length> header-height: 64px;
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;
2025-06-17 17:03:07 +02:00
private property <int> contextMenuEventSourceId: -1;
callback delete-event-request(source-id: int, event-id: int);
2024-10-29 15:02:46 +01:00
HorizontalLayout {
Rectangle {
//background: red;
width: 48px;
VerticalLayout {
y: 0;
height: header-height;
padding-right: 8px;
VText {
vertical-alignment: center;
horizontal-alignment: right;
text: "";
}
}
for index in 24: VerticalLayout {
y: day-start-y + index * hour-spacing - (hour-spacing / 2);
height: hour-spacing;
padding-right: 8px;
VText {
vertical-alignment: center;
horizontal-alignment: right;
text: "\{index}";
2024-10-29 15:02:46 +01:00
}
}
}
Rectangle {
2025-06-26 10:12:23 +02:00
Rectangle { // Last bar delimiting days
2025-06-25 12:06:33 +02:00
x: parent.width - 1px;
y: header-height - 32px;
width: 1px;
height: parent.height - self.y;
background: Palette.card-background.brighter(0.3);
}
2025-06-17 17:03:07 +02:00
min-width: 400px;
2024-10-29 15:02:46 +01:00
//background: green;
HorizontalLayout {
for day[day-index] in root.days: Rectangle {
2025-06-26 10:12:23 +02:00
Rectangle { // Bar delimiting days
2024-10-29 15:02:46 +01:00
x: 0;
y: header-height - 32px;
width: 1px;
2025-06-25 12:06:33 +02:00
height: parent.height - self.y;
background: Palette.card-background.brighter(0.3);
2024-10-29 15:02:46 +01:00
}
VerticalLayout {
y: 0;
height: header-height;
padding-right: 8px;
VText {
vertical-alignment: center;
horizontal-alignment: center;
text: day.header;
}
}
for hour[hour-index] in 24 : Rectangle {
2025-06-25 12:06:33 +02:00
background: Palette.card-background.brighter(0.3);
2024-10-29 15:02:46 +01:00
x: 0px;
width: parent.width;
y: day-start-y + hour-spacing * hour-index;
height: 1px;
}
if day.date == root.current-date : Rectangle {
background: Palette.red;
x: 0px;
y: day-start-y + hour-spacing * root.current-time.hour + (root.current-time.minute / 60 * hour-spacing);
2025-06-26 10:12:23 +02:00
width: parent.width;
height: 1px;
2025-06-26 10:12:23 +02:00
z: 100;
}
2024-10-29 15:02:46 +01:00
for event[event-index] in day.events : Rectangle {
2025-06-26 10:12:23 +02:00
Rectangle {
width: 100%;
height: 100%;
2025-06-29 20:07:11 +02:00
background: AppModels.get-source-color-from-id-as-color(event.source-id);
2025-06-26 10:12:23 +02:00
opacity: 0.05;
}
2024-10-29 15:02:46 +01:00
background: Palette.card-background;
border-radius: 4px;
x: 8px;
width: parent.width - 16px;
2025-06-29 20:07:11 +02:00
y: day-start-y + hour-spacing * event.starts_at.hour;
height: hour-spacing * (event.ends_at.hour - event.starts_at.hour) - 2px;
2024-10-29 15:02:46 +01:00
clip: true;
HorizontalLayout {
Rectangle {
width: 4px;
2025-06-29 20:07:11 +02:00
background: AppModels.get-source-color-from-id-as-color(event.source-id);
2024-10-29 15:02:46 +01:00
}
VerticalLayout {
padding: 16px;
VText {
text: event.title;
wrap: TextWrap.word-wrap;
}
}
}
2025-06-17 17:03:07 +02:00
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 => {
2025-06-29 20:07:11 +02:00
delete-event-request(event.source-id, event.id);
2025-06-17 17:03:07 +02:00
}
}
}
ta := TouchArea {
pointer-event(e) => {
if (e.button == PointerEventButton.right && e.kind == PointerEventKind.up) {
eventActionsPopup.show(ta.mouse-x, ta.mouse-y);
}
}
}
2024-10-29 15:02:46 +01:00
}
}
}
}
}
}