Skip to content

Commit e2b4501

Browse files
Add custom dropdown for temperatures
1 parent 1978adb commit e2b4501

6 files changed

Lines changed: 153 additions & 39 deletions

File tree

example_configs/simulator.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ host = "localhost"
77
port = 7125
88

99
[heater_presets]
10-
extruder = [ 200, 240, 280 ]
10+
extruder = [ 200, 240, 280, 290, 300, 310 ]
1111
heater_bed = [ 60, 70 ]
1212

1313
[ui]
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
import { Palette, ComboBox } from "std-widgets.slint";
2+
import { Constants } from "../constants.slint";
3+
import { VerticalScrollable, VerticalStart, VerticalScrollbar, VerticalStretch } from "vertical.slint";
4+
import { HorizontalStart } from "horizontal.slint";
5+
import { ActiveUi } from "../state.slint";
6+
7+
export component Dropdown inherits Rectangle {
8+
in property <string> text;
9+
in property <[string]> options;
10+
in property <length> element-length: 50px;
11+
out property <bool> is-open: false;
12+
13+
callback selected(option: string, index : int);
14+
15+
border-color: Palette.accent-background;
16+
border-width: 2px;
17+
border-radius: Constants.radius-md;
18+
19+
GridLayout {
20+
padding-left: Constants.padding;
21+
padding-right: Constants.padding;
22+
Text {
23+
text: text;
24+
vertical-alignment: center;
25+
horizontal-alignment: center;
26+
font-weight: Constants.font-weight-bold;
27+
}
28+
}
29+
30+
TouchArea {
31+
clicked => {
32+
popup.show();
33+
}
34+
}
35+
36+
popup := PopupWindow {
37+
x: 0;
38+
y: root.height;
39+
width: max(root.width, 100px);
40+
height: min(options.length * element-length, ActiveUi.height);
41+
42+
Rectangle {
43+
background: Palette.alternate-background;
44+
drop-shadow-color: #0000004C;
45+
drop-shadow-blur: 2px;
46+
drop-shadow-offset-y: 1px;
47+
border-radius: Constants.radius-md;
48+
border-color: Palette.accent-background;
49+
border-width: 1px;
50+
}
51+
52+
FocusScope {
53+
changed has-focus => {
54+
if !self.has-focus {
55+
popup.close();
56+
}
57+
}
58+
59+
VerticalStretch {
60+
padding: 0;
61+
spacing: 0;
62+
for i in options.length: Rectangle {
63+
bg := Rectangle {
64+
HorizontalStart {
65+
padding-left: Constants.padding;
66+
padding-right: Constants.padding;
67+
Text {
68+
text: options[i];
69+
color: Palette.alternate-foreground;
70+
vertical-alignment: center;
71+
}
72+
}
73+
74+
states [
75+
pressed when touch-area.pressed : {
76+
bg.background: Palette.selection-background;
77+
}
78+
]
79+
80+
touch-area := TouchArea {
81+
clicked => {
82+
selected(options[i], i);
83+
popup.close();
84+
}
85+
}
86+
}
87+
}
88+
}
89+
}
90+
}
91+
}
92+
93+
// For testing in the slint live preview
94+
component LivePreviewTest {
95+
width: 480px;
96+
height: 272px;
97+
98+
VerticalStart {
99+
Dropdown {
100+
text: "Test Test Test";
101+
options: ["One", "Two", "Three"];
102+
}
103+
Dropdown {
104+
text: "Long";
105+
options: ["One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten"];
106+
}
107+
108+
ComboBox {
109+
model: ["One", "Two", "Three", "Four", "Five", "Six", "Seven", "Eight", "Nine", "Ten"];
110+
}
111+
}
112+
}

ui/components/vertical.slint

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { StyleMetrics } from "std-widgets.slint";
1+
import { StyleMetrics, ScrollView } from "std-widgets.slint";
22
import { Constants } from "../constants.slint";
33

