fix(android): adaptive tableau fan fraction fills portrait viewport
On a 360 dp portrait phone the card width is set by the 9-column
horizontal packing (360/9 = 40 dp); the fixed 0.25 fan fraction then
places the worst-case 13-card column in the top ~44 % of the screen,
leaving the bottom 56 % empty black.
`compute_layout` now solves for the fan fraction that exactly uses the
available vertical space below the tableau row:
ideal = avail / (12 * card_height)
On height-limited (desktop) windows ideal ≈ 0.25 and the clamp to the
minimum keeps existing behaviour. On width-limited (portrait phone)
windows the fan expands — ≈ 0.84 at 360 × 800 dp — stretching the
tableau to fill the screen.
Both `tableau_fan_frac` and `tableau_facedown_fan_frac` (scaled
proportionally) are stored on the `Layout` struct. `card_plugin` and
`input_plugin` read from the struct so rendering and hit-testing stay
in sync at every viewport size.
Three new regression tests:
- portrait phone expands fan_frac beyond desktop minimum
- expanded fan fits inside phone viewport (no overflow)
- desktop fan_frac stays at minimum 0.25
Closes P1 "Portrait-first card spacing" in PLAYABILITY_TODO.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -667,9 +667,9 @@ fn card_positions<'a>(game: &'a GameState, layout: &Layout) -> Vec<(&'a Card, Ve
|
||||
out.push((card, pos, z));
|
||||
if is_tableau {
|
||||
let step = if card.face_up {
|
||||
TABLEAU_FAN_FRAC
|
||||
layout.tableau_fan_frac
|
||||
} else {
|
||||
TABLEAU_FACEDOWN_FAN_FRAC
|
||||
layout.tableau_facedown_fan_frac
|
||||
};
|
||||
y_offset -= layout.card_size.y * step;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user