slint/demos/home-automation/ui/components/mainView/mainScreen.slint
Nigel Breslaw beef5d9cde
Time fix for home-auto demo (#8473)
* Landscape time was not hidden in portrait

* Apply landscape time fix to portrait
2025-05-19 14:53:38 +03:00

416 lines
14 KiB
Text

// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT
import { DoorState, Doors } from "../general/doors.slint";
import { WidgetLoader } from "widgetLoader.slint";
import { WidgetLoaderSoftwareRenderer } from "widgetLoaderSoftwareRenderer.slint";
import { Palette as StdPalette } from "std-widgets.slint";
import { Palette, Animation, Style } from "../../common.slint";
import { AppState, Orientation } from "../../appState.slint";
import { FullScreenView } from "fullScreenView.slint";
import { Page } from "../../../../printerdemo/ui/common.slint";
import { HaText } from "../general/haText.slint";
import { Api } from "../../api.slint";
export component PageButton inherits Rectangle {
in property label <=> t.text;
in property <int> target-page;
in property <image> icon;
property <length> default-font-size: AppState.graphics-accelerator-available ? 16px : 22px;
property <bool> selected: AppState.target-page == target-page;
width: AppState.orientation == Orientation.landscape ? 120px : 140px;
height: 40px;
Rectangle {
t := Text {
font-size: default-font-size;
font-weight: selected ? 400 : 100;
font-family: AppState.default-font-family;
color: black;
Text {
x: -1px;
y: -1px;
text: t.text;
font-size: default-font-size;
font-weight: selected ? 400 : 100;
font-family: AppState.default-font-family;
color: #ffffff;
}
}
}
TouchArea {
clicked => {
AppState.target-page = target-page;
AppState.first-run = false;
AppState.end-kiosk-mode();
}
}
}
component PageButtonHighlighter {
Rectangle {
y: parent.height - parent.height * 15%;
width: parent.width * 50%;
height: 1px;
background: white;
}
}
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.graphics-accelerator-available {
AppState.current-page = AppState.target-page;
} else {
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 {
running: false;
interval: 1400ms;
triggered => {
self.running = false;
transitioning = false;
AppState.current-page = AppState.target-page;
}
}
background: Palette.background-gradient;
Image {
x: 30px;
y: AppState.orientation == Orientation.landscape ? 35px : 36px;
source: @image-url("../../images/slint-logo.png");
animate opacity { duration: Animation.transition-duration; }
states [
kiosk-mode when AppState.kiosk-mode : {
opacity: 50%;
colorize: white;
}
]
}
if AppState.orientation == Orientation.landscape: Rectangle {
property <bool> showing-time: true;
property <length> margin: AppState.graphics-accelerator-available ? 5px : 20px;
width: 200px;
height: 50px;
x: parent.width - self.width - margin;
y: AppState.orientation == Orientation.landscape ? 24px : 30px;
opacity: 80%;
TouchArea {
clicked => {
showing-time = !showing-time;
}
}
if !showing-time: HorizontalLayout {
alignment: center;
spacing: 10px;
HaText {
text: Api.return-month();
color: Palette.info-foreground;
font-size: Style.H1-font-size;
font-weight: 100;
}
HaText {
text: Api.current-date.day;
color: Palette.info-foreground;
font-size: Style.H1-font-size;
font-weight: 400;
}
}
if showing-time: HorizontalLayout {
alignment: center;
HaText {
text: Api.current-time.hour.mod(12) == 0 ? 12 : Api.current-time.hour.mod(12);
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: Api.current-time.minute;
horizontal-alignment: center;
vertical-alignment: center;
color: Palette.info-foreground;
font-size: Style.H1-font-size;
}
HaText {
text: Api.current-time.hour >= 12 ? " PM" : " AM";
horizontal-alignment: center;
vertical-alignment: center;
color: Palette.info-foreground;
font-size: Style.H2-font-size;
}
}
}
if AppState.orientation == Orientation.portrait: HorizontalLayout {
y: root.height - self.height - 10px;
alignment: center;
spacing: 30px;
height: 50px;
opacity: 80%;
HorizontalLayout {
spacing: 10px;
HaText {
text: Api.return-month();
font-size: Style.H1-font-size;
font-weight: 100;
}
HaText {
text: Api.current-date.day;
color: Palette.info-foreground;
font-size: Style.H1-font-size;
font-weight: 400;
}
}
HorizontalLayout {
HaText {
text: Api.current-time.hour.mod(12) == 0 ? 12 : Api.current-time.hour.mod(12);
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: Api.current-time.minute;
horizontal-alignment: center;
vertical-alignment: center;
color: Palette.info-foreground;
font-size: Style.H1-font-size;
}
HaText {
text: Api.current-time.hour > 12 ? " PM" : " AM";
horizontal-alignment: center;
vertical-alignment: center;
color: Palette.info-foreground;
font-size: Style.H2-font-size;
font-weight: 100;
}
}
}
Rectangle {
x: 0;
y: 0;
width: root.width;
height: root.height;
cache-rendering-hint: door-component-loaded;
navigation := Rectangle {
nav-bar := Rectangle {
property <length> portrait-x: 110px;
x: AppState.orientation == Orientation.landscape ? (parent.width - self.width) / 2 : portrait-x;
y: AppState.graphics-accelerator-available ? 26px : 35px;
width: AppState.orientation == Orientation.landscape ? 600px : root.width - portrait-x;
height: 40px;
if !AppState.graphics-accelerator-available: Image {
width: parent.width;
height: self.source.height * 1px;
source: @image-url("../../images/title-frame.png", nine-slice(0 50 0 50));
}
if AppState.graphics-accelerator-available: Rectangle {
Rectangle {
border-radius: self.height / 2;
drop-shadow-blur: 5px;
drop-shadow-color: black.transparentize(0.5);
drop-shadow-offset-x: 3px;
drop-shadow-offset-y: 3px;
background: #241433;
}
Rectangle {
border-width: 1px;
border-color: Palette.glass-border;
border-radius: self.height / 2;
background: Palette.glass-background;
}
}
// We need to have two different highlighter because of #7999
if AppState.graphics-accelerator-available: PageButtonHighlighter {
x: home.x + (tabs.spacing + self.width) * AppState.target-page;
animate x {
duration: Animation.transition-duration;
easing: ease-in-out-sine;
}
width: AppState.orientation == Orientation.landscape ? 120px : 140px;
height: 100%;
}
if !AppState.graphics-accelerator-available : PageButtonHighlighter {
x: home.x + (tabs.spacing + self.width) * AppState.target-page;
width: AppState.orientation == Orientation.landscape ? 120px : 140px;
height: 100%;
}
tabs := HorizontalLayout {
alignment: center;
spacing: 0px;
y: AppState.graphics-accelerator-available ? 0 : -5px;
home := PageButton {
label: "Home";
target-page: 0;
}
PageButton {
label: "Kitchen";
target-page: 1;
}
PageButton {
label: "Bedroom";
target-page: 2;
}
if AppState.orientation == Orientation.landscape: PageButton {
label: "Office";
target-page: 3;
}
if AppState.orientation == Orientation.landscape && AppState.graphics-accelerator-available: Rectangle {
width: 50px;
height: 40px;
lock := Image {
source: @image-url("../../images/lock.svg");
colorize: white;
opacity: lta.pressed ? 100% : 50%;
}
lta := TouchArea {
clicked => {
door-component-loaded = true;
}
}
}
}
}
}
fs-holder := Rectangle {
y: 20px;
if AppState.graphics-accelerator-available: 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.graphics-accelerator-available: Rectangle {
width: 100%;
height: 100%;
for i[index] in AppState.component-details: WidgetLoaderSoftwareRenderer {
index: index;
type: AppState.component-details[index].type;
data: AppState.current-layout-data.components[index];
}
}
if AppState.showing-full-screen: fullScreenWidgetHolder := FullScreenView {
nudge-y: fs-holder.y;
}
}
}
if AppState.graphics-accelerator-available && 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;
}
kiosk-blocker := TouchArea {
visible: AppState.kiosk-mode && !door-component-loaded;
clicked => {
AppState.end-kiosk-mode();
}
}
Timer {
interval: 30s;
running: !AppState.kiosk-mode && !door-component-loaded && !AppState.disable-kiosk-mode;
triggered => {
AppState.first-run = false;
AppState.kiosk-mode = true;
}
}
kiosk-mode-animator := Timer {
running: AppState.kiosk-mode && !door-component-loaded;
interval: 5s;
triggered => {
if AppState.orientation == Orientation.landscape {
if AppState.current-page < 3 {
AppState.target-page = AppState.target-page + 1;
} else {
AppState.target-page = 0;
}
} else {
if AppState.current-page < 2 {
AppState.target-page = AppState.target-page + 1;
} else {
AppState.target-page = 0;
}
}
}
}
}