feat(engine): add Menu dropdown for Stats/Achievements/Profile/Settings/Leaderboard
Continues the UI-first pass. The five informational overlays were each behind a single-key shortcut (S/A/P/O/L) with no visible UI affordance. Add a "Menu ▾" button to the action bar that toggles a popover with one row per overlay. Each row dispatches the same code path the keyboard accelerator uses by writing a new `Toggle*RequestEvent`: - Stats → ToggleStatsRequestEvent - Achievements → ToggleAchievementsRequestEvent - Profile → ToggleProfileRequestEvent - Settings → ToggleSettingsRequestEvent - Leaderboard → ToggleLeaderboardRequestEvent Each plugin's existing toggle handler now reads either its key or the matching request event so the spawn / despawn / fetch logic stays in the owning plugin (the popover never duplicates that behaviour). Action bar order is now (left → right): Menu ▾ Undo Pause Help Modes ▾ New Game Menu sits on the far left because it's a navigation aggregator; New Game stays on the far right as the most consequential action. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -14,7 +14,7 @@ use bevy::tasks::{futures_lite::future, AsyncComputeTaskPool, Task};
|
||||
use solitaire_data::settings::SyncBackend;
|
||||
use solitaire_sync::LeaderboardEntry;
|
||||
|
||||
use crate::events::InfoToastEvent;
|
||||
use crate::events::{InfoToastEvent, ToggleLeaderboardRequestEvent};
|
||||
use crate::settings_plugin::SettingsResource;
|
||||
use crate::sync_plugin::SyncProviderResource;
|
||||
|
||||
@@ -73,6 +73,7 @@ impl Plugin for LeaderboardPlugin {
|
||||
.init_resource::<ClosedThisFrame>()
|
||||
.init_resource::<OptInTask>()
|
||||
.init_resource::<OptOutTask>()
|
||||
.add_message::<ToggleLeaderboardRequestEvent>()
|
||||
.add_systems(
|
||||
Update,
|
||||
(
|
||||
@@ -99,18 +100,22 @@ fn reset_closed_flag(mut flag: ResMut<ClosedThisFrame>) {
|
||||
flag.0 = false;
|
||||
}
|
||||
|
||||
/// `L` key — open or close the leaderboard panel.
|
||||
/// On open, starts a new fetch if no data is cached or a fetch is not in flight.
|
||||
/// `L` keyboard accelerator or `ToggleLeaderboardRequestEvent` from the
|
||||
/// HUD Menu popover — open or close the leaderboard panel. On open,
|
||||
/// starts a new fetch if no data is cached or a fetch is not in flight.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
fn toggle_leaderboard_screen(
|
||||
mut commands: Commands,
|
||||
keys: Res<ButtonInput<KeyCode>>,
|
||||
mut requests: MessageReader<ToggleLeaderboardRequestEvent>,
|
||||
screens: Query<Entity, With<LeaderboardScreen>>,
|
||||
data: Res<LeaderboardResource>,
|
||||
provider: Option<Res<SyncProviderResource>>,
|
||||
mut task_res: ResMut<LeaderboardFetchTask>,
|
||||
mut closed_flag: ResMut<ClosedThisFrame>,
|
||||
) {
|
||||
if !keys.just_pressed(KeyCode::KeyL) {
|
||||
let button_clicked = requests.read().count() > 0;
|
||||
if !keys.just_pressed(KeyCode::KeyL) && !button_clicked {
|
||||
return;
|
||||
}
|
||||
if let Ok(entity) = screens.single() {
|
||||
|
||||
Reference in New Issue
Block a user