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:
2026-08-25 00:28:40 -05:00
parent aff59bfcf7
commit 7b452b7b81
7 changed files with 382 additions and 65 deletions

View File

@@ -114,6 +114,22 @@ void main() {
'the row with no gap', () async {
final controller = HudLayoutController(await freshConfig());
// FB-09's title-driven defaultFor no longer puts all four default-visible
// metrics in row 0 with uniform colSpan 1 (avgSpeed and elapsedTime need 2
// columns for their longer titles). Force that uniform row-0 arrangement
// explicitly here so this test exercises _reflowRow's own algorithm in
// isolation, independent of exactly where defaultFor happens to place things.
controller.updateSize(HudMetric.elapsedTime, 1, 2);
controller.updateSize(HudMetric.avgSpeed, 1, 2);
controller.updatePosition(HudMetric.elapsedTime, 2, 0);
expect(
[HudMetric.speed, HudMetric.avgSpeed, HudMetric.elapsedTime, HudMetric.distance]
.map((m) => controller.state[m]!.row)
.toSet(),
{0},
reason: 'test setup assumes all four land in row 0',
);
controller.setVisible(HudMetric.avgSpeed, false);
final remaining = [HudMetric.speed, HudMetric.distance, HudMetric.elapsedTime]
@@ -155,7 +171,14 @@ void main() {
'members reflows that row to fit it', () async {
final controller = HudLayoutController(await freshConfig());
// maxSpeed and movingTime both default to row 2, hidden, at adjacent columns.
// FB-09's title-driven defaultFor no longer necessarily lands maxSpeed and
// movingTime in the same row (their default rows depend on every metric's
// individual title width). Move both hidden metrics into the same row
// explicitly, before enabling either, so this test is independent of exactly
// where defaultFor happens to place them.
controller.updatePosition(HudMetric.maxSpeed, 0, 6);
controller.updatePosition(HudMetric.movingTime, 1, 6);
controller.setVisible(HudMetric.maxSpeed, true);
controller.setVisible(HudMetric.movingTime, true);