mirror of
https://github.com/kunkundi/crossdesk.git
synced 2026-10-20 03:01:52 +08:00
[ui] simplify DeskHub controls and unify device status styling
This commit is contained in:
@@ -0,0 +1,108 @@
|
||||
import { CompactButton, FontAwesomeIcons } from "common.slint";
|
||||
|
||||
export struct GalleryMenuItem { label: string, enabled: bool }
|
||||
|
||||
export component GalleryMenuButton inherits Rectangle {
|
||||
in property <string> text;
|
||||
in property <bool> primary: false;
|
||||
in property <bool> enabled: true;
|
||||
in property <bool> opens-up: false;
|
||||
in property <length> menu-width: 200px;
|
||||
in property <[GalleryMenuItem]> items;
|
||||
private property <int> current-index: 0;
|
||||
callback opened;
|
||||
callback selected(int);
|
||||
|
||||
height: 24px;
|
||||
forward-focus: trigger-focus;
|
||||
accessible-role: button;
|
||||
accessible-label: root.text;
|
||||
accessible-enabled: root.enabled;
|
||||
accessible-expandable: true;
|
||||
accessible-expanded: popup.is-open;
|
||||
accessible-action-default => { root.open-menu(); }
|
||||
changed enabled => { if !root.enabled { popup.close(); } }
|
||||
changed visible => { if !root.visible { popup.close(); } }
|
||||
|
||||
public function close-menu() { popup.close(); }
|
||||
function open-menu() {
|
||||
if !root.enabled || root.items.length == 0 { return; }
|
||||
if popup.is-open { popup.close(); return; }
|
||||
root.opened();
|
||||
root.current-index = 0;
|
||||
popup.show();
|
||||
}
|
||||
function choose(index: int) {
|
||||
if !root.enabled || index < 0 || index >= root.items.length || !root.items[index].enabled { return; }
|
||||
popup.close();
|
||||
trigger-focus.focus();
|
||||
root.selected(index);
|
||||
}
|
||||
function handle-key(event: KeyEvent) -> EventResult {
|
||||
if !root.enabled { return reject; }
|
||||
if event.text == Key.Escape && popup.is-open {
|
||||
popup.close(); trigger-focus.focus(); return accept;
|
||||
}
|
||||
if event.text == Key.Return || event.text == " " {
|
||||
if popup.is-open { root.choose(root.current-index); } else { root.open-menu(); }
|
||||
return accept;
|
||||
}
|
||||
if event.text == Key.UpArrow || event.text == Key.DownArrow {
|
||||
if !popup.is-open { root.open-menu(); }
|
||||
else { root.current-index = clamp(root.current-index + (event.text == Key.UpArrow ? -1 : 1), 0, root.items.length - 1); }
|
||||
return accept;
|
||||
}
|
||||
return reject;
|
||||
}
|
||||
trigger-focus := FocusScope {
|
||||
enabled: root.enabled;
|
||||
key-pressed(event) => { return root.handle-key(event); }
|
||||
CompactButton {
|
||||
width: parent.width; height: parent.height;
|
||||
enabled: root.enabled; primary: root.primary;
|
||||
clicked => { trigger-focus.focus(); root.open-menu(); }
|
||||
}
|
||||
Text {
|
||||
x: 6px; width: parent.width - 24px; height: parent.height;
|
||||
text: root.text; color: root.enabled ? #24272d : #8e9298;
|
||||
font-size: 11px; overflow: elide; horizontal-alignment: center; vertical-alignment: center;
|
||||
}
|
||||
Text {
|
||||
x: parent.width - 19px; width: 12px; height: parent.height;
|
||||
text: root.opens-up ? FontAwesomeIcons.angle-up : FontAwesomeIcons.angle-down;
|
||||
font-family: "Font Awesome 6 Free"; font-weight: 900; font-size: 9px;
|
||||
color: root.enabled ? #62666d : #8e9298;
|
||||
horizontal-alignment: center; vertical-alignment: center;
|
||||
}
|
||||
}
|
||||
popup := PopupWindow {
|
||||
x: root.width - self.width;
|
||||
y: root.opens-up ? -self.height - 4px : root.height + 4px;
|
||||
width: root.menu-width; height: root.items.length * 30px + 8px;
|
||||
close-policy: close-on-click-outside;
|
||||
forward-focus: popup-focus;
|
||||
popup-focus := FocusScope {
|
||||
key-pressed(event) => { return root.handle-key(event); }
|
||||
Rectangle {
|
||||
background: white; border-width: 1px; border-color: #c9cdd2; border-radius: 4px;
|
||||
for item[index] in root.items: Rectangle {
|
||||
x: 4px; y: 4px + index * 30px; width: parent.width - 8px; height: 30px;
|
||||
border-radius: 3px;
|
||||
background: item.enabled && index == root.current-index ? #edf4fc : transparent;
|
||||
accessible-role: button; accessible-label: item.label; accessible-enabled: item.enabled;
|
||||
accessible-action-default => { root.choose(index); }
|
||||
Text {
|
||||
x: 10px; width: parent.width - 20px; height: parent.height;
|
||||
text: item.label; color: item.enabled ? #30343b : #92979f;
|
||||
font-size: 12px; vertical-alignment: center;
|
||||
}
|
||||
TouchArea {
|
||||
enabled: item.enabled;
|
||||
changed has-hover => { if self.has-hover { root.current-index = index; } }
|
||||
clicked => { root.choose(index); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user