Coverage for src / lilbee / cli / tui / widgets / progress_cell.py: 100%
19 statements
« prev ^ index » next coverage.py v7.13.4, created at 2026-04-29 19:16 +0000
« prev ^ index » next coverage.py v7.13.4, created at 2026-04-29 19:16 +0000
1"""Block-character progress bar renderables for the Task Center row.
3Returns plain strings so the enclosing Static's CSS colors the bar
4per task state (active / done / failed / cancelled). Using Rich Text
5here would hard-code a palette and fight the theme.
6"""
8from __future__ import annotations
10_BAR_WIDTH = 60
11_FULL = "█"
12_EMPTY = "░"
15def progress_cell(percent: float, width: int = _BAR_WIDTH) -> str:
16 """Render a 0-100 percent value as a block-character bar + trailing %."""
17 pct = max(0.0, min(percent, 100.0))
18 filled = int(width * pct / 100)
19 bar = _FULL * filled + _EMPTY * (width - filled)
20 return f"{bar} {pct:5.1f}%"
23def indeterminate_cell(tick: int, width: int = _BAR_WIDTH) -> str:
24 """Render an indeterminate pulse bar by sliding a 3-char window."""
25 pos = tick % (width + 3)
26 cells = [_EMPTY] * width
27 for offset in (-1, 0, 1):
28 i = pos + offset
29 if 0 <= i < width:
30 cells[i] = _FULL
31 return "".join(cells) + " ···"
34def frozen_indeterminate_cell(width: int = _BAR_WIDTH) -> str:
35 """Render a non-animating indeterminate bar for terminal-state rows.
37 The bar is fully filled and trailing dots are dropped so the row no
38 longer reads as 'work in progress' once the task has finished. The
39 trailing percentage is omitted because an indeterminate task never
40 had a real percentage to report.
41 """
42 return _FULL * width