FB-09: size default HUD widgets by title, not a fixed uniform cell
Adds minColSpanForLabel as a character-count proxy for how many grid columns a metric's title needs, reworks HudWidgetLayout.defaultFor into a left-to-right row-packing layout using it, enforces the same minimum as a floor on manual resize, and splits _HudMetricValue's FittedBox so the title renders at a fixed reference size while only the value shrinks/grows to fill the remaining space. Confirms a real, documented interaction with FB-08's _reflowRow: its even column split has no awareness of a member's title-driven minimum and can push one below it. Left unfixed per this ticket's own Out-of-scope section -- _reflowRow's algorithm is FB-08's, not this ticket's, to change. Test count 426 -> 434, all green. flutter analyze unchanged (same 4 pre-existing, unrelated info-level issues).
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# FB-09 — HUD default sizing follows the title, not a fixed uniform cell
|
||||
|
||||
**Depends on** FB-08 (same files, sequence after it merges) · **Size** L · **Status** Not started
|
||||
**Depends on** FB-08 (same files, sequence after it merges) · **Size** L · **Status** Done
|
||||
|
||||
## Goal
|
||||
A HUD widget's title must always fit at a fixed, readable size. A HUD widget's value
|
||||
@@ -258,3 +258,71 @@ merged, and re-run FB-08's own tests to confirm the two features compose correct
|
||||
`colSpan` — if `_reflowRow`'s even split would push a widget below its own minimum,
|
||||
that is a real interaction between the two tickets worth checking explicitly and
|
||||
documenting in this ticket's Outcome section).
|
||||
|
||||
## Outcome
|
||||
Implemented exactly as designed, with no changes to the Design section's approach:
|
||||
|
||||
- `minColSpanForLabel(String label)` added to `hud_widget_layout.dart`, verbatim.
|
||||
- `HudWidgetLayout.defaultFor` reworked into the left-to-right row-packing factory
|
||||
from the Design section, verbatim.
|
||||
- `draggable_resizable_hud_widget.dart`'s resize handle `onPanEnd` now clamps
|
||||
`snappedColSpan` up to `minColSpanForLabel(layout.metric.label)` (floor) and down to
|
||||
`hudMaxColSpan` (ceiling), instead of the generic `hudMinSpan` floor the grid-level
|
||||
clamp (`clampedToGrid`, still called downstream in `HudLayoutController`) applies to
|
||||
every other span.
|
||||
- `_HudMetricValue.build()` in `record_screen.dart` now renders the title as a plain,
|
||||
unwrapped `Text` (with `maxLines: 1`/`TextOverflow.ellipsis` restored as a safety
|
||||
net) at its fixed reference size, and wraps only the value `Text` in
|
||||
`Flexible(child: FittedBox(fit: BoxFit.scaleDown, ...))`.
|
||||
|
||||
**Risk #1 (four even columns no longer even) — confirmed, as predicted, not a
|
||||
regression.** With real label lengths, the default row-0 packing is now: Speed (span
|
||||
1), Average speed (span 2), Distance (span 1) filling all 4 columns — Elapsed time (a
|
||||
fourth default-visible metric, still marked `visible: true` by the unchanged
|
||||
`index < 4` rule) wraps to row 2 alongside Max speed, rather than sharing row 0 with
|
||||
the other three. This is the ticket's own predicted, intended outcome of sizing by
|
||||
title rather than by a fixed 4-per-row assumption, not a bug. (Note: the worked
|
||||
example table in the Design section above lists slightly different character counts
|
||||
for "Average speed"/"Elevation gain"/"Points captured" than their actual `String`
|
||||
lengths in `hud_metric.dart` — the real lengths are 13/14/15, one less than the
|
||||
table's 14/15/16 — which changes "Elevation gain" from the table's predicted span-3 to
|
||||
an actual span-2. This doesn't affect correctness of the implemented function, which
|
||||
matches the Design section's code verbatim; it only means the packing result differs
|
||||
slightly from the table's worked example. No grid-bounds issue results: the last
|
||||
default row (`pointsCaptured` alone) lands at `row: 6`, `rowSpan: 2`, exactly at
|
||||
`hudGridRows`'s (8) boundary.)
|
||||
|
||||
**Risk #2 / FB-08 interaction (named in Out of scope) — confirmed real, left
|
||||
unfixed per the ticket's own scope.** Checked directly: `_reflowRow`'s even split
|
||||
divides `hudGridColumns` (4) across however many visible members now share a row,
|
||||
with no awareness of any member's `minColSpanForLabel`. Simulating every membership
|
||||
count `_reflowRow` ever handles (2, 3, or 4 -- it no-ops below 2) against every real
|
||||
`HudMetric` label shows the even split pushes a member below its own title-driven
|
||||
minimum in *every* case where that member's label needs more than 1 column:
|
||||
- 2 members -> both get span 2 -- too small for "Points captured" (needs 3).
|
||||
- 3 members -> spans of 2/1/1 -- too small for any member needing 2 (e.g. "Average
|
||||
speed", "Elapsed time", "Moving time", "Elevation gain") unless it happens to be the
|
||||
one member that lands on span 2, and always too small for "Points captured".
|
||||
- 4 members -> all get span 1 -- too small for any label longer than "Speed",
|
||||
"Distance", or "Max speed".
|
||||
This is a real, reproducible gap between FB-08's `_reflowRow` and this ticket's
|
||||
`minColSpanForLabel`, but per this ticket's own "Out of scope" section it is
|
||||
deliberately left unfixed here — `_reflowRow` is FB-08's function, and changing its
|
||||
even-split algorithm to respect a per-label minimum (e.g. giving longer-labeled
|
||||
members first claim on any spare columns, falling back to letting a row simply not
|
||||
fill exactly 4 columns when it can't be split evenly and legibly) is a follow-up
|
||||
ticket's work, not this one's.
|
||||
|
||||
Test suite: `flutter analyze` stays at the same 4 pre-existing, unrelated info-level
|
||||
issues as the pre-FB-09 baseline (none in files this ticket touches). `flutter test`
|
||||
went from 426 to **434** tests, all green (8 net new: 5 in
|
||||
`hud_widget_layout_test.dart` for `minColSpanForLabel`/`defaultFor`'s new invariants,
|
||||
3 in `hud_edit_overlay_test.dart` for the resize-floor clamp, the longest-label
|
||||
minimum-width no-overflow case, and the fixed-title/flexible-value split). Two
|
||||
pre-existing `hud_layout_controller_test.dart` tests (FB-08's own reflow tests) had to
|
||||
be updated, not because `_reflowRow` broke, but because they asserted on *which
|
||||
specific row* certain metrics defaulted into -- an assumption that no longer holds now
|
||||
that `defaultFor` packs by title width instead of a fixed 4-per-row index. Both were
|
||||
rewritten to explicitly position their metrics into a shared row via
|
||||
`updatePosition`/`updateSize` before exercising `_reflowRow`, so they test the reflow
|
||||
behavior itself rather than an incidental default-layout coincidence.
|
||||
|
||||
Reference in New Issue
Block a user