Add new home-automation demo (#6654)

This commit is contained in:
Nigel Breslaw 2024-10-25 15:55:03 +02:00 committed by GitHub
parent 04edafe121
commit e0557536a6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
104 changed files with 4117 additions and 0 deletions

View file

@ -139,6 +139,10 @@ Files: examples/orbit-animation/images/*.png examples/orbit-animation/images/*.s
Copyright: Copyright © SixtyFPS GmbH <info@slint.dev>
License: MIT
Files: demos/home-automation/ui/images/*.png demos/home-automation/ui/images/*.svg demos/home-automation/ui/images/*.jpg
Copyright: Copyright © SixtyFPS GmbH <info@slint.dev>
License: MIT
Files: examples/fancy-switches/images/*.png examples/fancy-switches/images/*.svg
Copyright: Copyright © SixtyFPS GmbH <info@slint.dev>
License: MIT

View file

@ -29,6 +29,7 @@ members = [
'examples/virtual_keyboard/rust',
'examples/carousel/rust',
'demos/energy-monitor',
'demos/home-automation/rust',
'examples/mcu-board-support',
'examples/uefi-demo',
'examples/weather-demo',

View file

@ -0,0 +1,11 @@
<!-- Copyright © SixtyFPS GmbH <info@slint.dev> ; SPDX-License-Identifier: MIT -->
### `Home Automation Demo`
A fictional user interface for the touch screen of a printer
| `.slint` Design | Rust Source | C++ Source | Node Source | Online wasm Preview | Open in SlintPad |
| --- | --- | --- | --- | --- | --- |
| [`ui.slint`](./ui/demo.slint) | [`main.rs`](./rust/main.rs) | | [`main.js`](./node/main.js) | [Online simulation](https://slint.dev/snapshots/master/demos/home-automation/) | [Preview in Online Code Editor](https://slint.dev/snapshots/master/editor?load_url=https://raw.githubusercontent.com/slint-ui/slint/master/demos/home-automation/ui/demo.slint) |
![Screenshot of the Home Automation Demo](https://github.com/user-attachments/assets/3856b9cf-e7c7-478e-8efe-0f7e8aa43e85 "Home Automation Demo")

View file

@ -0,0 +1,10 @@
#!/usr/bin/env node
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT
import * as slint from "slint-ui";
const ui = slint.loadFile("../ui/demo.slint");
const window = new ui.AppWindow();
await window.run();

View file

@ -0,0 +1,18 @@
{
"name": "home_automation",
"version": "1.9.0",
"main": "main.js",
"type": "module",
"dependencies": {
"@biomejs/biome": "1.9.3",
"slint-ui": "../../../api/node"
},
"scripts": {
"start": "node .",
"check": "biome check",
"format": "biome format",
"format:fix": "biome format --write",
"lint": "biome lint",
"lint:fix": "biome lint --fix"
}
}

View file

@ -0,0 +1,27 @@
# Copyright © SixtyFPS GmbH <info@slint.dev>
# SPDX-License-Identifier: MIT
[package]
name = "home-automation"
version = "1.9.0"
authors = ["Slint Developers <info@slint.dev>"]
edition = "2021"
publish = false
license = "MIT"
[[bin]]
path = "main.rs"
name = "home-automation"
[lib]
crate-type = ["lib", "cdylib"]
path = "lib.rs"
name = "home_automation_lib"
[dependencies]
slint = { path = "../../../api/rs/slint" }
[target.'cfg(target_arch = "wasm32")'.dependencies]
wasm-bindgen = { version = "0.2" }
web-sys = { version = "0.3", features=["console"] }
console_error_panic_hook = "0.1.5"

View file

@ -0,0 +1,40 @@
<!DOCTYPE html>
<!-- Copyright © SixtyFPS GmbH <info@slint.dev> -->
<!-- SPDX-License-Identifier: MIT -->
<html>
<head>
<style>
#loading {
margin-top: 20px;
text-align: center;
}
.overlay {
position: absolute;
display: flex;
top: 0;
width: 100%;
}
canvas {
top: 0;
padding-left: 0;
padding-right: 0;
margin-left: auto;
margin-right: auto;
margin-top: 20px;
display: block;
}
</style>
</head>
<body>
<div id="loading">Loading...</div>
<div class="overlay">
<!-- canvas required by the Slint runtime -->
<canvas id="canvas" data-slint-auto-resize-to-preferred="true" unselectable="on"></canvas>
<script type="module">
// import the generated file.
import init from "./pkg/home_automation.js";
init();
</script>
</div>
</body>
</html>

View file

@ -0,0 +1,19 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT
#[cfg(target_arch = "wasm32")]
use wasm_bindgen::prelude::*;
slint::slint! {
export { AppWindow } from "../ui/demo.slint";
}
#[cfg_attr(target_arch = "wasm32", wasm_bindgen(start))]
pub fn main() {
// This provides better error messages in debug mode.
// It's disabled in release mode so it doesn't bloat up the file size.
#[cfg(all(debug_assertions, target_arch = "wasm32"))]
console_error_panic_hook::set_once();
AppWindow::new().expect("AppWindow::new() failed").run().expect("AppWindow::run() failed");
}

View file

@ -0,0 +1,6 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT
fn main() {
home_automation_lib::main();
}

View file

@ -0,0 +1,451 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT
export enum WidgetType { lamp, appliance, overhead, info, graph, control, music, hvac, camera, dishwasher, microwave, alarm, weatherInfo, timeInfo, powerInfo }
struct Widget {
id: string,
type: WidgetType,
visible: bool,
}
export struct ComponentData {
id: string,
x: int,
y: int,
width: int,
height: int,
visible: bool,
background: brush
}
export struct DataGroup {
id: string,
components: [ComponentData]
}
export global AppState {
in-out property <bool> first-run: true;
in-out property <int> current-page: 0; // Don't use this directly. Use target-page instead.
in-out property <int> target-page: 0;
out property <DataGroup> current-layout-data: pageData[current-page];
in property <length> window-width;
in property <length> window-height;
out property <float> x-scale: window-width / 1920px;
out property <float> y-scale: window-height / 1080px;
in-out property <bool> showing-full-screen: false;
out property <int> full-screen-index: -1;
in-out property <int> last-selected-index: -1;
callback showFullScreen(int);
showFullScreen(index)=> {
full-screen-index = index;
if full-screen-index != -1 {
last-selected-index = index;
showing-full-screen = true;
}
}
out property <string> default-font-family;
out property <[{id: string, name: string, type: WidgetType }]> component-details: [
{ id: "lamp1", name: "His Nightstand", type: WidgetType.lamp },
{ id: "lamp2", name: "Her Nightstand", type: WidgetType.lamp },
{ id: "lamp3", name: "Stove", type: WidgetType.lamp },
{ id: "lamp4", name: "Front Entry", type: WidgetType.lamp },
{ id: "lamp5", name: "Back Porch", type: WidgetType.lamp },
{ id: "lamp6", name: "Yard", type: WidgetType.lamp },
{ id: "lamp7", name: "Hall Lights", type: WidgetType.lamp },
{ id: "appliance1",name: "Dishwasher", type: WidgetType.dishwasher },
{ id: "appliance2",name: "Microwave", type: WidgetType.microwave },
{ id: "overhead1", name: "Dining Area", type: WidgetType.overhead, },
{ id: "overhead2", name: "Kitchen Island", type: WidgetType.overhead, },
{ id: "overhead3", name: "Stove", type: WidgetType.overhead, },
{ id: "overhead4", name: "Walk-In Closet", type: WidgetType.overhead, },
{ id: "overhead5",name: "En-Suite Bathroom", type: WidgetType.overhead, },
{ id: "overhead6",name: "Master Bedroom 1", type: WidgetType.overhead, },
{ id: "overhead7",name: "Master Bedroom 2", type: WidgetType.overhead, },
{ id: "overhead8",name: "Master Bedroom 3", type: WidgetType.overhead, },
{ id: "overhead9",name: "Master Bedroom 4", type: WidgetType.overhead, },
{ id: "overhead10",name: "Office", type: WidgetType.overhead, },
{ id: "overhead11",name: "Basement", type: WidgetType.overhead, },
{ id: "info1", name:"Date-Time",type: WidgetType.timeInfo },
{ id: "info2", name:"Weather",type: WidgetType.weatherInfo },
{ id: "info3", name:"Power Usage",type: WidgetType.powerInfo },
{ id: "graph1", name:"Humidity",type: WidgetType.graph },
{ id: "graph2", name:"Pressure",type: WidgetType.graph },
{ id: "control1", name:"Music",type: WidgetType.music },
{ id: "control2", name:"Front Camera",type: WidgetType.camera },
{ id: "control3", name:"Alarm",type: WidgetType.alarm },
{ id: "control4", name:"Heating / Air Conditioning",type: WidgetType.hvac },
];
out property <[DataGroup]> pageData: [
{
id: "house",
components: [
{ id: "lamp1", x: 890.063, y: 620.552, width: 140.693, height: 140.693, background: #ffbe00, visible: false },
{ id: "lamp2", x: 890.063, y: 620.552, width: 140.693, height: 140.693, background: #ffbe00, visible: false },
{ id: "lamp3", x: 890.063, y: 620.552, width: 140.693, height: 140.693, background: #ffbe00, visible: false },
{ id: "lamp4", x: 36.41, y: 157.445, width: 435.0, height: 314.0, background: #ffbe00, visible: true },
{ id: "lamp5", x: 507.41, y: 157.445, width: 435.0, height: 314.0, background: #ffbe00, visible: true },
{ id: "lamp6", x: 978.41, y: 157.445, width: 435.0, height: 314.0, background: #ffbe00, visible: true },
{ id: "lamp7", x: 915.453, y: 645.893, width: 89.914, height: 90.012, background: #ffbe00, visible: false },
{ id: "appliance1", x: 890.063, y: 620.552, width: 140.693, height: 140.693, background: #b5b5b5, visible: false },
{ id: "appliance2", x: 890.063, y: 620.552, width: 140.693, height: 140.693, background: #b5b5b5, visible: false },
{ id: "overhead1", x: 915.453, y: 645.941, width: 89.914, height: 89.914, background: #fff291, visible: false },
{ id: "overhead2", x: 915.453, y: 645.941, width: 89.914, height: 89.914, background: #fff291, visible: false },
{ id: "overhead3", x: 915.453, y: 645.941, width: 89.914, height: 89.914, background: #fff291, visible: false },
{ id: "overhead4", x: 915.453, y: 645.941, width: 89.914, height: 89.914, background: #fff291, visible: false },
{ id: "overhead5", x: 915.453, y: 645.941, width: 89.914, height: 89.914, background: #fff291, visible: false },
{ id: "overhead6", x: 839.284, y: 645.941, width: 242.252, height: 89.914, background: #fff291, visible: false },
{ id: "overhead7", x: 915.453, y: 645.941, width: 89.914, height: 89.914, background: #fff291, visible: false },
{ id: "overhead8", x: 915.453, y: 645.941, width: 89.914, height: 89.914, background: #fff291, visible: false },
{ id: "overhead9", x: 915.453, y: 645.941, width: 89.914, height: 89.914, background: #fff291, visible: false },
{ id: "overhead10", x: 915.453, y: 645.941, width: 89.914, height: 89.914, background: #fff291, visible: false },
{ id: "overhead11", x: 915.453, y: 645.941, width: 89.914, height: 89.914, background: #fff291, visible: false },
{ id: "info1", x: 1449.41, y: 854.445, width: 435.0, height: 121.0, background: #00acff, visible: true },
{ id: "info2", x: 1449.41, y: 697.445, width: 435.0, height: 121.0, background: #00acff, visible: true },
{ id: "info3", x: 1449.41, y: 540.445, width: 435.0, height: 121.0, background: #00acff, visible: true },
{ id: "graph1", x: 890.063, y: 620.552, width: 140.693, height: 140.693, background: #ba00ff, visible: false },
{ id: "graph2", x: 864.674, y: 620.552, width: 191.473, height: 140.693, background: #ba00ff, visible: false },
{ id: "control1", x: 1449.41, y: 36.445, width: 435.0, height: 471.0, background: #00bf1d, visible: true },
{ id: "control2", x: 36.41, y: 507.445, width: 435.0, height: 471.0, background: #00bf1d, visible: true },
{ id: "control3", x: 507.41, y: 507.445, width: 435.0, height: 471.0, background: #00bf1d, visible: true },
{ id: "control4", x: 978.41, y: 507.445, width: 435.0, height: 471.0, background: #00bf1d, visible: true },
{ id: "filter", x: 36.41, y: 1007.85, width: 1848.0, height: 72.6, background: #8d8d8d, visible: true },
{ id: "nav", x: 36.41, y: 0.145, width: 1377.0, height: 121.0, background: #8d8d8d, visible: true },
]
},
{
id: "kitchen",
components: [
{ id: "lamp1", x: 430.614, y: 398.545, width: 121.0, height: 121.0, background: #ffbe00, visible: false },
{ id: "lamp2", x: 430.614, y: 398.545, width: 121.0, height: 121.0, background: #ffbe00, visible: false },
{ id: "lamp3", x: 430.614, y: 398.545, width: 121.0, height: 121.0, background: #ffbe00, visible: false },
{ id: "lamp4", x: 430.614, y: 398.545, width: 121.0, height: 121.0, background: #ffbe00, visible: false },
{ id: "lamp5", x: 430.614, y: 398.545, width: 121.0, height: 121.0, background: #ffbe00, visible: false },
{ id: "lamp6", x: 430.614, y: 398.545, width: 121.0, height: 121.0, background: #ffbe00, visible: false },
{ id: "lamp7", x: 452.449, y: 420.339, width: 77.329, height: 77.412, background: #ffbe00, visible: false },
{ id: "appliance1", x: 507.642, y: 157.445, width: 435.0, height: 471.0, background: #b5b5b5, visible: true },
{ id: "appliance2", x: 36.642, y: 157.445, width: 435.0, height: 471.0, background: #b5b5b5, visible: true },
{ id: "overhead1", x: 36.642, y: 664.445, width: 278.0, height: 314.0, background: #fff291, visible: true },
{ id: "overhead2", x: 350.642, y: 664.445, width: 278.0, height: 314.0, background: #fff291, visible: true },
{ id: "overhead3", x: 664.642, y: 664.445, width: 278.0, height: 314.0, background: #fff291, visible: true },
{ id: "overhead4", x: 452.449, y: 420.381, width: 77.329, height: 77.329, background: #fff291, visible: false },
{ id: "overhead5", x: 452.449, y: 420.381, width: 77.329, height: 77.329, background: #fff291, visible: false },
{ id: "overhead6", x: 386.942, y: 420.381, width: 208.343, height: 77.329, background: #fff291, visible: false },
{ id: "overhead7", x: 452.449, y: 420.381, width: 77.329, height: 77.329, background: #fff291, visible: false },
{ id: "overhead8", x: 452.449, y: 420.381, width: 77.329, height: 77.329, background: #fff291, visible: false },
{ id: "overhead9", x: 452.449, y: 420.381, width: 77.329, height: 77.329, background: #fff291, visible: false },
{ id: "overhead10", x: 452.449, y: 420.381, width: 77.329, height: 77.329, background: #fff291, visible: false },
{ id: "overhead11", x: 452.449, y: 420.381, width: 77.329, height: 77.329, background: #fff291, visible: false },
{ id: "info1", x: 978.642, y: 700.445, width: 435.0, height: 121.0, background: #00acff, visible: true },
{ id: "info2", x: 978.642, y: 857.445, width: 435.0, height: 121.0, background: #00acff, visible: true },
{ id: "info3", x: 430.614, y: 442.217, width: 121.0, height: 33.657, background: #00acff, visible: false },
{ id: "graph1", x: 978.642, y: 157.445, width: 435.0, height: 507.0, background: #ba00ff, visible: true },
{ id: "graph2", x: 408.778, y: 398.545, width: 164.671, height: 121.0, background: #ba00ff, visible: false },
{ id: "control1", x: 1449.64, y: 36.445, width: 435.0, height: 942.0, background: #00bf1d, visible: true },
{ id: "control2", x: 430.614, y: 420.381, width: 121.0, height: 77.329, background: #00bf1d, visible: false },
{ id: "control3", x: 430.614, y: 420.381, width: 121.0, height: 77.329, background: #00bf1d, visible: false },
{ id: "control4", x: 1259.29, y: 628.145, width: 121.0, height: 121.0, background: #00ac0f, visible: false },
{ id: "filter", x: 36.642, y: 1007.85, width: 1848.0, height: 72.6, background: #8d8d8d, visible: true },
{ id: "nav", x: 36.642, y: 0.445, width: 1377.0, height: 121.0, background: #8d8d8d, visible: true },
]
},
{
id: "bedroom1",
components: [
{ id: "lamp1", x: 36.86, y: 543.745, width: 435.0, height: 435.0, background: #ffbe00, visible: true },
{ id: "lamp2", x: 978.86, y: 543.745, width: 435.0, height: 435.0, background: #ffbe00, visible: true },
{ id: "lamp3", x: 852.921, y: 687.395, width: 105.071, height: 105.071, background: #ffbe00, visible: false },
{ id: "lamp4", x: 852.921, y: 687.395, width: 105.071, height: 105.071, background: #ffbe00, visible: false },
{ id: "lamp5", x: 852.921, y: 687.395, width: 105.071, height: 105.071, background: #ffbe00, visible: false },
{ id: "lamp6", x: 892.968, y: 685.715, width: 65.233, height: 64.659, background: #ffbe00, visible: false },
{ id: "lamp7", x: 891.162, y: 691.453, width: 64.824, height: 64.426, background: #ffbe00, visible: false },
{ id: "appliance1", x: 852.921, y: 687.395, width: 105.071, height: 105.071, background: #b5b5b5, visible: false },
{ id: "appliance2", x: 852.921, y: 687.395, width: 105.071, height: 105.071, background: #b5b5b5, visible: false },
{ id: "overhead1", x: 477.76, y: 664.745, width: 278.0, height: 121.0, background: #fff291, visible: false },
{ id: "overhead2", x: 791.76, y: 664.745, width: 278.0, height: 121.0, background: #fff291, visible: false },
{ id: "overhead3", x: 1105.76, y: 664.745, width: 278.0, height: 121.0, background: #fff291, visible: false },
{ id: "overhead4", x: 1135.86, y: 354.977, width: 277.716, height: 152.469, background: #fff291, visible: true },
{ id: "overhead5", x: 822.144, y: 354.977, width: 277.716, height: 152.469, background: #fff291, visible: true },
{ id: "overhead6", x: 507.86, y: 354.977, width: 277.716, height: 152.469, background: #fff291, visible: true },
{ id: "overhead7", x: 507.86, y: 157.145, width: 278.0, height: 152.469, background: #fff291, visible: true },
{ id: "overhead8", x: 1135.86, y: 157.145, width: 277.716, height: 152.469, background: #fff291, visible: true },
{ id: "overhead9", x: 821.86, y: 157.145, width: 275.274, height: 152.469, background: #fff291, visible: true },
{ id: "overhead10", x: 871.882, y: 706.356, width: 67.149, height: 67.149, background: #fff291, visible: false },
{ id: "overhead11", x: 871.882, y: 706.356, width: 67.149, height: 67.149, background: #fff291, visible: false },
{ id: "info1", x: 880.956, y: 733.116, width: 49.0, height: 13.63, background: #00acff, visible: false },
{ id: "info2", x: 880.956, y: 733.116, width: 49.0, height: 13.63, background: #00acff, visible: false },
{ id: "info3", x: 852.921, y: 725.318, width: 105.071, height: 29.227, background: #00acff, visible: false },
{ id: "graph1", x: 773.46, y: 507.445, width: 435.0, height: 435.0, background: #ba00ff, visible: false },
{ id: "graph2", x: 833.96, y: 687.395, width: 142.994, height: 105.071, background: #ba00ff, visible: false },
{ id: "control1", x: 1449.86, y: 36.445, width: 435.0, height: 942.0, background: #00bf1d, visible: true },
{ id: "control2", x: 36.86, y: 157.145, width: 435.0, height: 350.3, background: #00bf1d, visible: true },
{ id: "control3", x: 852.921, y: 706.356, width: 105.071, height: 67.149, background: #00bf1d, visible: false },
{ id: "control4", x: 852.921, y: 687.395, width: 105.071, height: 105.071, background: #00ac0f, visible: false },
{ id: "filter", x: 36.86, y: 1007.85, width: 1848.0, height: 72.6, background: #8d8d8d, visible: true },
{ id: "nav", x: 36.86, y: 0.445, width: 1377.0, height: 121.0, background: #8d8d8d, visible: true },
]
},
{
id: "office",
components: [
{ id: "lamp1", x: 181.594, y: 362.545, width: 435.0, height: 435.0, background: #ffbe00, visible: false },
{ id: "lamp2", x: 1123.59, y: 362.545, width: 435.0, height: 435.0, background: #ffbe00, visible: false },
{ id: "lamp3", x: 864.855, y: 542.195, width: 105.071, height: 105.071, background: #ffbe00, visible: false },
{ id: "lamp4", x: 864.855, y: 542.195, width: 105.071, height: 105.071, background: #ffbe00, visible: false },
{ id: "lamp5", x: 864.855, y: 542.195, width: 105.071, height: 105.071, background: #ffbe00, visible: false },
{ id: "lamp6", x: 904.902, y: 540.515, width: 65.233, height: 64.659, background: #ffbe00, visible: false },
{ id: "lamp7", x: 36.678, y: 157.145, width: 278.016, height: 278.0, background: #ffbe00, visible: true },
{ id: "appliance1", x: 864.855, y: 542.195, width: 105.071, height: 105.071, background: #b5b5b5, visible: false },
{ id: "appliance2", x: 864.855, y: 542.195, width: 105.071, height: 105.071, background: #b5b5b5, visible: false },
{ id: "overhead1", x: 489.694, y: 519.545, width: 278.0, height: 121.0, background: #fff291, visible: false },
{ id: "overhead2", x: 803.694, y: 519.545, width: 278.0, height: 121.0, background: #fff291, visible: false },
{ id: "overhead3", x: 1117.69, y: 519.545, width: 278.0, height: 121.0, background: #fff291, visible: false },
{ id: "overhead4", x: 1111.78, y: 598.045, width: 277.716, height: 121.0, background: #fff291, visible: false },
{ id: "overhead5", x: 798.062, y: 598.045, width: 277.716, height: 121.0, background: #fff291, visible: false },
{ id: "overhead6", x: 483.778, y: 598.045, width: 277.716, height: 121.0, background: #fff291, visible: false },
{ id: "overhead7", x: 483.778, y: 441.045, width: 278.0, height: 121.0, background: #fff291, visible: false },
{ id: "overhead8", x: 1111.78, y: 441.045, width: 277.716, height: 121.0, background: #fff291, visible: false },
{ id: "overhead9", x: 797.778, y: 441.045, width: 275.274, height: 121.0, background: #fff291, visible: false },
{ id: "overhead10", x: 350.694, y: 157.145, width: 278.0, height: 278.0, background: #fff291, visible: true },
{ id: "overhead11", x: 883.816, y: 561.156, width: 67.149, height: 67.149, background: #fff291, visible: false },
{ id: "info1", x: 892.89, y: 587.916, width: 49.0, height: 13.63, background: #00acff, visible: false },
{ id: "info2", x: 660.558, y: 314.145, width: 753.136, height: 121.0, background: #00acff, visible: true },
{ id: "info3", x: 660.558, y: 157.145, width: 753.136, height: 121.0, background: #00acff, visible: true },
{ id: "graph1", x: 652.594, y: 362.545, width: 435.0, height: 435.0, background: #ba00ff, visible: false },
{ id: "graph2", x: 845.894, y: 542.195, width: 142.994, height: 105.071, background: #ba00ff, visible: false },
{ id: "control1", x: 1449.86, y: 36.445, width: 435.0, height: 942.0, background: #00bf1d, visible: true },
{ id: "control2", x: 36.678, y: 471.445, width: 435.0, height: 504.0, background: #00bf1d, visible: true },
{ id: "control3", x: 507.694, y: 471.445, width: 435.0, height: 504.0, background: #00bf1d, visible: true },
{ id: "control4", x: 978.694, y: 471.445, width: 435.0, height: 504.0, background: #00ac0f, visible: true },
{ id: "filter", x: 36.694, y: 1007.85, width: 1848.0, height: 72.6, background: #8d8d8d, visible: true },
{ id: "nav", x: 36.694, y: 0.145, width: 1377.0, height: 121.0, background: #8d8d8d, visible: true },
]
},
{
id: "controls",
components: [
{ id: "lamp1", x: 836.464, y: 752.089, width: 67.312, height: 67.312, background: #ffbe00, visible: false },
{ id: "lamp2", x: 836.464, y: 752.089, width: 67.312, height: 67.312, background: #ffbe00, visible: false },
{ id: "lamp3", x: 836.464, y: 752.053, width: 67.312, height: 67.384, background: #ffbe00, visible: false },
{ id: "lamp4", x: 836.464, y: 752.089, width: 67.312, height: 67.312, background: #ffbe00, visible: false },
{ id: "lamp5", x: 836.464, y: 752.053, width: 67.312, height: 67.384, background: #ffbe00, visible: false },
{ id: "lamp6", x: 836.464, y: 752.053, width: 67.312, height: 67.384, background: #ffbe00, visible: false },
{ id: "lamp7", x: 836.464, y: 752.053, width: 67.312, height: 67.384, background: #ffbe00, visible: false },
{ id: "appliance1", x: 817.457, y: 733.082, width: 105.326, height: 105.326, background: #b5b5b5, visible: false },
{ id: "appliance2", x: 817.457, y: 733.082, width: 105.326, height: 105.326, background: #b5b5b5, visible: false },
{ id: "overhead1", x: 836.464, y: 752.089, width: 67.312, height: 67.312, background: #fff291, visible: false },
{ id: "overhead2", x: 836.464, y: 752.089, width: 67.312, height: 67.312, background: #fff291, visible: false },
{ id: "overhead3", x: 836.464, y: 752.089, width: 67.312, height: 67.312, background: #fff291, visible: false },
{ id: "overhead4", x: 836.464, y: 752.089, width: 67.312, height: 67.312, background: #fff291, visible: false },
{ id: "overhead5", x: 836.464, y: 752.089, width: 67.312, height: 67.312, background: #fff291, visible: false },
{ id: "overhead6", x: 779.442, y: 752.089, width: 181.354, height: 67.312, background: #fff291, visible: false },
{ id: "overhead7", x: 836.464, y: 752.089, width: 67.312, height: 67.312, background: #fff291, visible: false },
{ id: "overhead8", x: 836.464, y: 752.089, width: 67.312, height: 67.312, background: #fff291, visible: false },
{ id: "overhead9", x: 836.464, y: 752.089, width: 67.312, height: 67.312, background: #fff291, visible: false },
{ id: "overhead10", x: 836.464, y: 752.089, width: 67.312, height: 67.312, background: #fff291, visible: false },
{ id: "overhead11", x: 836.464, y: 752.089, width: 67.312, height: 67.312, background: #fff291, visible: false },
{ id: "info1", x: 817.457, y: 771.096, width: 105.326, height: 29.297, background: #00acff, visible: false },
{ id: "info2", x: 817.457, y: 771.096, width: 105.326, height: 29.297, background: #00acff, visible: false },
{ id: "info3", x: 817.457, y: 771.096, width: 105.326, height: 29.297, background: #00acff, visible: false },
{ id: "graph1", x: 817.457, y: 733.082, width: 105.326, height: 105.326, background: #ba00ff, visible: false },
{ id: "graph2", x: 798.45, y: 733.082, width: 143.34, height: 105.326, background: #ba00ff, visible: false },
{ id: "control1", x: 36.719, y: 157.745, width: 435.0, height: 435.0, background: #00bf1d, visible: true },
{ id: "control2", x: 507.719, y: 157.745, width: 435.0, height: 435.0, background: #00bf1d, visible: true },
{ id: "control3", x: 978.719, y: 157.745, width: 435.0, height: 435.0, background: #00bf1d, visible: true },
{ id: "control4", x: 1449.72, y: 157.745, width: 435.0, height: 435.0, background: #00bf1d, visible: true },
{ id: "filter", x: 36.719, y: 1008.14, width: 1848.0, height: 72.6, background: #8d8d8d, visible: true },
{ id: "nav", x: 36.719, y: 0.445, width: 1848.0, height: 121.0, background: #8d8d8d, visible: true },
]
},
{
id: "lamps",
components: [
{ id: "lamp1", x: 36.147, y: 157.745, width: 278.0, height: 278.0, background: #ffbe00, visible: true },
{ id: "lamp2", x: 350.147, y: 157.745, width: 278.0, height: 278.0, background: #ffbe00, visible: true },
{ id: "lamp3", x: 664.147, y: 157.445, width: 278.0, height: 278.3, background: #ffbe00, visible: true },
{ id: "lamp4", x: 978.147, y: 157.144, width: 278.0, height: 278.0, background: #ffbe00, visible: true },
{ id: "lamp5", x: 1292.15, y: 157.745, width: 278.0, height: 278.3, background: #ffbe00, visible: true },
{ id: "lamp6", x: 1606.15, y: 156.844, width: 278.0, height: 278.3, background: #ffbe00, visible: true },
{ id: "lamp7", x: 36.147, y: 471.144, width: 278.0, height: 278.3, background: #ffbe00, visible: true },
{ id: "appliance1", x: 931.21, y: 642.871, width: 70.274, height: 70.274, background: #b5b5b5, visible: false },
{ id: "appliance2", x: 931.21, y: 642.871, width: 70.274, height: 70.274, background: #b5b5b5, visible: false },
{ id: "overhead1", x: 943.892, y: 655.553, width: 44.911, height: 44.911, background: #fff291, visible: false },
{ id: "overhead2", x: 943.892, y: 655.553, width: 44.911, height: 44.911, background: #fff291, visible: false },
{ id: "overhead3", x: 943.892, y: 655.553, width: 44.911, height: 44.911, background: #fff291, visible: false },
{ id: "overhead4", x: 943.892, y: 655.553, width: 44.911, height: 44.911, background: #fff291, visible: false },
{ id: "overhead5", x: 943.892, y: 655.553, width: 44.911, height: 44.911, background: #fff291, visible: false },
{ id: "overhead6", x: 905.847, y: 655.553, width: 121.0, height: 44.911, background: #fff291, visible: false },
{ id: "overhead7", x: 943.892, y: 655.553, width: 44.911, height: 44.911, background: #fff291, visible: false },
{ id: "overhead8", x: 943.892, y: 655.553, width: 44.911, height: 44.911, background: #fff291, visible: false },
{ id: "overhead9", x: 943.892, y: 655.553, width: 44.911, height: 44.911, background: #fff291, visible: false },
{ id: "overhead10", x: 943.892, y: 655.553, width: 44.911, height: 44.911, background: #fff291, visible: false },
{ id: "overhead11", x: 943.892, y: 655.553, width: 44.911, height: 44.911, background: #fff291, visible: false },
{ id: "info1", x: 931.21, y: 668.234, width: 70.274, height: 19.547, background: #00acff, visible: false },
{ id: "info2", x: 931.21, y: 668.234, width: 70.274, height: 19.547, background: #00acff, visible: false },
{ id: "info3", x: 931.21, y: 668.234, width: 70.274, height: 19.547, background: #00acff, visible: false },
{ id: "graph1", x: 931.21, y: 642.871, width: 70.274, height: 70.274, background: #ba00ff, visible: false },
{ id: "graph2", x: 918.529, y: 642.871, width: 95.637, height: 70.274, background: #ba00ff, visible: false },
{ id: "control1", x: 931.21, y: 642.871, width: 70.274, height: 70.274, background: #00bf1d, visible: false },
{ id: "control2", x: 931.21, y: 642.871, width: 70.274, height: 70.274, background: #00bf1d, visible: false },
{ id: "control3", x: 931.21, y: 642.871, width: 70.274, height: 70.274, background: #00bf1d, visible: false },
{ id: "control4", x: 931.21, y: 642.871, width: 70.274, height: 70.274, background: #00ac0f, visible: false },
{ id: "filter", x: 36.147, y: 1002.95, width: 1848.0, height: 72.6, background: #8d8d8d, visible: true },
{ id: "nav", x: 36.147, y: 0.445, width: 1848.0, height: 121.0, background: #8d8d8d, visible: true },
]
},
{
id: "overhead",
components: [
{ id: "lamp1", x: 835.959, y: 752.089, width: 67.312, height: 67.312, background: #ffbe00, visible: false },
{ id: "lamp2", x: 835.959, y: 752.089, width: 67.312, height: 67.312, background: #ffbe00, visible: false },
{ id: "lamp3", x: 835.959, y: 752.053, width: 67.312, height: 67.384, background: #ffbe00, visible: false },
{ id: "lamp4", x: 835.959, y: 752.089, width: 67.312, height: 67.312, background: #ffbe00, visible: false },
{ id: "lamp5", x: 835.959, y: 752.053, width: 67.312, height: 67.384, background: #ffbe00, visible: false },
{ id: "lamp6", x: 835.959, y: 752.053, width: 67.312, height: 67.384, background: #ffbe00, visible: false },
{ id: "lamp7", x: 835.959, y: 752.053, width: 67.312, height: 67.384, background: #ffbe00, visible: false },
{ id: "appliance1", x: 816.952, y: 733.082, width: 105.326, height: 105.326, background: #b5b5b5, visible: false },
{ id: "appliance2", x: 816.952, y: 733.082, width: 105.326, height: 105.326, background: #b5b5b5, visible: false },
{ id: "overhead1", x: 36.215, y: 157.745, width: 435.0, height: 157.0, background: #fff291, visible: true },
{ id: "overhead2", x: 507.215, y: 157.745, width: 435.0, height: 157.0, background: #fff291, visible: true },
{ id: "overhead3", x: 978.215, y: 157.745, width: 435.0, height: 157.0, background: #fff291, visible: true },
{ id: "overhead4", x: 1449.21, y: 157.745, width: 435.0, height: 157.0, background: #fff291, visible: true },
{ id: "overhead5", x: 36.991, y: 350.745, width: 434.223, height: 157.0, background: #fff291, visible: true },
{ id: "overhead6", x: 507.215, y: 350.745, width: 435.0, height: 157.0, background: #fff291, visible: true },
{ id: "overhead7", x: 978.215, y: 350.745, width: 435.0, height: 157.0, background: #fff291, visible: true },
{ id: "overhead8", x: 1449.21, y: 347.795, width: 435.0, height: 157.0, background: #fff291, visible: true },
{ id: "overhead9", x: 36.991, y: 543.745, width: 434.223, height: 157.0, background: #fff291, visible: true },
{ id: "overhead10", x: 507.215, y: 543.745, width: 435.0, height: 157.0, background: #fff291, visible: true },
{ id: "overhead11", x: 978.215, y: 543.745, width: 435.0, height: 157.0, background: #fff291, visible: true },
{ id: "info1", x: 816.952, y: 771.096, width: 105.326, height: 29.297, background: #00acff, visible: false },
{ id: "info2", x: 816.952, y: 771.096, width: 105.326, height: 29.297, background: #00acff, visible: false },
{ id: "info3", x: 816.952, y: 771.096, width: 105.326, height: 29.297, background: #00acff, visible: false },
{ id: "graph1", x: 816.952, y: 733.082, width: 105.326, height: 105.326, background: #ba00ff, visible: false },
{ id: "graph2", x: 797.945, y: 733.082, width: 143.34, height: 105.326, background: #ba00ff, visible: false },
{ id: "control1", x: 24.115, y: 567.945, width: 435.0, height: 435.0, background: #00bf1d, visible: false },
{ id: "control2", x: 491.149, y: 166.5, width: 435.0, height: 435.0, background: #00bf1d, visible: false },
{ id: "control3", x: 1437.12, y: 531.945, width: 435.0, height: 435.0, background: #00bf1d, visible: false },
{ id: "control4", x: 1449.21, y: 157.745, width: 435.0, height: 435.0, background: #00bf1d, visible: false },
{ id: "filter", x: 36.215, y: 1008.14, width: 1848.0, height: 72.6, background: #8d8d8d, visible: true },
{ id: "nav", x: 36.215, y: 0.445, width: 1848.0, height: 121.0, background: #8d8d8d, visible: true },
]
},
{
id: "appliances",
components: [
{ id: "lamp1", x: 890.347, y: 620.851, width: 140.693, height: 140.693, background: #ffbe00, visible: false },
{ id: "lamp2", x: 890.347, y: 620.851, width: 140.693, height: 140.693, background: #ffbe00, visible: false },
{ id: "lamp3", x: 890.347, y: 620.851, width: 140.693, height: 140.693, background: #ffbe00, visible: false },
{ id: "lamp4", x: 36.694, y: 157.745, width: 435.0, height: 314.0, background: #ffbe00, visible: false },
{ id: "lamp5", x: 507.694, y: 157.745, width: 435.0, height: 314.0, background: #ffbe00, visible: false },
{ id: "lamp6", x: 978.694, y: 157.745, width: 435.0, height: 314.0, background: #ffbe00, visible: false },
{ id: "lamp7", x: 915.736, y: 646.192, width: 89.914, height: 90.012, background: #ffbe00, visible: false },
{ id: "appliance1", x: 36.694, y: 157.745, width: 435.0, height: 471.0, background: #b5b5b5, visible: true },
{ id: "appliance2", x: 507.694, y: 157.745, width: 435.0, height: 471.0, background: #b5b5b5, visible: true },
{ id: "overhead1", x: 915.736, y: 646.241, width: 89.914, height: 89.914, background: #fff291, visible: false },
{ id: "overhead2", x: 915.736, y: 646.241, width: 89.914, height: 89.914, background: #fff291, visible: false },
{ id: "overhead3", x: 915.736, y: 646.241, width: 89.914, height: 89.914, background: #fff291, visible: false },
{ id: "overhead4", x: 915.736, y: 646.241, width: 89.914, height: 89.914, background: #fff291, visible: false },
{ id: "overhead5", x: 915.736, y: 646.241, width: 89.914, height: 89.914, background: #fff291, visible: false },
{ id: "overhead6", x: 839.568, y: 646.241, width: 242.252, height: 89.914, background: #fff291, visible: false },
{ id: "overhead7", x: 915.736, y: 646.241, width: 89.914, height: 89.914, background: #fff291, visible: false },
{ id: "overhead8", x: 915.736, y: 646.241, width: 89.914, height: 89.914, background: #fff291, visible: false },
{ id: "overhead9", x: 915.736, y: 646.241, width: 89.914, height: 89.914, background: #fff291, visible: false },
{ id: "overhead10", x: 915.736, y: 646.241, width: 89.914, height: 89.914, background: #fff291, visible: false },
{ id: "overhead11", x: 915.736, y: 646.241, width: 89.914, height: 89.914, background: #fff291, visible: false },
{ id: "info1", x: 36.694, y: 157.745, width: 592.0, height: 121.0, background: #00acff, visible: false },
{ id: "info2", x: 664.694, y: 157.745, width: 592.0, height: 121.0, background: #00acff, visible: false },
{ id: "info3", x: 1292.69, y: 157.745, width: 592.0, height: 121.0, background: #00acff, visible: false },
{ id: "graph1", x: 890.347, y: 620.851, width: 140.693, height: 140.693, background: #ba00ff, visible: false },
{ id: "graph2", x: 864.957, y: 620.851, width: 191.473, height: 140.693, background: #ba00ff, visible: false },
{ id: "control1", x: 1449.69, y: 36.745, width: 435.0, height: 471.0, background: #00bf1d, visible: false },
{ id: "control2", x: 36.694, y: 507.745, width: 435.0, height: 471.0, background: #00bf1d, visible: false },
{ id: "control3", x: 507.694, y: 507.745, width: 435.0, height: 471.0, background: #00bf1d, visible: false },
{ id: "control4", x: 978.694, y: 507.745, width: 435.0, height: 471.0, background: #00bf1d, visible: false },
{ id: "filter", x: 36.694, y: 1008.14, width: 1848.0, height: 72.6, background: #8d8d8d, visible: true },
{ id: "nav", x: 36.694, y: 0.445, width: 1848.0, height: 121.0, background: #8d8d8d, visible: true },
]
},
{
id: "info",
components: [
{ id: "lamp1", x: 890.509, y: 620.851, width: 140.693, height: 140.693, background: #ffbe00, visible: false },
{ id: "lamp2", x: 890.509, y: 620.851, width: 140.693, height: 140.693, background: #ffbe00, visible: false },
{ id: "lamp3", x: 890.509, y: 620.851, width: 140.693, height: 140.693, background: #ffbe00, visible: false },
{ id: "lamp4", x: 36.856, y: 157.745, width: 435.0, height: 314.0, background: #ffbe00, visible: false },
{ id: "lamp5", x: 507.856, y: 157.745, width: 435.0, height: 314.0, background: #ffbe00, visible: false },
{ id: "lamp6", x: 978.856, y: 157.745, width: 435.0, height: 314.0, background: #ffbe00, visible: false },
{ id: "lamp7", x: 915.899, y: 646.192, width: 89.914, height: 90.012, background: #ffbe00, visible: false },
{ id: "appliance1", x: 890.509, y: 620.851, width: 140.693, height: 140.693, background: #b5b5b5, visible: false },
{ id: "appliance2", x: 890.509, y: 620.851, width: 140.693, height: 140.693, background: #b5b5b5, visible: false },
{ id: "overhead1", x: 915.899, y: 646.241, width: 89.914, height: 89.914, background: #fff291, visible: false },
{ id: "overhead2", x: 915.899, y: 646.241, width: 89.914, height: 89.914, background: #fff291, visible: false },
{ id: "overhead3", x: 915.899, y: 646.241, width: 89.914, height: 89.914, background: #fff291, visible: false },
{ id: "overhead4", x: 915.899, y: 646.241, width: 89.914, height: 89.914, background: #fff291, visible: false },
{ id: "overhead5", x: 915.899, y: 646.241, width: 89.914, height: 89.914, background: #fff291, visible: false },
{ id: "overhead6", x: 839.73, y: 646.241, width: 242.252, height: 89.914, background: #fff291, visible: false },
{ id: "overhead7", x: 915.899, y: 646.241, width: 89.914, height: 89.914, background: #fff291, visible: false },
{ id: "overhead8", x: 915.899, y: 646.241, width: 89.914, height: 89.914, background: #fff291, visible: false },
{ id: "overhead9", x: 915.899, y: 646.241, width: 89.914, height: 89.914, background: #fff291, visible: false },
{ id: "overhead10", x: 915.899, y: 646.241, width: 89.914, height: 89.914, background: #fff291, visible: false },
{ id: "overhead11", x: 915.899, y: 646.241, width: 89.914, height: 89.914, background: #fff291, visible: false },
{ id: "info1", x: 36.856, y: 157.745, width: 592.0, height: 121.0, background: #00acff, visible: true },
{ id: "info2", x: 36.856, y: 314.445, width: 592.0, height: 121.0, background: #00acff, visible: true },
{ id: "info3", x: 36.856, y: 471.745, width: 592.0, height: 121.0, background: #00acff, visible: true },
{ id: "graph1", x: 890.509, y: 620.851, width: 140.693, height: 140.693, background: #ba00ff, visible: false },
{ id: "graph2", x: 865.12, y: 620.851, width: 191.473, height: 140.693, background: #ba00ff, visible: false },
{ id: "control1", x: 495.756, y: 423.345, width: 435.0, height: 471.0, background: #00bf1d, visible: false },
{ id: "control2", x: 36.856, y: 507.745, width: 435.0, height: 471.0, background: #00bf1d, visible: false },
{ id: "control3", x: 507.856, y: 507.745, width: 435.0, height: 471.0, background: #00bf1d, visible: false },
{ id: "control4", x: 978.856, y: 507.745, width: 435.0, height: 471.0, background: #00bf1d, visible: false },
{ id: "filter", x: 36.856, y: 1008.14, width: 1848.0, height: 72.6, background: #8d8d8d, visible: true },
{ id: "nav", x: 36.856, y: 0.445, width: 1848.0, height: 121.0, background: #8d8d8d, visible: true },
]
},
{
id: "graphs",
components: [
{ id: "lamp1", x: 889.685, y: 620.851, width: 140.693, height: 140.693, background: #ffbe00, visible: false },
{ id: "lamp2", x: 889.685, y: 620.851, width: 140.693, height: 140.693, background: #ffbe00, visible: false },
{ id: "lamp3", x: 889.685, y: 620.851, width: 140.693, height: 140.693, background: #ffbe00, visible: false },
{ id: "lamp4", x: 36.031, y: 157.745, width: 435.0, height: 314.0, background: #ffbe00, visible: false },
{ id: "lamp5", x: 507.031, y: 157.745, width: 435.0, height: 314.0, background: #ffbe00, visible: false },
{ id: "lamp6", x: 978.031, y: 157.745, width: 435.0, height: 314.0, background: #ffbe00, visible: false },
{ id: "lamp7", x: 915.074, y: 646.192, width: 89.914, height: 90.012, background: #ffbe00, visible: false },
{ id: "appliance1", x: 36.031, y: 157.745, width: 278.0, height: 314.0, background: #b5b5b5, visible: false },
{ id: "appliance2", x: 350.031, y: 157.745, width: 275.747, height: 314.0, background: #b5b5b5, visible: false },
{ id: "overhead1", x: 915.074, y: 646.241, width: 89.914, height: 89.914, background: #fff291, visible: false },
{ id: "overhead2", x: 915.074, y: 646.241, width: 89.914, height: 89.914, background: #fff291, visible: false },
{ id: "overhead3", x: 915.074, y: 646.241, width: 89.914, height: 89.914, background: #fff291, visible: false },
{ id: "overhead4", x: 915.074, y: 646.241, width: 89.914, height: 89.914, background: #fff291, visible: false },
{ id: "overhead5", x: 915.074, y: 646.241, width: 89.914, height: 89.914, background: #fff291, visible: false },
{ id: "overhead6", x: 838.906, y: 646.241, width: 242.252, height: 89.914, background: #fff291, visible: false },
{ id: "overhead7", x: 915.074, y: 646.241, width: 89.914, height: 89.914, background: #fff291, visible: false },
{ id: "overhead8", x: 915.074, y: 646.241, width: 89.914, height: 89.914, background: #fff291, visible: false },
{ id: "overhead9", x: 915.074, y: 646.241, width: 89.914, height: 89.914, background: #fff291, visible: false },
{ id: "overhead10", x: 915.074, y: 646.241, width: 89.914, height: 89.914, background: #fff291, visible: false },
{ id: "overhead11", x: 915.074, y: 646.241, width: 89.914, height: 89.914, background: #fff291, visible: false },
{ id: "info1", x: 36.031, y: 157.745, width: 592.0, height: 121.0, background: #00acff, visible: false },
{ id: "info2", x: 664.031, y: 157.745, width: 592.0, height: 121.0, background: #00acff, visible: false },
{ id: "info3", x: 1292.03, y: 157.745, width: 592.0, height: 121.0, background: #00acff, visible: false },
{ id: "graph1", x: 36.031, y: 157.745, width: 435.0, height: 471.0, background: #ba00ff, visible: true },
{ id: "graph2", x: 507.031, y: 157.745, width: 435.0, height: 471.0, background: #ba00ff, visible: true },
{ id: "control1", x: 1449.03, y: 36.745, width: 435.0, height: 471.0, background: #00bf1d, visible: false },
{ id: "control2", x: 36.031, y: 507.745, width: 435.0, height: 471.0, background: #00bf1d, visible: false },
{ id: "control3", x: 507.031, y: 507.745, width: 435.0, height: 471.0, background: #00bf1d, visible: false },
{ id: "control4", x: 978.031, y: 507.745, width: 435.0, height: 471.0, background: #00bf1d, visible: false },
{ id: "filter", x: 36.031, y: 1008.14, width: 1848.0, height: 72.6, background: #8d8d8d, visible: true },
{ id: "nav", x: 36.031, y: 0.445, width: 1848.0, height: 121.0, background: #8d8d8d, visible: true },
]
},
];
}

View file

@ -0,0 +1,156 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT
export global Measurements {
out property <length> zone-button-spacing: 30px;
out property <length> tile-radius: 20px;
out property <length> page-height: 1080px;
out property <length> page-width: 1920px;
out property <length> padding: 12px;
out property <length> small-width-tile: 278px;
out property <length> small-height-tile: 153px;
out property <length> medium-height-tile: 278px;
out property <length> medium-width-tile: 435px;
out property <length> large-height-tile: 906px;
out property <length> large-width-tile: 435px;
out property <length> sidebar-width: 400px;
out property <length> tile-shadow-blur: 20px;
out property <length> sidebar-padding: 36px;
out property <length> sidebar-spacing: 36px;
out property <length> application-width: 1920px;
out property <length> application-height: 1080px;
}
export global Style {
out property <length> icon-title-font-size: 20px;
out property <length> normal-font-size: 24px;
out property <length> H1-font-size: 64px;
out property <length> H2-font-size: 42px;
out property <length> H3-font-size: 36px;
out property <length> tile-title-font-size: 20pt;
}
export global Animation {
out property <duration> theme-change-duration: 300ms;
out property <duration> full-screen-duration: 300ms;
out property <duration> transitionDuration: 500ms;
}
export global Colors {
out property <color> white: #ffffff;
out property <color> black: #000000;
out property <color> gray10: #1a1a1a;
out property <color> gray20: #2C2C2C;
out property <color> gray30: #4d4d4d;
out property <color> gray40: #666666;
out property <color> gray50: #808080;
out property <color> gray60: #999999;
out property <color> gray70: #b3b3b3;
out property <color> gray80: #cccccc;
out property <color> gray98: #fdfdfd;
out property <color> gray98_lineedit:#f8f8f8;
out property <color> gray100: self.white;
out property <color> orange100: #f1d789;
out property <color> orange90: #dd5f00;
out property <color> orange80: #aa4f00;
out property <color> orange70: #993f00;
out property <color> orange60: #7a1a00;
out property <color> purple100: #D9D5F2;
out property <color> purple90: #7E5EF2;
out property <color> purple80: #643DF2;
out property <color> purple70: #6a00ff;
out property <color> purple60: #5a00ff;
out property <color> purple50: #4a00ff;
out property <color> purple40: #3A3056;
out property <color> purple30: #1D182A;
out property <color> blue100: #007bff;
out property <color> paleblue: #9eaeb8;
out property <color> foggypeat: #25261E;
out property <color> foggydirt: #595845;
out property <color> foggyblue: #828C81;
out property <color> foggylight: #F2EBD5;
out property <color> foggyyellow: #D9C49C;
out property <color> foggybeige: #D9CAAD;
out property <color> foggysky: #D8DBD2;
out property <color> dustypurpledirt:#564569;
out property <color> dustypurplelight:#7F496D;
out property <color> dustyshadow:#132240;
out property <color> dustyblue:#587AA6;
out property <color> dustygold:#dc9f2f;
out property <color> blue90: #0062cc;
out property <color> blue80: #005cbf;
out property <color> blue70: #004fdf;
out property <color> blue60: #0044cc;
out property <color> blue50: #003bc2;
out property <color> blue40: #0033b2;
out property <color> blue30: #0029a3;
out property <color> blue20: #001f91;
out property <color> blue10: #1B1A40;
out property <color> green100: #00ff99;
out property <color> green90: #00cc66;
out property <color> green80: #00b352;
out property <color> green70: #00993d;
out property <color> green60: #008033;
out property <color> green50: #00662c;
out property <color> green40: #004d23;
out property <color> green30: #00331a;
out property <color> fadedyellow: #F2EED5;
out property <brush> dark-ramp: @linear-gradient(50deg, Colors.purple40, Colors.purple30);
out property <brush> light-ramp: @linear-gradient(0deg, Colors.foggybeige, Colors.foggylight);
out property <brush> music-gradient: @linear-gradient(0deg, Colors.white, Colors.foggylight);
}
export global Palette {
in-out property <bool> dark-color-scheme:true;
out property <brush> background: dark-color-scheme ? Colors.gray10 : Colors.white;
out property <brush> date-background: dark-color-scheme ? Colors.dustypurpledirt : Colors.foggylight;
out property <brush> foreground: dark-color-scheme ? Colors.gray70 : Colors.gray50;
out property <brush> alternate-background: dark-color-scheme ? Colors.gray20 : Colors.gray98;
out property <brush> lineedit-background: dark-color-scheme ? Colors.gray20 : Colors.gray98_lineedit;
out property <brush> alternate-foreground: dark-color-scheme ? Colors.white : Colors.black;
out property <brush> accent-background: dark-color-scheme ? Colors.orange100 : Colors.green70;
out property <brush> accent-foreground: dark-color-scheme ? Colors.white : Colors.black;
out property <brush> selection-background: dark-color-scheme ? Colors.orange100 : Colors.blue100;
out property <brush> selection-foreground: dark-color-scheme ? Colors.white : Colors.black;
out property <brush> border: dark-color-scheme ? Colors.gray60 : Colors.gray30;
out property <brush> dimmer: dark-color-scheme ? Colors.gray98 : Colors.gray10;
out property <brush> shadow-color: dark-color-scheme ? Colors.black.transparentize(0.4) : Colors.foggypeat.transparentize(0.5);
out property <brush> glow-color: dark-color-scheme ? Colors.white.transparentize(0.8) : Colors.foggylight.transparentize(0.8);
out property <brush> background-gradient: dark-color-scheme ? Colors.dark-ramp : Colors.light-ramp;
out property <brush> alternate-background-gradient: dark-color-scheme ? Colors.dark-ramp.brighter(0.3) : Colors.light-ramp.darker(0.3);
out property <brush> info-background: dark-color-scheme ? Colors.dustyshadow : Colors.foggydirt;
out property <brush> info-alternate-background: dark-color-scheme ? Colors.dustyblue.transparentize(0.7) : Colors.foggyblue;
out property <brush> lamp-background: dark-color-scheme ? Colors.orange100 : Colors.foggyblue;
out property <brush> slider-background: dark-color-scheme ? Colors.purple40 : Colors.gray80;
out property <brush> slider-foreground: dark-color-scheme ? Colors.white : Colors.orange100;
out property <brush> control-foreground: dark-color-scheme ? Colors.white : Colors.foggylight;
out property <brush> control-background: dark-color-scheme ? Colors.dustypurpledirt : Colors.foggypeat;
out property <brush> control-alternate-background: dark-color-scheme ? Colors.dustypurpledirt : Colors.foggydirt;
out property <brush> control-alternate-foreground: dark-color-scheme ? Colors.purple100 : Colors.foggysky;
out property <brush> music-alternate-foreground: dark-color-scheme ? Colors.dustypurpledirt : Colors.foggypeat;
out property <brush> music-gradient: dark-color-scheme ? Colors.music-gradient.brighter(0.3) : Colors.music-gradient;
out property <brush> info-foreground: dark-color-scheme ? Colors.white : Colors.white;
out property <brush> info-alternate-foreground: dark-color-scheme ? Colors.white : Colors.foggysky;
out property <brush> lamp-foreground: dark-color-scheme ? Colors.purple30 : Colors.foggylight;
out property <brush> lamp-alternate-foreground: dark-color-scheme ? Colors.purple90 : Colors.gray80;
out property <brush> lamp-shadow: dark-color-scheme ? Colors.dustygold : Colors.foggydirt;
out property <brush> appliance-foreground: dark-color-scheme ? Colors.white : Colors.foggylight;
out property <brush> appliance-background: dark-color-scheme ? Colors.dustyblue : Colors.foggyblue;
out property <brush> appliance-alternate-background: dark-color-scheme ? Colors.paleblue : Colors.foggyblue;
out property <brush> appliance-alternate-foreground: dark-color-scheme ? Colors.white : Colors.foggybeige;
out property <brush> overhead-shadow: dark-color-scheme ? Colors.fadedyellow : Colors.foggylight;
out property <brush> overhead-background: dark-color-scheme ? Colors.fadedyellow.brighter(0.5) : Colors.foggyyellow.brighter(0.5);
out property <brush> overhead-foreground: dark-color-scheme ? Colors.blue10 : Colors.blue10;
out property <brush> overhead-alternate-foreground: dark-color-scheme ? Colors.purple90 : Colors.foggydirt;
out property <brush> graph-foreground: dark-color-scheme ? Colors.white : Colors.foggylight;
out property <brush> graph-alternate-foreground: dark-color-scheme ? Colors.dustygold : Colors.foggysky;
out property <brush> graph-background: dark-color-scheme ? Colors.purple30 : Colors.foggydirt;
out property <brush> doors-background: dark-color-scheme ? @linear-gradient(180deg, #34373F, #1D2026) : @linear-gradient(180deg, #e1e1d7, #ffffff);
out property <brush> doors-notch-background: dark-color-scheme ? @linear-gradient(180deg, #2e3037, #25272c) : @linear-gradient(180deg, #ebebe4, #f5f5f1);
out property <brush> door-light-on: dark-color-scheme ? Colors.orange100 : Colors.orange100;
out property <brush> door-light-off: dark-color-scheme ? Colors.black : Colors.green30;
out property <brush> hvac-knob-background: dark-color-scheme ? @radial-gradient(circle, Colors.dustypurpledirt.darker(0.2) 0%, Colors.dustypurpledirt.darker(0.5) 100%) : @radial-gradient(circle, Colors.foggydirt 0%, Colors.foggypeat 100%);
out property <brush> hvac-knob-foreground: dark-color-scheme ? Colors.white : Colors.foggylight;
out property <brush> hvac-foreground: dark-color-scheme ? Colors.purple100 : Colors.foggylight;
out property <brush> tab: dark-color-scheme ? Colors.blue10 : Colors.foggybeige;
out property <brush> tab-highlight: dark-color-scheme ? Colors.dustygold.transparentize(0.8) : Colors.black.transparentize(0.5);
}

View file

@ -0,0 +1,242 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT
import { Animation, Measurements, Colors, Style, Palette } from "../common.slint";
import { Control} from "control.slint";
import { AppState } from "../appState.slint";
import { HaText } from "general/haText.slint";
import { LineEdit } from "std-widgets.slint";
export component ArmButton inherits Rectangle {
callback clicked <=> ta.clicked;
in property <int> label;
background: ta.pressed ? Palette.control-alternate-background.transparentize(0.5) : Palette.control-alternate-background;
border-radius: 10px;
width: 130px;
height: 95px;
HaText {
font-size: root.label == -2 ? Style.H1-font-size * 0.6 : Style.H2-font-size;
text: root.label == -2 ? "⌫" : root.label;
color: Palette.control-alternate-foreground;
visible: root.label != -1;
}
ta := TouchArea {
enabled: root.label != -1;
}
}
export component Alarm inherits Control {
property <int> current-page: AppState.current-page;
property <bool> unlocked: false;
property <bool> is-active: false;
property <string> passcode;
property <string> indirect-passcode: passcode == "-1" ? "" : passcode;
show-label: false;
hidden-text := HaText {
font-size: Style.H1-font-size;
text: root.indirect-passcode;
opacity: 0;
}
content := Rectangle {
TouchArea {
clicked => {
AppState.showFullScreen(root.index);
}
}
HaText {
visible: root.full-screen;
text: "Enter Code";
horizontal-alignment: center;
font-size: Style.H2-font-size;
color: Palette.hvac-knob-foreground;
font-weight: 300;
x: parent.width / 2 - self.width / 2;
y: 100px;
}
Rectangle {
drop-shadow-blur: Measurements.tile-shadow-blur * 10;
drop-shadow-color: Palette.glow-color;
width: 70%;
height: 70%;
VerticalLayout {
visible: !root.full-screen;
alignment: center;
spacing: 80px;
HaText {
text: "Home Alarm \nOff";
horizontal-alignment: center;
font-size: Style.H2-font-size;
color: Palette.hvac-knob-foreground;
font-weight: 300;
x: parent.width / 2 - self.width / 2;
}
Rectangle {
width: 100%;
height: 50px;
border-radius: self.height / 2;
background: Palette.alternate-background;
HaText {
text: "Arm Alarm";
color: Palette.foreground;
font-size: 2rem;
}
}
}
Rectangle {
width: 400px;
states [
isVisible when root.full-screen: {
opacity: 1;
in {
animate opacity {
duration: 300ms;
easing: ease-in-out-sine;
}
}
}
notVisible when !root.full-screen: {
opacity: 0;
in {
animate opacity {
duration: 300ms;
easing: ease-in-out-sine;
}
}
}
]
x: parent.width / 2 - self.width / 2;
Rectangle {
width: 130px * 3 + 2 * 10px;
height: (95px * 5) + (4 * 10px);
visible: root.full-screen;
container := Rectangle {
y: 0;
border-radius: 10px;
width: 100%;
height: 95px;
background: Palette.alternate-background;
le := LineEdit {
font-size: Style.H1-font-size;
text: root.indirect-passcode;
input-type: password;
width: Math.max(290px, hidden-text.width);
changed width => {
if self.width > 300px {
root.passcode = -1;
}
}
}
mask := Rectangle {
width: le.width + (17px * 2);
height: container.height - 1px;
x: le.x - 17px;
y: container.y + 1px;
border-width: 18px;
border-color: Palette.lineedit-background;
}
Rectangle {
width: (container.width - mask.width) / 2;
height: container.height;
x: container.x;
y: container.y;
border-radius: 10px;
background: Palette.lineedit-background;
}
Rectangle {
width: (container.width - mask.width) / 2;
height: container.height;
x: mask.x + mask.width;
y: container.y;
border-radius: 10px;
background: Palette.lineedit-background;
}
}
TouchArea { }
for row-model[r] in [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
[-1, 0, -2],
]: Rectangle {
y: (r * 105px) + 105px;
width: 100%;
height: 170px;
HorizontalLayout {
spacing: 10px;
for num[c] in row-model: ArmButton {
label: num;
clicked => {
if num >= 0 && root.passcode == -1 {
root.passcode = num;
} else if num >= 0 {
root.passcode += num;
} else if num == -2 {
root.passcode = -1;
}
}
}
}
}
}
}
}
x: 0;
VerticalLayout {
alignment: end;
spacing: 5px;
padding: 5px;
controls := Rectangle {
border-radius: 20px;
width: 95%;
height: self.preferred-height;
background: Palette.music-gradient.transparentize(0.2);
animate height {
duration: 1000ms;
easing: ease-in-out-sine;
}
HorizontalLayout {
alignment: space-around;
padding-top: 15px;
padding-bottom: 15px;
}
}
}
}
closeButton := Image {
opacity: root.full-screen ? 1 : 0;
animate opacity {
duration: Animation.full-screen-duration;
easing: ease-in-out-sine;
}
source: @image-url("../images/reduce.svg");
colorize: white;
x: root.width - self.width - 30px;
y: 30px;
width: 60px;
height: 60px;
TouchArea {
enabled: closeButton.opacity > 0.1;
clicked => {
root.full-screen = false;
AppState.showFullScreen(-1);
}
}
}
}

View file

@ -0,0 +1,80 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT
import { Palette, Measurements, Colors } from "../common.slint";
import { AppState } from "../appState.slint";
import { HaText } from "general/haText.slint";
export component Appliance {
in property <brush> background: #b5b5b5;
in property <string> name;
in property <string> id;
in property <int> index;
in property <bool> full-screen: false;
in property <length> image-size: self.width;
in property <string> time-remaining: "00:00 hrs";
in property <image> appliance-image: @image-url("../images/microwave.jpg");
property <color> text-color: Palette.appliance-background;
tile := Rectangle {
clip: true;
background: Palette.appliance-background;
border-radius: Measurements.tile-radius;
Rectangle {
clip: true;
min-width: tile.width;
max-width: tile.width;
height: tile.height / 2;
x: 0;
y: tile.height - self.height;
// border-radius: Measurements.tile-radius;
background: Palette.appliance-alternate-background;
if (root.width > Measurements.small-width-tile): Image {
width: parent.width;
height: image-size;
y: -80px;
image-fit: cover;
source: appliance-image;
}
}
VerticalLayout {
padding: (tile.height > Measurements.small-height-tile) ? 36px : 18px;
width: 100%;
height: 100%;
alignment: start;
HaText {
text: "Appliance";
font-size: 16pt;
font-weight: 400;
color: Palette.appliance-alternate-foreground;
}
HaText {
text: root.name;
font-size: 20pt;
font-weight: 400;
color: Palette.appliance-foreground;
}
Rectangle {
height: 10px;
}
VerticalLayout {
// spacing: -10px;
HaText {
text: "Time Remaining: ";
font-size: 16pt;
font-weight: 400;
color: Palette.appliance-foreground;
}
HaText {
text: root.time-remaining;
font-size: 30pt;
font-weight: 500;
color: Palette.appliance-foreground;
}
}
}
}
}

View file

@ -0,0 +1,97 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT
import { Measurements, Colors, Palette } from "../common.slint";
import { Control } from "control.slint";
import { AppState } from "../appState.slint";
export component Camera inherits Control {
property <int> current-page: AppState.current-page;
property <bool> unlocked: false;
property <image> cam: @image-url("../images/front-porch.jpg");
property <bool> is-active: false;
tile := Rectangle {
x: 0cm;
Rectangle {
border-radius: Measurements.tile-radius;
clip: true;
Image {
source: root.cam;
width: tile.width;
image-fit: cover;
height: tile.height;
horizontal-alignment: center;
vertical-alignment: center;
}
}
VerticalLayout {
alignment: end;
spacing: 5px;
padding: 5px;
HorizontalLayout {
width: tile.width;
alignment: start;
padding-left: 10px;
}
controls := Rectangle {
border-radius: 20px;
width: 95%;
height: self.preferred-height;
background: Palette.music-gradient.transparentize(0.2);
animate height {
duration: 1000ms;
easing: ease-in-out-sine;
}
HorizontalLayout {
alignment: space-around;
padding-top: 15px;
padding-bottom: 15px;
}
}
}
TouchArea {
enabled: !AppState.showing-full-screen;
clicked => {
AppState.showFullScreen(root.index);
}
}
Image {
source: @image-url("../images/enlarge.svg");
opacity: root.full-screen ? 0 : 1;
width: 40px;
colorize: Colors.white;
x: root.width - self.width - 30px;
y: 30px;
animate opacity {
duration: 500ms;
easing: ease-in-out-sine;
}
}
closeButton := Image {
opacity: root.full-screen ? 1 : 0;
animate opacity {
duration: 500ms;
easing: ease-in-out-sine;
}
source: @image-url("../images/reduce.svg");
colorize: white;
x: root.width - self.width - 30px;
y: 30px;
width: 60px;
height: 60px;
}
TouchArea {
enabled: closeButton.opacity > 0.1;
clicked => {
root.full-screen = false;
AppState.showFullScreen(-1);
}
}
}
}

View file

@ -0,0 +1,66 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT
import { Animation, Palette, Measurements, Colors } from "../common.slint";
import { FancySlider } from "general/fancySlider.slint";
import { AppState } from "../appState.slint";
import { HaText } from "general/haText.slint";
export component Control inherits Rectangle {
in property <string> name;
in property <string> id;
in property <bool> type-label: true;
in property <bool> name-label: true;
in property <bool> full-screen: false;
in property <bool> control-label: true;
in property <length> control-label-position: 5px;
in property <int> index;
in property <length> tile-shadow-blur: Measurements.tile-shadow-blur;
in property <brush> tile-background: Palette.control-background;
in property <brush> tile-shadow-color: Palette.shadow-color;
in property <bool> show-label: true;
Image {
x: -23px;
y: -23px;
width: parent.width + 46px;
height: parent.height + 46px;
source: @image-url("../images/shadow-rounded.png", nine-slice(50));
colorize: tile-shadow-color;
animate colorize {
duration: AppState.first-run ? 0 : Animation.theme-change-duration;
easing: ease-in-out-sine;
}
}
tile := Rectangle {
clip: true;
background: tile-background;
border-radius: Measurements.tile-radius;
@children
if show-label: Rectangle {
x: control-label-position;
y: 5px;
border-radius: Measurements.tile-radius;
background: Colors.black.transparentize(0.7);
width: self.preferred-width;
height: self.preferred-height;
VerticalLayout {
alignment: space-between;
padding: (tile.height > Measurements.small-height-tile) ? 18px : 9px;
width: 100%;
height: 100%;
VerticalLayout {
alignment: start;
spacing: 10px;
Text {
text: root.name;
font-size: 20pt;
font-weight: 400;
color: Palette.control-foreground;
}
}
}
}
}
}

View file

@ -0,0 +1,93 @@
// 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: 240px;
}
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: 425px;
height: 427px;
knob := Rectangle {
base := Rectangle {
Image {
y: 18px;
source: Palette.dark-color-scheme ? @image-url("../../images/dial-frame.png") : @image-url("../../images/dial-frame-lite.png");
width: self.source.width * 1px;
height: self.source.height * 1px;
}
Image {
source: @image-url("../../images/lines.png");
colorize: Palette.dark-color-scheme ? #fff : #000;
rotation-angle: root.dialAngle;
width: self.source.width * 1.1 * 1px;
height: self.source.height * 1.1 * 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: 212px;
y: 210px;
Rectangle {
width: 0px;
height: 0px;
x: 110px * root.dialAngle.cos();
y: 110px * root.dialAngle.sin();
Image {
source: Palette.dark-color-scheme ? @image-url("../../images/notch.png") : @image-url("../../images/notch-lite.png");
width: self.source.width * 0.8 * 1px;
height: self.source.height * 0.8 * 1px;
}
}
}
}

View file

@ -0,0 +1,79 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT
import { DialState } from "dial.slint";
import { Palette } from "../../common.slint";
export component Light {
function pulseAnimation(duration: duration) -> float {
return 1 * (1 - abs(sin(360deg * animation-tick() / duration)));
}
in property <int> index;
in property <int> volume;
property <angle> gap: (360deg - (DialState.startAngle - DialState.endAngle)) / DialState.totalLights;
property <angle> angle: (index * gap) + DialState.startAngle;
property <bool> lightOn: index <= volume;
property <float> pulse: index == 0 && lightOn && volume <= 1 ? pulseAnimation(5s) : 1.0;
x: DialState.elementRadius * angle.cos();
y: DialState.elementRadius * angle.sin();
width: 0;
height: 0;
states [
lightOff when !root.lightOn: {
dialLed.opacity: 0;
}
lightOn when root.lightOn: {
dialLed.opacity: pulse;
in {
animate dialLed.opacity {
duration: 100ms;
easing: ease-in-sine;
}
}
out {
animate dialLed.opacity {
duration: 600ms;
easing: ease-out-sine;
}
}
}
]
Rectangle {
Rectangle {
width: 10px;
height: self.width;
border-radius: self.width / 2;
background: Palette.door-light-off;
opacity: 0.1;
}
dialLed := Image {
source: Palette.dark-color-scheme ? @image-url("../../images/led-dark.png") : @image-url("../../images/led.png");
}
}
}
export component DialLights {
width: 425px;
height: 427px;
in property <int> volume;
Rectangle {
width: 1px;
height: 1px;
x: 212px;
y: 210px;
lightHolder := Rectangle {
x: 0px;
y: 2px;
for i in DialState.totalLights + 1: Light {
index: i;
volume: root.volume;
}
}
}
}

View file

@ -0,0 +1,8 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT
import { Palette,Measurements,Colors } from "../common.slint";
import { Appliance } from "appliance.slint";
export component Dishwasher inherits Appliance {
time-remaining: "1:45 hrs";
appliance-image: @image-url("../images/dishwasher.jpg");
}

View file

@ -0,0 +1,169 @@
// 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: -60px;
width: parent.width / 2 + 140px;
height: 100%;
background: Palette.doors-background;
border-width: 10px;
border-color: notch-border-color;
border-radius: 60px;
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;
source: @image-url("../../images/logo-fragment.png");
opacity: Palette.dark-color-scheme ? 0.08 : 0.02;
}
DialLights {
x: parent.width - 250px;
volume: dial.volume;
}
}
states [
doorsOpen when target-door-state == DoorState.open: {
leftDoor.x: -leftDoor.width;
rightDoor.x: root.width + 170px;
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: -60px;
rightDoor.x: root.width / 2;
in {
animate rightDoor.x, leftDoor.x {
duration: 800ms;
easing: ease-in-expo;
}
}
}
]
rightDoor := Rectangle {
property <length> notch-width: 440px;
property <length> notch-border: 8px;
property <length> notch-indent: 40px;
x: parent.width / 2;
width: parent.width / 2 + 60px;
height: 100%;
Rectangle {
background: Palette.doors-background;
clip: true;
border-radius: 60px;
Image {
x: parent.width - self.width;
y: parent.height - self.height;
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: 60px;
}
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) - 250px;
source: @image-url("../../images/open-lock.svg");
colorize: Palette.dark-color-scheme ? #000 : #6f6f6f;
width: self.source.width * 1.4 * 1px;
height: self.source.height * 1.4 * 1px;
opacity: 0.4;
}
dial := Dial {
x: -164px;
y: (parent.height - self.height) / 2 - 2px;
interactive: root.demo-locked;
changed volume => {
if self.volume >= 60 {
root.unlockDemo()
}
}
}
}
}

View file

@ -0,0 +1,109 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT
import { Palette, Measurements, Colors } from "../../common.slint";
export component FancySlider inherits Rectangle {
in-out property <float> value: 0.0;
in property <float> minValue: 0;
in property <float> maxValue: 1;
in property <image> icon;
out property <bool> active;
in property <color> colorize-icon: Palette.slider-background;
property <duration> anim-duration: 300ms;
property <float> previous-value;
callback toggle();
toggle => {
if value > 0.05 {
previous-value = value;
anim-duration = 50ms;
animated-value = 0;
} else {
anim-duration = 300ms;
// previous value is less than 10% between min and max
if previous-value < 0.1 {
animated-value = 1;
} else {
animated-value = previous-value;
}
}
}
property <float> animated-value: value;
animate animated-value {
duration: anim-duration;
easing: ease-in-out-sine;
}
changed animated-value => {
value = animated-value;
}
height: 30px;
border-radius: self.height / 2;
TouchArea {
width: 100%;
height: 300%;
y: parent.height / 2 - self.height / 2;
property <bool> first-touch: false;
property <length> initial-position;
property <float> initial-value;
property <float> previous-value;
property <float> change-value;
clicked => {
if self.mouse-x == initial-position {
anim-duration = 300ms;
animated-value = (self.mouse-x / self.width) * (maxValue - minValue) + minValue;
}
}
moved => {
if !first-touch {
first-touch = true;
initial-position = self.mouse-x;
initial-value = (self.mouse-x / self.width) * (maxValue - minValue) + minValue;
previous-value = value;
anim-duration = 0ms;
} else {
change-value = ((self.mouse-x / self.width) * (maxValue - minValue) + minValue) - initial-value;
value = Math.clamp(previous-value + change-value, minValue, maxValue);
animated-value = value;
}
}
changed pressed => {
if !self.pressed {
first-touch = false;
}
}
}
Rectangle {
clip: true;
border-radius: root.border-radius;
background: Palette.slider-background;
border-color: Palette.lamp-foreground;
Rectangle {
x: 0;
background: Palette.slider-foreground;
width: parent.width * (value - minValue) / (maxValue - minValue);
height: 100%;
}
VerticalLayout {
alignment: center;
x: - parent.width / 2 + 20px;
Image {
colorize: root.colorize-icon;
height: 60%;
source: root.icon;
}
}
}
Rectangle {
border-radius: root.border-radius;
border-width: 1px;
border-color: Palette.lamp-foreground;
}
}

View file

@ -0,0 +1,7 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT
import { AppState } from "../../appState.slint";
export component HaText inherits Text {
font-family: AppState.default-font-family;
}

View file

@ -0,0 +1,45 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT
import { Palette, Measurements, Colors } from "../../common.slint";
import { AppState } from "../../appState.slint";
export component InnerShadowRectangle inherits Rectangle {
in property <length> inner-shadow-blur: 15px;
in property <brush> inner-color: Palette.background;
in property <brush> inner-shadow-color: Palette.shadow-color;
in property <bool> nine-slice: true;
clip: true;
if nine-slice:
Rectangle {
clip: true;
width: 100%;
height: 100%;
background: inner-color;
animate background, border-color, drop-shadow-blur, drop-shadow-color {
duration: 0;
easing: ease-in-out-sine;
}
Image {
source: @image-url("../../images/inner-shadow-box-soft.png", nine-slice(50));
colorize: inner-shadow-color;
width: 100%;
height: 100%;
}
}
if !nine-slice:
Rectangle {
height: root.height;
width: root.width;
clip: true;
border-color: Palette.alternate-background;
background: inner-shadow-color;
Rectangle {
border-radius: parent.border-radius;
background: transparent;
drop-shadow-blur: inner-shadow-blur + 0.01px;
drop-shadow-color: inner-color;
width: parent.width - (inner-shadow-blur + 0.01px) * 2;
height: parent.height - (inner-shadow-blur + 0.01px) * 2;
}
}
}

View file

@ -0,0 +1,186 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT
import { Palette } from "../../common.slint";
import { Palette as StdPalette } from "std-widgets.slint";
global Utils {
public pure function MapRange(value: length, inMin: length, inMax: length, outMin: length, outMax: length) -> length {
return clamp(outMin, (value - inMin) * (outMax - outMin) / (inMax - inMin) + outMin, outMax);
}
}
component SunMoonThumb {
in property <float> scale: 1;
in property <length> thumb-position: 50px;
Rectangle {
width: 200px * scale;
height: 100px * scale;
border-radius: self.height / 2;
clip: true;
Rectangle {
width: 0px;
height: 0px;
x: root.thumb-position;
Rectangle {
width: 260px * scale;
height: self.width;
background: white;
border-radius: self.width / 2;
opacity: 0.05;
}
Rectangle {
width: 200px * scale;
height: self.width;
background: white;
border-radius: self.width / 2;
opacity: 0.05;
}
Rectangle {
x: 0;
width: 140px * scale;
height: self.width;
background: white;
border-radius: self.width / 2;
opacity: 0.05;
}
clipper := Rectangle {
width: 85px * scale;
height: self.width;
border-radius: self.width / 2;
clip: true;
sun := Rectangle {
width: 85px * scale;
height: self.width;
background: @radial-gradient(circle, #ffce08 0%, #fdd224 80%, #fce37f 100%);
border-radius: self.width / 2;
}
moon := Rectangle {
x: Utils.MapRange(root.thumb-position, 50px * scale, 100px * scale, 85px * scale, 0px);
width: 85px * scale;
height: self.width;
background: @radial-gradient(circle, #bcbcbc 0%, #e7e7e7 80%, #ffffff 100%);
border-radius: self.width / 2;
}
}
}
}
}
enum Theme { day, night }
export component ThemeSwitch {
in property <float> scale: 1;
width: 200px * scale;
height: 100px * scale;
property <Theme> theme: Theme.night;
frameBacker := Rectangle {
width: parent.width;
height: parent.height;
background: #1e2232;
border-radius: self.height / 2;
}
Rectangle {
width: parent.width;
height: parent.height;
clip: true;
border-radius: self.height / 2;
clouds-background := Image {
x: 14px * scale;
y: -6px * scale;
width: 202px * scale;
source: @image-url("../../images/clouds-background.png");
}
clouds-foreground := Image {
x: 30px * scale;
y: 5px * scale;
width: 202px * scale;
source: @image-url("../../images/clouds-front.png");
}
stars := Image {
x: 15px * scale;
y: 15px * scale;
width: 80px * scale;
source: @image-url("../../images/stars.png");
}
}
Rectangle {
border-radius: self.height / 2;
border-color: #474747;
border-width: 1phx;
}
thumb := SunMoonThumb {
scale: root.scale;
}
TouchArea {
clicked => {
if root.theme == Theme.day {
root.theme = Theme.night;
Palette.dark-color-scheme = true;
StdPalette.color-scheme = ColorScheme.dark;
} else {
root.theme = Theme.day;
Palette.dark-color-scheme = false;
StdPalette.color-scheme = ColorScheme.light;
}
}
}
states [
nightMode when root.theme == Theme.night: {
thumb.thumb-position: root.width - thumb.width - (50px * scale);
frameBacker.background: #1e2232;
clouds-background.y: 120px;
clouds-foreground.y: 120px;
in {
animate frameBacker.background, stars.y, stars.opacity {
easing: ease-out-sine;
duration: 200ms;
}
animate thumb.thumb-position {
easing: cubic-bezier(0.61, 0.21, 0.68, 1.22);
duration: 300ms;
}
animate clouds-background.y, clouds-foreground.y {
easing: ease-in-sine;
duration: 150ms;
}
}
}
dayMode when root.theme == Theme.day: {
thumb.thumb-position: 50px * scale;
frameBacker.background: #3d85ba;
stars.y: - 60px;
stars.opacity: 0.4;
in {
animate frameBacker.background, stars.y, stars.opacity {
easing: ease-out-sine;
duration: 200ms;
}
animate thumb.thumb-position {
easing: cubic-bezier(0.61, 0.21, 0.68, 1.22);
duration: 300ms;
}
animate clouds-background.y {
easing: ease-out-sine;
duration: 300ms;
}
animate clouds-foreground.y {
easing: cubic-bezier(0.61, 0.21, 0.68, 1.22);
duration: 350ms;
}
}
}
]
}

View file

@ -0,0 +1,126 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT
import { Palette } from "../../common.slint";
import { InnerShadowRectangle } from "innerShadowRectangle.slint";
export component DropShadowToggle inherits Rectangle {
in-out property <string> labelOff:"";
in-out property <string> labelOn: "ON";
in property <percent> scale: 100%;
in property <float> toggleOpacity: 1.0;
in-out property <bool> active:true;
in property <color> inner-color-active:Palette.accent-background;
in property <color> inner-color-inactive: Palette.foreground.transparentize(0.85);
in property <color> inner-shadow-color: Palette.shadow-color;
in property <color> control-color: Palette.alternate-background;
in property <bool> touchEnabled:true;
property <duration> animation-duration: 100ms;
callback toggle();
width: self.preferred-width;
height: 90px * root.scale;
toggle => {
active = !active;
}
HorizontalLayout {
alignment: LayoutAlignment.stretch;
spacing: 20px;
// LEFT LABEL
Text {
visible: labelOff != "";
vertical-alignment: center;
horizontal-alignment: right;
text: labelOff;
font-size: root.height / 2;
font-weight: 700;
}
toggleBox := Rectangle {
width: root.height * 1.7;
InnerShadowRectangle {
clip: true;
opacity: toggleOpacity;
border-radius: self.height / 2;
nine-slice: false;
states [
active when root.active: {
inner-color: inner-color-active;
in {
animate inner-color {
duration: animation-duration;
easing: ease-out;
}
}
}
inactive when !root.active: {
inner-color: inner-color-inactive;
in {
animate inner-color {
duration: animation-duration;
easing: ease-out;
}
}
}
]
background: inner-shadow-color;
// CONTROL BUTTON
TouchArea {
enabled: touchEnabled;
clicked => {
root.active = !root.active;
}
}
animate drop-shadow-color {
duration: animation-duration;
easing: ease-in;
delay: 0;
}
// CONTROL
Rectangle {
property <length> thumb-margin: 11px * root.scale;
border-radius: self.height / 2;
height: parent.height * 0.78;
width: parent.height * 0.78;
background: control-color;
states [
active when root.active: {
x: parent.width - self.width - thumb-margin;
in {
animate x {
duration: animation-duration;
easing: ease-out;
}
}
}
inactive when !root.active: {
x: thumb-margin;
in {
animate x {
duration: animation-duration;
easing: ease-out;
}
}
}
]
}
border-color: Palette.foreground;
}
}
// RIGHT LABEL
Text {
visible: labelOn != "";
text: labelOn;
horizontal-alignment: left;
vertical-alignment: center;
font-size: root.height / 2;
font-weight: 700;
}
}
}

View file

@ -0,0 +1,160 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT
import { Palette,Measurements } from "../common.slint";
import { AppState } from "../appState.slint";
import { HaText } from "general/haText.slint";
export component Graph {
in property <string> name;
in property <string> id;
in property <bool> full-screen: false;
property <[int]> grid: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
property <[int]> values: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
tile := Rectangle {
clip: true;
background: Palette.graph-background;
border-radius: Measurements.tile-radius;
VerticalLayout {
padding: (tile.height > Measurements.small-height-tile) ? 36px : 18px;
width: 100%;
height: tile.height;
VerticalLayout {
alignment: start;
spacing: 10px;
HaText {
text: root.name;
font-size: 20pt;
font-weight: 400;
color: Palette.graph-foreground;
}
Rectangle {
height: 20px;
}
}
}
Rectangle {
width: 2px;
height: parent.height * 0.6;
background: Palette.graph-foreground.transparentize(0.8);
x: tile.width * 0.1;
y: tile.height * 0.3;
}
for i in grid: Rectangle {
width: 2px;
height: parent.width * 0.6;
background: Palette.graph-foreground.transparentize(0.9);
x: tile.width * 0.1 * i;
y: tile.height * 0.3;
}
for i in values: HaText {
horizontal-alignment: right;
y: tile.height * 0.9 - (tile.height * i / 10);
x: tile.width * 0.05;
text: i * 20;
color: Palette.graph-foreground.transparentize(0.8);
}
Rectangle {
height: 2px;
width: parent.width * 0.8;
background: Palette.graph-foreground.transparentize(0.8);
x: tile.width * 0.1;
y: tile.height * 0.9;
}
Path {
width: tile.width * 0.8;
x: tile.width * 0.1;
height: 100px;
stroke: Palette.graph-alternate-foreground;
stroke-width: 4px;
MoveTo {
x: 0;
y: 0;
}
LineTo {
x: 50;
y: 100;
}
LineTo {
x: 100;
y: 90;
}
LineTo {
x: 150;
y: 95;
}
LineTo {
x: 200;
y: 85;
}
LineTo {
x: 250;
y: 70;
}
LineTo {
x: 300;
y: 65;
}
LineTo {
x: 350;
y: 25;
}
LineTo {
x: 400;
y: 85;
}
LineTo {
x: 450;
y: 95;
}
LineTo {
x: 500;
y: 100;
}
LineTo {
x: 550;
y: 90;
}
LineTo {
x: 600;
y: 100;
}
LineTo {
x: 650;
y: 90;
}
LineTo {
x: 700;
y: 100;
}
LineTo {
x: 750;
y: 90;
}
LineTo {
x: 800;
y: 100;
}
}
}
}

View file

@ -0,0 +1,257 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT
import { Animation, Measurements, Colors, Palette, Style } from "../common.slint";
import { Control} from "control.slint";
import { AppState } from "../appState.slint";
import { HaText } from "general/haText.slint";
enum Mode { increment, decrement }
component TempAdjustButton inherits Rectangle {
in property <Mode> mode: increment;
callback clicked <=> ta.clicked;
width: 70px;
height: self.width;
border-radius: self.height / 2;
background: ta.pressed ? Palette.accent-background.transparentize(0.9) : Palette.accent-background.transparentize(0.8);
Rectangle {
width: 0;
height: self.width;
property <length> icon-size: 35px;
Rectangle {
border-radius: self.height / 2;
width: icon-size;
height: 4px;
background: Palette.hvac-foreground;
}
if mode == Mode.increment: Rectangle {
border-radius: self.width / 2;
width: 4px;
height: icon-size;
background: Palette.hvac-foreground;
}
}
ta := TouchArea { }
}
export component ZoneButton inherits Rectangle {
in property <string> zone-name: "Zone 1";
in-out property <int> zone-set-point: 22;
in property <int> min-temp: 12;
in property <int> max-temp: 32;
width: 400px;
height: 80px;
HorizontalLayout {
alignment: space-between;
HaText {
horizontal-alignment: left;
vertical-alignment: center;
font-size: 20pt;
text: root.zone-name;
color: Palette.hvac-foreground;
}
HorizontalLayout {
width: 100px;
spacing: Measurements.zone-button-spacing;
alignment: end;
TempAdjustButton {
mode: Mode.decrement;
clicked => {
if zone-set-point > min-temp {
zone-set-point = zone-set-point - 1;
}
}
}
HaText {
width: 120px;
vertical-alignment: center;
horizontal-alignment: center;
font-size: 30pt;
text: root.zone-set-point + "°C";
color: Palette.hvac-foreground;
}
TempAdjustButton {
mode: Mode.increment;
clicked => {
if zone-set-point < max-temp {
zone-set-point = zone-set-point + 1;
}
}
}
}
}
}
export component HVAC inherits Control {
property <int> current-page: AppState.current-page;
property <bool> unlocked: false;
property <bool> is-active: false;
show-label: false;
tile := Rectangle {
shadow := Image {
source: @image-url("../images/shadow-circle-soft.png");
width: dial.width * 1.25;
// height: dial.height * 1.25;
colorize: Palette.glow-color;
x: (Math.min(parent.width, parent.height) - self.height) / 2;
height: root.full-screen ? 550px * 1.25 : 400px * 1.25;
animate height {
duration: Animation.full-screen-duration;
easing: ease-in-out-sine;
}
}
TouchArea {
enabled: !AppState.showing-full-screen;
clicked => {
AppState.showFullScreen(root.index);
}
}
dial := Rectangle {
background: Palette.hvac-knob-background;
width: self.height;
height: root.full-screen ? 550px : 400px;
animate height {
duration: Animation.full-screen-duration;
easing: ease-in-out-sine;
}
x: (Math.min(parent.width, parent.height) - self.height) / 2;
border-radius: self.width / 2;
Image {
height: 40px;
width: 40px;
y: dial.height / 4;
x: dial.width * 3 / 4;
source: @image-url("../images/cold.svg");
colorize: Palette.hvac-foreground;
}
VerticalLayout {
x: dial.width / 2 - self.preferred-width / 2;
alignment: center;
// spacing: -30px;
HaText {
text: "Current";
font-size: Style.tile-title-font-size;
color: Palette.hvac-knob-foreground;
font-weight: 300;
x: parent.width / 2 - self.width / 2;
}
HaText {
text: "22°C";
font-size: 90pt;
color: Palette.hvac-knob-foreground.transparentize(0.5);
font-weight: 300;
x: parent.width / 2 - self.width / 2;
}
HaText {
text: "Setpoint: 19°C";
font-size: Style.tile-title-font-size;
color: Palette.hvac-knob-foreground;
font-weight: 300;
x: parent.width / 2 - self.width / 2;
}
}
}
VerticalLayout {
y: root.height / 2 - self.preferred-height / 2;
x: Math.max(36px + root.width / 2,root.height);
spacing: Measurements.padding;
// animate the opacity as it reduces some visual pop when HVAC minimises to
// not be full screen.
opacity: root.full-screen ? 1 : 0;
animate opacity {
duration: Animation.full-screen-duration / 2;
easing: ease-in-out-sine;
}
ZoneButton {
zone-name: "Kitchen";
zone-set-point: 22;
}
ZoneButton {
zone-name: "Living Room";
zone-set-point: 22;
}
ZoneButton {
zone-name: "Office";
zone-set-point: 19;
}
ZoneButton {
zone-name: "Master Bedroom";
zone-set-point: 17;
}
}
x: 0;
VerticalLayout {
alignment: end;
spacing: 5px;
padding: 5px;
controls := Rectangle {
border-radius: 20px;
width: 95%;
height: self.preferred-height;
background: Palette.music-gradient.transparentize(0.2);
animate height {
duration: 1000ms;
easing: ease-in-out-sine;
}
HorizontalLayout {
alignment: space-around;
padding-top: 15px;
padding-bottom: 15px;
}
}
}
Image {
source: @image-url("../images/enlarge.svg");
opacity: root.full-screen ? 0 : 0.6;
width: 40px;
colorize: Palette.foreground;
x: root.width - self.width - 30px;
y: 30px;
animate opacity {
duration: Animation.full-screen-duration;
easing: ease-in-out-sine;
}
}
closeButton := Image {
opacity: root.full-screen ? 1 : 0;
animate opacity {
duration: Animation.full-screen-duration;
easing: ease-in-out-sine;
}
source: @image-url("../images/reduce.svg");
colorize: white;
x: root.width - self.width - 30px;
y: 30px;
width: 60px;
height: 60px;
TouchArea {
enabled: closeButton.opacity > 0.1;
clicked => {
root.full-screen = false;
AppState.showFullScreen(-1);
}
}
}
}
}

View file

@ -0,0 +1,20 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT
import { Palette,Measurements,Colors } from "../common.slint";
import { AppState } from "../appState.slint";
import { HaText } from "general/haText.slint";
import { InnerShadowRectangle } from "general/innerShadowRectangle.slint";
export component Info {
in property <string> name;
in property <string> id;
in property <bool> full-screen: false;
tile := InnerShadowRectangle {
inner-color: Palette.info-alternate-background;
inner-shadow-blur: 40px;
// clip: true;
background: Palette.info-background;
border-radius: Measurements.tile-radius;
@children
}
}

View file

@ -0,0 +1,123 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT
import { Palette, Measurements, Colors, Style } from "../common.slint";
import { FancySlider } from "general/fancySlider.slint";
import { InnerShadowRectangle } from "general/innerShadowRectangle.slint";
import { Control } from "control.slint";
import { AppState } from "../appState.slint";
import { HaText } from "general/haText.slint";
import { DropShadowToggle} from "general/toggle.slint";
export component Lamp inherits Control {
in property <length> tilePadding: (root.height > Measurements.small-height-tile) ? 36px : 18px;
show-label: false;
tile-shadow-blur: 0px;
tile := InnerShadowRectangle {
width: 100%;
height: 100%;
clip: true;
inner-color: Palette.lamp-background.mix(Palette.lamp-shadow,(slider.value / 24));
inner-shadow-color: Palette.lamp-shadow;
inner-shadow-blur: tile.height / 5;
TouchArea {
clicked => {
slider.toggle();
}
}
Rectangle {
x: tile.width - self.width + 40px;
y: (root.width > Measurements.small-width-tile) ? -120px : -80px;
animate y {
duration: 300ms;
easing: ease-in-out-sine;
}
clip: true;
width: 70%;
height: 100%;
sh := Image {
property <[image]> frames: [
@image-url("../images/lamp/0000.png"),
@image-url("../images/lamp/0001.png"),
@image-url("../images/lamp/0002.png"),
@image-url("../images/lamp/0003.png"),
@image-url("../images/lamp/0004.png"),
@image-url("../images/lamp/0005.png"),
@image-url("../images/lamp/0006.png"),
@image-url("../images/lamp/0007.png"),
@image-url("../images/lamp/0008.png"),
@image-url("../images/lamp/0009.png"),
@image-url("../images/lamp/0010.png"),
@image-url("../images/lamp/0011.png"),
@image-url("../images/lamp/0012.png"),
@image-url("../images/lamp/0013.png"),
@image-url("../images/lamp/0014.png"),
@image-url("../images/lamp/0015.png"),
@image-url("../images/lamp/0016.png"),
@image-url("../images/lamp/0017.png"),
@image-url("../images/lamp/0018.png"),
@image-url("../images/lamp/0019.png"),
@image-url("../images/lamp/0020.png"),
@image-url("../images/lamp/0021.png"),
@image-url("../images/lamp/0022.png"),
@image-url("../images/lamp/0023.png"),
@image-url("../images/lamp/0024.png"),
];
property <int> frame: 0;
source: frames[slider.value];
animate frame {
duration: 300ms;
easing: ease-in-out-sine;
}
}
}
v := VerticalLayout {
padding: tilePadding;
width: 100%;
height: 100%;
alignment: space-between;
Rectangle {
width: 100%;
VerticalLayout {
alignment: start;
HaText {
text: root.name;
font-size: Style.tile-title-font-size;
font-weight: 400;
color: Palette.lamp-foreground;
}
}
}
slider := FancySlider {
maxValue: 24;
value: self.maxValue;
width: root.width * 0.8;
icon: @image-url("../images/brightness.svg");
colorize-icon: Colors.black;
}
}
switch := DropShadowToggle {
y: root.height < Measurements.medium-height-tile ? root.height - self.height - tilePadding : tilePadding * 2.5;
x: root.height < Measurements.medium-height-tile ? root.width - self.width : root.x + tilePadding/2;
labelOff: "";
labelOn: "";
scale: 33%;
toggleOpacity: 0.4;
active: slider.value > 0;
touchEnabled: false;
control-color: self.active ? Palette.lamp-background : Palette.lamp-shadow ;
inner-shadow-color: self.active ? Palette.shadow-color : Palette.slider-background.darker(0.1);
inner-color-inactive: Palette.slider-background;
inner-color-active: Palette.slider-foreground;
}
}
}

View file

@ -0,0 +1,67 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT
import { AppState, ComponentData } from "../../appState.slint";
import { FullScreenWidgetLoader } from "fullScreenWidgetLoader.slint";
export component FullScreenView inherits Rectangle {
property <ComponentData> full-screen-data: { id: "", x: 60, y: 60, width: 1800, height: 900, background: #00bf1d, visible: true };
property <bool> full-screen: false;
backdrop := Rectangle {
width: 100%;
height: 100%;
opacity: 0;
background: black;
touchCatcher := TouchArea { }
states [
isVisible when AppState.full-screen-index != -1 && full-screen: {
opacity: 0.7;
in {
animate opacity {
duration: 300ms;
easing: ease-in-out-sine;
}
}
out {
animate opacity {
duration: 300ms;
easing: ease-in-out-sine;
}
}
}
]
}
fsw := FullScreenWidgetLoader {
in-out property <ComponentData> normal-layout-data;
data: full-screen ? full-screen-data : normal-layout-data;
property <string> full-screen-index: AppState.full-screen-index;
changed full-screen-index => {
full-screen = false;
closeTimer.running = true;
}
init => {
fsw.index = AppState.full-screen-index;
fsw.type = AppState.component-details[AppState.full-screen-index].type;
fsw.normal-layout-data = AppState.current-layout-data.components[AppState.full-screen-index];
}
}
closeTimer := Timer {
running: false;
interval: 300ms;
triggered => {
AppState.showing-full-screen = false;
AppState.last-selected-index = -1;
}
}
Timer {
interval: 1ms;
triggered => {
self.running = false;
full-screen = true;
}
}
}

View file

@ -0,0 +1,124 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT
import { AppState, WidgetType, ComponentData } from "../../appState.slint";
import { Lamp } from "../lamp.slint";
import { Appliance } from "../appliance.slint";
import { Overhead } from "../overhead.slint";
import { Info } from "../info.slint";
import { Graph } from "../graph.slint";
import { Control } from "../control.slint";
import { MusicPlayer } from "../musicPlayer.slint";
import { Camera } from "../camera.slint";
import { HVAC } from "../hvac.slint";
import { Alarm } from "../alarm.slint";
import { Measurements, Animation } from "../../common.slint";
export component FullScreenWidgetLoader {
in property <int> index;
in property <ComponentData> data;
property <bool> show: false;
property <bool> moveMode: false;
in property <bool> skip-initial-fade: false;
in property <WidgetType> type;
property <length> animTargetX: data.x * 1px;
property <length> animTargetY: data.y * 1px;
property <length> animTargetWidth: data.width * 1px;
property <length> animTargetHeight: data.height * 1px;
animate animTargetX, animTargetY, animTargetWidth, animTargetHeight {
duration: Animation.full-screen-duration;
easing: ease-in-out-sine;
}
changed data => {
animTargetX = self.data.x * 1px;
animTargetY = self.data.y * 1px;
animTargetWidth = self.data.width * 1px;
animTargetHeight = self.data.height * 1px;
}
opacity: 1;
x: animTargetX * AppState.x-scale;
y: animTargetY * AppState.y-scale;
width: animTargetWidth * AppState.x-scale;
height: animTargetHeight * AppState.y-scale;
// Use the correct component based on type
if root.type == WidgetType.lamp: Lamp {
name: AppState.component-details[root.index].name;
id: AppState.component-details[root.index].id;
width: root.width;
height: root.height;
full-screen: true;
}
if root.type == WidgetType.appliance: Appliance {
name: AppState.component-details[root.index].name;
id: AppState.component-details[root.index].id;
width: root.width;
height: root.height;
full-screen: true;
}
if root.type == WidgetType.overhead: Overhead {
name: AppState.component-details[root.index].name;
id: AppState.component-details[root.index].id;
width: root.width;
height: root.height;
full-screen: true;
}
if root.type == WidgetType.info: Info {
name: AppState.component-details[root.index].name;
id: AppState.component-details[root.index].id;
width: root.width;
height: root.height;
full-screen: true;
}
if root.type == WidgetType.graph: Graph {
name: AppState.component-details[root.index].name;
id: AppState.component-details[root.index].id;
width: root.width;
height: root.height;
full-screen: true;
}
if root.type == WidgetType.control: Control {
name: AppState.component-details[root.index].name;
id: AppState.component-details[root.index].id;
width: root.width;
height: root.height;
full-screen: true;
}
if root.type == WidgetType.music: MusicPlayer {
name: AppState.component-details[root.index].name;
id: AppState.component-details[root.index].id;
width: root.width;
height: root.height;
full-screen: true;
}
if root.type == WidgetType.hvac: HVAC {
name: AppState.component-details[root.index].name;
id: AppState.component-details[root.index].id;
index: root.index;
width: root.width;
height: root.height;
full-screen: true;
}
if root.type == WidgetType.camera: Camera {
name: AppState.component-details[root.index].name;
id: AppState.component-details[root.index].id;
width: root.width;
height: root.height;
full-screen: true;
}
if root.type == WidgetType.alarm: Alarm {
name: AppState.component-details[root.index].name;
id: AppState.component-details[root.index].id;
width: root.width;
height: root.height;
full-screen: true;
}
}

View file

@ -0,0 +1,305 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT
import { DoorState, Doors } from "../general/doors.slint";
import { ViewButton } from "../mainView/viewButton.slint";
import { Sidebar } from "sidebar.slint";
import { WidgetLoader } from "widgetLoader.slint";
import { Switch, Palette as StdPalette } from "std-widgets.slint";
import { InnerShadowRectangle } from "../general/innerShadowRectangle.slint";
import { Measurements, Palette, Animation } from "../../common.slint";
import { AppState, ComponentData } from "../../appState.slint";
import { FullScreenWidgetLoader } from "fullScreenWidgetLoader.slint";
import { FullScreenView } from "fullScreenView.slint";
export component MainScreen inherits Rectangle {
property <int> internal-target-page: AppState.target-page;
property <bool> transitioning: false;
in-out property <bool> door-component-loaded: true;
in-out property <DoorState> initial-door-state: closed;
property <bool> demo-locked: true;
width: 100%;
height: 100%;
changed width => {
AppState.window-width = self.width;
}
changed height => {
AppState.window-height = self.height;
}
init => {
AppState.window-width = self.width;
AppState.window-height = self.height;
StdPalette.color-scheme = ColorScheme.dark;
}
changed internal-target-page => {
if AppState.target-page != AppState.current-page {
if !transitioning {
AppState.current-page = AppState.target-page;
}
transitioning = true;
enableTouch.running = false;
enableTouch.running = true;
}
}
enableTouch := Timer {
interval: 1400ms;
triggered => {
self.running = false;
transitioning = false;
AppState.current-page = AppState.target-page;
}
}
background: Palette.background-gradient;
animate background {
duration: Animation.theme-change-duration;
easing: ease-in-out-sine;
}
swipe := TouchArea {
x: 0;
y: 0;
width: 500px;
in-out property <bool> showing-sidebar: false;
property <bool> first-touch: false;
property <length> initial-position;
property <length> alt-side-bar-x: 0;
out property <bool> swiping: false;
in-out property <bool> blocker-enabled: true;
changed pressed => {
if !self.pressed {
if alt-side-bar-x >= (sidebar.width * 0.4) {
showing-sidebar = true;
}
if showing-sidebar {
alt-side-bar-x = sidebar.width;
} else {
alt-side-bar-x = 0;
}
swipe.swiping = false;
first-touch = false;
}
}
moved => {
if !first-touch {
first-touch = true;
swiping = true;
initial-position = self.mouse-x;
} else {
alt-side-bar-x = clamp(self.mouse-x - initial-position, 0, sidebar.width);
}
}
Rectangle {
x: 0;
y: 0;
width: root.width;
height: root.height;
navigation := Rectangle {
filterShadow := Rectangle {
x: 0;
y: 0;
width: 100%;
height: root.height - 100px;
border-radius: 0px;
drop-shadow-blur: (AppState.current-page > 3) ? 15px : 1px;
drop-shadow-color: Palette.shadow-color;
background: Palette.background-gradient;
animate background {
duration: Animation.theme-change-duration;
easing: ease-in-out-sine;
}
}
navBar := Rectangle {
x: 36px;
y: self.height / 5;
width: AppState.current-page > (AppState.pageData.length - 7) ? 1848px : 1380px;
animate width {
duration: Animation.transitionDuration;
easing: ease-in-out-sine;
}
height: 121px;
HorizontalLayout {
spacing: 10px;
ViewButton {
target-page: 0;
text: "House";
}
ViewButton {
target-page: 1;
text: "Kitchen";
}
ViewButton {
target-page: 2;
text: "Master Bedroom";
}
ViewButton {
target-page: 3;
text: "Office";
}
}
}
filterBar := Rectangle {
Rectangle {
y: root.height - self.height;
height: 120px;
HorizontalLayout {
spacing: 10px;
ViewButton {
font-size: 2rem;
target-page: 4;
text: "Controls";
}
ViewButton {
font-size: 2rem;
target-page: 5;
text: "Lamps";
}
ViewButton {
font-size: 2rem;
target-page: 6;
text: "Overhead Lights";
}
ViewButton {
font-size: 2rem;
target-page: 7;
text: "Appliances";
}
ViewButton {
font-size: 2rem;
target-page: 8;
text: "Info";
}
ViewButton {
font-size: 2rem;
target-page: 9;
text: "Graphs";
}
}
}
}
// This whole holder could be animated off screen, faded, whatever when the camera fills the screen.
widgetHolder := Rectangle {
width: 100%;
height: 100%;
for i[index] in AppState.component-details: WidgetLoader {
index: index;
type: AppState.component-details[index].type;
data: AppState.current-layout-data.components[index];
}
}
if AppState.showing-full-screen: fullScreenWidgetHolder := FullScreenView { }
Rectangle {
opacity: 0.5 * (sidebar-holder.x / sidebar.width);
background: black;
ta-blocker := TouchArea {
enabled: blocker-enabled && parent.opacity > 0.1;
changed pressed => {
if !self.pressed {
if alt-side-bar-x <= (sidebar.width * 0.6) {
showing-sidebar = false;
}
if showing-sidebar {
alt-side-bar-x = sidebar.width;
} else {
alt-side-bar-x = 0;
}
blocker-enabled = true;
swipe.swiping = false;
first-touch = false;
}
}
clicked => {
if self.mouse-x > sidebar.width {
showing-sidebar = false;
}
}
moved => {
if !first-touch {
first-touch = true;
swiping = true;
initial-position = self.mouse-x;
} else {
alt-side-bar-x = clamp(sidebar.width + self.mouse-x - initial-position, 0, sidebar.width);
}
}
}
}
sidebar-holder := Rectangle {
states [
showing-sidebar when showing-sidebar && !swipe.swiping: {
x: sidebar.width;
in {
animate x {
duration: 150ms;
easing: ease-in;
}
}
}
swiping when swipe.swiping: {
x: alt-side-bar-x;
}
not-showing-sidebar when !showing-sidebar && !swipe.swiping: {
x: 0;
in {
animate x {
duration: 150ms;
easing: ease-in;
}
}
}
]
sidebar := Sidebar {
drop-shadow-blur: sidebar-holder.x == 0 ? 0 : 30px;
drop-shadow-color: black.transparentize(0.5);
x: -self.width;
lockDemo => {
showing-sidebar = false;
door-component-loaded = true;
if showing-sidebar {
alt-side-bar-x = sidebar.width;
} else {
alt-side-bar-x = 0;
}
blocker-enabled = true;
swipe.swiping = false;
first-touch = false;
}
}
}
}
}
}
if door-component-loaded: doors := Doors {
doorsOpened => {
door-component-loaded = false;
initial-door-state = DoorState.open;
}
demo-locked: demo-locked;
initial-door-state: initial-door-state;
}
}

View file

@ -0,0 +1,149 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT
import { Measurements, Palette } from "../../common.slint";
import { ThemeSwitch } from "../general/themeSwitch.slint";
import { AboutSlint, Button } from "std-widgets.slint";
import { AppState } from "../../appState.slint";
import { HaText } from "../general/haText.slint";
export component Sidebar inherits Rectangle {
width: Measurements.sidebar-width;
height: 100%;
callback lockDemo();
Rectangle {
x: root.width - self.width / 2;
border-radius: self.width / 4;
width: 30px;
height: 100px;
background: Palette.tab;
drop-shadow-blur: 4px;
drop-shadow-color: black.transparentize(0.5);
drop-shadow-offset-x: 2px;
drop-shadow-offset-y: 2px;
Rectangle {
height: 85%;
width: 3px;
x: parent.width - 7px;
background: Palette.tab-highlight;
}
}
Rectangle {
background: Palette.background-gradient;
Rectangle {
opacity: root.x / Measurements.sidebar-width;
background: Palette.background;
}
VerticalLayout {
alignment: space-between;
padding-top: Measurements.sidebar-padding;
spacing: Measurements.sidebar-spacing;
VerticalLayout {
alignment: start;
spacing: Measurements.sidebar-spacing;
padding: Measurements.sidebar-padding;
HorizontalLayout {
spacing: 10px;
alignment: stretch;
HaText {
text: "Theme: ";
horizontal-stretch: 0;
vertical-alignment: center;
color: Palette.foreground;
font-size: 2rem;
}
VerticalLayout {
alignment: center;
ThemeSwitch {
scale: 0.5;
}
}
}
Rectangle {
width: 100%;
height: 50px;
border-radius: self.height / 2;
background: Palette.alternate-background;
HorizontalLayout {
alignment: space-around;
HaText {
vertical-alignment: center;
text: "Lock Controls ";
color: Palette.foreground;
font-size: 2rem;
}
VerticalLayout {
alignment: center;
Image {
source: @image-url("../../images/lock.svg");
width: 30px;
height: 30px;
colorize: Palette.foreground;
}
}
}
TouchArea {
clicked => {
root.lockDemo();
}
}
}
Rectangle {
width: 100%;
height: 50px;
border-radius: self.height / 2;
background: ta2.pressed ? Palette.background : Palette.alternate-background;
ta2 := TouchArea { }
HaText {
text: "setting 2";
color: Palette.foreground;
font-size: 2rem;
TouchArea { }
}
}
Rectangle {
width: 100%;
height: 50px;
border-radius: self.height / 2;
background: ta3.pressed ? Palette.background : Palette.alternate-background;
ta3 := TouchArea { }
HaText {
text: "setting 3";
color: Palette.foreground;
font-size: 2rem;
TouchArea { }
}
}
Rectangle {
width: 100%;
height: 50px;
border-radius: self.height / 2;
background: ta4.pressed ? Palette.background : Palette.alternate-background;
ta4 := TouchArea { }
HaText {
text: "setting 4";
color: Palette.foreground;
font-size: 2rem;
TouchArea { }
}
}
}
AboutSlint {
width: root.width * 0.8;
x: root.width * 0.1;
}
}
}
}

View file

@ -0,0 +1,43 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT
import { Palette } from "../../common.slint";
import { AppState } from "../../appState.slint";
import { HaText } from "../general/haText.slint";
export component ViewButton inherits Rectangle {
in property <int> target-page;
in property <string> text <=> t.text;
in property <brush> active-color: Palette.selection-foreground;
in property <brush> inactive-color: Palette.foreground;
in property <length> font-size: 3rem;
property <bool> is-active: target-page == AppState.target-page;
TouchArea {
clicked => {
AppState.target-page = target-page;
AppState.first-run = false;
}
}
Rectangle {
background: is-active ? Palette.accent-background : Palette.accent-background.transparentize(0.9);
animate background {
duration: 200ms;
easing: ease-in-out-sine;
}
border-radius: self.height / 2;
width: is-active ? t.width : t.width * 0.8;
animate width {
duration: 500ms;
easing: ease-in-out-sine;
}
height: 3px;
y: parent.height - 30px;
}
t := HaText {
x: (parent.width - self.width) / 2;
y: (parent.height - self.height) / 2;
font-size: root.font-size;
color: is-active ? root.active-color : root.inactive-color;
}
}

View file

@ -0,0 +1,217 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT
import { AppState, WidgetType, ComponentData } from "../../appState.slint";
import { Lamp } from "../lamp.slint";
import { Appliance } from "../appliance.slint";
import { Overhead } from "../overhead.slint";
import { Info } from "../info.slint";
import { Graph } from "../graph.slint";
import { Control } from "../control.slint";
import { MusicPlayer } from "../musicPlayer.slint";
import { Camera } from "../camera.slint";
import { HVAC } from "../hvac.slint";
import { Dishwasher } from "../dishwasher.slint";
import { Microwave } from "../microwave.slint";
import { WeatherInfo } from "../weatherInfo.slint";
import { TimeInfo } from "../timeInfo.slint";
import { PowerInfo } from "../powerInfo.slint";
import { Alarm } from "../alarm.slint";
import { Measurements, Animation } from "../../common.slint";
export component WidgetLoader {
in property <int> index;
in property <ComponentData> data;
property <bool> show: data.visible;
property <bool> moveMode: false;
in property <WidgetType> type;
property <length> targetX;
property <length> targetY;
property <length> targetWidth;
property <length> targetHeight;
property <length> animTargetX;
property <length> animTargetY;
property <length> animTargetWidth;
property <length> animTargetHeight;
animate animTargetX, animTargetY, animTargetWidth, animTargetHeight {
duration: Animation.transitionDuration;
easing: ease-in-out-sine;
}
changed data => {
if root.show != self.data.visible {
// hiding then set the position so it fades in on the correct place
if !root.show {
targetX = self.data.x * 1px;
targetY = self.data.y * 1px;
targetWidth = self.data.width * 1px;
targetHeight = self.data.height * 1px;
animTargetX = self.data.x * 1px;
animTargetY = self.data.y * 1px;
animTargetWidth = self.data.width * 1px;
animTargetHeight = self.data.height * 1px;
} // but if visible don't change the pos so it just fades away.
root.show = self.data.visible == true;
} else {
targetX = self.data.x * 1px;
targetY = self.data.y * 1px;
targetWidth = self.data.width * 1px;
targetHeight = self.data.height * 1px;
animTargetX = self.data.x * 1px;
animTargetY = self.data.y * 1px;
animTargetWidth = self.data.width * 1px;
animTargetHeight = self.data.height * 1px;
}
}
init => {
targetX = root.data.x * 1px;
targetY = root.data.y * 1px;
targetWidth = root.data.width * 1px;
targetHeight = root.data.height * 1px;
animTargetX = root.data.x * 1px;
animTargetY = root.data.y * 1px;
animTargetWidth = root.data.width * 1px;
animTargetHeight = root.data.height * 1px;
root.show = root.data.visible;
}
opacity: 0;
x: AppState.first-run ? targetX : (root.opacity < 1 ? targetX : animTargetX) * AppState.x-scale;
y: AppState.first-run ? targetY : (root.opacity < 1 ? targetY : animTargetY) * AppState.y-scale;
width: AppState.first-run ? targetWidth : (root.opacity < 1 ? targetWidth : animTargetWidth) * AppState.x-scale;
height: AppState.first-run ? targetHeight : (root.opacity < 1 ? targetHeight : animTargetHeight) * AppState.y-scale;
visible: AppState.last-selected-index != self.index && root.opacity > 0;
states [
instantVisible when root.show && AppState.first-run: {
root.opacity: 1;
}
isVisible when root.show && !AppState.first-run: {
root.opacity: 1;
in {
animate root.opacity {
delay: Animation.transitionDuration / 2;
duration: Animation.transitionDuration;
easing: ease-in-out-sine;
}
}
out {
animate root.opacity {
duration: Animation.transitionDuration / 2;
easing: ease-in-out-sine;
}
}
}
]
// Use the correct component based on type
if root.type == WidgetType.lamp: Lamp {
name: AppState.component-details[root.index].name;
id: AppState.component-details[root.index].id;
index: root.index;
width: root.width;
height: root.height;
}
if root.type == WidgetType.appliance: Appliance {
name: AppState.component-details[root.index].name;
id: AppState.component-details[root.index].id;
width: root.width;
height: root.height;
}
if root.type == WidgetType.overhead: Overhead {
name: AppState.component-details[root.index].name;
id: AppState.component-details[root.index].id;
width: root.width;
height: root.height;
}
if root.type == WidgetType.info: Info {
name: AppState.component-details[root.index].name;
id: AppState.component-details[root.index].id;
width: root.width;
height: root.height;
}
if root.type == WidgetType.graph: Graph {
name: AppState.component-details[root.index].name;
id: AppState.component-details[root.index].id;
width: root.width;
height: root.height;
}
if root.type == WidgetType.control: Control {
name: AppState.component-details[root.index].name;
id: AppState.component-details[root.index].id;
index: root.index;
width: root.width;
height: root.height;
}
if root.type == WidgetType.music: MusicPlayer {
name: AppState.component-details[root.index].name;
id: AppState.component-details[root.index].id;
index: root.index;
width: root.width;
height: root.height;
}
if root.type == WidgetType.camera: Camera {
name: AppState.component-details[root.index].name;
id: AppState.component-details[root.index].id;
index: root.index;
width: root.width;
height: root.height;
}
if root.type == WidgetType.hvac: HVAC {
index: root.index;
name: AppState.component-details[root.index].name;
id: AppState.component-details[root.index].id;
width: root.width;
height: root.height;
}
if root.type == WidgetType.microwave: Microwave {
index: root.index;
name: AppState.component-details[root.index].name;
id: AppState.component-details[root.index].id;
width: root.width;
height: root.height;
}
if root.type == WidgetType.dishwasher: Dishwasher {
index: root.index;
name: AppState.component-details[root.index].name;
id: AppState.component-details[root.index].id;
width: root.width;
height: root.height;
}
if root.type == WidgetType.weatherInfo: WeatherInfo {
index: root.index;
name: AppState.component-details[root.index].name;
id: AppState.component-details[root.index].id;
width: root.width;
height: root.height;
}
if root.type == WidgetType.timeInfo: TimeInfo {
index: root.index;
name: AppState.component-details[root.index].name;
id: AppState.component-details[root.index].id;
width: root.width;
height: root.height;
}
if root.type == WidgetType.powerInfo: PowerInfo {
index: root.index;
name: AppState.component-details[root.index].name;
id: AppState.component-details[root.index].id;
width: root.width;
height: root.height;
}
if root.type == WidgetType.alarm: Alarm {
index: root.index;
name: AppState.component-details[root.index].name;
id: AppState.component-details[root.index].id;
width: root.width;
height: root.height;
}
}

View file

@ -0,0 +1,9 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT
import { Palette,Measurements,Colors } from "../common.slint";
import { Appliance } from "appliance.slint";
export component Microwave inherits Appliance {
time-remaining: "0:12 mins";
image-size: self.width * 1;
appliance-image: @image-url("../images/microwave.jpg");
}

View file

@ -0,0 +1,235 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT
import { Measurements, Colors, Palette } from "../common.slint";
import { Control} from "control.slint";
import { AppState } from "../appState.slint";
import { HaText } from "general/haText.slint";
export component AudioVisualizer inherits Rectangle {
width: self.preferred-width;
height: 100px;
y: 0px;
// Define the number of bars
property <int> numBars: 50;
// Define the bar width and spacing
property <length> barWidth: self.width / numBars;
property <length> spacing: 2px;
HorizontalLayout {
spacing: parent.spacing;
alignment: start;
y: 80px;
// Random heights for demonstration purposes
property <[float]> getBarHeight:
[
0.536607,
0.927906,
0.865396,
0.503682,
0.225622,
0.038002,
0.756923,
0.914055,
0.783485,
0.614367,
0.981598,
0.399460,
0.577364,
0.786051,
0.521291,
0.716059,
0.917610,
0.555306,
0.935384,
0.166469,
0.677960,
0.331542,
0.828376,
0.334301,
0.493934,
0.742222,
0.743564,
0.126049,
0.501512,
0.933921,
0.600989,
0.876927,
0.364581,
0.942666,
0.197834,
0.762524,
0.835514,
0.134315,
0.407657,
0.960525,
0.222813,
0.176457,
0.610204,
0.0296424,
0.4449036,
0.9250662,
0.6634989,
0.1265369,
0.636468,
0.320777
];
// Create the visualizer bars
for bar[i] in numBars: Rectangle {
width: barWidth;
height: getBarHeight[i] * 1px * 4000%;
background: Palette.music-gradient.transparentize(0.2);
y: -self.height / 2;
}
}
}
export component MusicPlayer inherits Control {
property <string> title: "Maxwell's Silver Hammer";
property <int> current-page: AppState.current-page;
property <string> artist: "The Beatles";
property <string> album: "Abbey Road";
property <bool> unlocked: false;
property <image> cover-art: @image-url("../images/abbey-road.jpg");
property <bool> is-active: false;
tile := Rectangle {
border-color: white;
border-width: 2px;
x: 0cm;
Image {
source: cover-art;
width: 100%;
image-fit: cover;
height: 100%;
horizontal-alignment: center;
vertical-alignment: center;
}
VerticalLayout {
alignment: end;
spacing: 5px;
padding: 5px;
HorizontalLayout {
width: tile.width;
alignment: start;
padding-left: 10px;
AudioVisualizer {
width: tile.width * 0.7;
states [
isVisible when root.height < Measurements.large-height-tile: {
opacity: 0.0;
in {
animate opacity {
duration: 300ms;
easing: ease-in-out-sine;
}
}
}
isNotVisible when root.height >= Measurements.large-height-tile: {
opacity: 1.0;
in {
animate opacity {
duration: 300ms;
easing: ease-in-out-sine;
}
}
}
]
}
}
controls := Rectangle {
border-radius: 20px;
width: 95%;
height: self.preferred-height;
background: Palette.music-gradient.transparentize(0.2);
animate height {
duration: 1000ms;
easing: ease-in-out-sine;
}
HorizontalLayout {
alignment: space-around;
padding-top: 15px;
padding-bottom: 15px;
Image {
source: @image-url("../images/back.svg");
width: 35px;
height: 35px;
colorize: Palette.music-alternate-foreground;
}
Image {
source: @image-url("../images/pause.svg");
width: 35px;
height: 35px;
colorize: Palette.music-alternate-foreground;
}
Image {
source: @image-url("../images/fwd.svg");
width: 35px;
height: 35px;
colorize: Palette.music-alternate-foreground;
}
}
}
info := Rectangle {
border-radius: 20px;
width: 95%;
height: self.preferred-height;
background: Palette.music-gradient.transparentize(0.2);
animate height {
duration: 1000ms;
easing: ease-in-out-sine;
}
VerticalLayout {
padding-top: (tile.height > Measurements.small-height-tile) ? 36px : 18px;
padding: (tile.height <= Measurements.small-height-tile) ? 36px : 18px;
spacing: 10px;
HaText {
color: Palette.control-background;
text: title;
font-size: 3rem;
font-weight: 500;
horizontal-alignment: left;
vertical-alignment: center;
}
Rectangle {
height: 10px;
}
HaText {
color: Palette.control-background;
text: artist;
font-size: 2rem;
font-weight: 400;
horizontal-alignment: left;
vertical-alignment: center;
}
Rectangle {
height: 20px;
}
HaText {
color: Palette.music-alternate-foreground;
text: "Album: " + album;
font-size: 2rem;
font-weight: 400;
horizontal-alignment: left;
vertical-alignment: center;
}
}
}
}
}
}

View file

@ -0,0 +1,72 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT
import { Palette, Measurements, Animation } from "../common.slint";
import { FancySlider } from "general/fancySlider.slint";
import { AppState } from "../appState.slint";
import { HaText } from "general/haText.slint";
import { InnerShadowRectangle } from "general/innerShadowRectangle.slint";
import { DropShadowToggle} from "general/toggle.slint";
import { Control } from "control.slint";
export component Overhead inherits Control {
show-label: false;
full-screen: false;
tile-shadow-blur: 0px;
in property <length> tilePadding: (root.height > Measurements.small-height-tile) ? 36px : 18px;
tile := InnerShadowRectangle {
width: 100%;
height: 100%;
clip: true;
inner-color: Palette.overhead-background.mix(Palette.overhead-shadow,(slider.value));
inner-shadow-color: Palette.overhead-shadow;
inner-shadow-blur: tile.height / 5;
TouchArea {
clicked => {
slider.toggle();
}
}
VerticalLayout {
alignment: space-between;
padding: tilePadding;
width: 100%;
height: 100%;
HorizontalLayout {
spacing: 10px;
alignment: space-between;
VerticalLayout {
alignment: start;
HaText {
text: root.name;
font-size: 20pt;
font-weight: 400;
color: Palette.overhead-foreground;
}
}
}
slider := FancySlider {
width: (root.height < Measurements.medium-height-tile) ? root.width - switch.width - 36px : root.width * 0.8;
value: 0.0;
icon: @image-url("../images/brightness.svg");
}
}
switch := DropShadowToggle {
y: root.height < Measurements.medium-height-tile ? root.height - self.height - tilePadding : tilePadding * 2.5;
x: root.height < Measurements.medium-height-tile ? root.width - self.width : root.x + (tilePadding / 2);
labelOff: "";
labelOn: "";
scale: 33%;
toggleOpacity: 0.2;
active: slider.value > 0;
touchEnabled: false;
control-color: self.active ? Palette.overhead-background : Palette.overhead-shadow;
inner-shadow-color: self.active ? Palette.overhead-background : Palette.overhead-foreground;
inner-color-inactive: Palette.slider-background;
inner-color-active: Palette.slider-foreground;
}
}
}

View file

@ -0,0 +1,77 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT
import { Palette,Measurements,Colors, Style } from "../common.slint";
import { Info } from "info.slint";
import { HaText } from "./general/haText.slint";
export component PowerInfo inherits Info {
in property <int> index;
in property <int> hours: 3;
in property <int> minutes: 15;
tile := Rectangle {
layout := VerticalLayout {
padding: (tile.height > Measurements.small-height-tile) ? 36px : 18px;
width: 100%;
height: 100%;
alignment: space-between;
Rectangle {
width: 100%;
VerticalLayout {
alignment: start;
HorizontalLayout {
alignment: start;
HaText {
text: root.name;
font-size: Style.tile-title-font-size;
font-weight: 400;
color: Palette.info-foreground;
}
HaText {
text: " today is ";
font-size: Style.tile-title-font-size;
font-weight: 400;
color: Palette.info-foreground;
}
HaText {
text: "320 W";
font-size: Style.tile-title-font-size;
font-weight: 800;
color: Colors.dustygold;
}
}
}
}
graph := Rectangle {
height: tile.height * 0.2;
HorizontalLayout {
alignment: center;
y: graph.height * 0.15;
Rectangle {
background: Colors.green70;
width: 30%;
}
Rectangle {
background: Colors.dustygold;
width: 50%;
}
Rectangle {
background: Colors.orange60;
width: 20%;
}
}
Rectangle {
height:tile.height * 0.3;
width: 8px;
drop-shadow-blur: 10px;
drop-shadow-color: Colors.black;
background: Colors.white;
y: -2px;
}
}
}
}
}

View file

@ -0,0 +1,75 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT
import { Palette,Measurements,Colors, Style } from "../common.slint";
import { Info } from "info.slint";
import { HaText } from "./general/haText.slint";
export component TimeInfo inherits Info {
in property <int> index;
in property <int> hours: 3;
in property <int> minutes: 15;
HorizontalLayout {
alignment: center;
spacing: 40px;
HorizontalLayout {
alignment: center;
HaText {
text: hours;
horizontal-alignment: center;
vertical-alignment: center;
color: Palette.info-foreground;
font-size: Style.H1-font-size;
}
HaText {
text: ":";
horizontal-alignment: center;
vertical-alignment: center;
color: Palette.info-foreground;
font-size: Style.H1-font-size;
}
HaText {
text: minutes;
horizontal-alignment: center;
vertical-alignment: center;
color: Palette.info-foreground;
font-size: Style.H1-font-size;
}
HaText {
text: " PM";
horizontal-alignment: center;
vertical-alignment: center;
color: Palette.info-foreground;
font-size: Style.H2-font-size;
}
}
date := Rectangle {
y: root.height * 0.15;
clip: true;
height: root.height * 0.7;
border-radius: 15px;
width: self.height;
background: Palette.date-background;
Rectangle {
height: 30%;
y: 0;
background: Palette.accent-background;
HaText {
text: "Oct";
font-size: Style.icon-title-font-size;
}
}
HaText {
text: "18";
y: parent.height * 0.4;
color: Palette.foreground;
font-size: Style.H2-font-size;
font-weight: 600;
}
}
}
}

View file

@ -0,0 +1,83 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT
import { Palette,Measurements,Colors, Style } from "../common.slint";
import { Info } from "info.slint";
import { HaText } from "./general/haText.slint";
export component Day inherits Rectangle {
in property <string> condition: "sunny";
in property <float> temp: 20.0;
in property <string> day: "Monday";
in property <bool> hilite: false;
if hilite: Rectangle {
border-bottom-left-radius: Measurements.tile-radius;
border-top-left-radius: Measurements.tile-radius;
background: Palette.info-alternate-background;
}
VerticalLayout {
alignment: center;
HaText {
text: day;
horizontal-alignment: center;
color: Palette.info-foreground;
font-size: Style.icon-title-font-size;
}
if condition == "sunny": Image {
height: 50px;
source: @image-url("../images/sunny.png");
}
if condition == "cloudy": Image {
height: 50px;
source: @image-url("../images/cloudy.png");
}
if condition == "rainy": Image {
height: 50px;
source: @image-url("../images/rainy.png");
}
HaText {
text: temp + "°C";
horizontal-alignment: center;
color: Palette.info-alternate-foreground;
font-size: Style.icon-title-font-size;
}
}
}
export component WeatherInfo inherits Info {
in property <int> index;
HorizontalLayout {
Day {
hilite: true;
condition: "sunny";
day: "Today";
temp: 21.0;
}
Day {
condition: "rainy";
day: "Tue";
temp: 16.0;
}
Day {
condition: "rainy";
day: "Wed";
temp: 18.0;
}
Day {
condition: "cloudy";
day: "Thu";
temp: 20.0;
}
Day {
condition: "sunny";
day: "Fri";
temp: 22.0;
}
}
}

View file

@ -0,0 +1,15 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT
import { MainScreen } from "components/mainView/mainScreen.slint";
export component AppWindow inherits Window {
preferred-width: 1920px;
preferred-height: 1080px;
min-width: 1000px;
min-height: 600px;
MainScreen {
door-component-loaded: false;
initial-door-state: open;
}
}

View file

@ -0,0 +1,12 @@
// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT
import { MainScreen } from "components/mainView/mainScreen.slint";
export component AppWindow inherits Window {
preferred-width: 1920px;
preferred-height: 1080px;
min-width: 1000px;
min-height: 600px;
MainScreen { }
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View file

@ -0,0 +1 @@
<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 27 22" xmlns="http://www.w3.org/2000/svg"><g fill="#2b263f" transform="translate(497.237 -963.987)"><path d="m-497.148 964.435h5.633v20.956h-5.633z"/><path d="m-481.037 964.435 10.479 20.956h-20.957z" transform="matrix(0 -1 .836269 0 -1294.88 493.876)"/></g></svg>

After

Width:  |  Height:  |  Size: 368 B

View file

@ -0,0 +1 @@
<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="1.5" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg"><g fill="none"><path d="m0 0h100v100h-100z"/><g stroke="#000"><circle cx="49.999315" cy="50.000218" r="16.783984" stroke-width="4.58955"/><g stroke-width="3.14"><path d="m50 32.774v-13.728" transform="matrix(1.39339 0 0 1.39339 -19.6694 -19.6694)"/><path d="m50 32.774v-13.728" transform="matrix(1.20671 .696694 -.696694 1.20671 24.4992 -45.1701)"/><path d="m50 32.774v-13.728" transform="matrix(.696694 1.20671 -1.20671 .696694 75.5008 -45.1701)"/><path d="m50 32.774v-13.728" transform="matrix(0 1.39339 -1.39339 0 119.669 -19.6694)"/><path d="m50 32.774v-13.728" transform="matrix(-.696694 1.20671 -1.20671 -.696694 145.17 24.4992)"/><path d="m50 32.774v-13.728" transform="matrix(-1.20671 .696694 -.696694 -1.20671 145.17 75.5008)"/><path d="m50 32.774v-13.728" transform="matrix(-1.39339 0 0 -1.39339 119.669 119.669)"/><path d="m50 32.774v-13.728" transform="matrix(-1.20671 -.696694 .696694 -1.20671 75.5008 145.17)"/><path d="m50 32.774v-13.728" transform="matrix(-.696694 -1.20671 1.20671 -.696694 24.4992 145.17)"/><path d="m50 32.774v-13.728" transform="matrix(0 -1.39339 1.39339 0 -19.6694 119.669)"/><path d="m50 32.774v-13.728" transform="matrix(.696694 -1.20671 1.20671 .696694 -45.1701 75.5008)"/><path d="m50 32.774v-13.728" transform="matrix(1.20671 -.696694 .696694 1.20671 -45.1701 24.4992)"/></g></g></g></svg>

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View file

@ -0,0 +1 @@
<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="1.5" viewBox="0 0 89 89" xmlns="http://www.w3.org/2000/svg"><g fill="none" stroke="#333"><path d="m428.144 792.813v76.18" stroke-width="9.86" transform="matrix(.67271754 0 0 .53717482 -243.877441 -422.106666)"/><path d="m403.913 792.813 25.03 25.03" stroke-width="9.91" transform="matrix(.58551323 0 0 .62421117 -208.044007 -489.539641)"/><path d="m403.913 792.813 25.03 25.03" stroke-width="9.91" transform="matrix(-.58551323 0 0 .62421117 296.328636 -489.539641)"/><path d="m428.144 792.813v76.18" stroke-width="9.86" transform="matrix(0 -.67272125 .53717595 0 -422.658531 332.720802)"/><path d="m403.913 792.813 25.03 25.03" stroke-width="9.91" transform="matrix(0 -.58551646 .62421248 0 -490.091648 296.88717)"/><path d="m403.913 792.813 25.03 25.03" stroke-width="9.91" transform="matrix(0 .58551646 .62421248 0 -490.091648 -207.488255)"/><path d="m428.144 792.813v76.18" stroke-width="9.86" transform="matrix(-.67271754 0 0 -.53717482 332.163622 511.501666)"/><path d="m403.913 792.813 25.03 25.03" stroke-width="9.91" transform="matrix(-.58551323 0 0 -.62421117 296.330188 578.934641)"/><path d="m403.913 792.813 25.03 25.03" stroke-width="9.91" transform="matrix(.58551323 0 0 -.62421117 -208.042456 578.934641)"/><path d="m428.144 792.813v76.18" stroke-width="9.86" transform="matrix(0 .67272125 -.53717595 0 510.943986 -243.323002)"/><path d="m403.913 792.813 25.03 25.03" stroke-width="9.91" transform="matrix(0 .58551646 -.62421248 0 578.377103 -207.48937)"/><path d="m403.913 792.813 25.03 25.03" stroke-width="9.91" transform="matrix(0 -.58551646 -.62421248 0 578.377103 296.886055)"/><g stroke-width="6.29"><path d="m397.421 798.974 61.268 61.269" transform="matrix(.95392602 0 0 .953928 -364.189251 -746.689)"/><path d="m397.421 798.974 61.268 61.269" transform="matrix(0 -.953928 .95392602 0 -747.24148 453.031)"/></g></g></svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

View file

@ -0,0 +1 @@
<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 105 106" xmlns="http://www.w3.org/2000/svg"><g fill="#333"><path d="m161.256 784.519v134.482h-134.482v-134.482zm-7.727 7.726h-119.029v119.029h119.029z" transform="matrix(.77653103 0 0 .776533 -20.239227 -608.56476)"/><path d="m105.405 836.507-.001-26.914c0-2.132 1.731-3.863 3.864-3.863 2.132 0 3.863 1.731 3.863 3.863v17.588l28.141-28.142c1.508-1.508 3.956-1.508 5.464 0 1.508 1.507 1.508 3.955 0 5.463l-28.142 28.142h17.587c2.133 0 3.864 1.731 3.864 3.863s-1.731 3.863-3.864 3.863h-26.913c-1.041 0-2.014-.414-2.732-1.132-.717-.717-1.132-1.691-1.131-2.731z" transform="matrix(-.77653103 0 0 -.776533 171.671187 668.37924)"/><path d="m105.405 836.507-.001-26.914c0-2.132 1.731-3.863 3.864-3.863 2.132 0 3.863 1.731 3.863 3.863v17.588l28.141-28.142c1.508-1.508 3.956-1.508 5.464 0 1.508 1.507 1.508 3.955 0 5.463l-28.142 28.142h17.587c2.133 0 3.864 1.731 3.864 3.863s-1.731 3.863-3.864 3.863h-26.913c-1.041 0-2.014-.414-2.732-1.132-.717-.717-1.132-1.691-1.131-2.731z" transform="matrix(.77653103 0 0 .776533 -67.220708 -561.58316)"/></g></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

View file

@ -0,0 +1 @@
<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 28 22" xmlns="http://www.w3.org/2000/svg"><g fill="#2b263f" transform="matrix(-1 0 0 1 -470.084 -963.987)"><path d="m-497.148 964.435h5.633v20.956h-5.633z"/><path d="m-481.037 964.435 10.479 20.956h-20.957z" transform="matrix(0 -1 .836269 0 -1294.88 493.876)"/></g></svg>

After

Width:  |  Height:  |  Size: 375 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6 KiB

View file

@ -0,0 +1 @@
<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="m23.498 9.77c1.592.177 2.832 1.529 2.832 3.168v6.375c0 1.759-1.428 3.187-3.187 3.187h-10.172c-1.759 0-3.187-1.428-3.187-3.187v-6.375c0-1.639 1.24-2.991 2.832-3.168v-2.69c0-1.443.573-2.827 1.593-3.847s2.404-1.593 3.847-1.593h.002c1.443 0 2.827.573 3.847 1.593s1.593 2.404 1.593 3.847zm-8.882-.02h6.882v-2.67c0-.913-.362-1.788-1.007-2.433-.646-.645-1.521-1.007-2.433-1.007h-.002c-.913 0-1.788.362-2.433 1.007s-1.007 1.52-1.007 2.433z" transform="translate(-6.05696)"/></svg>

After

Width:  |  Height:  |  Size: 627 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View file

@ -0,0 +1 @@
<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round" stroke-miterlimit="1.5" viewBox="0 0 46 49" xmlns="http://www.w3.org/2000/svg"><path d="m211.425 40.939c-.107-12.818 9.843-21.966 21.966-21.966s21.966 9.842 21.966 21.966c0 12.123-9.854 22.491-21.966 21.965 3.115-6.629 6.941-13.485-.311-21.178-6.458-6.852-17.477-2.966-21.655-.787z" fill="none" stroke="#fff" stroke-width="4" transform="matrix(-.894684 -.446699 .446699 -.894684 214.492 165.055)"/></svg>

After

Width:  |  Height:  |  Size: 496 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View file

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" class="size-6">
<path d="M18 1.5c2.9 0 5.25 2.35 5.25 5.25v3.75a.75.75 0 0 1-1.5 0V6.75a3.75 3.75 0 1 0-7.5 0v3a3 3 0 0 1 3 3v6.75a3 3 0 0 1-3 3H3.75a3 3 0 0 1-3-3v-6.75a3 3 0 0 1 3-3h9v-3c0-2.9 2.35-5.25 5.25-5.25Z" />
</svg>

After

Width:  |  Height:  |  Size: 309 B

View file

@ -0,0 +1 @@
<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 22 22" xmlns="http://www.w3.org/2000/svg"><g fill="#2b263f"><path d="m-497.148 964.435h5.633v20.956h-5.633z" transform="matrix(1.39903 0 0 1 696.144 -963.987)"/><path d="m-497.148 964.435h5.633v20.956h-5.633z" transform="matrix(1.49763 0 0 1 757.557 -963.987)"/></g></svg>

After

Width:  |  Height:  |  Size: 376 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View file

@ -0,0 +1 @@
<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 106 106" xmlns="http://www.w3.org/2000/svg"><g fill="#333"><path d="m161.256 784.519v134.482h-134.482v-134.482zm-7.727 7.726h-119.029v119.029h119.029z" transform="matrix(.77653103 0 0 .776533 -19.970542 -608.56476)"/><path d="m105.405 836.507-.001-26.914c0-2.132 1.731-3.863 3.864-3.863 2.132 0 3.863 1.731 3.863 3.863v17.588l28.141-28.142c1.508-1.508 3.956-1.508 5.464 0 1.508 1.507 1.508 3.955 0 5.463l-28.142 28.142h17.587c2.133 0 3.864 1.731 3.864 3.863s-1.731 3.863-3.864 3.863h-26.913c-1.041 0-2.014-.414-2.732-1.132-.717-.717-1.132-1.691-1.131-2.731z" transform="matrix(.77653103 0 0 .776533 -23.745932 -604.78926)"/><path d="m105.405 836.507-.001-26.914c0-2.132 1.731-3.863 3.864-3.863 2.132 0 3.863 1.731 3.863 3.863v17.588l28.141-28.142c1.508-1.508 3.956-1.508 5.464 0 1.508 1.507 1.508 3.955 0 5.463l-28.142 28.142h17.587c2.133 0 3.864 1.731 3.864 3.863s-1.731 3.863-3.864 3.863h-26.913c-1.041 0-2.014-.414-2.732-1.132-.717-.717-1.132-1.691-1.131-2.731z" transform="matrix(-.77653103 0 0 -.776533 129.720979 710.59924)"/></g></svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

View file

@ -0,0 +1 @@
<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg"><path d="m46.938.54-37.034 24.795s-1.671.928-1.671 2.392c0 1.949 2.114 2.584 2.114 2.584l20.373 7.794c.727.271 1.731-.5.791-1.475l-6.745-6.544s-1.874-1.776-1.874-2.946c0-1.171 1.151-2.207 1.151-2.207l24.529-22.897c.888-.815-.289-2.294-1.634-1.496z" fill-rule="nonzero"/></svg>

After

Width:  |  Height:  |  Size: 422 B

View file

@ -0,0 +1 @@
<svg clip-rule="evenodd" fill-rule="evenodd" stroke-linejoin="round" stroke-miterlimit="2" viewBox="0 0 64 64" xmlns="http://www.w3.org/2000/svg"><g fill="#d7dae0" fill-rule="nonzero"><path d="m17.024 63.411 37.034-24.799s1.671-.928 1.671-2.392c0-1.949-2.114-2.583-2.114-2.583l-20.373-7.791c-.727-.275-1.728.497-.791 1.475l6.745 6.522s1.874 1.78 1.874 2.946c0 1.167-1.151 2.207-1.151 2.207l-24.544 22.915c-.873.816.308 2.294 1.649 1.5z"/><path d="m46.938.54-37.034 24.795s-1.671.928-1.671 2.392c0 1.949 2.114 2.584 2.114 2.584l20.373 7.794c.727.271 1.731-.5.791-1.475l-6.745-6.544s-1.874-1.776-1.874-2.946c0-1.171 1.151-2.207 1.151-2.207l24.529-22.897c.888-.815-.289-2.294-1.634-1.496z"/></g></svg>

After

Width:  |  Height:  |  Size: 698 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Some files were not shown because too many files have changed in this diff Show more