1// Copyright © 2025 David Haig
2// SPDX-License-Identifier: MIT
3
4export global Globals {
5 in property <bool> hardware-user-btn-pressed;
6 callback toggle-btn(bool);
7}
8
9global Palette {
10 out property <color> neutralSecondaryAlt: #8a8886;
11 out property <color> neutralLight: #edebe9;
12 out property <color> white: #ffffff;
13 out property <color> black: #000000;
14 out property <color> neutralDark: #201f1e;
15}
16
17export global Theme {
18 out property <color> page-background-color: Palette.white;
19 out property <color> text-foreground-color: Palette.black;
20 out property <length> font-size-standard: 24px;
21 out property <length> page-width: 800px;
22 out property <length> page-height: 480px;
23}
24
25export component Button {
26 callback clicked;
27 in property <string> text <=> text.text;
28 out property <bool> pressed: touch.pressed;
29 in property <bool> checkable;
30 in-out property <bool> checked;
31 in property <length> font-size <=> text.font-size;
32 in property <color> background: Palette.white;
33 Rectangle {
34 border-width: 1px;
35 border-radius: 2px;
36 border-color: Palette.neutralSecondaryAlt;
37 background: (touch.pressed || root.checked) ? Palette.neutralLight : root.background;
38 }
39
40 horizontal-stretch: 0;
41 vertical-stretch: 0;
42 min-height: max(32px, l.min-height);
43 l := HorizontalLayout {
44 padding-left: 10px;
45 padding-right: 10px;
46 padding-top: 3px;
47 padding-bottom: 3px;
48 text := Text {
49 color: Palette.neutralDark;
50 horizontal-alignment: center;
51 vertical-alignment: center;
52 font-size: Theme.font-size-standard;
53 }
54 }
55
56 touch := TouchArea {
57 clicked => {
58 if (root.checkable) {
59 root.checked = !root.checked;
60 }
61 root.clicked();
62 }
63 }
64
65 @children
66}
67
68export component Toggle inherits Rectangle {
69 callback clicked();
70 in-out property <bool> on;
71 width: 100px;
72 height: 40px;
73
74 Rectangle {
75 width: 100px;
76 height: 40px;
77 background: on ? blue : gray;
78 animate background {
79 duration: 100ms;
80 easing: ease;
81 }
82 border-radius: 20px;
83
84 Text {
85 text: on ? "On" : "Off";
86 x: on ? 8px : parent.width - 50px;
87 color: white;
88 font-size: Theme.font-size-standard;
89 }
90
91 Rectangle {
92 width: parent.height - 4px;
93 height: parent.height - 4px;
94 x: on ? parent.width - (parent.height - 2px) : 2px;
95 animate x {
96 duration: 100ms;
97 easing: ease;
98 }
99 y: 2px;
100 background: white;
101 border-radius: (parent.height - 4px) / 2;
102 }
103 }
104
105 TouchArea {
106 clicked => {
107 on = !on;
108 root.clicked();
109 }
110 }
111}
112