// Copyright © SixtyFPS GmbH // SPDX-License-Identifier: MIT import { DemoPalette, PushButton } from "./common.slint"; export struct PrinterQueueItem { status: string, progress: int, title: string, owner: string, pages: int, size: string, // number instead and format in .slint? submission-date: string } export global PrinterQueue { in property <[PrinterQueueItem]> printer-queue: [ { status: "printing", progress: 63, title: "Slint-Demo.jpeg", owner: "info@slint.dev", pages: 6, size: "143kb", submission-date: "11:41 25/01/21" }, { status: "waiting", title: "Adressliste.docx", owner: "info@slint.dev", pages: 6, size: "143kb", submission-date: "11:41 25/01/21" }, { status: "waiting", title: "210106-FinalPresentation.pdf", owner: "info@slint.dev", pages: 6, size: "143kb", submission-date: "11:41 25/01/21" }, ]; callback start-job(string); callback cancel-job(int); callback pause-job(int); public pure function statusString(status: string) -> string { if (status == "printing") { "PRINTING" } else if (status == "waiting") { "WAITING..." } else { "Unknown job status" } } } component PrintQueueDetailsLabel inherits Text { font-weight: 500; color: DemoPalette.control-foreground; horizontal-stretch: 0; font-size: DemoPalette.base-font-size * 0.9375; } component PrintQueueSeparator inherits Rectangle { height: 1px; border-width: 1px; border-color: #BDC0D1; horizontal-stretch: 2; } component PrintDetails inherits GridLayout { in property queue-item; spacing: 3px; Row { PrintQueueDetailsLabel { text: "Owner"; } Text { text: root.queue-item.owner; color: DemoPalette.secondary-foreground-color; overflow: elide; horizontal-stretch: 1; font-size: DemoPalette.base-font-size * 0.9375; } } Row { PrintQueueSeparator { colspan: 2; } } Row { PrintQueueDetailsLabel { text: "Pages"; } Text { text: root.queue-item.pages; color: DemoPalette.secondary-foreground-color; overflow: elide; horizontal-stretch: 1; font-size: DemoPalette.base-font-size * 0.9375; } } Row { PrintQueueSeparator { colspan: 2; } } Row { PrintQueueDetailsLabel { text: "Size"; } Text { text: root.queue-item.pages; color: DemoPalette.secondary-foreground-color; overflow: elide; horizontal-stretch: 1; font-size: DemoPalette.base-font-size * 0.9375; } } Row { PrintQueueSeparator { colspan: 2; } } Row { PrintQueueDetailsLabel { text: "Submitted"; } Text { text: root.queue-item.submission-date; color: DemoPalette.secondary-foreground-color; overflow: elide; horizontal-stretch: 1; font-size: DemoPalette.base-font-size * 0.9375; } } } component NarrowPrintQueueElement inherits Rectangle { in property queue-item; in-out property expanded; private property expanded-opacity: 0; callback cancel-job(); border-color: DemoPalette.control-outline-color; border-radius: 6px; border-width: 1px; background: DemoPalette.printer-queue-item-background-color; clip: true; height: always-visible.min-height + layout.padding * 2; states [ expanded when root.expanded : { height: layout.min-height; expanded-opacity: 1; in { animate height { duration: 200ms; easing: ease; } animate expanded-opacity { duration: 200ms; } } out { animate height { duration: 200ms; easing: ease; } animate expanded-opacity { duration: 200ms; } } } ] TouchArea { pointer-event(ev) => { if (ev.kind == PointerEventKind.up) { root.expanded = !root.expanded; } } } Rectangle { height: 100%; layout := VerticalLayout { padding: root.border-radius; spacing: 4px; alignment: start; always-visible := VerticalLayout { padding: 0; spacing: parent.spacing; Text { // TODO: text-transform: uppercase text: { if (root.queue-item.status == "printing") { "\{root.queue-item.progress}% - \{PrinterQueue.statusString(root.queue-item.status)}" } else { PrinterQueue.statusString(root.queue-item.status) } } color: DemoPalette.status-label-text-color; font-size: DemoPalette.base-font-size * 0.75; font-weight: 800; letter-spacing: 1.26px; } Text { text: root.queue-item.title; overflow: elide; color: DemoPalette.text-foreground-color; font-weight: 800; font-size: DemoPalette.base-font-size * 1.125; } } if (root.expanded || root.expanded-opacity > 0) : PrintDetails { padding: 0px; padding-bottom: root.border-radius / 2; queue-item: root.queue-item; opacity: root.expanded-opacity; } if (root.expanded || root.expanded-opacity > 0) : HorizontalLayout { Rectangle { horizontal-stretch: 0; width: 10%; } PushButton { clicked => { root.cancel-job(); } opacity: root.expanded-opacity; text: "Delete"; icon: @image-url("images/delete.svg"); } Rectangle { horizontal-stretch: 0; width: 10%; } } } } } component NarrowPrinterQueueList inherits Flickable { VerticalLayout { alignment: start; padding: 0px; spacing: 6px; for queue-item[idx] in PrinterQueue.printer-queue: NarrowPrintQueueElement { cancel-job => { PrinterQueue.cancel-job(idx) } width: root.width; queue-item: queue-item; } } } export component PrinterQueueView inherits Rectangle { border-radius: 18px; background: DemoPalette.night-mode ? DemoPalette.printer-action-background-color : #F4F6FF; VerticalLayout { padding: 6px; spacing: 6px; queue-list := NarrowPrinterQueueList { } } }