1// Copyright © SixtyFPS GmbH <info@slint.dev>
2// SPDX-License-Identifier: MIT
3
4import { StateLayer } from "../components/state_layer.slint";
5import { ScrollView } from "scroll_view.slint";
6import { Theme } from "../theme.slint";
7import { Images } from "../images.slint";
8import { StateLayer } from "../components/state_layer.slint";
9
10component 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
62export 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