From c5670840cc6eae4c239f3320ed3c0bba8fb771f8 Mon Sep 17 00:00:00 2001 From: Jasen Borisov <40234599+jamadazi@users.noreply.github.com> Date: Mon, 15 Feb 2021 18:59:23 +0100 Subject: [PATCH] Use System Chains to handle Buttons (#12) * Use System Chains to handle Buttons * cargo fmt --- src/main.rs | 22 ++++++++++++++++++++-- src/menu/main_menu.rs | 27 +++++++++++++++++++++++---- src/menu/mod.rs | 40 ++++++++++++++++++++-------------------- src/menu/settings.rs | 10 ++++++++-- 4 files changed, 71 insertions(+), 28 deletions(-) diff --git a/src/main.rs b/src/main.rs index b08e26f..ca2c183 100644 --- a/src/main.rs +++ b/src/main.rs @@ -57,7 +57,23 @@ fn main() { .on_state_update( APPSTATES, AppState::MainMenu, - menu::button_interact.system(), + menu::button_interact:: + .system() + .chain(menu::main_menu::button_exit_app.system()), + ) + .on_state_update( + APPSTATES, + AppState::MainMenu, + menu::button_interact:: + .system() + .chain(menu::main_menu::button_enter_game.system()), + ) + .on_state_update( + APPSTATES, + AppState::MainMenu, + menu::button_interact:: + .system() + .chain(menu::main_menu::button_open_settings_menu.system()), ) .on_state_exit( APPSTATES, @@ -73,7 +89,9 @@ fn main() { .on_state_update( APPSTATES, AppState::SettingsMenu, - menu::button_interact.system(), + menu::button_interact:: + .system() + .chain(menu::settings::button_exit_settings_menu.system()), ) .on_state_exit( APPSTATES, diff --git a/src/menu/main_menu.rs b/src/menu/main_menu.rs index d058038..f705de2 100644 --- a/src/menu/main_menu.rs +++ b/src/menu/main_menu.rs @@ -1,11 +1,30 @@ +use bevy::app::AppExit; use bevy::prelude::*; -use crate::menu::{ClickAction, MenuAssets}; +use crate::menu::{button, MenuAssets}; use crate::AppState; /// Marker for despawning when exiting `AppState::MainMenu` pub struct StateCleanup; +pub fn button_exit_app(In(clicked): In, mut app_exit: ResMut>) { + if clicked { + app_exit.send(AppExit); + } +} + +pub fn button_enter_game(In(clicked): In, mut state: ResMut>) { + if clicked { + state.set_next(AppState::Overworld).unwrap(); + } +} + +pub fn button_open_settings_menu(In(clicked): In, mut state: ResMut>) { + if clicked { + state.set_next(AppState::SettingsMenu).unwrap(); + } +} + pub fn setup(commands: &mut Commands, assets: Res) { let button_style = Style { size: Size::new(Val::Auto, Val::Auto), @@ -98,7 +117,7 @@ pub fn setup(commands: &mut Commands, assets: Res) { style: button_style.clone(), ..Default::default() }) - .with(ClickAction::ChangeState(AppState::Overworld)) + .with(button::EnterGame) .with_children(|button| { button.spawn(TextBundle { text: Text::with_section( @@ -124,7 +143,7 @@ pub fn setup(commands: &mut Commands, assets: Res) { style: button_style.clone(), ..Default::default() }) - .with(ClickAction::ChangeState(AppState::SettingsMenu)) + .with(button::OpenSettingsMenu) .with_children(|button| { button.spawn(TextBundle { text: Text::with_section( @@ -141,7 +160,7 @@ pub fn setup(commands: &mut Commands, assets: Res) { style: button_style.clone(), ..Default::default() }) - .with(ClickAction::Exit) + .with(button::ExitApp) .with_children(|button| { button.spawn(TextBundle { text: Text::with_section( diff --git a/src/menu/mod.rs b/src/menu/mod.rs index b3b726c..19c1c95 100644 --- a/src/menu/mod.rs +++ b/src/menu/mod.rs @@ -1,11 +1,18 @@ -use bevy::app::AppExit; use bevy::prelude::*; -use crate::AppState; - pub mod main_menu; pub mod settings; +/// Every logical action for which we can have a UI button +/// +/// Use as marker components to identify the buttons. +pub mod button { + pub struct EnterGame; + pub struct ExitApp; + pub struct OpenSettingsMenu; + pub struct ExitSettingsMenu; +} + pub struct MenuAssets { button_normal: Handle, button_hover: Handle, @@ -47,32 +54,25 @@ impl FromResources for MenuAssets { } } -pub enum ClickAction { - ChangeState(AppState), - Exit, -} - -pub fn button_interact( - mut state: ResMut>, - mut app_exit: ResMut>, +pub fn button_interact( materials: Res, mut query: Query< - (&Interaction, &mut Handle, &ClickAction), - (Mutated, With