slint/demos/printerdemo/ui/printerdemo.slint
Tobias Hunger 081452bee9 live-preview: Explicitly set live-data values on reload
Set all values that are changed compared to the initial
set of values right after loading a new component.

This also includes a small change to the printerdemo,
so that it exposes more data to the business logic,
so that we have something to demonstrate;-)
2025-04-09 09:39:04 +02:00

187 lines
6 KiB
Text

// Copyright © SixtyFPS GmbH <info@slint.dev>
// SPDX-License-Identifier: MIT
import { DemoPalette, Page } from "common.slint";
import { HomePage } from "./home_page.slint";
import { InkLevel, InkPage } from "./ink_page.slint";
import { SettingsPage, PrinterSettings } from "./settings_page.slint";
import { PrinterQueue } from "./printer_queue.slint";
// re-export for the native code
export { PrinterQueue, PrinterSettings }
import "./fonts/NotoSans-Regular.ttf";
import "./fonts/NotoSans-Bold.ttf";
component SideBarIcon inherits Rectangle {
in-out property <bool> active;
in-out property <image> icon <=> i.source;
in-out property <brush> icon-colorize <=> i.colorize;
callback activate;
width: DemoPalette.side-bar-width;
height: 72px;
Rectangle {
x: DemoPalette.side-bar-margin;
GridLayout {
padding: 0px;
@children
}
i := Image {
colorize: root.active ? DemoPalette.active-page-icon-color : DemoPalette.inactive-page-icon-color;
animate colorize { duration: 125ms; }
}
}
TouchArea {
clicked => { root.activate(); }
}
}
export component MainWindow inherits Window {
/// Note that this property is overwritten in the .cpp and .rs code.
/// The data is only in this file so it looks good in the viewer
in property <[InkLevel]> ink-levels: [
{color: #0ff, level: 60%},
{color: #ff0, level: 80%},
{color: #f0f, level: 70%},
{color: #000, level: 30%},
];
in-out property <int> active-page: 0;
in-out property <bool> dark-mode <=> DemoPalette.dark-mode;
callback quit();
min-width: 772px;
min-height: 504px;
title: @tr("Slint printer demo");
background: DemoPalette.primary;
default-font-family: "Noto Sans";
default-font-size: DemoPalette.base-font-size;
HorizontalLayout {
padding: 10px;
padding-left: 67px;
main-view := Rectangle {
height: 100%;
border-radius: 30px;
background: DemoPalette.background;
Rectangle {
clip: true;
x: main-view.border-radius / 2;
y: main-view.border-radius / 2;
width: main-view.width - main-view.border-radius;
height: main-view.height - main-view.border-radius;
function calcPageY(pageNumber: int) -> length {
if (root.active-page == pageNumber) {
return 0;
}
return root.active-page < pageNumber ? - self.height / 2 : parent.height / 2;
}
property <duration> page-animation-duration: 250ms;
home-page := HomePage {
property <int> pageNumber: 0;
y: calcPageY(0);
opacity: root.active-page == 0 ? 1 : 0;
animate y {
duration: page-animation-duration;
easing: ease-out-quad;
}
animate opacity {
duration: page-animation-duration;
easing: ease-out-quad;
}
}
SettingsPage {
property <int> pageNumber: 1;
y: calcPageY(1);
opacity: root.active-page == pageNumber ? 1 : 0;
animate y {
duration: page-animation-duration;
easing: ease-out-quad;
}
animate opacity {
duration: page-animation-duration;
easing: ease-out-quad;
}
}
InkPage {
property <int> pageNumber: 2;
y: calcPageY(pageNumber);
opacity: root.active-page == pageNumber ? 1 : 0;
ink-levels <=> root.ink-levels;
page-visible: root.active-page == pageNumber;
animate y {
duration: page-animation-duration;
easing: ease-out-quad;
}
animate opacity {
duration: page-animation-duration;
easing: ease-out-quad;
}
}
}
}
}
sidebar := Rectangle {
function icon-y(index: int) -> length {
return 100px // top padding
+ index * 72px;
}
x: 0px;
width: DemoPalette.side-bar-width;
Image {
x: parent.width - self.width + 1px; // workaround pixel gap
y: sidebar.icon-y(root.active-page) - self.width / 2;
source: @image-url("images/page_selection.svg");
colorize: DemoPalette.background;
animate y { duration: 125ms; }
}
VerticalLayout {
y: 82px;
for page-icon[idx] in [
@image-url("images/home.svg"),
@image-url("images/settings.svg"),
@image-url("images/ink.svg"),
]: SideBarIcon {
activate => {
root.active-page = idx;
}
icon: page-icon;
active: root.active-page == idx;
}
}
Rectangle {
y: sidebar.icon-y(3) + 17px;
x: DemoPalette.side-bar-margin + 8px;
background: DemoPalette.background;
height: 2px;
width: 37px;
}
SideBarIcon {
activate => {
DemoPalette.dark-mode = !DemoPalette.dark-mode;
}
icon: DemoPalette.dark-mode ? @image-url("images/moon_full.svg") : @image-url("images/moon.svg");
icon-colorize: DemoPalette.dark-mode ? #F1FF98 : DemoPalette.inactive-page-icon-color;
y: sidebar.icon-y(4) - 17px;
}
}
}