style(ui): progress window matches conflict + login
CI / test (3.10) (push) Successful in 7s
CI / test (3.11) (push) Successful in 7s
CI / test (3.12) (push) Successful in 7s
CI / build-pyz (push) Successful in 4s
CI / release (push) Has been skipped

Same skeleton: Prism-green badge ('↻') + uppercase title in the
header row, status text under it, indeterminate progress bar (dark
inset with Prism-green chunk), Cancel button bottom-right styled
as the shared 'secondary' button.

Bumped from 440x160 to 520x240 so the header reads at the same
weight as the other two dialogs. title.upper() applied in run_with
so callers can keep passing 'Cloud sync — pulling' without manual
uppercasing.

Three dialogs now share one visual language: Prism dark surface
(#313131), Prism-green accent (#96db59), monospace for code/data,
circled badge in the top-left of every header.
This commit is contained in:
2026-06-04 23:34:50 +02:00
parent aba6472292
commit fa04fade74
+78 -18
View File
@@ -85,8 +85,58 @@ def _apply_prism_dark(app: Any) -> None:
app.setPalette(p) app.setPalette(p)
_PROGRESS_QSS = """
QDialog { background: #313131; }
QLabel#title {
color: white;
font-size: 18pt;
font-weight: bold;
letter-spacing: 2px;
}
QLabel#badge {
color: #313131;
background: #96db59;
border-radius: 16px;
font-size: 18pt;
font-weight: bold;
qproperty-alignment: AlignCenter;
min-width: 32px;
max-width: 32px;
min-height: 32px;
max-height: 32px;
}
QLabel#status {
color: #c8c8c8;
font-size: 10pt;
}
QProgressBar {
background: #222222;
border: 1px solid #3a3a3a;
border-radius: 3px;
height: 14px;
}
QProgressBar::chunk {
background: #96db59;
border-radius: 2px;
}
QPushButton#secondary {
background: #303030;
color: white;
border: 1px solid #4a4a4a;
border-radius: 2px;
padding: 8px 20px;
font-size: 10pt;
}
QPushButton#secondary:hover { background: #3a3a3a; border-color: #96db59; }
QPushButton#secondary:pressed { background: #222222; }
QPushButton#secondary:disabled { color: #777; border-color: #2a2a2a; }
"""
class QtProgressWindow: class QtProgressWindow:
"""Modal Qt dialog: title + status + indeterminate progress + Cancel.""" """Modal Qt dialog: header badge + uppercase title + status + bar + Cancel.
Matches the conflict + login dialog skeleton in Prism dark."""
def __init__(self) -> None: def __init__(self) -> None:
QtWidgets, QtCore, Signal = import_qt() QtWidgets, QtCore, Signal = import_qt()
@@ -106,35 +156,45 @@ class QtProgressWindow:
self._dialog = QtWidgets.QDialog() self._dialog = QtWidgets.QDialog()
self._dialog.setWindowTitle("Cloud sync") self._dialog.setWindowTitle("Cloud sync")
self._dialog.setFixedSize(440, 160) self._dialog.setFixedSize(520, 240)
# Block ESC + window close X → mark cancelled, don't accept self._dialog.setStyleSheet(_PROGRESS_QSS)
self._dialog.setWindowFlag( self._dialog.setWindowFlag(
QtCore.Qt.WindowType.WindowContextHelpButtonHint, False QtCore.Qt.WindowType.WindowContextHelpButtonHint, False
) )
layout = QtWidgets.QVBoxLayout(self._dialog) outer = QtWidgets.QVBoxLayout(self._dialog)
layout.setContentsMargins(20, 20, 20, 20) outer.setContentsMargins(28, 24, 28, 20)
outer.setSpacing(14)
self._title_label = QtWidgets.QLabel("Working…") header = QtWidgets.QHBoxLayout()
font = self._title_label.font() header.setSpacing(12)
font.setBold(True) badge = QtWidgets.QLabel("")
font.setPointSize(font.pointSize() + 1) badge.setObjectName("badge")
self._title_label.setFont(font) header.addWidget(badge)
layout.addWidget(self._title_label) self._title_label = QtWidgets.QLabel("CLOUD SYNC")
self._title_label.setObjectName("title")
header.addWidget(self._title_label)
header.addStretch(1)
outer.addLayout(header)
self._status_label = QtWidgets.QLabel("Starting…") self._status_label = QtWidgets.QLabel("Starting…")
layout.addWidget(self._status_label) self._status_label.setObjectName("status")
self._status_label.setWordWrap(True)
outer.addWidget(self._status_label)
outer.addStretch(1)
self._bar = QtWidgets.QProgressBar() self._bar = QtWidgets.QProgressBar()
self._bar.setRange(0, 0) # indeterminate self._bar.setRange(0, 0) # indeterminate
self._bar.setTextVisible(False) self._bar.setTextVisible(False)
layout.addWidget(self._bar) outer.addWidget(self._bar)
button_row = QtWidgets.QHBoxLayout() foot = QtWidgets.QHBoxLayout()
button_row.addStretch(1) foot.addStretch(1)
self._cancel_btn = QtWidgets.QPushButton("Cancel") self._cancel_btn = QtWidgets.QPushButton("Cancel")
button_row.addWidget(self._cancel_btn) self._cancel_btn.setObjectName("secondary")
layout.addLayout(button_row) foot.addWidget(self._cancel_btn)
outer.addLayout(foot)
self._bridge = _Bridge() self._bridge = _Bridge()
self._bridge.status_changed.connect(self._status_label.setText) self._bridge.status_changed.connect(self._status_label.setText)
@@ -155,7 +215,7 @@ class QtProgressWindow:
return self._cancelled return self._cancelled
def run_with(self, worker: Callable[[], int], title: str) -> int: def run_with(self, worker: Callable[[], int], title: str) -> int:
self._title_label.setText(title) self._title_label.setText(title.upper())
self._status_label.setText("Starting…") self._status_label.setText("Starting…")
def thread_target() -> None: def thread_target() -> None: