| 1 | // Copyright © SixtyFPS GmbH <info@slint.dev> |
| 2 | // SPDX-License-Identifier: MIT |
| 3 | |
| 4 | import { CheckBox, ListView, HorizontalBox } from "std-widgets.slint" ; |
| 5 | import { StateLayer } from "./state_layer.slint" ; |
| 6 | import { FocusTouchArea } from "./focus_touch_area.slint" ; |
| 7 | import { SizeSettings, TodoPalette, FontSettings, Icons } from "styling.slint" ; |
| 8 | import { IconButton } from "icon_button.slint" ; |
| 9 | |
| 10 | @rust-attr(derive(serde::Serialize, serde::Deserialize)) |
| 11 | export struct SelectionListViewItem { |
| 12 | text: string, |
| 13 | checked: bool, |
| 14 | description: string, |
| 15 | } |
| 16 | |
| 17 | export component SelectionListViewItemDelegate { |
| 18 | callback toggle; |
| 19 | callback remove; |
| 20 | |
| 21 | in property <string> text <=> text-label.text; |
| 22 | in property <string> description <=> description-label.text; |
| 23 | in-out property <bool> checked <=> check-box.checked; |
| 24 | |
| 25 | min-width: content-layer.min-width; |
| 26 | min-height: max(SizeSettings.control-height, content-layer.min-height); |
| 27 | forward-focus: touch-area; |
| 28 | |
| 29 | touch-area := FocusTouchArea { |
| 30 | width: 100%; |
| 31 | height: 100%; |
| 32 | |
| 33 | clicked => { |
| 34 | root.toggle(); |
| 35 | } |
| 36 | } |
| 37 | |
| 38 | StateLayer { |
| 39 | width: 100%; |
| 40 | height: 100%; |
| 41 | focus-padding: -1px; |
| 42 | pressed: touch-area.pressed || touch-area.enter-pressed; |
| 43 | has-focus: touch-area.has-focus; |
| 44 | has-hover: touch-area.has-hover; |
| 45 | } |
| 46 | |
| 47 | content-layer := HorizontalBox { |
| 48 | accessible-role: list-item; |
| 49 | |
| 50 | check-box := CheckBox { |
| 51 | horizontal-stretch: 0; |
| 52 | y: (parent.height - self.height) / 2; |
| 53 | accessible-label: @tr("Task Done" ); |
| 54 | toggled => { |
| 55 | root.toggle(); |
| 56 | } |
| 57 | } |
| 58 | |
| 59 | VerticalLayout { |
| 60 | alignment: center; |
| 61 | text-label := Text { |
| 62 | horizontal-alignment: left; |
| 63 | color: TodoPalette.foreground; |
| 64 | font-size: FontSettings.body-strong.font-size; |
| 65 | font-weight: FontSettings.body-strong.font-weight; |
| 66 | overflow: elide; |
| 67 | } |
| 68 | |
| 69 | description-label := Text { |
| 70 | color: TodoPalette.foreground; |
| 71 | font-size: FontSettings.body.font-size; |
| 72 | font-weight: FontSettings.body.font-weight; |
| 73 | overflow: elide; |
| 74 | } |
| 75 | } |
| 76 | |
| 77 | IconButton { |
| 78 | y: (parent.height - self.height) / 2; |
| 79 | icon: Icons.remove; |
| 80 | accessible-label: @tr("Delete Task" ); |
| 81 | clicked => { |
| 82 | root.remove(); |
| 83 | } |
| 84 | } |
| 85 | } |
| 86 | } |
| 87 | |
| 88 | export component SelectionListView inherits ListView { |
| 89 | in property <[SelectionListViewItem]> model; |
| 90 | |
| 91 | callback toggle(/* index */ int); |
| 92 | callback remove(/* index */ int); |
| 93 | |
| 94 | accessible-role: list; |
| 95 | |
| 96 | for item[index] in root.model: SelectionListViewItemDelegate { |
| 97 | width: root.visible-width; |
| 98 | text: item.text; |
| 99 | description: item.description; |
| 100 | checked: item.checked; |
| 101 | toggle => { |
| 102 | root.toggle(index); |
| 103 | } |
| 104 | |
| 105 | remove => { |
| 106 | root.remove(index); |
| 107 | } |
| 108 | } |
| 109 | } |
| 110 | |