mirror of
https://github.com/kunkundi/crossdesk.git
synced 2026-10-26 15:28:53 +08:00
[ui] simplify DeskHub controls and unify device status styling
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { GalleryStrings } from "device_strings.slint";
|
||||
import { DeviceCardActions, DeviceCardStyle } from "device_card_actions.slint";
|
||||
import { GalleryMenuButton } from "gallery_menu_button.slint";
|
||||
import { GroupFilter } from "group_filter.slint";
|
||||
import { ScrollView, LineEdit } from "std-widgets.slint";
|
||||
import { CompactButton, FontAwesomeIcons, ImGuiCheckBox } from "common.slint";
|
||||
@@ -27,28 +28,32 @@ export struct GalleryActionDevice {
|
||||
name: string,
|
||||
connected: bool,
|
||||
}
|
||||
|
||||
export component GalleryView inherits Rectangle {
|
||||
in property <bool> controlling: false;
|
||||
in property <bool> simplified: false;
|
||||
private property <length> grid-gap: root.simplified ? 6px : 12px;
|
||||
private property <length> rail-card-height: root.simplified ? 92px : 76px;
|
||||
private property <string> focused-id: root.focused.id;
|
||||
private property <string> rail-tooltip-id;
|
||||
private property <string> rail-tooltip-text;
|
||||
private property <length> rail-tooltip-x;
|
||||
private property <bool> rail-tooltip-visible: false;
|
||||
changed focused-id => { root.rail-tooltip-id = ""; }
|
||||
changed visible => { root.rail-tooltip-id = ""; }
|
||||
changed rail-tooltip-id => {
|
||||
root.rail-tooltip-visible = false;
|
||||
rail-tooltip-timer.running = root.rail-tooltip-id != "";
|
||||
if root.rail-tooltip-id != "" { rail-tooltip-timer.restart(); }
|
||||
private property <string> device-tooltip-id;
|
||||
private property <string> device-tooltip-text;
|
||||
private property <length> device-tooltip-x;
|
||||
private property <length> device-tooltip-y;
|
||||
private property <bool> device-tooltip-visible: false;
|
||||
changed focused-id => { root.device-tooltip-id = ""; }
|
||||
changed visible => { root.device-tooltip-id = ""; if !root.visible { add-menu.close-menu(); batch-menu.close-menu(); } }
|
||||
changed width => { root.device-tooltip-id = ""; }
|
||||
changed height => { root.device-tooltip-id = ""; }
|
||||
changed device-tooltip-id => {
|
||||
root.device-tooltip-visible = false;
|
||||
device-tooltip-timer.running = root.device-tooltip-id != "";
|
||||
if root.device-tooltip-id != "" { device-tooltip-timer.restart(); }
|
||||
}
|
||||
rail-tooltip-timer := Timer {
|
||||
device-tooltip-timer := Timer {
|
||||
interval: 450ms; running: false;
|
||||
triggered => {
|
||||
self.running = false;
|
||||
root.rail-tooltip-visible = root.rail-tooltip-id != "";
|
||||
root.device-tooltip-visible = root.device-tooltip-id != "";
|
||||
}
|
||||
}
|
||||
// Pointer mapping must use the exact image viewport, including its inset.
|
||||
@@ -66,6 +71,9 @@ export component GalleryView inherits Rectangle {
|
||||
in property <int> pages: 1;
|
||||
in property <int> count: 0;
|
||||
in property <int> connected-count: 0;
|
||||
private property <string> connected-summary: root.connected-count + " / " + root.count
|
||||
+ GalleryStrings.tr(" 台已连接", " connected", " подключено");
|
||||
callback network-open;
|
||||
in property <int> selected-count: 0;
|
||||
in property <bool> selected-audio-available: false;
|
||||
in property <bool> selected-audio-muted: false;
|
||||
@@ -91,7 +99,11 @@ export component GalleryView inherits Rectangle {
|
||||
background: white;
|
||||
changed adding => { if root.adding { root.action("release", ""); } }
|
||||
changed importing => { root.action(root.importing ? "release" : "recent-close", ""); }
|
||||
public function reset-transient() { root.batch = false; root.adding = false; root.importing = false; root.confirming = false; }
|
||||
public function reset-transient() {
|
||||
root.batch = false; root.adding = false; root.importing = false; root.confirming = false;
|
||||
root.device-tooltip-id = ""; add-menu.close-menu(); batch-menu.close-menu();
|
||||
}
|
||||
changed batch => { root.device-tooltip-id = ""; batch-menu.close-menu(); }
|
||||
function confirm-action(code: string, name: string) {
|
||||
root.action-code = code; root.action-name = name; root.confirming = true;
|
||||
}
|
||||
@@ -102,49 +114,67 @@ export component GalleryView inherits Rectangle {
|
||||
GroupFilter { width: 155px; height: 24px; system-count: 1; model: root.groups; current-index <=> root.group-index;
|
||||
selected(index) => { root.action("group", index); }
|
||||
}
|
||||
Text {
|
||||
text: root.count + GalleryStrings.tr(" 台设备", " devices", " устройств");
|
||||
font-size: 11px; color: #858c96; vertical-alignment: center;
|
||||
}
|
||||
Rectangle { horizontal-stretch: 1; }
|
||||
CompactButton { width: 82px; primary: root.batch; text: root.batch ? GalleryStrings.tr("完成", "Done", "Готово") : GalleryStrings.tr("批量选择", "Select", "Выбрать"); clicked => { root.batch = !root.batch; root.action("selection", ""); } }
|
||||
CompactButton { width: 116px; text: GalleryStrings.tr("从最近连接添加", "Add from recent", "Из недавних"); clicked => { root.action("recent-open", ""); root.importing = true; } }
|
||||
CompactButton { width: 90px; primary: true; text: GalleryStrings.tr("添加设备", "Add device", "Добавить"); clicked => { root.action("add-open", ""); root.adding = true; } }
|
||||
CompactButton {
|
||||
width: 72px; quiet: true; primary: root.batch;
|
||||
text: root.batch ? GalleryStrings.tr("完成", "Done", "Готово") : GalleryStrings.tr("选择", "Select", "Выбрать");
|
||||
clicked => { root.batch = !root.batch; root.action("selection", ""); }
|
||||
}
|
||||
add-menu := GalleryMenuButton {
|
||||
width: 90px; primary: true;
|
||||
text: GalleryStrings.tr("添加", "Add", "Добавить"); menu-width: 232px;
|
||||
items: [
|
||||
{label: GalleryStrings.tr("通过设备 ID 添加", "Add by device ID", "Добавить по ID устройства"), enabled: true},
|
||||
{label: GalleryStrings.tr("从近期连接添加", "Add from recent", "Добавить из недавних"), enabled: true},
|
||||
];
|
||||
opened => { root.device-tooltip-id = ""; root.action("release", ""); }
|
||||
selected(index) => {
|
||||
if index == 0 { root.action("add-open", ""); root.adding = true; }
|
||||
else { root.action("recent-open", ""); root.importing = true; }
|
||||
}
|
||||
}
|
||||
}
|
||||
grid := Rectangle {
|
||||
x: root.simplified ? 12px : toolbar.x;
|
||||
y: root.simplified ? 12px : toolbar.y + toolbar.height + 12px;
|
||||
width: parent.width - self.x * 2;
|
||||
height: (root.simplified && root.pages <= 1 ? parent.height - 12px : footer.y - 12px) - self.y;
|
||||
height: footer.y - 12px - self.y;
|
||||
visible: root.focused.id == "";
|
||||
for tile[index] in root.tiles: Rectangle {
|
||||
for tile[index] in root.tiles: tile-card := Rectangle {
|
||||
private property <string> presence: tile.online ? GalleryStrings.tr("在线", "Online", "В сети")
|
||||
: tile.presence-known ? GalleryStrings.tr("离线", "Offline", "Не в сети") : GalleryStrings.tr("未知", "Unknown", "Неизвестно");
|
||||
private property <string> details: tile.name + "\nID: " + tile.id + "\n" + self.presence;
|
||||
accessible-role: button; accessible-label: self.details;
|
||||
accessible-action-default => { root.action(root.batch && !root.simplified ? "select" : "focus", tile.id); }
|
||||
changed details => { if tile-touch.has-hover { tile-touch.show-details(); } }
|
||||
x: mod(index, root.columns) * (grid.width + root.grid-gap) / root.columns;
|
||||
y: floor(index / root.columns) * (grid.height + root.grid-gap) / root.rows;
|
||||
width: (grid.width - (root.columns - 1) * root.grid-gap) / root.columns;
|
||||
height: (grid.height - (root.rows - 1) * root.grid-gap) / root.rows;
|
||||
border-radius: root.simplified ? 0px : 6px;
|
||||
background: root.simplified ? #24272d : tile.selected ? #eaf3ff : #eff0f2;
|
||||
background: !tile.online ? DeviceCardStyle.offline-background : root.simplified ? #24272d : tile.selected ? #eaf3ff : #eff0f2;
|
||||
border-width: root.simplified ? 0px : tile.selected ? 2px : 1px;
|
||||
border-color: tile.selected ? #76aeea : root.batch && tile-touch.has-hover ? #94bdeb : #c9cdd2;
|
||||
border-color: tile.selected ? #76aeea : root.batch && tile-touch.has-hover ? #94bdeb : !tile.online ? DeviceCardStyle.offline-border : #c9cdd2;
|
||||
Rectangle {
|
||||
x: root.simplified ? 0px : 6px; y: self.x;
|
||||
width: parent.width - self.x * 2;
|
||||
height: root.simplified ? parent.height : parent.height - 36px;
|
||||
background: #24272d;
|
||||
if tile.has-frame: Image { x: 0px; y: 0px; width: parent.width; height: parent.height; source: tile.frame; image-fit: contain; opacity: tile.stale ? 0.45 : 1; }
|
||||
background: tile.online ? #24272d : DeviceCardStyle.offline-preview;
|
||||
if tile.has-frame && tile.online: Image { x: 0px; y: 0px; width: parent.width; height: parent.height; source: tile.frame; image-fit: contain; opacity: tile.stale ? 0.45 : 1; }
|
||||
if !root.simplified && (!tile.has-frame || !tile.connected || tile.stale): Text {
|
||||
text: tile.status; color: #ffffff; font-size: 12px;
|
||||
text: tile.status; color: tile.online ? #ffffff : DeviceCardStyle.offline-placeholder; font-size: 12px;
|
||||
horizontal-alignment: center; vertical-alignment: center;
|
||||
wrap: word-wrap;
|
||||
}
|
||||
}
|
||||
Text { visible: !root.simplified; x: 9px; y: parent.height - 28px; width: (tile-touch.has-hover && !root.batch ? parent.width - DeviceCardStyle.toolbar-width - 6px : presence-badge.x) - 17px; height: 28px; text: tile.name; color: #24272d; font-size: 12px; overflow: elide; vertical-alignment: center; }
|
||||
presence-badge := Rectangle {
|
||||
visible: !root.simplified && (root.batch || !tile-touch.has-hover);
|
||||
x: parent.width - (root.batch ? 35px : 9px) - self.width; y: parent.height - 23px;
|
||||
width: presence-label.preferred-width + 12px; height: 18px;
|
||||
border-radius: 9px; background: tile.online ? #eaf6ee : #e2e5e9;
|
||||
presence-label := Text {
|
||||
x: 6px; height: parent.height;
|
||||
text: tile.online ? GalleryStrings.tr("在线", "Online", "В сети") : tile.presence-known ? GalleryStrings.tr("离线", "Offline", "Не в сети") : GalleryStrings.tr("未知", "Unknown", "Неизвестно");
|
||||
color: tile.online ? #17854c : #62666d; font-size: 10px; vertical-alignment: center;
|
||||
}
|
||||
Text {
|
||||
visible: !root.simplified; x: 9px; y: parent.height - 28px;
|
||||
width: parent.width - self.x - (tile-touch.has-hover && !root.batch ? DeviceCardStyle.toolbar-width + 12px : root.batch ? 35px : 9px);
|
||||
height: 28px; text: tile.name; color: tile.online ? #24272d : DeviceCardStyle.offline-text; font-size: 12px; overflow: elide; vertical-alignment: center;
|
||||
}
|
||||
if root.batch && !root.simplified: Rectangle {
|
||||
x: parent.width - 27px; y: parent.height - 23px;
|
||||
@@ -159,7 +189,19 @@ export component GalleryView inherits Rectangle {
|
||||
}
|
||||
}
|
||||
tile-touch := TouchArea {
|
||||
clicked => { root.action(root.batch && !root.simplified ? "select" : "focus", tile.id); }
|
||||
function show-details() {
|
||||
// Avoid covering the per-device action buttons with a tooltip.
|
||||
if self.mouse-y >= tile-card.height - 28px && !root.simplified { root.device-tooltip-id = ""; return; }
|
||||
root.device-tooltip-id = tile.id; root.device-tooltip-text = tile-card.details;
|
||||
root.device-tooltip-x = grid.x + tile-card.x;
|
||||
root.device-tooltip-y = grid.y + tile-card.y + tile-card.height + 4px;
|
||||
}
|
||||
changed has-hover => {
|
||||
if self.has-hover { self.show-details(); }
|
||||
else if root.device-tooltip-id == tile.id { root.device-tooltip-id = ""; }
|
||||
}
|
||||
moved => { self.show-details(); }
|
||||
clicked => { root.device-tooltip-id = ""; root.action(root.batch && !root.simplified ? "select" : "focus", tile.id); }
|
||||
if tile-touch.has-hover && !root.batch && !root.simplified: DeviceCardActions {
|
||||
x: parent.width - self.width - 6px; y: parent.height - 26px;
|
||||
remove-label: GalleryStrings.tr("从桌面墙移除", "Remove from DeskHub", "Убрать из DeskHub");
|
||||
@@ -182,13 +224,13 @@ export component GalleryView inherits Rectangle {
|
||||
focus-view := Rectangle {
|
||||
visible: root.focused.id != "";
|
||||
x: 29px; y: 7px; width: parent.width - 58px;
|
||||
height: parent.height - (root.simplified && root.pages <= 1 ? 19px : 51px);
|
||||
height: footer.y - 12px - self.y;
|
||||
HorizontalLayout {
|
||||
x: 0px; y: 0px; width: parent.width; height: 28px; spacing: 8px;
|
||||
CompactButton { width: 52px; text: GalleryStrings.tr("返回", "Back", "Назад"); clicked => { root.action("focus", ""); } }
|
||||
Rectangle {
|
||||
horizontal-stretch: 1; min-width: 0px;
|
||||
Text { x: 0px; width: parent.width; height: parent.height; text: root.focused.name; color: #303943; font-size: 12px; font-weight: 600; overflow: elide; horizontal-alignment: left; vertical-alignment: center; }
|
||||
Text { x: 0px; width: parent.width; height: parent.height; text: root.focused.name; color: root.focused.online ? #303943 : DeviceCardStyle.offline-text; font-size: 12px; font-weight: 600; overflow: elide; horizontal-alignment: left; vertical-alignment: center; }
|
||||
}
|
||||
Rectangle {
|
||||
width: min(focus-state.preferred-width + 16px, 110px); height: 22px;
|
||||
@@ -207,12 +249,12 @@ export component GalleryView inherits Rectangle {
|
||||
Rectangle {
|
||||
x: 0px; y: rail.visible ? rail.y + rail.height + 10px : 36px;
|
||||
width: parent.width; height: parent.height - self.y;
|
||||
background: #eff1f4; border-radius: 6px;
|
||||
border-width: root.controlling ? 2px : 1px; border-color: root.controlling ? #76aeea : #d5dbe3;
|
||||
background: root.focused.online ? #eff1f4 : DeviceCardStyle.offline-background; border-radius: 6px;
|
||||
border-width: root.controlling ? 2px : 1px; border-color: root.controlling ? #76aeea : root.focused.online ? #d5dbe3 : DeviceCardStyle.offline-border;
|
||||
video := Rectangle {
|
||||
x: 4px; y: 4px; width: parent.width - 8px; height: parent.height - 8px;
|
||||
background: #24272d;
|
||||
if root.focused.has-frame: Image {
|
||||
background: root.focused.online ? #24272d : DeviceCardStyle.offline-preview;
|
||||
if root.focused.has-frame && root.focused.online: Image {
|
||||
width: parent.width; height: parent.height; source: root.focused.frame; image-fit: contain;
|
||||
opacity: root.focused.stale || !root.focused.connected ? 0.4 : 1;
|
||||
}
|
||||
@@ -245,7 +287,7 @@ export component GalleryView inherits Rectangle {
|
||||
}
|
||||
}
|
||||
}
|
||||
if !root.focused.has-frame || root.focused.stale || !root.focused.connected: Text { text: root.focused.status; color: white; horizontal-alignment: center; vertical-alignment: center; }
|
||||
if !root.focused.has-frame || root.focused.stale || !root.focused.connected: Text { text: root.focused.status; color: root.focused.online ? white : DeviceCardStyle.offline-placeholder; horizontal-alignment: center; vertical-alignment: center; }
|
||||
}
|
||||
}
|
||||
rail := ScrollView {
|
||||
@@ -257,14 +299,14 @@ export component GalleryView inherits Rectangle {
|
||||
horizontal-scrollbar-policy: as-needed;
|
||||
vertical-scrollbar-policy: always-off;
|
||||
changed width => {
|
||||
root.rail-tooltip-id = "";
|
||||
root.device-tooltip-id = "";
|
||||
self.viewport-x = clamp(self.viewport-x, min(0px, self.width - self.viewport-width), 0px);
|
||||
}
|
||||
changed viewport-width => {
|
||||
root.rail-tooltip-id = "";
|
||||
root.device-tooltip-id = "";
|
||||
self.viewport-x = clamp(self.viewport-x, min(0px, self.width - self.viewport-width), 0px);
|
||||
}
|
||||
changed viewport-x => { root.rail-tooltip-id = ""; }
|
||||
changed viewport-x => { root.device-tooltip-id = ""; }
|
||||
HorizontalLayout {
|
||||
x: 0px; y: 0px; height: root.rail-card-height; spacing: 0px; padding: 0px;
|
||||
for tile in root.tiles: rail-slot := Rectangle {
|
||||
@@ -276,106 +318,138 @@ export component GalleryView inherits Rectangle {
|
||||
: tile.presence-known ? GalleryStrings.tr("离线", "Offline", "Не в сети") : GalleryStrings.tr("未知", "Unknown", "Неизвестно");
|
||||
private property <string> details: tile.name + "\nID: " + tile.id + "\n" + self.presence;
|
||||
width: 136px; height: root.rail-card-height; border-radius: 5px;
|
||||
background: #f5f6f8; border-width: 1px; border-color: #d5dbe3;
|
||||
background: tile.online ? #f5f6f8 : DeviceCardStyle.offline-background; border-width: 1px; border-color: tile.online ? #d5dbe3 : DeviceCardStyle.offline-border;
|
||||
accessible-role: button;
|
||||
accessible-label: self.details;
|
||||
accessible-action-default => { root.action("focus", tile.id); }
|
||||
changed details => { if rail-touch.has-hover { rail-touch.show-details(); } }
|
||||
Rectangle {
|
||||
x: 5px; y: 5px; width: 126px; height: root.simplified ? 82px : 52px; background: #24272d;
|
||||
if tile.has-frame: Image { width: parent.width; height: parent.height; source: tile.frame; image-fit: contain; opacity: tile.stale || !tile.connected ? 0.4 : 1; }
|
||||
x: 5px; y: 5px; width: 126px; height: root.simplified ? 82px : 52px; background: tile.online ? #24272d : DeviceCardStyle.offline-preview;
|
||||
if tile.has-frame && tile.online: Image { width: parent.width; height: parent.height; source: tile.frame; image-fit: contain; opacity: tile.stale || !tile.connected ? 0.4 : 1; }
|
||||
if !root.simplified && (!tile.has-frame || tile.stale || !tile.connected): Text {
|
||||
text: tile.status; color: #e2e6ed; font-size: 10px; overflow: elide;
|
||||
text: tile.status; color: tile.online ? #e2e6ed : DeviceCardStyle.offline-placeholder; font-size: 10px; overflow: elide;
|
||||
horizontal-alignment: center; vertical-alignment: center;
|
||||
}
|
||||
}
|
||||
Rectangle {
|
||||
visible: !root.simplified;
|
||||
x: 7px; y: 63px; width: 6px; height: 6px; border-radius: 3px;
|
||||
background: tile.online ? #17854c : tile.presence-known ? #8a939e : transparent;
|
||||
border-width: 1px; border-color: tile.online ? #17854c : #8a939e;
|
||||
}
|
||||
Text {
|
||||
visible: !root.simplified;
|
||||
x: 18px; y: 58px; width: 111px; height: 16px;
|
||||
text: tile.name; color: #303943; font-size: 11px;
|
||||
x: 7px; y: 58px; width: 122px; height: 16px;
|
||||
text: tile.name; color: tile.online ? #303943 : DeviceCardStyle.offline-text; font-size: 11px;
|
||||
overflow: elide; vertical-alignment: center;
|
||||
}
|
||||
rail-touch := TouchArea {
|
||||
function show-details() {
|
||||
root.rail-tooltip-id = tile.id;
|
||||
root.rail-tooltip-text = parent.details;
|
||||
root.rail-tooltip-x = rail.x + rail.viewport-x + rail-slot.x;
|
||||
root.device-tooltip-id = tile.id;
|
||||
root.device-tooltip-text = parent.details;
|
||||
root.device-tooltip-x = focus-view.x + rail.x + rail.viewport-x + rail-slot.x;
|
||||
root.device-tooltip-y = focus-view.y + rail.y + rail.height + 4px;
|
||||
}
|
||||
changed has-hover => {
|
||||
if self.has-hover { self.show-details(); }
|
||||
else if root.rail-tooltip-id == tile.id { root.rail-tooltip-id = ""; }
|
||||
else if root.device-tooltip-id == tile.id { root.device-tooltip-id = ""; }
|
||||
}
|
||||
moved => { if self.has-hover { self.show-details(); } }
|
||||
clicked => { root.rail-tooltip-id = ""; root.action("focus", tile.id); }
|
||||
clicked => { root.device-tooltip-id = ""; root.action("focus", tile.id); }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Keep full device details outside the clipped thumbnail rail.
|
||||
if root.rail-tooltip-visible && rail.visible && root.rail-tooltip-id != "" && root.rail-tooltip-id != root.focused.id: Rectangle {
|
||||
x: clamp(root.rail-tooltip-x, 0px, parent.width - self.width);
|
||||
y: rail.y + rail.height + 4px;
|
||||
width: min(320px, parent.width); height: rail-tooltip-label.preferred-height + 16px;
|
||||
background: #22252bf2; border-width: 1px; border-color: #ffffff38; border-radius: 5px;
|
||||
rail-tooltip-label := Text {
|
||||
x: 8px; y: 8px; width: parent.width - 16px;
|
||||
text: root.rail-tooltip-text; color: white; font-size: 11px; wrap: word-wrap;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Reuse the footer for selection actions so entering batch mode never
|
||||
// changes card geometry or moves a device beneath the pointer.
|
||||
footer := HorizontalLayout {
|
||||
x: toolbar.x; y: parent.height - 36px; width: toolbar.width; height: 24px; spacing: root.batch ? 8px : 12px;
|
||||
visible: !root.simplified || root.pages > 1;
|
||||
if root.batch && !root.simplified: CompactButton {
|
||||
width: 90px; enabled: root.count > 0;
|
||||
text: root.count > 0 && root.selected-count == root.count
|
||||
? GalleryStrings.tr("取消全选", "Deselect all", "Снять выбор")
|
||||
: GalleryStrings.tr("全选", "Select all", "Выбрать все");
|
||||
clicked => { root.action("all-select", ""); }
|
||||
}
|
||||
Rectangle {
|
||||
horizontal-stretch: 1; min-width: 0px;
|
||||
Rectangle {
|
||||
y: parent.height - 44px; height: 44px; background: #fafbfc;
|
||||
Rectangle { y: 0px; width: parent.width; height: 1px; background: #e1e4e8; }
|
||||
}
|
||||
// Fixed selection widths keep the cards, actions and pager stationary.
|
||||
footer := Rectangle {
|
||||
x: root.simplified ? 12px : toolbar.x; y: parent.height - 34px;
|
||||
width: parent.width - self.x * 2; height: 24px;
|
||||
status-area := Rectangle {
|
||||
x: 0px; y: 0px; width: parent.width - 124px; height: parent.height;
|
||||
visible: !root.batch || root.simplified;
|
||||
border-radius: 3px; background: network-touch.has-hover ? #edf0f4 : transparent;
|
||||
accessible-role: button;
|
||||
accessible-label: GalleryStrings.tr("网络状态", "Network", "Сеть") + ": " + root.connected-summary;
|
||||
accessible-action-default => { root.network-open(); }
|
||||
Text {
|
||||
visible: !root.simplified;
|
||||
y: 0px; width: parent.width; height: root.batch && root.hidden-selected > 0 ? 13px : parent.height;
|
||||
text: root.batch ? GalleryStrings.tr("已选 ", "Selected ", "Выбрано ") + root.selected-count : root.connected-count + " / " + root.count + GalleryStrings.tr(" 台已连接", " connected", " подключено");
|
||||
color: #62666d; vertical-alignment: center; font-size: 12px; overflow: elide;
|
||||
x: 0px; width: parent.width - 20px; height: parent.height;
|
||||
text: root.connected-summary + " · " + GalleryStrings.tr("网络状态", "Network", "Сеть");
|
||||
color: #62666d; vertical-alignment: center; font-size: 11px; overflow: elide;
|
||||
}
|
||||
if root.batch && !root.simplified && root.hidden-selected > 0: Text {
|
||||
y: 14px; width: parent.width; height: 10px;
|
||||
text: GalleryStrings.tr("跨页 ", "Other pages ", "Вне страницы ") + root.hidden-selected;
|
||||
color: #80858d; font-size: 10px; overflow: elide;
|
||||
Text {
|
||||
x: parent.width - 13px; width: 12px; height: parent.height;
|
||||
text: FontAwesomeIcons.angle-up; font-family: "Font Awesome 6 Free"; font-weight: 900;
|
||||
font-size: 9px; color: #858c96; vertical-alignment: center;
|
||||
}
|
||||
network-touch := TouchArea {
|
||||
mouse-cursor: pointer;
|
||||
changed has-hover => {
|
||||
if self.has-hover {
|
||||
root.device-tooltip-id = "network-status";
|
||||
root.device-tooltip-text = root.connected-summary + "\n" + GalleryStrings.tr("点击查看网络状态", "Click to view network status", "Нажмите для просмотра состояния сети");
|
||||
root.device-tooltip-x = footer.x; root.device-tooltip-y = footer.y;
|
||||
} else if root.device-tooltip-id == "network-status" { root.device-tooltip-id = ""; }
|
||||
}
|
||||
clicked => { root.device-tooltip-id = ""; root.network-open(); }
|
||||
}
|
||||
}
|
||||
if root.batch && !root.simplified: HorizontalLayout {
|
||||
width: 280px; spacing: 8px;
|
||||
CompactButton { width: 58px; enabled: root.selected-count > 0; text: GalleryStrings.tr("连接", "Connect", "Связь"); clicked => { root.action("connect", ""); } }
|
||||
CompactButton { width: 62px; enabled: root.selected-count > 0; text: GalleryStrings.tr("断开", "Close", "Отключить"); clicked => { root.confirm-action("disconnect", self.text); } }
|
||||
CompactButton {
|
||||
width: 58px; enabled: root.selected-audio-available;
|
||||
text: root.selected-audio-muted
|
||||
? GalleryStrings.tr("取消静音", "Unmute", "Со звуком")
|
||||
: GalleryStrings.tr("静音", "Mute", "Без звука");
|
||||
clicked => { root.action(root.selected-audio-muted ? "unmute" : "mute", ""); }
|
||||
selection-actions := HorizontalLayout {
|
||||
x: 0px; y: 0px; height: parent.height;
|
||||
visible: root.batch && !root.simplified; width: 408px; spacing: 6px;
|
||||
Rectangle {
|
||||
width: 100px;
|
||||
Text {
|
||||
x: 0px; y: 0px; width: parent.width; height: root.hidden-selected > 0 ? 13px : parent.height;
|
||||
text: GalleryStrings.tr("已选 ", "Selected ", "Выбрано ") + root.selected-count + GalleryStrings.tr(" 台", "", "");
|
||||
color: #62666d; vertical-alignment: center; font-size: 11px; overflow: elide;
|
||||
}
|
||||
if root.hidden-selected > 0: Text {
|
||||
y: 14px; width: parent.width; height: 10px;
|
||||
text: GalleryStrings.tr("跨页 ", "Other pages ", "Вне страницы ") + root.hidden-selected;
|
||||
color: #80858d; font-size: 10px; overflow: elide;
|
||||
}
|
||||
}
|
||||
CompactButton {
|
||||
width: 90px; quiet: true; enabled: root.count > 0;
|
||||
text: root.count > 0 && root.selected-count == root.count
|
||||
? GalleryStrings.tr("取消全选", "Deselect all", "Снять выбор")
|
||||
: GalleryStrings.tr("全选", "Select all", "Выбрать все");
|
||||
clicked => { root.action("all-select", ""); }
|
||||
}
|
||||
CompactButton { width: 60px; primary: true; enabled: root.selected-count > 0; text: GalleryStrings.tr("连接", "Connect", "Связь"); clicked => { root.action("connect", ""); } }
|
||||
CompactButton { width: 64px; enabled: root.selected-count > 0; text: GalleryStrings.tr("断开", "Close", "Отключить"); clicked => { root.confirm-action("disconnect", self.text); } }
|
||||
batch-menu := GalleryMenuButton {
|
||||
width: 70px; enabled: root.selected-count > 0; opens-up: true;
|
||||
text: GalleryStrings.tr("更多", "More", "Ещё");
|
||||
items: [
|
||||
{label: root.selected-audio-muted ? GalleryStrings.tr("取消静音", "Unmute", "Со звуком") : GalleryStrings.tr("静音", "Mute", "Без звука"), enabled: root.selected-audio-available},
|
||||
{label: GalleryStrings.tr("分发文件", "Send file", "Отправить файл"), enabled: root.selected-count > 0},
|
||||
];
|
||||
opened => { root.device-tooltip-id = ""; root.action("release", ""); }
|
||||
selected(index) => {
|
||||
if index == 0 { root.action(root.selected-audio-muted ? "unmute" : "mute", ""); }
|
||||
else { root.confirm-action("file", GalleryStrings.tr("分发文件", "Send file", "Отправить файл")); }
|
||||
}
|
||||
}
|
||||
CompactButton { width: 78px; enabled: root.selected-count > 0; text: GalleryStrings.tr("分发文件", "Send file", "Файл"); clicked => { root.confirm-action("file", self.text); } }
|
||||
}
|
||||
HorizontalLayout {
|
||||
width: 112px; height: 24px; spacing: 6px;
|
||||
x: parent.width - self.width; y: 0px; width: 112px; height: 24px; spacing: 6px;
|
||||
CompactButton { width: 24px; text: "‹"; text-size: 16px; enabled: root.page > 0; clicked => { root.action("page", "previous"); } }
|
||||
Text { text: (root.page + 1) + " / " + root.pages; min-width: 0px; overflow: elide; horizontal-alignment: center; vertical-alignment: center; }
|
||||
CompactButton { width: 24px; text: "›"; text-size: 16px; enabled: root.page + 1 < root.pages; clicked => { root.action("page", "next"); } }
|
||||
}
|
||||
}
|
||||
// Share one delayed tooltip across cards and keep it inside the view.
|
||||
if root.device-tooltip-visible && root.device-tooltip-id != "": Rectangle {
|
||||
x: clamp(root.device-tooltip-x, 8px, parent.width - self.width - 8px);
|
||||
y: clamp(root.device-tooltip-y + self.height > footer.y ? root.device-tooltip-y - self.height - 8px : root.device-tooltip-y, 4px, parent.height - self.height - 4px);
|
||||
width: min(320px, parent.width - 16px); height: device-tooltip-label.preferred-height + 16px;
|
||||
background: #22252bf2; border-width: 1px; border-color: #ffffff38; border-radius: 5px;
|
||||
device-tooltip-label := Text {
|
||||
x: 8px; y: 8px; width: parent.width - 16px;
|
||||
text: root.device-tooltip-text; color: white; font-size: 11px; wrap: word-wrap;
|
||||
}
|
||||
}
|
||||
if root.adding: Rectangle {
|
||||
background: #00000042;
|
||||
TouchArea {}
|
||||
|
||||
Reference in New Issue
Block a user