chore: sync local working copy as of 2026-08-15
The Gitea repo was initialised from an earlier snapshot, so main and the machine this runs on had drifted apart in 153 files before any UI work started. This commit brings the branch up to the local tree as it stood on 2026-08-15 21:31 (from cowork_local.7z), so the redesign that follows shows up as its own reviewable diff instead of being mixed in with the pre-existing divergence. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
+32
-28
@@ -8,36 +8,40 @@ from pathlib import Path
|
||||
from PySide6.QtCore import QEvent, QObject, QPointF, QRectF, Qt, Signal
|
||||
from PySide6.QtGui import QColor, QPainter, QPen
|
||||
from PySide6.QtWidgets import (
|
||||
QAbstractSpinBox, QComboBox, QDoubleSpinBox, QFrame, QGraphicsDropShadowEffect,
|
||||
QAbstractSpinBox, QComboBox, QDoubleSpinBox, QFrame,
|
||||
QHBoxLayout, QLabel, QListWidget, QListWidgetItem, QPushButton, QSizePolicy,
|
||||
QVBoxLayout, QWidget,
|
||||
)
|
||||
|
||||
from ..core.flows import STEP_DONE, STEP_ERROR, STEP_PENDING, STEP_RUNNING
|
||||
from ..theme import ACCENT
|
||||
from ..theme import current_palette
|
||||
from .icons import DOT_BLUE, DOT_GREEN, DOT_GREY, DOT_RED, dot_icon, icon
|
||||
|
||||
|
||||
def _style_card(frame: QFrame) -> None:
|
||||
"""Give a stat/budget card its surface. Flat by design: the raised surface
|
||||
plus a hairline is what separates it from the page — the old drop shadow
|
||||
made a grid of these look like it was hovering off the screen."""
|
||||
p = current_palette()
|
||||
frame.setStyleSheet(
|
||||
f"QFrame {{ background: {p.surface}; border: 1px solid {p.border};"
|
||||
f" border-radius: {p.radius_lg}px; }}")
|
||||
|
||||
|
||||
class StatCard(QFrame):
|
||||
"""A titled value card (e.g. token count + its cost as the subtitle) —
|
||||
shared by Dashboard and Monitoring's token/cost displays."""
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.setFrameShape(QFrame.StyledPanel)
|
||||
self.setStyleSheet(
|
||||
"QFrame { border: 1px solid rgba(140,146,152,0.35); border-radius: 16px; }")
|
||||
shadow = QGraphicsDropShadowEffect(self)
|
||||
shadow.setBlurRadius(18)
|
||||
shadow.setOffset(0, 3)
|
||||
shadow.setColor(QColor(0, 0, 0, 60))
|
||||
self.setGraphicsEffect(shadow)
|
||||
self.setFrameShape(QFrame.NoFrame)
|
||||
_style_card(self)
|
||||
lay = QVBoxLayout(self)
|
||||
self.title_lbl = QLabel("")
|
||||
self.title_lbl.setObjectName("hint")
|
||||
self.title_lbl.setStyleSheet("border: none;")
|
||||
self.value_lbl = QLabel("—")
|
||||
self.value_lbl.setStyleSheet("border: none; font-size: 20px; font-weight: 700;")
|
||||
self.value_lbl.setStyleSheet("border: none; font-size: 22px; font-weight: 600;")
|
||||
self.sub_lbl = QLabel("")
|
||||
self.sub_lbl.setObjectName("hint")
|
||||
self.sub_lbl.setStyleSheet("border: none;")
|
||||
@@ -66,20 +70,14 @@ class BudgetCard(QFrame):
|
||||
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.setFrameShape(QFrame.StyledPanel)
|
||||
self.setStyleSheet(
|
||||
"QFrame { border: 1px solid rgba(140,146,152,0.35); border-radius: 16px; }")
|
||||
shadow = QGraphicsDropShadowEffect(self)
|
||||
shadow.setBlurRadius(18)
|
||||
shadow.setOffset(0, 3)
|
||||
shadow.setColor(QColor(0, 0, 0, 60))
|
||||
self.setGraphicsEffect(shadow)
|
||||
self.setFrameShape(QFrame.NoFrame)
|
||||
_style_card(self)
|
||||
lay = QVBoxLayout(self)
|
||||
self.title_lbl = QLabel("")
|
||||
self.title_lbl.setObjectName("hint")
|
||||
self.title_lbl.setStyleSheet("border: none;")
|
||||
self.value_lbl = QLabel("—")
|
||||
self._value_style = "border: none; font-size: 20px; font-weight: 700;"
|
||||
self._value_style = "border: none; font-size: 22px; font-weight: 600;"
|
||||
self.value_lbl.setStyleSheet(self._value_style)
|
||||
self.sub_lbl = QLabel("")
|
||||
self.sub_lbl.setObjectName("hint")
|
||||
@@ -109,7 +107,7 @@ class BudgetCard(QFrame):
|
||||
self.title_lbl.setText(title)
|
||||
self.value_lbl.setText(value)
|
||||
self.value_lbl.setStyleSheet(
|
||||
self._value_style + (" color: #E5484D;" if warn else ""))
|
||||
self._value_style + (f" color: {current_palette().danger};" if warn else ""))
|
||||
self.sub_lbl.setText(sub)
|
||||
|
||||
|
||||
@@ -185,15 +183,16 @@ class CollapseStrip(QWidget):
|
||||
p = QPainter(self)
|
||||
p.setRenderHint(QPainter.Antialiasing)
|
||||
w = self.width()
|
||||
accent = QColor(ACCENT) if self._hover else QColor("#8b8d98")
|
||||
tok = current_palette()
|
||||
accent = QColor(tok.accent) if self._hover else QColor(tok.text_faint)
|
||||
|
||||
# A small rounded "button" at the top carries the expand arrow so the
|
||||
# collapsed panel always shows a clear, clickable affordance.
|
||||
bw = min(w - 2.0, 16.0)
|
||||
btn = QRectF((w - bw) / 2.0, 6.0, bw, 18.0)
|
||||
p.setPen(QPen(QColor(139, 144, 150, 130), 1.0))
|
||||
p.setBrush(QColor(155, 160, 166, 70) if self._hover else QColor(155, 160, 166, 32))
|
||||
p.drawRoundedRect(btn, 4.0, 4.0)
|
||||
p.setPen(QPen(QColor(tok.border_strong), 1.0))
|
||||
p.setBrush(QColor(tok.hover if self._hover else tok.surface))
|
||||
p.drawRoundedRect(btn, float(tok.radius_sm), float(tok.radius_sm))
|
||||
|
||||
cx = w / 2.0
|
||||
cy = btn.center().y()
|
||||
@@ -211,7 +210,7 @@ class CollapseStrip(QWidget):
|
||||
|
||||
# thin handle line below the button
|
||||
p.setPen(Qt.NoPen)
|
||||
p.setBrush(QColor(155, 160, 166, 90))
|
||||
p.setBrush(QColor(tok.border_strong))
|
||||
line_w = 2.0
|
||||
x = (w - line_w) / 2.0
|
||||
ltop = btn.bottom() + 6.0
|
||||
@@ -226,7 +225,12 @@ class PlanSection(QWidget):
|
||||
close). Hidden until it has steps; updated in place as the agent calls
|
||||
``update_plan``."""
|
||||
|
||||
_COLORS = {STEP_RUNNING: ACCENT, STEP_DONE: "#6fe3a4", STEP_ERROR: "#ef6368"}
|
||||
@staticmethod
|
||||
def _step_color(status: str) -> str | None:
|
||||
"""Row text colour per step status; None leaves the default. Resolved
|
||||
per call so it follows a live theme switch."""
|
||||
p = current_palette()
|
||||
return {STEP_RUNNING: p.accent, STEP_DONE: p.success, STEP_ERROR: p.danger}.get(status)
|
||||
|
||||
@staticmethod
|
||||
def _step_icon(status: str):
|
||||
@@ -272,7 +276,7 @@ class PlanSection(QWidget):
|
||||
continue
|
||||
status = str((s or {}).get("status", STEP_PENDING)).strip().lower()
|
||||
item = QListWidgetItem(self._step_icon(status), f" {title}")
|
||||
color = self._COLORS.get(status)
|
||||
color = self._step_color(status)
|
||||
if color:
|
||||
item.setForeground(QColor(color))
|
||||
self.list.addItem(item)
|
||||
|
||||
Reference in New Issue
Block a user