1 | // Copyright © SixtyFPS GmbH <info@slint.dev> |
2 | // SPDX-License-Identifier: MIT |
3 | |
4 | import { StateLayer } from "../components/state_layer.slint" ; |
5 | import { ScrollView } from "scroll_view.slint" ; |
6 | import { Theme } from "../theme.slint" ; |
7 | import { Images } from "../images.slint" ; |
8 | import { StateLayer } from "../components/state_layer.slint" ; |
9 | |
10 | component ListViewItem { |
11 | in property <string> text <=> i-text.text; |
12 | in property <bool> selected; |
13 | |
14 | callback clicked <=> i-state-layer.clicked; |
15 | |
16 | min-height: 40px; |
17 | |
18 | states [ |
19 | selected when selected : { |
20 | i-container.border-color: Theme.palette.lemon-green; |
21 | i-icon.visible: true; |
22 | } |
23 | ] |
24 | |
25 | i-container := Rectangle { |
26 | background: Theme.palette.dark-deep-blue; |
27 | border-radius: 4px; |
28 | border-width: 1px; |
29 | border-color: Theme.palette.slint-blue-400; |
30 | } |
31 | |
32 | HorizontalLayout { |
33 | padding-left: Theme.spaces.medium; |
34 | padding-top: Theme.spaces.medium; |
35 | padding-bottom: Theme.spaces.medium; |
36 | padding-right: Theme.spaces.medium; |
37 | spacing: Theme.spaces.medium; |
38 | |
39 | i-text := Text { |
40 | horizontal-stretch: 1; |
41 | color: Theme.palette.white; |
42 | font-size: Theme.typo.description.size; |
43 | font-weight: Theme.typo.description.weight; |
44 | vertical-alignment: center; |
45 | } |
46 | |
47 | i-icon := Image { |
48 | horizontal-stretch: 0; |
49 | visible: false; |
50 | source: Images.check; |
51 | colorize: Theme.palette.lemon-green; |
52 | } |
53 | } |
54 | |
55 | i-state-layer := StateLayer { |
56 | width: i-container.width; |
57 | height: i-container.height; |
58 | border-radius: i-container.border-radius; |
59 | } |
60 | } |
61 | |
62 | export component ListView { |
63 | in property <[StandardListViewItem]> model; |
64 | in-out property <int> selected-index; |
65 | |
66 | callback selection-changed(/* index */ int); |
67 | |
68 | function select(index: int) { |
69 | selected-index = index; |
70 | selection-changed(index); |
71 | } |
72 | |
73 | i-scroll-view := ScrollView { |
74 | i-blub := VerticalLayout { |
75 | alignment: start; |
76 | spacing: Theme.spaces.medium; |
77 | |
78 | for item[index] in model : ListViewItem { |
79 | clicked => { |
80 | select(index); |
81 | } |
82 | |
83 | private property <length> offset: i-scroll-view.viewport-y + index * (self.height + parent.spacing); |
84 | |
85 | text: item.text; |
86 | selected: index == selected-index; |
87 | |
88 | animate opacity { duration: Theme.durations.fast; } |
89 | } |
90 | } |
91 | } |
92 | } |
93 | |