fix(android): wrap HUD column and action button row on narrow viewport

The v0.22.3 hardware screenshot showed the 6-button action row
(~510 px when laid out) overflowing into a 360 dp viewport from
the right anchor, with Menu and Undo clipped off-screen left and
Pause/Help/Modes/New_Game overlapping the left HUD column's
Score / Moves / Timer text.

Cap both clusters at `max_width: 50 %` so on mobile each takes
half the viewport (~180 px) and on desktop the cap is wider than
either cluster's natural width so the existing single-line
layout is preserved.

- Action button row: adds `flex_wrap: Wrap`, `row_gap`, and
  `justify_content: FlexEnd` so the row breaks to multiple
  right-aligned lines instead of clipping. 6 buttons become 2-3
  lines of 2-3 buttons.
- HUD column tier rows: add `flex_wrap: Wrap` and `row_gap` to
  the shared `row_node` helper so a long Mode/Challenge/Draw-cycle
  combo soft-wraps onto two lines instead of pushing into the
  action button column.

Closes P0 #2 of docs/android/PLAYABILITY_TODO.md. All 854 engine
tests pass; clippy clean.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
funman300
2026-05-10 20:45:41 -07:00
parent 304cb050a7
commit 89a21c0587
2 changed files with 40 additions and 3 deletions
+8 -3
View File
@@ -36,9 +36,14 @@ rewrites required.
change-detection fix-up system re-applies `base_top + insets.top`
whenever the resource updates. Bottom inset is captured but not
yet consumed (waits for bottom-anchored UI).
- [ ] **Mobile HUD layout.** Wrap to two rows, drop redundant text, or
move secondary actions (Help, Modes) into a hamburger / drawer.
Current single-row layout requires desktop width.
- [x] **Mobile HUD layout.** *Closed 2026-05-10.* Both the left HUD
column and the right action button row are now capped at
`max_width: 50 %` and the button row + tier-row child Nodes carry
`flex_wrap: Wrap`. On a 360 dp viewport the 6-button row breaks
to multiple lines (right-justified) and the tier rows wrap
individually instead of overflowing into the action column. On
desktop (≥ 1280 px) the 50 % cap is wider than any natural row
width so the existing single-line layout is unchanged.
- [x] **Card-back asset not rendering.** *Closed 2026-05-10 by
`fcc7337`.* `AssetPlugin::file_path = "../assets"` was set
unconditionally to fix the desktop `cargo run -p solitaire_app`
+32
View File
@@ -444,6 +444,16 @@ fn spawn_hud(
let row_node = || Node {
flex_direction: FlexDirection::Row,
column_gap: VAL_SPACE_3,
// On a narrow viewport the four tier rows (Score/Moves/Timer,
// Mode/Challenge/Draw-cycle/Won-previously, Undos/Recycles/
// Auto-complete, selection chip) can collectively be wider than
// the available space and overflow into the action-button column
// on the right. `flex_wrap: Wrap` lets each tier soft-wrap onto
// a second line; on a desktop window the rows stay single-line
// because the parent column has no width cap and the row never
// exceeds the natural line width.
flex_wrap: FlexWrap::Wrap,
row_gap: VAL_SPACE_1,
align_items: AlignItems::Baseline,
..default()
};
@@ -455,6 +465,14 @@ fn spawn_hud(
left: VAL_SPACE_3,
top: Val::Px(SPACE_2 + top_inset),
flex_direction: FlexDirection::Column,
// Cap the column at 50% of viewport so on narrow
// (mobile) widths the inner tier rows have a bounded
// width to wrap against, and the column can't bleed
// into the right-anchored action button row (also
// capped at 50%). On desktop 50% of 1920 = 960 px,
// wider than any tier row's natural width, so the
// visible layout is unaffected.
max_width: Val::Percent(50.0),
row_gap: VAL_SPACE_1,
..default()
},
@@ -603,7 +621,21 @@ fn spawn_action_buttons(
right: VAL_SPACE_3,
top: Val::Px(SPACE_2 + top_inset),
flex_direction: FlexDirection::Row,
// 6 buttons total ~510 px wide; on a desktop window
// (typically >= 1280 px) `max_width: 50%` is >= 640 px
// and the row stays a single line. On a 360 dp phone
// 50% is 180 px and the row wraps to two-three lines —
// which keeps the buttons out of the left HUD column's
// horizontal range and prevents the off-screen-left
// clipping seen in the v0.22.3 hardware screenshot.
max_width: Val::Percent(50.0),
flex_wrap: FlexWrap::Wrap,
// When the row wraps, buttons pack to the *end* of each
// line so the row stays visually right-aligned (matches
// the `right: VAL_SPACE_3` anchor).
justify_content: JustifyContent::FlexEnd,
column_gap: VAL_SPACE_2,
row_gap: VAL_SPACE_2,
align_items: AlignItems::Center,
..default()
},