feat(engine): restyle replay progress text as Terminal MOVE chip
Closes the centre-text half of the replay-overlay enrichments arc. The plain "Move N of M" text becomes a 1px ACCENT_PRIMARY-bordered chip containing "MOVE N/M" — uppercase + slash separator reads as a Terminal output line and matches the floating-chip motif in docs/ui-mockups/replay-overlay-mobile.html. The chip lives in-banner rather than floating above the focused card; the screen-takeover treatment that requires plumbing cursor → card identity remains deferred per SESSION_HANDOFF. Implementation: the centre Text spawn is now wrapped in a Node with 1px border + axes(VAL_SPACE_2, VAL_SPACE_1) padding and no background fill (Terminal aesthetic gets depth from borders + tonal layering, not shadows). The ReplayOverlayProgressText marker stays on the inner Text so update_progress_text continues to repaint contents unchanged. format_progress now returns "MOVE N/M" for Playing and "REPLAY COMPLETE" for Completed (uppercase to match the chip's typographic treatment); Inactive still returns "" since the overlay shouldn't be spawned in that state. Used BorderColor::all(ACCENT_PRIMARY) — Bevy's BorderColor is per-side in 0.18, no longer the tuple struct it was earlier. Module-level docstring + ReplayOverlayScrubFill doc comment both updated to quote the new "MOVE N/M" string. Test overlay_progress_text_reflects_cursor swapped its assertion to match. 1182 tests still pass; clippy clean. This closes Option C from the SESSION_HANDOFF Resume prompt's banner- local enrichments. The full screen-takeover redesign (mini-tableau, playback controls, move-log scroll, WIN MOVE marker requiring a win_move_index field on Replay) remains the multi-session item.
This commit is contained in:
@@ -4,8 +4,9 @@
|
||||
//!
|
||||
//! - A "▌ replay" label on the left so the player knows the surface is
|
||||
//! under playback control rather than live input.
|
||||
//! - A "Move N of M" progress indicator in the centre, recomputed every
|
||||
//! frame the cursor advances.
|
||||
//! - A "MOVE N/M" progress chip in the centre, recomputed every frame
|
||||
//! the cursor advances and bordered in cyan ACCENT_PRIMARY so it
|
||||
//! reads as a discrete callout.
|
||||
//! - A "Stop" button on the right that aborts playback and returns
|
||||
//! control to the player.
|
||||
//!
|
||||
@@ -30,7 +31,7 @@ use crate::replay_playback::{stop_replay_playback, ReplayPlaybackState};
|
||||
use crate::ui_modal::{spawn_modal_button, ButtonVariant};
|
||||
use crate::ui_theme::{
|
||||
ACCENT_PRIMARY, BG_ELEVATED_HI, BORDER_SUBTLE, TEXT_PRIMARY, TEXT_SECONDARY, TYPE_BODY,
|
||||
TYPE_CAPTION, TYPE_HEADLINE, VAL_SPACE_2, VAL_SPACE_4, Z_DROP_OVERLAY,
|
||||
TYPE_CAPTION, TYPE_HEADLINE, VAL_SPACE_1, VAL_SPACE_2, VAL_SPACE_4, Z_DROP_OVERLAY,
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -110,7 +111,7 @@ pub struct ReplayOverlayGameCaption;
|
||||
/// continuous visual cue of how far through the replay they are.
|
||||
///
|
||||
/// Distinct from the simpler text-based `ReplayOverlayProgressText`
|
||||
/// (which spells out "Move N of M"): the scrub fill gives immediate
|
||||
/// (which spells out "MOVE N/M" in a chip): the scrub fill gives immediate
|
||||
/// at-a-glance positioning; the text gives the exact numbers. Both
|
||||
/// surfaces stay together because they answer the same question for
|
||||
/// players with different scanning preferences.
|
||||
@@ -284,10 +285,23 @@ fn spawn_overlay(
|
||||
));
|
||||
});
|
||||
|
||||
// Centre: progress readout — neutral primary text
|
||||
// colour so the eye treats it as data, not a
|
||||
// callout.
|
||||
// Centre: progress readout, wrapped in a 1 px
|
||||
// ACCENT_PRIMARY-bordered chip so it reads as a
|
||||
// discrete callout rather than free-floating
|
||||
// text. No fill — the Terminal aesthetic gets
|
||||
// depth from borders + tonal layering, not
|
||||
// shadows. The marker stays on the inner Text so
|
||||
// `update_progress_text` keeps working unchanged.
|
||||
row.spawn((
|
||||
Node {
|
||||
border: UiRect::all(Val::Px(1.0)),
|
||||
padding: UiRect::axes(VAL_SPACE_2, VAL_SPACE_1),
|
||||
..default()
|
||||
},
|
||||
BorderColor::all(ACCENT_PRIMARY),
|
||||
))
|
||||
.with_children(|chip| {
|
||||
chip.spawn((
|
||||
ReplayOverlayProgressText,
|
||||
Text::new(progress_label),
|
||||
TextFont {
|
||||
@@ -297,6 +311,7 @@ fn spawn_overlay(
|
||||
},
|
||||
TextColor(TEXT_PRIMARY),
|
||||
));
|
||||
});
|
||||
|
||||
// Right: Stop button. Tertiary variant — the
|
||||
// action is available but not the loudest element
|
||||
@@ -452,8 +467,11 @@ fn format_game_caption(state: &ReplayPlaybackState) -> Option<String> {
|
||||
/// path produce the exact same string.
|
||||
fn format_progress(state: &ReplayPlaybackState) -> String {
|
||||
match state.progress() {
|
||||
Some((cursor, total)) => format!("Move {cursor} of {total}"),
|
||||
None if state.is_completed() => "Replay complete".to_string(),
|
||||
// `MOVE N/M` (uppercase + slash) reads as a Terminal output
|
||||
// line and matches the floating-chip motif in the mockup at
|
||||
// `docs/ui-mockups/replay-overlay-mobile.html`.
|
||||
Some((cursor, total)) => format!("MOVE {cursor}/{total}"),
|
||||
None if state.is_completed() => "REPLAY COMPLETE".to_string(),
|
||||
None => String::new(),
|
||||
}
|
||||
}
|
||||
@@ -604,7 +622,7 @@ mod tests {
|
||||
);
|
||||
app.update();
|
||||
|
||||
assert_eq!(progress_text(&mut app), "Move 5 of 10");
|
||||
assert_eq!(progress_text(&mut app), "MOVE 5/10");
|
||||
}
|
||||
|
||||
/// Pressing the Stop button resets the state back to `Inactive` and
|
||||
|
||||
Reference in New Issue
Block a user