style(ui): progress window matches conflict + login
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:
+78
-18
@@ -85,8 +85,58 @@ def _apply_prism_dark(app: Any) -> None:
|
||||
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:
|
||||
"""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:
|
||||
QtWidgets, QtCore, Signal = import_qt()
|
||||
@@ -106,35 +156,45 @@ class QtProgressWindow:
|
||||
|
||||
self._dialog = QtWidgets.QDialog()
|
||||
self._dialog.setWindowTitle("Cloud sync")
|
||||
self._dialog.setFixedSize(440, 160)
|
||||
# Block ESC + window close X → mark cancelled, don't accept
|
||||
self._dialog.setFixedSize(520, 240)
|
||||
self._dialog.setStyleSheet(_PROGRESS_QSS)
|
||||
self._dialog.setWindowFlag(
|
||||
QtCore.Qt.WindowType.WindowContextHelpButtonHint, False
|
||||
)
|
||||
|
||||
layout = QtWidgets.QVBoxLayout(self._dialog)
|
||||
layout.setContentsMargins(20, 20, 20, 20)
|
||||
outer = QtWidgets.QVBoxLayout(self._dialog)
|
||||
outer.setContentsMargins(28, 24, 28, 20)
|
||||
outer.setSpacing(14)
|
||||
|
||||
self._title_label = QtWidgets.QLabel("Working…")
|
||||
font = self._title_label.font()
|
||||
font.setBold(True)
|
||||
font.setPointSize(font.pointSize() + 1)
|
||||
self._title_label.setFont(font)
|
||||
layout.addWidget(self._title_label)
|
||||
header = QtWidgets.QHBoxLayout()
|
||||
header.setSpacing(12)
|
||||
badge = QtWidgets.QLabel("↻")
|
||||
badge.setObjectName("badge")
|
||||
header.addWidget(badge)
|
||||
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…")
|
||||
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.setRange(0, 0) # indeterminate
|
||||
self._bar.setTextVisible(False)
|
||||
layout.addWidget(self._bar)
|
||||
outer.addWidget(self._bar)
|
||||
|
||||
button_row = QtWidgets.QHBoxLayout()
|
||||
button_row.addStretch(1)
|
||||
foot = QtWidgets.QHBoxLayout()
|
||||
foot.addStretch(1)
|
||||
self._cancel_btn = QtWidgets.QPushButton("Cancel")
|
||||
button_row.addWidget(self._cancel_btn)
|
||||
layout.addLayout(button_row)
|
||||
self._cancel_btn.setObjectName("secondary")
|
||||
foot.addWidget(self._cancel_btn)
|
||||
outer.addLayout(foot)
|
||||
|
||||
self._bridge = _Bridge()
|
||||
self._bridge.status_changed.connect(self._status_label.setText)
|
||||
@@ -155,7 +215,7 @@ class QtProgressWindow:
|
||||
return self._cancelled
|
||||
|
||||
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…")
|
||||
|
||||
def thread_target() -> None:
|
||||
|
||||
Reference in New Issue
Block a user