Files
dashboard/dashboard/ui/main.slint
2026-08-16 19:40:08 +02:00

260 lines
6.3 KiB
Plaintext

import { BottomAppBar } from "./material/material.slint";
import {
Palette,
StyleMetrics,
Button,
ScrollView,
StandardTableView,
} from "std-widgets.slint";
import {
CalendarEventData,
MainPage,
WeatherData,
ThermostatData,
} from "./main_page.slint";
// import { } from "./calendar.slint";
import { Calendar } from "calendar.slint";
import { Energy } from "energy.slint";
import {
TabBar,
Switch,
MaterialStyleMetrics,
MaterialPalette,
ElevatedButton,
FilledButton,
} from "material/material.slint";
import { Icons } from "material/ui/icons/icons.slint";
export struct LightData {
id: string,
name: string,
on: bool,
available: bool,
}
export struct ThermometerData {
id: string,
name: string,
value: string,
unit: string,
}
export struct DateTimeData {
id: string,
date: string,
time: string,
}
export struct BatteryData {
state: string,
percent: float,
}
component Clock {
in property <DateTimeData> date-time;
VerticalLayout {
alignment: center;
padding-left: 5px;
padding-right: StyleMetrics.layout-padding;
Text {
text: date-time.date;
height: 16px;
font-weight: 100;
horizontal-alignment: right;
}
Text {
text: date-time.time;
font-size: 19px;
height: 19px;
font-weight: 500;
horizontal-alignment: right;
}
}
}
component Battery {
in property <BatteryData> battery;
VerticalLayout {
alignment: center;
padding-left: 5px;
padding-right: StyleMetrics.layout-padding;
Text {
text: battery.state;
height: 16px;
font-weight: 100;
horizontal-alignment: left;
}
Text {
text: "\{battery.percent}%";
font-size: 19px;
height: 19px;
font-weight: 500;
horizontal-alignment: left;
}
}
}
component Thermometer inherits Rectangle {
in property <ThermometerData> thermometer;
border-radius: 16px + 19px;
border-width: 2px;
border-color: MaterialPalette.surface_container_low;
background: MaterialPalette.surface_container_low;
VerticalLayout {
alignment: center;
padding-left: parent.border-radius / 2;
padding-right: parent.border-radius / 2;
Text {
text: thermometer.name;
height: 16px;
font-weight: 100;
color: MaterialPalette.primary;
}
Text {
text: "\{thermometer.value} \{thermometer.unit}";
height: 19px;
font-size: 19px;
font-weight: 500;
color: MaterialPalette.primary;
}
}
}
component LightTile inherits Rectangle {
in property <LightData> light;
callback clicked();
if light.on: FilledButton {
width: 100%;
height: 100%;
text: light.name;
enabled: light.available;
clicked => root.clicked();
}
if !light.on: ElevatedButton {
width: 100%;
height: 100%;
text: light.name;
enabled: light.available;
clicked => root.clicked();
}
}
export component AppWindow inherits Window {
title: "Dashboard";
width: 1024px;
height: 600px;
default-font-size: 16px;
pure callback render_plot(int) -> image;
in-out property <ColorScheme> color-scheme <=> Palette.color-scheme;
in property <BatteryData> battery;
in property <DateTimeData> date-time;
in property <[ThermostatData]> thermostats;
in property <WeatherData> weather;
in property <bool> is-night;
callback set_temperature(string, float);
callback toggle_thermostat(string);
in property <[CalendarEventData]> calendar-events;
in property <string> next-event-date;
in property <string> next-event-time;
in property <string> next-event-summary;
in property <[ThermometerData]> thermometers;
in property <[LightData]> lights;
callback toggle-light(string);
VerticalLayout {
width: root.width;
height: root.height;
HorizontalLayout {
alignment: center;
height: 64px;
spacing: 15px;
padding: StyleMetrics.layout-padding / 2;
Battery {
battery: battery;
}
Rectangle {
preferred-width: parent.width;
height: parent.height;
}
for thermometer[index] in root.thermometers: Thermometer {
thermometer: thermometer;
}
Rectangle {
preferred-width: parent.width;
height: parent.height;
}
Clock {
date-time: date-time;
}
}
HorizontalLayout {
height: root.height - 64px;
Rectangle {
width: (root.width / 4) * 3;
VerticalLayout {
MainPage {
calendar-events: calendar-events;
thermostats: thermostats;
is-night: is-night;
weather: weather;
set_temperature(entity_id, value) => { root.set_temperature(entity_id, value); }
toggle_thermostat(entity_id) => { toggle_thermostat(entity_id) }
}
// Rectangle {
// tab-bar := TabBar {
// width: parent.width;
// items: [
// { icon: Icons.wb_sunny, text: "Climate" },
// { icon: Icons.calendar_today, text: "Calendar" },
// { icon: Icons.energy_savings_leaf, text: "Energy" }
// ];
// }
// }
}
}
VerticalLayout {
padding: MaterialStyleMetrics.spacing_8;
spacing: MaterialStyleMetrics.spacing_8;
width: root.width / 4;
for light[index] in root.lights: LightTile {
light: light;
clicked => { toggle-light(light.id) }
}
}
}
}
}