1// Copyright © SixtyFPS GmbH <info@slint.dev>
2// SPDX-License-Identifier: MIT
3
4import { SpinBox, Button, CheckBox, Slider, GroupBox, StandardListView } from "std-widgets.slint";
5import { Label, Page, Preview } from "common.slint";
6import { CopyPage } from "copy_page.slint";
7import { FaxPage } from "fax_page.slint";
8import { PrintPage } from "print_page.slint";
9import { SettingsPage } from "settings_page.slint";
10
11component TopPanel inherits Rectangle {
12 in-out property <int> active-page: 0;
13
14 callback quit();
15
16 background: white;
17
18 HorizontalLayout {
19 alignment: center;
20 Text {
21 text: "PrintMachine";
22 color: root.active-page == 0 ? black : #0000;
23 font-size: root.width * 5%;
24 horizontal-alignment: center;
25 vertical-alignment: center;
26
27 animate color { duration: 200ms; }
28 }
29 Text {
30 text: "2000";
31 color: root.active-page == 0 ? #918e8c : #0000;
32 font-size: root.width * 5%;
33 horizontal-alignment: center;
34 vertical-alignment: center;
35
36 animate color { duration: 200ms; }
37
38 }
39 }
40 power-button := Image {
41 x: parent.width - self.width - 20px;
42 y: (parent.height - self.height) / 2;
43 source: @image-url("images/power.svg");
44 width: 5%;
45 height: self.width;
46
47 TouchArea {
48 clicked => {
49 root.quit();
50 }
51 }
52 }
53}
54
55struct InkLevel {
56 color: color,
57 level: float,
58}
59
60export component MainWindow inherits Window {
61 /// Note that this property is overwritten in the .cpp and .rs code.
62 /// The data is only in this file so it looks good in the viewer
63 in-out property <[InkLevel]> ink-levels: [
64 {color: #0ff, level: 60%},
65 {color: #ff0, level: 80%},
66 {color: #f0f, level: 70%},
67 {color: #000, level: 30%},
68 ];
69 /// Aliased to the fax number in the fax page
70 in-out property <string> fax-number;
71 in-out property <int> active-page: 0;
72
73 callback quit();
74 callback fax-number-erase;
75 callback fax-send;
76
77 /// That's just a default implementation for the viewer, but the .cpp and .rs code
78 /// overwrite that to erase only the last character
79 fax-number-erase => { root.fax-number = ""; }
80
81 width: 800px;
82 height: 600px;
83 title: "Slint printer demo";
84
85 panel := TopPanel {
86 quit => { root.quit(); }
87
88 y: 0;
89 active-page: root.active-page;
90 width: 100%;
91 height: 12.5%;
92 }
93
94 for page-info[idx] in [
95 { color: #1ac80a, text: "Copy", img-small: @image-url("images/replicate.svg") },
96 { color: #00c889, text: "Fax", img-small: @image-url("images/laptop.svg") },
97 { color: #00bbc8, text: "Print", img-small: @image-url("images/printer.svg") },
98 { color: #009dc8, text: "Settings", img-small: @image-url("images/list.svg") },
99 ] : Rectangle {
100 property <length> w: root.width / 5;
101
102 width: self.w;
103 height: root.height / 3;
104 y: root.height / 4;
105 x: idx * (self.w + (root.width - self.w*4) / 5) + (root.width - self.w*4)/5;
106 border-radius: 25px;
107 background: page-info.color;
108
109 animate x, y, height, width, background, border-radius {
110 duration: 300ms;
111 easing: ease-in-out;
112 }
113
114 states [
115 active when root.active-page == idx + 1: {
116 x: 0phx;
117 y: 0phx;
118 height: root.height * 12.5%;
119 width: root.width;
120 border-radius: 0px;
121 img.x: root.height * 12.5%;
122 img.width: root.height * 10%;
123 img.height: root.height * 10%;
124 text.y: 0phx;
125 }
126 pressed when root.active-page == 0 && touch.pressed : {
127 w: root.width / 5 + 6px;
128 height: root.height / 3 + 6px ;
129 y: root.height / 4 - 3px;
130 }
131 invisible when root.active-page > 0 && root.active-page != idx + 1 : {
132 color: transparent;
133 // FIXME: should probably hide the entire item under with z-ordering
134 img.y: 1000000000px;
135 text.color: #0000;
136 }
137 ]
138
139 img := Image {
140 y: 5px;
141 x: (w - (root.width / 6.25)) / 2;
142 width: root.width / 6.25;
143 height: root.height / 4.68;
144 source: page-info.img-small;
145
146 animate width, height, x, y {
147 duration: 300ms;
148 easing: ease-in-out;
149 }
150 }
151
152 text := Text {
153 y: root.height / 10;
154 x: 5px;
155 width: 100%;
156 height: 100%;
157 horizontal-alignment: center;
158 vertical-alignment: center;
159 text: page-info.text;
160 font-size: 28px;
161
162 animate x, y {
163 duration: 300ms;
164 easing: ease-in-out;
165 }
166 }
167 touch := TouchArea {
168 clicked => {
169 if (root.active-page == 0) {
170 root.active-page = idx + 1;
171 }
172 }
173 }
174 }
175
176 if (root.active-page != 0) : Rectangle {
177 x:0;y:0;
178 width: self.height;
179 height: 12.5%;
180
181 Text {
182 width: 100%;
183 height: 100%;
184 text: "←";
185 color: white;
186 font-size: root.height / 10;
187 horizontal-alignment: center;
188 vertical-alignment: center;
189 }
190
191 TouchArea {
192 clicked => { root.active-page = 0; }
193 }
194 }
195
196
197 Rectangle {
198 property <bool> full-screen;
199
200 width: root.width / 5;
201 height: root.height / 5;
202 x: root.width - self.width - 20px;
203 y: root.height - self.height - 20px;
204 background: #eee;
205
206 states [
207 full-screen when self.full-screen : {
208 width: root.width - 35px;
209 height: 7/8 * root.height - 40px ;
210 }
211 ]
212 animate width, height { duration: 200ms; easing: ease; }
213
214 HorizontalLayout {
215 spacing: 10px;
216 padding: 10px;
217
218 for color-info[idx] in root.ink-levels : Rectangle {
219 background: white;
220
221 Rectangle {
222 width: parent.width;
223 height: parent.height * color-info.level;
224 y: parent.height - self.height;
225 background: color-info.color;
226
227 states [
228 inactive when root.active-page != 0 : {
229 height: 0phx;
230 out {
231 animate height { duration: 750ms; easing: ease-in-out; }
232 }
233 }
234 ]
235
236 }
237 }
238 }
239
240 TouchArea {
241 clicked => {
242 if (root.active-page == 0) {
243 parent.full-screen = !parent.full-screen;
244 }
245 }
246 }
247 }
248
249 CopyPage {
250 height: root.height - root.height / 8;
251 width: 100%;
252 y: root.height;
253
254 states [
255 active when root.active-page == 1: {
256 y: root.height / 8;
257 }
258 ]
259 }
260
261 FaxPage {
262 fax-number-erase => { root.fax-number-erase(); }
263 fax-send => { root.fax-send(); }
264
265 height: root.height - root.height / 8;
266 width: 100%;
267 y: root.height;
268 fax-number <=> root.fax-number;
269
270 states [
271 active when root.active-page == 2: {
272 y: root.height / 8;
273 }
274 ]
275 }
276
277 PrintPage {
278 height: root.height - root.height / 8;
279 width: 100%;
280 y: root.height;
281
282 states [
283 active when root.active-page == 3: {
284 y: root.height / 8;
285 }
286 ]
287 }
288
289 SettingsPage {
290 height: root.height - root.height / 8;
291 width: 100%;
292 y: root.height;
293
294 states [
295 active when root.active-page == 4: {
296 y: root.height / 8;
297 }
298 ]
299 }
300}
301