slint/demos/home-automation/ui/components/dial/dial.slint
Nigel Breslaw 287a976bd0
Updated Home Automation demo (#7890)
Adds:

Kiosk mode. After 30 seconds demo will cycle through views.
Landscape support.
{ API } to work with the new data tab in live-preview.
SW Renderer support (use of PNG images over gradients, Rectangles, shadows, etc).
Removes side-bar and theming.
Refreshed look.
2025-03-21 19:04:58 +02:00

90 lines
3 KiB
Text

// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT
import { Palette } from "../../common.slint";
export global DialState {
out property <int> totalLights: 60;
out property <angle> degreesFilledWithLights: 360deg - (startAngle - endAngle);
out property <angle> startAngle: 104deg;
out property <angle> endAngle: -startAngle;
in-out property <length> elementRadius: 120px;
}
export component Dial {
pure public function normalizeAngle(angle: angle) -> angle {
return (angle + 360deg).mod(360deg);
}
in property <bool> interactive: true;
property <bool> moving: ta.firstTouch;
in-out property <angle> dialAngle: DialState.startAngle;
out property <int> volume: ((dialAngle - DialState.startAngle) / DialState.degreesFilledWithLights) * DialState.totalLights;
width: 212px;
height: 213px;
knob := Rectangle {
base := Rectangle {
Image {
x: 0px;
y: 9px;
source: @image-url("../../images/dial-frame.png");
}
Image {
source: @image-url("../../images/lines.png");
colorize: Palette.dark-color-scheme ? #fff : #000;
rotation-angle: root.dialAngle;
width: self.source.width * 0.55 * 1px;
height: self.source.height * 0.55 * 1px;
opacity: 0.03;
}
ta := TouchArea {
property <length> centerX: self.width / 2;
property <length> centerY: self.height / 2;
property <length> relativeX;
property <length> relativeY;
property <angle> newAngle;
property <angle> deltaDegrees;
property <bool> firstTouch: false;
width: parent.width;
height: parent.height;
enabled: root.interactive;
changed pressed => {
if !self.pressed {
firstTouch = false;
}
}
moved => {
relativeX = ta.mouse-x - centerX;
relativeY = ta.mouse-y - centerY;
newAngle = normalizeAngle(atan2(relativeY / 1px, relativeX / 1px));
if !firstTouch {
firstTouch = true;
deltaDegrees = normalizeAngle(root.dialAngle - newAngle);
} else {
root.dialAngle = normalizeAngle(deltaDegrees + newAngle).clamp(DialState.startAngle, 260deg);
}
}
}
}
}
Rectangle {
width: 1px;
height: 1px;
x: 106px;
y: 105px;
Rectangle {
width: 0px;
height: 0px;
x: 55px * root.dialAngle.cos();
y: 55px * root.dialAngle.sin();
Image {
source: @image-url("../../images/notch.png");
}
}
}
}