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)
|
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:
|
||||||
|
|||||||
Reference in New Issue
Block a user