1786023101

This commit is contained in:
2026-08-06 15:31:41 +02:00
parent 345a487f18
commit 4b30c6b4f6
13 changed files with 256 additions and 50 deletions

122
Cargo.lock generated
View File

@@ -127,6 +127,12 @@ version = "0.7.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56" checksum = "d3fb67a6e08acf24fdeccbac2cb6ac4305825bd1f117462e0e6f2f193345ad56"
[[package]]
name = "as-raw-xcb-connection"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "175571dd1d178ced59193a6fc02dde1b972eb0bc56c892cde9beeceac5bf0f6b"
[[package]] [[package]]
name = "as-slice" name = "as-slice"
version = "0.2.1" version = "0.2.1"
@@ -697,6 +703,7 @@ dependencies = [
"objc2 0.5.2", "objc2 0.5.2",
"objc2-app-kit 0.2.2", "objc2-app-kit 0.2.2",
"objc2-foundation 0.2.2", "objc2-foundation 0.2.2",
"x11-clipboard",
] ]
[[package]] [[package]]
@@ -809,6 +816,15 @@ version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5"
[[package]]
name = "ctor"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "83cf0d42651b16c6dfe68685716d18480d18a9c39c62d76e8cf3eb6ed5d8bcbf"
dependencies = [
"dtor",
]
[[package]] [[package]]
name = "cursor-icon" name = "cursor-icon"
version = "1.2.0" version = "1.2.0"
@@ -1016,6 +1032,12 @@ dependencies = [
"linux-raw-sys 0.9.4", "linux-raw-sys 0.9.4",
] ]
[[package]]
name = "dtor"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "edf234dd1594d6dd434a8fb8cada51ddbbc593e40e4a01556a0b31c62da2775b"
[[package]] [[package]]
name = "either" name = "either"
version = "1.17.0" version = "1.17.0"
@@ -1488,6 +1510,16 @@ dependencies = [
"slab", "slab",
] ]
[[package]]
name = "gethostname"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1bd49230192a3797a9a4d6abe9b3eed6f7fa4c8a8a4947977c6f80025f92cbd8"
dependencies = [
"rustix 1.1.4",
"windows-link",
]
[[package]] [[package]]
name = "getopts" name = "getopts"
version = "0.2.24" version = "0.2.24"
@@ -1570,6 +1602,7 @@ dependencies = [
"cgl", "cgl",
"dispatch2", "dispatch2",
"glutin_egl_sys", "glutin_egl_sys",
"glutin_glx_sys",
"glutin_wgl_sys", "glutin_wgl_sys",
"libloading", "libloading",
"objc2 0.6.4", "objc2 0.6.4",
@@ -1579,6 +1612,19 @@ dependencies = [
"once_cell", "once_cell",
"raw-window-handle", "raw-window-handle",
"windows-sys 0.52.0", "windows-sys 0.52.0",
"x11-dl",
]
[[package]]
name = "glutin-winit"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85edca7075f8fc728f28cb8fbb111a96c3b89e930574369e3e9c27eb75d3788f"
dependencies = [
"cfg_aliases",
"glutin",
"raw-window-handle",
"winit",
] ]
[[package]] [[package]]
@@ -1591,6 +1637,16 @@ dependencies = [
"windows-sys 0.52.0", "windows-sys 0.52.0",
] ]
[[package]]
name = "glutin_glx_sys"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a7bb2938045a88b612499fbcba375a77198e01306f52272e692f8c1f3751185"
dependencies = [
"gl_generator",
"x11-dl",
]
[[package]] [[package]]
name = "glutin_wgl_sys" name = "glutin_wgl_sys"
version = "0.6.1" version = "0.6.1"
@@ -1746,6 +1802,8 @@ dependencies = [
"copypasta", "copypasta",
"derive_more", "derive_more",
"futures", "futures",
"glutin",
"glutin-winit",
"i-slint-common", "i-slint-common",
"i-slint-core", "i-slint-core",
"i-slint-core-macros", "i-slint-core-macros",
@@ -4281,7 +4339,9 @@ version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aac18da81ebbf05109ab275b157c22a653bb3c12cf884450179942f81bcbf6c3" checksum = "aac18da81ebbf05109ab275b157c22a653bb3c12cf884450179942f81bcbf6c3"
dependencies = [ dependencies = [
"as-raw-xcb-connection",
"bytemuck", "bytemuck",
"fastrand",
"js-sys", "js-sys",
"ndk", "ndk",
"objc2 0.6.4", "objc2 0.6.4",
@@ -4291,10 +4351,13 @@ dependencies = [
"objc2-quartz-core 0.3.2", "objc2-quartz-core 0.3.2",
"raw-window-handle", "raw-window-handle",
"redox_syscall 0.5.18", "redox_syscall 0.5.18",
"rustix 1.1.4",
"tiny-xlib",
"tracing", "tracing",
"wasm-bindgen", "wasm-bindgen",
"web-sys", "web-sys",
"windows-sys 0.61.2", "windows-sys 0.61.2",
"x11rb",
] ]
[[package]] [[package]]
@@ -4554,6 +4617,19 @@ dependencies = [
"strict-num", "strict-num",
] ]
[[package]]
name = "tiny-xlib"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a90a0ca3ee6a69f2ad28fd11621a4c3f03b371f366be500b64df260c4ffbafb4"
dependencies = [
"as-raw-xcb-connection",
"ctor",
"libloading",
"pkg-config",
"tracing",
]
[[package]] [[package]]
name = "tinystr" name = "tinystr"
version = "0.8.3" version = "0.8.3"
@@ -5317,6 +5393,7 @@ dependencies = [
"atomic-waker", "atomic-waker",
"bitflags 2.13.1", "bitflags 2.13.1",
"block2 0.5.1", "block2 0.5.1",
"bytemuck",
"calloop 0.13.0", "calloop 0.13.0",
"cfg_aliases", "cfg_aliases",
"concurrent-queue", "concurrent-queue",
@@ -5332,6 +5409,7 @@ dependencies = [
"objc2-foundation 0.2.2", "objc2-foundation 0.2.2",
"objc2-ui-kit 0.2.2", "objc2-ui-kit 0.2.2",
"orbclient", "orbclient",
"percent-encoding",
"pin-project", "pin-project",
"raw-window-handle", "raw-window-handle",
"redox_syscall 0.4.1", "redox_syscall 0.4.1",
@@ -5344,6 +5422,8 @@ dependencies = [
"web-sys", "web-sys",
"web-time", "web-time",
"windows-sys 0.52.0", "windows-sys 0.52.0",
"x11-dl",
"x11rb",
"xkbcommon-dl", "xkbcommon-dl",
] ]
@@ -5390,6 +5470,48 @@ dependencies = [
"tap", "tap",
] ]
[[package]]
name = "x11-clipboard"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "662d74b3d77e396b8e5beb00b9cad6a9eccf40b2ef68cc858784b14c41d535a3"
dependencies = [
"libc",
"x11rb",
]
[[package]]
name = "x11-dl"
version = "2.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "38735924fedd5314a6e548792904ed8c6de6636285cb9fec04d5b1db85c1516f"
dependencies = [
"libc",
"once_cell",
"pkg-config",
]
[[package]]
name = "x11rb"
version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9993aa5be5a26815fe2c3eacfc1fde061fc1a1f094bf1ad2a18bf9c495dd7414"
dependencies = [
"as-raw-xcb-connection",
"gethostname",
"libc",
"libloading",
"once_cell",
"rustix 1.1.4",
"x11rb-protocol",
]
[[package]]
name = "x11rb-protocol"
version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ea6fc2961e4ef194dcbfe56bb845534d0dc8098940c7e5c012a258bfec6701bd"
[[package]] [[package]]
name = "xattr" name = "xattr"
version = "1.6.1" version = "1.6.1"

View File

@@ -11,5 +11,8 @@ framebuffer = "0.3.1"
linfb = { version = "0.2.1", default-features = false } linfb = { version = "0.2.1", default-features = false }
slint = { version = "1.17.1", default-features = false, features = ["std", "compat-1-2", "libm", "renderer-software", "unsafe-single-threaded"] } slint = { version = "1.17.1", default-features = false, features = ["std", "compat-1-2", "libm", "renderer-software", "unsafe-single-threaded"] }
[features]
dev = ["slint/backend-winit-x11"]
[build-dependencies] [build-dependencies]
slint-build = "1.17.1" slint-build = "1.17.1"

View File

@@ -1,20 +1,21 @@
mod rgba; mod rgba;
#[cfg(not(feature = "dev"))]
mod trekstor; mod trekstor;
use crate::trekstor::Trekstor;
slint::include_modules!(); slint::include_modules!();
fn main() -> Result<(), slint::PlatformError> { fn main() -> Result<(), slint::PlatformError> {
slint::platform::set_platform(Box::new(Trekstor::new())).expect("set platform"); #[cfg(not(feature = "dev"))]
slint::platform::set_platform(Box::new(crate::trekstor::Trekstor::new()))
.expect("set platform");
let ui = AppWindow::new()?; let ui = MainWindow::new()?;
let ui_handle = ui.as_weak(); // let ui_handle = ui.as_weak();
ui.on_request_increase_value(move || { // ui.on_request_increase_value(move || {
let ui = ui_handle.unwrap(); // let ui = ui_handle.unwrap();
ui.set_counter(ui.get_counter() + 1); // ui.set_counter(ui.get_counter() + 1);
}); // });
ui.run() ui.run()
} }

BIN
ui/images/blue-hint.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

BIN
ui/images/dial-frame.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 31 KiB

BIN
ui/images/dial-trim.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
ui/images/indicator.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 268 B

BIN
ui/images/light-hole.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 338 B

BIN
ui/images/light.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

BIN
ui/images/metal-dial.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 35 KiB

BIN
ui/images/metal-lights.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 57 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

View File

@@ -1,50 +1,130 @@
import { Button, VerticalBox, HorizontalBox, CheckBox } from "std-widgets.slint"; // Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT
export component AppWindow inherits Window { export global AppState {
default-font-size: 24px; out property <int> totalLights: 35;
in-out property<int> counter: 42; property <angle> degreesFilledWithLights: 360deg - (startAngle - endAngle);
callback request-increase-value(); out property <int> volume: (normalizeAngle(angle - startAngle) / degreesFilledWithLights) * (totalLights + 1);
HorizontalBox { out property <angle> startAngle: 120deg;
VerticalBox { out property <angle> endAngle: 60deg;
width: 50%; out property <angle> angleGap: startAngle - endAngle;
Text { in-out property <angle> angle: startAngle;
text: "Counter: \{root.counter}"; out property <length> elementRadius: 185px;
pure public function normalizeAngle(angle: angle) -> angle {
return (angle + 360deg).mod(360deg);
}
}
export component Light {
in property <int> index;
property <angle> gap: (360deg - (AppState.startAngle - AppState.endAngle)) / AppState.totalLights;
property <angle> angle: (index * gap) + AppState.startAngle;
property <bool> lightOn: index <= AppState.volume;
x: AppState.elementRadius * angle.cos();
y: AppState.elementRadius * angle.sin();
width: 0;
height: 0;
states [
lightOn when root.lightOn: {
blueLed.opacity: 0.6;
in {
animate blueLed.opacity {
duration: 100ms;
easing: ease-in-sine;
}
} }
Button { out {
text: "Increase value"; animate blueLed.opacity {
clicked => { duration: 600ms;
root.request-increase-value(); easing: ease-out-sine;
} }
} }
} }
VerticalBox { ]
width: 50%;
alignment: start; Image {
CheckBox { source: @image-url("images/light-hole.png");
text: "Armory Light"; }
}
CheckBox { blueLed := Image {
text: "Bedroom Light"; source: @image-url("images/light.png");
} opacity: 0;
CheckBox { }
text: "Hallway Light"; }
}
CheckBox { export component MainWindow inherits Window {
text: "Kitchen Light"; preferred-width: 500px;
} preferred-height: 500px;
CheckBox { background: #1e1d27;
text: "Living Room Light";
} base := Image {
CheckBox { source: @image-url("images/dial-frame.png");
text: "Shower Light"; }
}
CheckBox { ta := TouchArea {
text: "Utilities Light"; property <length> centerX: self.width / 2;
enabled: false; property <length> centerY: self.height / 2;
} property <length> relativeX: ta.mouse-x - centerX;
CheckBox { property <length> relativeY: ta.mouse-y - centerY;
text: "WC Light"; property <angle> lastAngle;
property <bool> hovering: Math.pow(relativeX / 1px, 2) + Math.pow(relativeY / 1px, 2) < metalKnob.width / 2px * metalKnob.height / 2px;
property <bool> touching: false;
width: base.width;
height: base.height;
mouse-cursor: touching ? grabbing : hovering ? grab : default;
pointer-event(event) => {
let newAngle = AppState.normalizeAngle(atan2(relativeY / 1px, relativeX / 1px));
if event.kind == PointerEventKind.down {
if hovering {
touching = true;
lastAngle = newAngle;
}
} else if event.kind == PointerEventKind.up {
touching = false;
} else if event.kind == PointerEventKind.move {
if touching {
let nextAngle = AppState.normalizeAngle(AppState.angle - lastAngle + newAngle);
// Check if the new angle is within the start and end angles
if nextAngle >= AppState.startAngle || nextAngle <= AppState.endAngle {
AppState.angle = nextAngle;
}
lastAngle = newAngle;
}
} }
} }
} }
metalKnob := Image {
source: @image-url("images/metal-dial.png");
transform-rotation: AppState.angle;
}
Image {
source: @image-url("images/metal-lights.png");
}
Image {
source: @image-url("images/dial-trim.png");
}
Rectangle {
x: parent.width / 2;
y: parent.height / 2;
Image {
property <float> r: 0.5;
x: r * root.width / 2 * AppState.angle.cos();
y: r * root.height / 2 * AppState.angle.sin();
source: @image-url("images/indicator.png");
}
for i in AppState.totalLights + 1: Light {
index: i;
}
}
} }