1786023101
122
Cargo.lock
generated
@@ -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"
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
19
src/main.rs
@@ -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
|
After Width: | Height: | Size: 5.6 KiB |
BIN
ui/images/dial-frame.png
Normal file
|
After Width: | Height: | Size: 31 KiB |
BIN
ui/images/dial-trim.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
BIN
ui/images/indicator.png
Normal file
|
After Width: | Height: | Size: 268 B |
BIN
ui/images/light-hole.png
Normal file
|
After Width: | Height: | Size: 338 B |
BIN
ui/images/light.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
BIN
ui/images/metal-dial.png
Normal file
|
After Width: | Height: | Size: 35 KiB |
BIN
ui/images/metal-lights.png
Normal file
|
After Width: | Height: | Size: 57 KiB |
BIN
ui/images/slint-logo-square-dark.png
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
162
ui/main.slint
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||