import { UiRadius } from "ui_radius.slint"; // Colors and spacing for the connection workbench; shapes are shared app-wide. export global WorkbenchStyle { out property canvas: #f2f5f9; out property surface: #ffffff; out property border: #c6cfdd; out property control-border: #b2bfd1; out property hover-border: #7f97b8; out property field-surface: #f5f7fb; out property hover-surface: #eef3fb; out property pressed-surface: #e4ebf6; out property separator: #e1e7ef; out property text: #1c2940; out property muted: #69788e; out property accent: #3564e3; out property success: #18835a; } export component WorkbenchButton inherits Rectangle { in property text; in property text-size: 13px; in property text-color: root.primary ? white : WorkbenchStyle.text; in property normal-border-color: WorkbenchStyle.control-border; in property icon; in property tooltip; in property tooltip-above: false; in property tooltip-suppressed: false; in property icon-color: root.primary ? (root.soft && !touch.has-hover && !root.show-focus ? WorkbenchStyle.accent : white) : WorkbenchStyle.muted; in property primary: false; in property soft: false; in property quiet: false; in property enabled: true; out property has-focus: button-focus.has-focus; private property keyboard-focus: false; private property show-focus: button-focus.has-focus && root.keyboard-focus; private property tooltip-active: root.enabled && root.tooltip != "" && !root.tooltip-suppressed && !touch.pressed && (touch.has-hover || root.show-focus); private property tooltip-visible: false; changed tooltip-active => { root.tooltip-visible = false; } callback clicked; width: 112px; height: 36px; border-radius: UiRadius.control; border-width: root.show-focus ? 2px : root.soft ? 0px : 1px; border-color: root.show-focus ? (root.primary ? #193da0 : WorkbenchStyle.accent) : root.primary ? WorkbenchStyle.accent : touch.has-hover ? WorkbenchStyle.hover-border : root.quiet ? transparent : root.normal-border-color; background: root.soft ? (root.primary ? (touch.pressed ? #254cc0 : touch.has-hover || root.show-focus ? WorkbenchStyle.accent : #edf2ff) : (touch.pressed ? WorkbenchStyle.pressed-surface : touch.has-hover ? WorkbenchStyle.hover-surface : WorkbenchStyle.field-surface)) : root.primary ? (touch.pressed ? #254cc0 : touch.has-hover ? #4574f0 : WorkbenchStyle.accent) : (touch.pressed ? WorkbenchStyle.pressed-surface : touch.has-hover ? WorkbenchStyle.hover-surface : root.quiet ? transparent : white); opacity: root.enabled ? 1 : 0.45; animate background, border-color { duration: 120ms; } forward-focus: button-focus; accessible-role: button; accessible-label: root.tooltip != "" ? root.tooltip : root.text; accessible-enabled: root.enabled; accessible-action-default => { if root.enabled { root.clicked(); } } HorizontalLayout { padding-left: root.text == "" ? 0px : 10px; padding-right: root.text == "" ? 0px : 10px; spacing: 8px; alignment: center; if root.icon != "": Text { text: root.icon; font-family: "Font Awesome 6 Free"; font-weight: 900; font-size: root.soft ? 12px : 14px; color: root.icon-color; vertical-alignment: center; accessible-role: none; } if root.text != "": Text { text: root.text; font-size: root.text-size; font-weight: root.primary ? 600 : 500; color: root.text-color; vertical-alignment: center; accessible-role: none; } } button-focus := FocusScope { enabled: root.enabled; focus-gained(reason) => { if reason == FocusReason.tab-navigation { root.keyboard-focus = true; } else if reason == FocusReason.pointer-click { root.keyboard-focus = false; } } key-pressed(event) => { root.keyboard-focus = true; if event.text == Key.Return || event.text == " " { root.clicked(); return accept; } return reject; } touch := TouchArea { enabled: root.enabled; mouse-cursor: pointer; pointer-event(event) => { if event.kind == PointerEventKind.down { root.keyboard-focus = false; } } // Keep focus for subsequent keyboard activation without leaving a // keyboard focus ring behind after a pointer click. clicked => { root.keyboard-focus = false; button-focus.focus(); root.clicked(); } } } tooltip-timer := Timer { interval: 450ms; running: root.tooltip-active && !root.tooltip-visible; triggered => { root.tooltip-visible = true; } } if root.tooltip-active && root.tooltip-visible: Rectangle { x: min(0px, root.width - self.width); y: root.tooltip-above ? -self.height - 6px : root.height + 6px; width: min(260px, tip.preferred-width + 20px); height: max(28px, tip.preferred-height + 12px); background: #24324a; border-radius: UiRadius.control; z: 20; tip := Text { x: 10px; y: 6px; width: parent.width - 20px; height: parent.height - 12px; text: root.tooltip; font-size: 12px; color: white; wrap: word-wrap; horizontal-alignment: center; vertical-alignment: center; } } } // A raised surface keeps transient action feedback distinct from the workbench. export component WorkbenchNotice inherits Rectangle { in property text; in property icon; in property error: false; in property width-limit: 360px; private property foreground: root.error ? #b42318 : #146c49; width: min(root.width-limit, max(280px, message.preferred-width + 64px)); height: 64px; background: root.error ? #fff1f0 : #e9f6ef; border-width: 1px; border-color: root.error ? #f0c4bf : #b9dfc9; border-radius: UiRadius.surface; drop-shadow-color: #14294424; drop-shadow-blur: 24px; drop-shadow-offset-y: 6px; accessible-role: AccessibleRole.text; accessible-label: root.text; Text { x: message.x - 28px; width: 18px; height: parent.height; text: root.icon; font-family: "Font Awesome 6 Free"; font-weight: 900; font-size: 16px; color: root.foreground; horizontal-alignment: center; vertical-alignment: center; accessible-role: none; } message := Text { x: (parent.width - self.width + 28px) / 2; width: min(self.preferred-width, parent.width - 64px); height: parent.height; text: root.text; font-size: 14px; font-weight: 600; color: root.foreground; overflow: elide; vertical-alignment: center; accessible-role: none; } } export component WorkbenchCard inherits Rectangle { background: WorkbenchStyle.surface; border-width: 1px; border-color: WorkbenchStyle.border; border-radius: UiRadius.surface; }