feat(engine): opt Profile / Leaderboard / Home into scrim-click dismiss
Follow-up to a54201e. The previous commit added ScrimDismissible to
Stats, Achievements, and Help; this one extends the same one-line
opt-in to the remaining three read-only modals so the click-outside-
to-close gesture is consistent across every informational surface.
Each modal now has the same shape: capture the scrim from
spawn_modal, attach ScrimDismissible after the build closure
returns. Three lines per file plus the import; no behaviour change
to the modal content itself.
Settings, Onboarding, Pause, Forfeit confirm, ConfirmNewGame, and
the win/game-over modals continue to opt OUT — all carry unsaved
or destructive state where an accidental scrim click would lose
work.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -26,6 +26,7 @@ use crate::progress_plugin::ProgressResource;
|
|||||||
use crate::ui_focus::{Disabled, FocusGroup, Focusable};
|
use crate::ui_focus::{Disabled, FocusGroup, Focusable};
|
||||||
use crate::ui_modal::{
|
use crate::ui_modal::{
|
||||||
spawn_modal, spawn_modal_actions, spawn_modal_button, spawn_modal_header, ButtonVariant,
|
spawn_modal, spawn_modal_actions, spawn_modal_button, spawn_modal_header, ButtonVariant,
|
||||||
|
ScrimDismissible,
|
||||||
};
|
};
|
||||||
use crate::ui_theme::{
|
use crate::ui_theme::{
|
||||||
ACCENT_PRIMARY, BG_ELEVATED_HI, BORDER_STRONG, BORDER_SUBTLE, RADIUS_MD, STATE_INFO,
|
ACCENT_PRIMARY, BG_ELEVATED_HI, BORDER_STRONG, BORDER_SUBTLE, RADIUS_MD, STATE_INFO,
|
||||||
@@ -359,7 +360,7 @@ fn handle_home_digit_keys(
|
|||||||
|
|
||||||
/// Spawns the Home modal with five mode cards plus a Cancel button.
|
/// Spawns the Home modal with five mode cards plus a Cancel button.
|
||||||
fn spawn_home_screen(commands: &mut Commands, level: u32, font_res: Option<&FontResource>) {
|
fn spawn_home_screen(commands: &mut Commands, level: u32, font_res: Option<&FontResource>) {
|
||||||
spawn_modal(commands, HomeScreen, Z_MODAL_PANEL, |card| {
|
let scrim = spawn_modal(commands, HomeScreen, Z_MODAL_PANEL, |card| {
|
||||||
spawn_modal_header(card, "Choose a Mode", font_res);
|
spawn_modal_header(card, "Choose a Mode", font_res);
|
||||||
|
|
||||||
for mode in [
|
for mode in [
|
||||||
@@ -383,6 +384,8 @@ fn spawn_home_screen(commands: &mut Commands, level: u32, font_res: Option<&Font
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
// Home is read-only — opt into click-outside-to-dismiss.
|
||||||
|
commands.entity(scrim).insert(ScrimDismissible);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tab-walk order for each mode card, matching the visual top-to-bottom
|
/// Tab-walk order for each mode card, matching the visual top-to-bottom
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ use crate::settings_plugin::SettingsResource;
|
|||||||
use crate::sync_plugin::SyncProviderResource;
|
use crate::sync_plugin::SyncProviderResource;
|
||||||
use crate::ui_modal::{
|
use crate::ui_modal::{
|
||||||
spawn_modal, spawn_modal_actions, spawn_modal_button, spawn_modal_header, ButtonVariant,
|
spawn_modal, spawn_modal_actions, spawn_modal_button, spawn_modal_header, ButtonVariant,
|
||||||
|
ScrimDismissible,
|
||||||
};
|
};
|
||||||
use crate::ui_theme::{
|
use crate::ui_theme::{
|
||||||
ACCENT_PRIMARY, BORDER_SUBTLE, STATE_INFO, TEXT_PRIMARY, TEXT_SECONDARY, TYPE_BODY,
|
ACCENT_PRIMARY, BORDER_SUBTLE, STATE_INFO, TEXT_PRIMARY, TEXT_SECONDARY, TYPE_BODY,
|
||||||
@@ -392,7 +393,7 @@ fn spawn_leaderboard_screen(
|
|||||||
remote_available: bool,
|
remote_available: bool,
|
||||||
font_res: Option<&FontResource>,
|
font_res: Option<&FontResource>,
|
||||||
) {
|
) {
|
||||||
spawn_modal(commands, LeaderboardScreen, Z_MODAL_PANEL, |card| {
|
let scrim = spawn_modal(commands, LeaderboardScreen, Z_MODAL_PANEL, |card| {
|
||||||
spawn_modal_header(card, "Leaderboard", font_res);
|
spawn_modal_header(card, "Leaderboard", font_res);
|
||||||
|
|
||||||
// Subhead — what the screen does + what the buttons control.
|
// Subhead — what the screen does + what the buttons control.
|
||||||
@@ -566,6 +567,8 @@ fn spawn_leaderboard_screen(
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
// Leaderboard is read-only — opt into click-outside-to-dismiss.
|
||||||
|
commands.entity(scrim).insert(ScrimDismissible);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn header_cell(parent: &mut ChildSpawnerCommands, text: &str, width: f32, font: &TextFont) {
|
fn header_cell(parent: &mut ChildSpawnerCommands, text: &str, width: f32, font: &TextFont) {
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ use crate::settings_plugin::SettingsResource;
|
|||||||
use crate::stats_plugin::{format_fastest_win, format_win_rate, StatsResource};
|
use crate::stats_plugin::{format_fastest_win, format_win_rate, StatsResource};
|
||||||
use crate::ui_modal::{
|
use crate::ui_modal::{
|
||||||
spawn_modal, spawn_modal_actions, spawn_modal_button, spawn_modal_header, ButtonVariant,
|
spawn_modal, spawn_modal_actions, spawn_modal_button, spawn_modal_header, ButtonVariant,
|
||||||
|
ScrimDismissible,
|
||||||
};
|
};
|
||||||
use crate::ui_theme::{
|
use crate::ui_theme::{
|
||||||
ACCENT_PRIMARY, BG_ELEVATED, BORDER_STRONG, SPACE_1, STATE_INFO, STATE_SUCCESS, TEXT_PRIMARY,
|
ACCENT_PRIMARY, BG_ELEVATED, BORDER_STRONG, SPACE_1, STATE_INFO, STATE_SUCCESS, TEXT_PRIMARY,
|
||||||
@@ -184,7 +185,7 @@ fn spawn_profile_screen(
|
|||||||
..default()
|
..default()
|
||||||
};
|
};
|
||||||
|
|
||||||
spawn_modal(commands, ProfileScreen, Z_MODAL_PANEL, |card| {
|
let scrim = spawn_modal(commands, ProfileScreen, Z_MODAL_PANEL, |card| {
|
||||||
spawn_modal_header(card, "Profile", font_res);
|
spawn_modal_header(card, "Profile", font_res);
|
||||||
|
|
||||||
// Scrollable body — the Profile panel renders sync info,
|
// Scrollable body — the Profile panel renders sync info,
|
||||||
@@ -395,6 +396,8 @@ fn spawn_profile_screen(
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
// Profile is read-only — opt into click-outside-to-dismiss.
|
||||||
|
commands.entity(scrim).insert(ScrimDismissible);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Spawn a fixed-height vertical spacer node.
|
/// Spawn a fixed-height vertical spacer node.
|
||||||
|
|||||||
Reference in New Issue
Block a user