fix(kit): hollow off-dot has no fill; toggle press keeps row selection; unknown states render off

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-06-10 17:04:41 -04:00
parent 44ef17ad38
commit a6394a2889
2 changed files with 43 additions and 2 deletions

View File

@@ -173,6 +173,8 @@ class InstrumentDelegate(QStyledItemDelegate):
def _paint_status(self, painter: QPainter, rect, index, t) -> None:
state = index.data(STATUS_ROLE) or "off"
if state not in ("ok", "warn", "alarm"):
state = "off"
color = qcolor({
"ok": t.ok, "warn": t.warn, "alarm": t.alarm, "off": t.offline,
}.get(state, t.offline))
@@ -198,7 +200,7 @@ class InstrumentDelegate(QStyledItemDelegate):
pen = QPen(color)
pen.setWidthF(1.5)
painter.setPen(pen)
painter.setBrush(qcolor(t.surface)) # fill interior surface so center stays clear
painter.setBrush(Qt.BrushStyle.NoBrush)
painter.drawEllipse(box.adjusted(0.75, 0.75, -0.75, -0.75)) # hollow circle
else:
painter.setPen(Qt.PenStyle.NoPen)
@@ -235,8 +237,10 @@ class InstrumentDelegate(QStyledItemDelegate):
Qt.ItemDataRole.CheckStateRole,
)
return True
if event.type() in (QEvent.Type.MouseButtonPress, QEvent.Type.MouseButtonDblClick):
if event.type() == QEvent.Type.MouseButtonDblClick:
return True # swallow, so the base checkbox hit-test never runs
if event.type() == QEvent.Type.MouseButtonPress:
return False # let the view select the row; release still toggles
return super().editorEvent(event, model, option, index)
# --- write feedback (spec §5.6 step 6) --------------------------------------

View File

@@ -181,6 +181,43 @@ def test_off_state_is_hollow(qtbot, render_cell):
assert _count_near(image, current().offline, (10, 10, 20, 20)) > 3 # the ring
def test_off_dot_interior_shows_the_selection_fill(qtbot, render_cell, near):
table, delegate = _status_table(qtbot, "off", "OFF")
state = QStyle.StateFlag.State_Selected | QStyle.StateFlag.State_Enabled
image = render_cell(delegate, table.model().index(0, 0), state=state)
# §1.2 "no fill": the ring interior shows the row background, not a surface disc
assert near(image.pixelColor(15, 15), current().accent_soft, tol=12)
def test_clicking_a_toggle_cell_still_selects_its_row(qtbot):
from PySide6.QtWidgets import QAbstractItemView
table, delegate = _table(qtbot, [["a", ""], ["b", ""]])
table.setSelectionBehavior(QAbstractItemView.SelectionBehavior.SelectRows)
delegate.set_column_kind(1, CellKind.TOGGLE)
for r in (0, 1):
item = table.item(r, 1)
item.setFlags(
Qt.ItemFlag.ItemIsEnabled
| Qt.ItemFlag.ItemIsUserCheckable
| Qt.ItemFlag.ItemIsSelectable
)
item.setCheckState(Qt.CheckState.Unchecked)
table.show()
rect = table.visualItemRect(table.item(1, 1))
qtbot.mouseClick(table.viewport(), Qt.MouseButton.LeftButton, pos=rect.center())
assert table.item(1, 1).checkState() == Qt.CheckState.Checked # toggled
assert table.currentRow() == 1 # and selected
def test_unknown_status_state_renders_hollow(qtbot, render_cell):
table, delegate = _status_table(qtbot, "offline-typo", "X")
image = render_cell(delegate, table.model().index(0, 0))
center = image.pixelColor(15, 15)
surface = qcolor(current().surface)
assert abs(center.red() - surface.red()) <= 12 # hollow, not a filled gray dot
def test_toggle_cell_paints_switch_and_click_flips_check_state(qtbot, render_cell, near):
table, delegate = _table(qtbot, [[""]])
delegate.set_column_kind(0, CellKind.TOGGLE)