The cooldown countdown centers its clock, reason, and Cancel chip

The wait dialog drew its three lines flush left while every other dialog in
the app centers its body — so the Cancel chip sat against the border, reading
as an afterthought beside the button rows it is a sibling of. It now centers
line by line the way ButtonDialog and ProgressDialog do, and takes the same
+12 breathing room in its content-sized width (49 cells at its widest, still
inside the PicoCalc's 53).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
Jean-Pierre MartineauandClaude Opus 5 committed 2026-09-06 12:10:26 -04:00
1 parent 8b724d270b
commit dda0a38ed0
2 files changed
+26 -12

No files matched your search

+14 -12
View File
@@ -662,7 +662,7 @@ class CountdownDialog(_KeylessDialog):
cell_len(self._reason),
len(" Cancel "),
)
return inner + 8
return inner + 12 # panel padding + border, plus breathing room (see ButtonDialog)
@staticmethod
def _clock_text(remaining: float) -> str:
@@ -671,18 +671,20 @@ class CountdownDialog(_KeylessDialog):
return f"Ready in {seconds}s"
def render_body(self, width: int) -> list[str]:
"""Draw the clock, its reason, and the Cancel chip."""
lines: list[Text] = [Text(self._clock_text(self._remaining), style="warn")]
"""Draw the clock and its reason centered above a centered Cancel chip.
Centered line by line, the way :class:`ButtonDialog` and :class:`ProgressDialog`
draw theirs: a chip is a chip wherever it appears, and one shoved against the left
border read as an afterthought beside its siblings' centered rows.
"""
parts: list[Text] = [
_center(Text(self._clock_text(self._remaining), style="warn"), width)
]
if self._reason:
lines.append(Text(self._reason, style="muted"))
lines.append(Text(""))
lines.append(Text(" Cancel ", style="selected"))
rendered: list[str] = []
for line in lines:
# An empty Text renders to no lines at all on its own, so the spacer above the
# chip has to be asked for explicitly or the chip rides up against the reason.
rendered.extend(render_lines(line, width) or [""])
return rendered
parts.append(_center(Text(self._reason, style="muted"), width))
parts.append(Text(""))
parts.append(_center(Text(" Cancel ", style="selected"), width))
return render_lines(Group(*parts), width)
def handle(self, action: str, data: str = "") -> None:
"""Enter and Esc both abandon: the only chip on the dialog is Cancel."""
+12
View File
@@ -110,6 +110,18 @@ def test_the_countdown_shows_the_clock_its_reason_and_the_way_out() -> None:
assert dialog.footer_hint == "Enter/Esc cancel"
def test_the_clock_its_reason_and_the_chip_are_all_centered() -> None:
"""Centered like every other dialog's body — a chip against the left border read as odd."""
dialog = CountdownDialog("Flood advert", 47.0, reason="reaches the whole mesh")
width = dialog.dialog_width - 8
for line in _lines(dialog):
if not line.strip():
continue
left = len(line) - len(line.lstrip(" "))
right = width - len(line.rstrip(" "))
assert abs(left - right) <= 1, line
def test_a_part_second_still_reads_as_a_second() -> None:
"""The clock counts the way a person would say it: 0.2s left is still "1s"."""
assert "Ready in 1s" in _lines(CountdownDialog("Advert", 0.2))[0]