import { Backend, TaskData } from "Backend.slint"; import { Button, VerticalBox, CheckBox, ScrollView, ComboBox } from "std-widgets.slint"; import { SideBar } from "SideBar.slint"; import { TaskLine } from "TaskLine.slint"; import { EventGroup } from "EventGroup.slint"; import { VPopupIconMenu, VDatePicker, VTimePicker, VCheckBox, VButton, VTag, VText, VTextInput, Palette } from "@vynui"; import { NewTaskData, SaveTaskData } from "Backend.slint"; export component MainView inherits Rectangle { background: Palette.background; private property icon-visible: @image-url("./images/visible.png"); private property icon-not-visible: @image-url("./images/not-visible.png"); private property completed-tasks-visible: false; pure function formatZeroPadding(number: int) -> string { if (number < 10) { return "0\{number}"; } return number; } VerticalLayout { horizontal-stretch: 1; padding: 16px; spacing: 16px; alignment: start; HorizontalLayout { horizontal-stretch: 1; alignment: start; spacing: 8px; VButton { text: "New task"; clicked => { Backend.open_new_task_form({ eventSourceId: -1, eventId: -1, })} icon-source: @image-url("./images/add.png"); icon-colorize: Colors.greenyellow; } VButton { text: "New event"; clicked => { Backend.open_new_event_form() } icon-source: @image-url("./images/add.png"); icon-colorize: Colors.greenyellow; } VButton { text: "Show/Hide completed tasks"; clicked => { Backend.toggle_show_completed_tasks(); completed-tasks-visible = !completed-tasks-visible; } icon-source: completed-tasks-visible ? icon-visible : icon-not-visible; icon-colorize: Palette.control-foreground; } } Rectangle { horizontal-stretch: 1; background: Palette.background.brighter(0.2); height: 1px; } Rectangle { border-color: newTaskTitleInput.text != "" ? Palette.card-background : transparent; border-width: newTaskTitleInput.text != "" ? 4px : 0px; border-radius: newTaskTitleInput.text != "" ? 8px : 0px; animate border-color, border-width { duration: 250ms; } VerticalLayout { in-out property task-or-event: 1; spacing: 8px; padding: newTaskTitleInput.text != "" ? 16px : 0px; animate padding { duration: 250ms; } Rectangle { min-height: 0px; max-height: newTaskTitleInput.text != "" ? 512px : 0px; opacity: newTaskTitleInput.text != "" ? 1 : 0; clip: true; animate max-height, opacity { duration: 250ms; } 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; sourceInput := ComboBox { model: Backend.sources; } } VText { text: "on"; vertical-alignment: bottom;} taskDateInput := VDatePicker { label: "Date"; enabled: true; } HorizontalLayout { visible: task-or-event == 0; HorizontalLayout { spacing: 4px; VText { text: "between"; vertical-alignment: bottom; } eventStartTimeInput := VTimePicker { label: "Starts at"; } VText { text: "and"; vertical-alignment: bottom; } eventEndTimeInput := VTimePicker { label: "Ends at"; } } } } } newTaskTitleInput := VTextInput { placeholder: "Add new Task / Event"; accepted => { if (task-or-event == 1) { Backend.createTask({ sourceId: sourceInput.current-index, eventId: -1, title: newTaskTitleInput.text, scheduled: taskDateInput.date.year != 0, date: taskDateInput.date }) } else { Backend.createEvent({ sourceId: sourceInput.current-index, title: newTaskTitleInput.text, date: taskDateInput.date, startsAt: eventStartTimeInput.time, endsAt: eventEndTimeInput.time, }); } newTaskTitleInput.text = ""; } } } } Flickable { horizontal-stretch: 1; VerticalLayout { alignment: start; spacing: 16px; if Backend.visible_tasks.length == 0 : VText { text: "There is no task to show"; horizontal-alignment: center; } for day[dayIndex] in Backend.visible_tasks: VerticalLayout { Rectangle { background: Palette.card-background; border-radius: 8px; VerticalLayout { padding: 16px; HorizontalLayout { alignment: start; VText { text: Backend.formatDate(day.date); color: day.isLate ? Palette.orange : Palette.foreground; font-size: 1.2rem; } VerticalLayout { alignment: center; VText { text: day.relativeDaysDiff == 0 ? " - today" : day.relativeDaysDiff == 1 ? " - tomorrow" : day.relativeDaysDiff == -1 ? " - yesterday" : day.relativeDaysDiff > 0 ? " - in \{day.relativeDaysDiff} days" : " - \{-day.relativeDaysDiff} days ago"; color: Palette.foreground-hint; font-size: 1rem; } } } for event[eventIndex] in day.events: VerticalLayout { padding-top: 16px; EventGroup { event: event; } } for task[taskIndex] in day.tasks: VerticalLayout { padding-top: taskIndex == 0 ? 16px : 0px; padding-bottom: 8px; TaskLine { task: task; source-index: task.sourceId; task-index: task.id; } } } } } if Backend.unscheduled-tasks.length > 0 : VerticalLayout { Rectangle { background: Palette.card-background; border-radius: 8px; VerticalLayout { padding: 16px; HorizontalLayout { alignment: start; VText { text: "Unscheduled"; color: Palette.foreground; font-size: 1.2rem; } } for task[taskIndex] in Backend.unscheduled-tasks: VerticalLayout { padding-top: taskIndex == 0 ? 16px : 0px; padding-bottom: 8px; TaskLine { task: task; source-index: task.sourceId; task-index: task.id; } } } } } } } } }