1// Copyright © SixtyFPS GmbH <info@slint.dev>
2// SPDX-License-Identifier: GPL-3.0-only OR LicenseRef-Slint-Royalty-free-2.0 OR LicenseRef-Slint-Software-3.0
3
4import { Icons, CosmicPalette, CosmicFontSettings, CosmicSizeSettings } from "styling.slint";
5
6export component StateLayerBase {
7 in property <length> border-radius <=> overlay.border-radius;
8 in property <bool> has-focus;
9 in property <bool> pressed;
10 in property <bool> has-hover;
11 in property <bool> checked;
12 in property <bool> enabled: true;
13 in property <length> focus-boder-margin: 3px;
14 out property <brush> background <=> overlay.background;
15
16 @children
17
18 overlay := Rectangle {}
19
20 if (root.has-focus && root.enabled) : Rectangle {
21 width: root.width + root.focus-boder-margin * 2;
22 height: root.height + root.focus-boder-margin * 2;
23 border-width: 1px;
24 border-radius: root.border-radius + root.focus-boder-margin;
25 border-color: CosmicPalette.state-focus;
26 }
27
28 states [
29 pressed when root.pressed : {
30 overlay.background: CosmicPalette.state-pressed;
31 }
32 hover when root.has-hover : {
33 overlay.background: CosmicPalette.state-hover;
34 }
35 checked when root.checked : {
36 overlay.background: CosmicPalette.state-selected;
37 }
38 ]
39}
40
41export component StateLayer inherits TouchArea {
42 in property <length> border-radius <=> base.border-radius;
43 out property <bool> has-focus: focus-scope.has-focus;
44 in-out property <bool> checked;
45 in property <length> focus-boder-margin <=> base.focus-boder-margin;
46
47 forward-focus: focus-scope;
48
49 focus-scope := FocusScope {
50 x: 0;
51 width: 0; // Do not react on clicks
52 enabled <=> root.enabled;
53
54 key-pressed(event) => {
55 if (event.text == " " || event.text == "\n") {
56 root.clicked();
57 return accept;
58 }
59
60 return reject;
61 }
62 }
63
64 base := StateLayerBase {
65 width: 100%;
66 height: 100%;
67 has-focus: root.has-focus;
68 pressed: root.pressed;
69 has-hover: root.has-hover;
70 checked: root.checked;
71 enabled: root.enabled;
72
73 @children
74 }
75}
76
77export component MenuBorder inherits Rectangle {
78 border-radius: 8px;
79 background: CosmicPalette.alternate-background;
80 drop-shadow-blur: 16px;
81 drop-shadow-offset-y: 4px;
82 drop-shadow-color: CosmicPalette.shadow;
83
84 Rectangle {
85 border-width: 1px;
86 border-radius: parent.border-radius;
87 border-color: CosmicPalette.control-divider;
88 }
89}
90
91export component ListItem {
92 in property <bool> is-selected;
93 in property <StandardListViewItem> item;
94 in property <bool> has-focus;
95 in property <bool> has-hover;
96 in property <bool> pressed;
97 in property <int> index;
98 in property <length> pressed-x;
99 in property <length> pressed-y;
100
101 min-width: layout.min-width;
102 min-height: max(CosmicSizeSettings.item-height, layout.min-height);
103 vertical-stretch: 0;
104 horizontal-stretch: 1;
105 accessible-role: list-item;
106 accessible-label: root.item.text;
107 accessible-item-selectable: true;
108 accessible-item-selected: root.is-selected;
109 accessible-item-index: root.index;
110
111 states [
112 is-selected when root.is-selected : {
113 text.color: CosmicPalette.accent-text;
114 }
115 ]
116
117 layout := HorizontalLayout {
118 padding-bottom: 8px;
119
120 StateLayerBase {
121 width: 100%;
122 pressed: root.pressed;
123 has-hover: root.has-hover;
124 has-focus: root.has-focus;
125 checked: root.is-selected;
126 border-radius: 16px;
127 focus-boder-margin: 0;
128
129 HorizontalLayout {
130 padding-left: 16px;
131 padding-right: 16px;
132 spacing: 8px;
133
134 text := Text {
135 text: root.item.text;
136 color: CosmicPalette.control-foreground;
137 font-size: CosmicFontSettings.body.font-size;
138 font-weight: CosmicFontSettings.body.font-weight;
139 vertical-alignment: center;
140 horizontal-alignment: left;
141 overflow: elide;
142 accessible-role: none;
143 }
144
145 Image {
146 width: 16px;
147 height: 16px;
148 y: (parent.height - self.height) / 2;
149 visible: root.is-selected;
150 colorize: text.color;
151 source: Icons.check-mark;
152 accessible-role: none;
153 }
154 }
155
156 @children
157 }
158 }
159}
160