44
export component VerticalStart inherits VerticalLayout {
@@ -19,6 +19,15 @@ export component VerticalScrollable inherits Flickable {
1919
in property <length> list-padding <=> layout.padding;
2020
in property <length> list-spacing <=> layout.spacing;
2121

22+
layout := VerticalStart {
23+
@children
24+
}
25+
}
26+
27+
export component VerticalScrollbar inherits ScrollView {
28+
in property <length> list-padding <=> layout.padding;
29+
in property <length> list-spacing <=> layout.spacing;
30+
2231
layout := VerticalStart {
2332
@children
2433
}

ui/main.slint

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { ProgressIndicator, Button, StyleMetrics, Palette, ScrollView, Slider, ComboBox, TabWidget } from "std-widgets.slint";
22
import { VirtualKeyboardButton } from "virtual_keyboard.slint";
33
import "../AdwaitaSans-Regular.ttf";
4-
import { TemperatureSensors, DisplayStatus, PrinterAdministration, GcodeCommands, Filesystem, Utils, Webhooks, UiSettings } from "state.slint";
4+
import { TemperatureSensors, DisplayStatus, PrinterAdministration, GcodeCommands, Filesystem, Utils, Webhooks, UiSettings, ActiveUi } from "state.slint";
55
import { Heater, TemperatureSensor, MoonrakerFile } from "types.slint";
66
import { Icons } from "constants.slint";
77
import { Page } from "components/page.slint";
@@ -117,6 +117,14 @@ component MainView inherits Rectangle
117117
export component AppWindow inherits Window {
118118
default-font-family: "Adwaita Sans";
119119

120+
changed width => {
121+
ActiveUi.width = self.width;
122+
}
123+
124+
changed height => {
125+
ActiveUi.height = self.height;
126+
}
127+
120128
if Webhooks.moonraker_connected && Webhooks.klipper_state == "Ready" : MainView {
121129
width: 100%;
122130
height: 100%;

ui/pages/temperature-page.slint

Lines changed: 15 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { TemperatureEntry } from "../components/number-pad.slint";
88
import { Icons, Constants } from "../constants.slint";
99
import { VerticalStart, VerticalScrollable, VerticalStretch, VerticalCenter } from "../components/vertical.slint";
1010
import { HorizontalStretch } from "../components/horizontal.slint";
11+
import { Dropdown } from "../components/dropdown-select.slint";
1112

1213
export component InteractableTemperatureElement {
1314
in property <Heater> heater;
@@ -53,43 +54,21 @@ export component InteractableTemperatureElement {
5354
}
5455
}
5556

56-
Rectangle {
57-
horizontal-stretch: 0;
58-
// TODO: Don't abuse combobox for this.
59-
ComboBox {
60-
model: Utils.create_temperature_lists(heater.presets);
61-
width: 90%;
62-
63-
selected(value) => {
64-
if value == "Off" {
65-
TemperatureSensors.set_new_target_temperature(heater.name, 0);
66-
}
67-
else if value == "Set" {
68-
on_manual_entry(heater.name, friendly-name);
69-
}
70-
else {
71-
TemperatureSensors.set_new_target_temperature(heater.name, Utils.convert_temperature_back(value));
72-
}
57+
Dropdown {
58+
options: Utils.create_temperature_lists(heater.presets);
59+
border-color: Palette.selection-background;
60+
text: target > 0
61+
? heater.temperature + "°C -> " + target + "°C"
62+
: heater.temperature + "°C";
63+
selected(option, index) => {
64+
if option == "Off" {
65+
TemperatureSensors.set_new_target_temperature(heater.name, 0);
7366
}
74-
}
75-
76-
Rectangle {
77-
background: Palette.background;
78-
border-color: Palette.accent-background;
79-
border-width: 2px;
80-
border-radius: Constants.radius-md;
81-
82-
GridLayout {
83-
padding-left: Constants.padding;
84-
padding-right: Constants.padding;
85-
Text {
86-
text: target > 0
87-
? heater.temperature + "°C -> " + target + "°C"
88-
: heater.temperature + "°C";
89-
vertical-alignment: center;
90-
horizontal-alignment: right;
91-
font-weight: Constants.font-weight-bold;
92-
}
67+
else if option == "Set" {
68+
on_manual_entry(heater.name, friendly-name);
69+
}
70+
else {
71+
TemperatureSensors.set_new_target_temperature(heater.name, heater.presets[index - 1]);
9372
}
9473
}
9574
}

ui/state.slint

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,4 +90,10 @@ export global QuickActions
9090
{
9191
in-out property <[string]> quick-actions: ["Action One", "Action Two"];
9292
callback execute_quick_action(action: string);
93+
}
94+
95+
export global ActiveUi
96+
{
97+
in-out property <length> width: 480px;
98+
in-out property <length> height: 272px;
9399
}

0 commit comments

Comments
 (0)