From 17e0737a100c843a46de5deb55915648604802b8 Mon Sep 17 00:00:00 2001 From: funman300 Date: Wed, 6 May 2026 15:13:26 +0000 Subject: [PATCH] feat(engine): Enter dismisses Win Summary and starts a fresh deal MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The post-win modal's "Play Again" was click-only — keyboard-only players had to reach for the mouse to leave the celebration screen, and the button advertised no accelerator the way every other modal button does. - handle_win_summary_keyboard reads Enter while WinSummaryOverlay is in the world; despawns the overlay and writes the same NewGameRequestEvent the click handler takes. - The button label gains a trailing return-key glyph so the keyboard path is discoverable on first sight. Co-Authored-By: Claude Opus 4.7 (1M context) --- solitaire_engine/src/win_summary_plugin.rs | 31 +++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/solitaire_engine/src/win_summary_plugin.rs b/solitaire_engine/src/win_summary_plugin.rs index c453d85..baac827 100644 --- a/solitaire_engine/src/win_summary_plugin.rs +++ b/solitaire_engine/src/win_summary_plugin.rs @@ -235,6 +235,7 @@ impl Plugin for WinSummaryPlugin { collect_session_achievements, spawn_win_summary_after_delay, handle_win_summary_buttons, + handle_win_summary_keyboard, apply_screen_shake, reveal_score_breakdown, ) @@ -624,6 +625,31 @@ fn handle_win_summary_buttons( } } +/// Keyboard accelerator for the win summary's "Play Again" button. +/// Enter / Return collapses the win modal and starts a fresh deal — +/// the same path the click handler takes — so a keyboard-only player +/// can dismiss the post-win celebration without reaching for the mouse. +fn handle_win_summary_keyboard( + keys: Option>>, + overlays: Query>, + mut commands: Commands, + mut new_game: MessageWriter, +) { + if overlays.is_empty() { + return; + } + let Some(keys) = keys else { + return; + }; + if !keys.just_pressed(KeyCode::Enter) { + return; + } + for entity in &overlays { + commands.entity(entity).despawn(); + } + new_game.write(NewGameRequestEvent::default()); +} + /// Applies a decaying sinusoidal offset to the main `Camera2d` each frame /// while `ScreenShakeResource::remaining > 0`. /// @@ -798,8 +824,11 @@ fn spawn_overlay( BackgroundColor(ACCENT_PRIMARY), )) .with_children(|b| { + // Append the Enter / Return glyph so keyboard players see + // the accelerator on the button itself — mirrors the + // chip-style hints on every modal button helper. b.spawn(( - Text::new("Play Again"), + Text::new("Play Again \u{21B5}"), TextFont { font_size: TYPE_BODY_LG, ..default() }, TextColor(BG_BASE), ));