Files
Windows-Gotify-Client-Rust/ui/dialogs.slint
T
KennethCheng d2de452c53 fix(ui): Phase 7 C3 修复 — AboutDialog 改用 Rectangle overlay + backdrop
原 AboutDialog inherits Slint Dialog(PopupWindow 子类)并 inline 实例化,没经过运行时 show(),close() 是空操作 → 用户点 Close 没反应、UI 卡死。\n- dialogs.slint:AboutDialog / ConfirmDialog 改为 inherits Rectangle,手写 backdrop(点击关闭)+ content card(Close 按钮调 close-dialog 回调)\n- app.slint:新增 show-about bool 属性;Sidebar About 点击同时触发 about-clicked + show-about=true;最外层 if root.show-about: AboutDialog 渲染\n- 删掉 selection==About 的右栏 marker(现在 About 是模态,不再需要)
2026-09-19 19:40:16 +08:00

218 lines
6.7 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// AGENTS.md §54 modals.
//
// Phase 7 C3 fix: the original `inherits Dialog` (a Slint
// PopupWindow-derived type) was instantiated inline inside
// MainWindow. PopupWindow expects to be `.show()`n via the Rust
// runtime; without that, it stays "declared but never properly
// popped up", and its `close()` no-op'd — the Close button became
// inert and the user had to force-kill the process.
//
// Fix: make AboutDialog an inline Rectangle overlay backed by a
// `visible` property toggled from Rust. A full-window dimmed
// backdrop catches outside-clicks to dismiss; the content card
// stays interactive. Same wiring pattern the rest of the UI uses
// (Slint `if root.show-about: AboutDialog { ... }`).
export component AboutDialog inherits Rectangle {
in property <string> version-string: "v0.1.0";
in property <string> build-date: "2026-09-19";
in property <color> bg-color: #28292d;
in property <color> text-primary-color: #e6e6e6;
in property <color> text-secondary-color: #a0a0a0;
in property <color> accent-color: #4ea1ff;
in property <color> button-bg: #2f3035;
in property <color> button-border: #3a3b40;
in property <color> backdrop-color: #000000;
callback close-dialog();
background: transparent;
// Backdrop: full-window dimmed layer that swallows clicks so
// clicking outside the card dismisses the dialog.
Rectangle {
x: 0;
y: 0;
width: 100%;
height: 100%;
background: backdrop-color;
opacity: 0.55;
TouchArea {
clicked => {
root.close-dialog();
}
}
}
// Card: 360x240-ish centered modal content.
Rectangle {
x: (parent.width - self.width) / 2;
y: (parent.height - self.height) / 2;
width: 380px;
height: 280px;
background: bg-color;
border-color: button-border;
border-width: 1px;
border-radius: 12px;
VerticalLayout {
padding: 24px;
spacing: 10px;
Text {
text: "Windows Gotify Client (Rust)";
color: text-primary-color;
font-size: 16px;
font-weight: 700;
}
Text {
text: version-string;
color: accent-color;
font-size: 13px;
}
Text {
text: "Built " + build-date;
color: text-secondary-color;
font-size: 11px;
}
Rectangle { height: 8px; }
Text {
text: "Lightweight, modern, Windows-native Gotify\ndesktop client. Phase 1–8 complete.";
color: text-secondary-color;
font-size: 12px;
wrap: word-wrap;
}
Rectangle { height: 8px; }
// Close button row.
HorizontalLayout {
alignment: end;
Rectangle {
width: 100px;
height: 32px;
background: button-bg;
border-color: button-border;
border-width: 1px;
border-radius: 6px;
Text {
x: (parent.width - self.width) / 2;
y: (parent.height - self.height) / 2;
text: "Close";
color: text-primary-color;
font-size: 12px;
}
// TouchArea last so it sits on top of the Text.
TouchArea {
clicked => {
root.close-dialog();
}
}
}
}
}
}
}
export component ConfirmDialog inherits Rectangle {
in property <string> title-text: "Confirm";
in property <string> message: "Are you sure?";
in property <string> confirm-label: "Confirm";
in property <string> cancel-label: "Cancel";
callback confirmed();
callback cancelled();
in property <color> bg-color: #28292d;
in property <color> text-primary-color: #e6e6e6;
in property <color> text-secondary-color: #a0a0a0;
in property <color> danger-color: #f44336;
in property <color> button-bg: #2f3035;
in property <color> button-border: #3a3b40;
in property <color> backdrop-color: #000000;
background: transparent;
Rectangle {
x: 0;
y: 0;
width: 100%;
height: 100%;
background: backdrop-color;
opacity: 0.55;
TouchArea {
clicked => {
root.cancelled();
}
}
}
Rectangle {
x: (parent.width - self.width) / 2;
y: (parent.height - self.height) / 2;
width: 380px;
height: 180px;
background: bg-color;
border-color: button-border;
border-width: 1px;
border-radius: 12px;
VerticalLayout {
padding: 24px;
spacing: 16px;
Text {
text: message;
color: text-primary-color;
font-size: 13px;
wrap: word-wrap;
}
HorizontalLayout {
spacing: 12px;
Rectangle { horizontal-stretch: 1; }
Rectangle {
width: 90px;
height: 32px;
background: button-bg;
border-color: button-border;
border-width: 1px;
border-radius: 6px;
Text {
x: (parent.width - self.width) / 2;
y: (parent.height - self.height) / 2;
text: cancel-label;
color: text-primary-color;
font-size: 12px;
}
TouchArea {
clicked => {
root.cancelled();
}
}
}
Rectangle {
width: 90px;
height: 32px;
background: danger-color;
border-radius: 6px;
Text {
x: (parent.width - self.width) / 2;
y: (parent.height - self.height) / 2;
text: confirm-label;
color: #ffffff;
font-size: 12px;
font-weight: 600;
}
TouchArea {
clicked => {
root.confirmed();
}
}
}
}
}
}
}