// Copyright © SixtyFPS GmbH // 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 active; in-out property icon <=> i.source; in-out property 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 active-page: 0; in-out property 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 page-animation-duration: 250ms; home-page := HomePage { property 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 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 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; } } }