slint/demos/home-automation/ui/components/general/doors.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

173 lines
5 KiB
Text

// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT
import { Dial, DialState } from "../dial/dial.slint";
import { DialLights } from "../dial/dialLights.slint";
import { Palette } from "../../common.slint";
export enum DoorState { closed, open }
export component Doors {
property <brush> notch-border-color: #0000005d;
in-out property <bool> demo-locked: true;
in-out property <DoorState> initial-door-state: closed;
property <DoorState> target-door-state: initial-door-state;
callback unlockDemo();
callback doorsOpened();
callback doorsOpening();
callback doorsClosed();
width: 100%;
height: 100%;
unlockDemo => {
demo-locked = false;
target-door-state = DoorState.open;
doorsOpening();
}
Timer {
interval: 1ms;
triggered => {
if initial-door-state == DoorState.open && demo-locked {
target-door-state = DoorState.closed;
initial-door-state = DoorState.closed;
}
self.running = false;
}
}
touch-catcher := Rectangle {
TouchArea { }
}
leftDoor := Rectangle {
x: -30px;
width: parent.width / 2 + 70px;
height: 100%;
background: Palette.doors-background;
border-width: 5px;
border-color: notch-border-color;
border-radius: 30px;
clip: true;
changed x => {
if root.initial-door-state == DoorState.closed && self.x <= -leftDoor.width {
root.doorsOpened();
}
if self.x == -60px {
root.doorsClosed();
}
}
Image {
x: 0;
y: 0;
width: self.source.width * 2 * 1px;
height: self.source.height * 2 * 1px;
source: @image-url("../../images/logo-fragment.png");
opacity: Palette.dark-color-scheme ? 0.08 : 0.02;
}
DialLights {
x: parent.width - 125px;
volume: dial.volume;
}
}
states [
doorsOpen when target-door-state == DoorState.open: {
leftDoor.x: -leftDoor.width;
rightDoor.x: root.width + 85px;
dial.dialAngle: DialState.startAngle;
in {
animate rightDoor.x, leftDoor.x {
duration: 800ms;
easing: ease-in-expo;
}
}
}
doorsClosed when target-door-state == DoorState.closed: {
leftDoor.x: -30px;
rightDoor.x: root.width / 2;
in {
animate rightDoor.x, leftDoor.x {
duration: 800ms;
easing: ease-in-expo;
}
}
}
]
rightDoor := Rectangle {
property <length> notch-width: 220px;
property <length> notch-border: 4px;
property <length> notch-indent: 20px;
x: parent.width / 2;
width: parent.width / 2 + 30px;
height: 100%;
Rectangle {
background: Palette.doors-background;
clip: true;
border-radius: 30px;
Image {
x: parent.width - self.width;
y: parent.height - self.height;
width: self.source.width * 2 * 1px;
height: self.source.height * 2 * 1px;
source: @image-url("../../images/logo-fragment.png");
rotation-angle: 180deg;
opacity: Palette.dark-color-scheme ? 0.08 : 0.02;
}
}
Rectangle {
border-width: notch-border;
border-color: notch-border-color;
border-radius: 30px;
}
Rectangle {
x: -(notch-width / 2) + notch-border;
width: (notch-width / 2);
// - notch-indent ;
height: notch-width;
clip: true;
Rectangle {
x: notch-indent;
y: 0;
width: notch-width;
height: self.width;
Rectangle {
width: notch-width;
height: self.width;
border-radius: self.width / 2;
background: Palette.doors-notch-background;
border-width: notch-border;
border-color: notch-border-color;
}
}
}
Image {
x: 20px;
y: (parent.height / 2) - 125px;
source: @image-url("../../images/open-lock.svg");
colorize: Palette.dark-color-scheme ? #000 : #6f6f6f;
width: 15px;
height: self.width;
opacity: 0.4;
}
dial := Dial {
x: -82px;
y: (parent.height - self.height) / 2 - 1px;
interactive: root.demo-locked;
changed volume => {
if self.volume >= 60 {
root.unlockDemo()
}
}
}
}
}