// Copyright © SixtyFPS GmbH // SPDX-License-Identifier: MIT import { Palette } from "std-widgets.slint"; struct ButtonColors { base: color, pressed: color, hovered: color, } struct ModeColors { background: color, primary: color, secondary: color, text-primary: color, text-secondary: color, destructive: color, } export global DemoPalette { in property dark-mode: Palette.color-scheme == ColorScheme.dark; property light-mode-colors: { background: #FFFFFF, primary: #0E133F, secondary: #FFBF63, text-primary: #000, text-secondary: #6284FF, destructive: #FF3B30, }; property dark-mode-colors: { background: #122F7B, primary: #0E133F, secondary: #FFBF63, text-primary: #F4F6FF, text-secondary: #F4F6FF, destructive: #FF3B30, }; out property background: dark-mode ? dark-mode-colors.background : light-mode-colors.background; out property primary: dark-mode ? dark-mode-colors.primary : light-mode-colors.primary; out property secondary: dark-mode ? dark-mode-colors.secondary : light-mode-colors.secondary; out property text-primary: dark-mode ? dark-mode-colors.text-primary : light-mode-colors.text-primary; out property text-secondary: dark-mode ? dark-mode-colors.text-secondary : light-mode-colors.text-secondary; out property destructive: dark-mode ? dark-mode-colors.destructive : light-mode-colors.destructive; // Fixed (non-themeable) colors out property push-button-text-color: white; // Color of the home/settings/ink buttons on the left side bar out property active-page-icon-color: root.dark-mode ? #6284FF : #122F7B; out property inactive-page-icon-color: #BDC0D1; out property neutral-box: #BDC0D1; out property secondary-foreground-color: root.dark-mode ? #C1C3CA : #6C6E7A; // Color used for the border / outline of items that can be clicked on, such as the // "Print"/"Scan" buttons, the printer queue items (for expansion) or controls such // as the combo box or spin box. out property control-secondary: #6284FF; out property control-foreground: root.dark-mode ? white : #122F7B; // FIXME: the night mode color was not part of the design out property primary-push-button-base: #6284FF; out property primary-push-button-colors: { base: root.primary-push-button-base, pressed: root.primary-push-button-base.darker(40%), hovered: root.primary-push-button-base.darker(20%), }; out property secondary-push-button-base: destructive; out property secondary-push-button-colors: { base: root.secondary-push-button-base, pressed: root.secondary-push-button-base.darker(40%), hovered: root.secondary-push-button-base.darker(20%), }; out property base-font-size: 16px; out property button-width: 130px; out property button-height: button-width + 30px; out property side-bar-width: 67px; out property side-bar-margin: 10px; } export component Page inherits Rectangle { in property header <=> h.text; in property has-back-button: false; callback back; background: DemoPalette.background; // Stop accidentally getting clicks dur to animation only moving page half way offscreen visible: self.opacity > 0; TouchArea { } // protect underneath controls if (root.has-back-button) : Image { x:0; source: @image-url("images/back.svg"); image-fit: contain; colorize: DemoPalette.control-secondary; y: h.y + (h.height - self.height) / 2; width: 14px; height: 24px; TouchArea { clicked => { root.back() } x: -14px; height: 200%; width: self.height; } } h := Text { font-weight: 900; font-size: DemoPalette.base-font-size * 2; color: DemoPalette.text-primary; y: 46px - self.font-size; x: root.has-back-button ? 24px + 16px : 0px; // Allow clicking on the title as well to get back easier when just // using fingers on a small screen. if (root.has-back-button) : TouchArea { clicked => { root.back() } } } } export component Label inherits Text { color: DemoPalette.text-primary; vertical-alignment: center; font-weight: 700; vertical-stretch: 0; } component SquareButton inherits Rectangle { in-out property img; callback clicked; border-radius: 3px; border-width: 2px; border-color: DemoPalette.secondary; touch := TouchArea { clicked => { root.clicked(); } } Image { height: 40%; width: 40%; x: (parent.width - self.width)/2; y: (parent.height - self.height)/2; source <=> root.img; image-fit: contain; colorize: DemoPalette.control-secondary; } } export component SpinBox inherits Rectangle { in property minimum; in property maximum: 100; in-out property value; height: 32px; HorizontalLayout { spacing: 12px; padding: 0; SquareButton { clicked => { if (root.value > root.minimum) { root.value -= 1; } } width: root.height - parent.padding * 2; img: @image-url("images/minus.svg"); } Rectangle { border-radius: 3px; border-width: 2px; border-color: DemoPalette.secondary; Text { width: 100%; height: 100%; vertical-alignment: center; horizontal-alignment: center; text: root.value; color: DemoPalette.control-foreground; } } SquareButton { clicked => { if (root.value < root.maximum) { root.value += 1; } } width: root.height - parent.padding * 2; img: @image-url("images/plus.svg"); } } } export component ComboBox inherits Rectangle { in-out property value; in property <[string]> choices; callback selected(int); border-radius: 3px; border-width: 2px; border-color: DemoPalette.secondary; height: 32px; min-width: label.x + label.width + i.width; horizontal-stretch: 1; // Work around #2284 label := Text { vertical-alignment: center; horizontal-alignment: left; text <=> root.value; color: DemoPalette.control-foreground; height: 100%; x: 12px; } i := Image { source: @image-url("images/down.svg"); colorize: DemoPalette.control-secondary; height: 40%; width: self.height; image-fit: contain; x: parent.width - self.width - self.y; y: (parent.height - self.height)/2; } TouchArea { clicked => { popup.show(); } width: 100%; height: 100%; } popup := PopupWindow { x:0; y: root.height; width: root.width; Rectangle { background: DemoPalette.background; border-radius: 3px; border-width: 2px; border-color: DemoPalette.secondary; } VerticalLayout { spacing: 6px; padding: 3px; function textColor(hashover: bool) -> color { if DemoPalette.dark-mode { return DemoPalette.text-primary; } // if hashover { return DemoPalette.text-primary; // } } for value[idx] in root.choices: Rectangle { border-radius: 3px; background: item-area.has-hover ? DemoPalette.primary-push-button-colors.hovered : #0000; HorizontalLayout { Text { text: value; color: item-area.has-hover ? DemoPalette.push-button-text-color : DemoPalette.text-primary; font-size: DemoPalette.base-font-size; } } item-area := TouchArea { clicked => { root.value = value; root.selected(idx); } } } } } } export component CheckBox inherits Rectangle { in property text; in-out property checked; height: 32px; HorizontalLayout { spacing: 12px; padding: 0; SquareButton { clicked => { root.checked = !root.checked; } width: root.height - parent.padding * 2; img: root.checked ? @image-url("images/check.svg") : @image-url(""); } Text { text <=> root.text; vertical-alignment: center; horizontal-alignment: center; color: DemoPalette.control-foreground; horizontal-stretch: 1; } } TouchArea { clicked => { root.checked = !root.checked; } } } export component PushButton inherits Rectangle { in property text <=> label.text; in property primary: true; out property pressed: touch-area.pressed; out property colors: root.primary ? DemoPalette.primary-push-button-colors : DemoPalette.secondary-push-button-colors; in-out property icon <=> img.source; callback clicked; border-radius: 13.5px; background: root.pressed ? root.colors.pressed : (touch-area.has-hover ? root.colors.hovered : root.colors.base); height: 27px; // line-height in the design horizontal-stretch: 1; HorizontalLayout { padding-top: 0px; padding-bottom: 0px; padding-left: parent.border-radius; padding-right: parent.border-radius; img := Image { horizontal-stretch: 0; colorize: DemoPalette.push-button-text-color; image-fit: contain; width: 17px; } label := Text { font-weight: 900; font-size: DemoPalette.base-font-size * 0.975; color: DemoPalette.push-button-text-color; horizontal-alignment: center; vertical-alignment: center; } } touch-area := TouchArea { clicked => { root.clicked() } } }