diff --git a/src/builder/builder.rs b/src/builder/builder.rs index 45c179f..745af22 100644 --- a/src/builder/builder.rs +++ b/src/builder/builder.rs @@ -23,7 +23,11 @@ pub struct GuiBuilder { } impl GuiBuilder { - pub fn new(gui_handler: &mut GuiHandler, path: &AssetPath) -> Result> { + pub fn new( + commands: &mut Commands, + gui_handler: &mut GuiHandler, + path: &AssetPath, + ) -> Result> { let validator = Validator::new( #[cfg(feature = "audio")] gui_handler, @@ -31,22 +35,28 @@ impl GuiBuilder { ) .with_context(|| format!("validator for {}", path.full_path()))?; - Ok(Arc::new(Self::_new(gui_handler, validator).with_context( - || format!("for file {}", path.full_path()), - )?)) + Ok(Arc::new( + Self::_new(commands, gui_handler, validator) + .with_context(|| format!("for file {}", path.full_path()))?, + )) } - pub fn from_str(gui_handler: &mut GuiHandler, s: &str) -> Result> { + pub fn from_str( + commands: &mut Commands, + gui_handler: &mut GuiHandler, + s: &str, + ) -> Result> { let validator = Validator::from_str( #[cfg(feature = "audio")] gui_handler, s, )?; - Ok(Arc::new(Self::_new(gui_handler, validator)?)) + Ok(Arc::new(Self::_new(commands, gui_handler, validator)?)) } pub fn merge<'a>( + commands: &mut Commands, gui_handler: &mut GuiHandler, pathes: impl IntoIterator, ) -> Result> { @@ -66,7 +76,7 @@ impl GuiBuilder { path, )?; - let builder = Self::_new(gui_handler, validator) + let builder = Self::_new(commands, gui_handler, validator) .with_context(|| format!("for file {}", path.full_path()))?; me.grids.extend(builder.grids); @@ -86,7 +96,11 @@ impl GuiBuilder { } #[inline] - fn _new(gui_handler: &mut GuiHandler, validator: Validator) -> Result { + fn _new( + commands: &mut Commands, + gui_handler: &mut GuiHandler, + validator: Validator, + ) -> Result { let root = validator.root(); let mut ids = HashMap::new(); @@ -97,6 +111,7 @@ impl GuiBuilder { for child in &root.children { let tree = Self::create_tree( + commands, gui_handler, &mut ids, child, @@ -179,7 +194,10 @@ impl GuiBuilder { impl Functionality for GuiBuilder { fn set_click_callbacks( &self, - functions: Vec<(&str, Box Result<()> + Send + Sync>)>, + functions: Vec<( + &str, + Box Result<()> + Send + Sync>, + )>, ) -> Result<()> { for (function_name, callback) in functions { let suffix_less_function_name = handle_function_suffix(function_name); @@ -195,7 +213,7 @@ impl Functionality for GuiBuilder { &self, _functions: Vec<( &str, - Box Result<()> + Send + Sync>, + Box Result<()> + Send + Sync>, )>, ) -> Result<()> { Ok(()) @@ -205,7 +223,7 @@ impl Functionality for GuiBuilder { &self, callbacks: Vec<( &str, - Box Result<()> + Send + Sync>, + Box Result<()> + Send + Sync>, )>, ) -> Result<()> { for (function_name, callback) in callbacks { @@ -222,7 +240,11 @@ impl Functionality for GuiBuilder { &self, callbacks: Vec<( &str, - Box Result + Send + Sync>, + Box< + dyn Fn(&mut Commands, &mut GuiHandler, ControllerButton) -> Result + + Send + + Sync, + >, )>, ) -> Result<()> { for (function_name, callback) in callbacks { @@ -245,9 +267,14 @@ impl Visibility for GuiBuilder { .unwrap_or(false) } - fn set_visibility(&self, world: &mut World, visibility: bool) -> Result<()> { + fn set_visibility( + &self, + commands: &mut Commands, + gui_handler: &mut GuiHandler, + visibility: bool, + ) -> Result<()> { for grid in &self.grids { - grid.set_visibility(world, visibility)?; + grid.set_visibility(commands, gui_handler, visibility)?; } Ok(()) @@ -269,7 +296,7 @@ impl GuiElementTraits for GuiBuilder { } impl TopGui for GuiBuilder { - fn decline(&self, _world: &mut World) -> Result<()> { + fn decline(&self, _commands: &mut Commands, _gui_handler: &mut GuiHandler) -> Result<()> { if let Some(decline_callback) = self.decline_callback.read().unwrap().as_ref() { decline_callback()?; } @@ -277,11 +304,21 @@ impl TopGui for GuiBuilder { Ok(()) } - fn next_tab(&self, _world: &mut World, _: bool) -> Result<()> { + fn next_tab( + &self, + _commands: &mut Commands, + _gui_handler: &mut GuiHandler, + _: bool, + ) -> Result<()> { Ok(()) } - fn previous_tab(&self, _world: &mut World, _: bool) -> Result<()> { + fn previous_tab( + &self, + _commands: &mut Commands, + _gui_handler: &mut GuiHandler, + _: bool, + ) -> Result<()> { Ok(()) } } @@ -303,18 +340,18 @@ impl TopLevelGui for GuiBuilder { Some(self) } - fn enable(&self, world: &mut World) -> Result<()> { - self.set_visibility(world, true)?; + fn enable(&self, commands: &mut Commands, gui_handler: &mut GuiHandler) -> Result<()> { + self.set_visibility(commands, gui_handler, true)?; if let Some(button) = &self.default_select { - button.select(world.resources.get_mut()?)?; + button.select(gui_handler)?; } Ok(()) } - fn disable(&self, world: &mut World) -> Result<()> { - self.set_visibility(world, false)?; + fn disable(&self, commands: &mut Commands, gui_handler: &mut GuiHandler) -> Result<()> { + self.set_visibility(commands, gui_handler, false)?; Ok(()) } @@ -342,6 +379,7 @@ impl_element!(MultiLineTextField); // private impl GuiBuilder { fn create_tree( + commands: &mut Commands, gui_handler: &mut GuiHandler, ids: &mut HashMap, root_grid_info: &Arc, @@ -394,6 +432,7 @@ impl GuiBuilder { for child in root_grid_info.children.read().unwrap().iter() { Self::create_child( + commands, gui_handler, child, &root_grid, @@ -408,6 +447,7 @@ impl GuiBuilder { } fn create_child( + commands: &mut Commands, gui_handler: &mut GuiHandler, child: &UiInfoElement, grid: &Grid, @@ -423,6 +463,7 @@ impl GuiBuilder { Self::insert_id(ids, &button_info.id, &button)?; grid.attach( + commands, gui_handler, button.clone(), button_info @@ -458,6 +499,7 @@ impl GuiBuilder { Self::insert_id(ids, &label_info.id, &label)?; grid.attach( + commands, gui_handler, label.clone(), label_info.x_slot.get().with_context(|| "x_slot of label")?, @@ -470,11 +512,12 @@ impl GuiBuilder { } UiInfoElement::MultiLineLabel(multi_line_label_info) => { let multi_line_label = - MultiLineLabel::try_from(multi_line_label_info, gui_handler)?; + MultiLineLabel::try_from(multi_line_label_info, commands, gui_handler)?; GuiBuilder::insert_id(ids, &multi_line_label_info.id, &multi_line_label)?; grid.attach( + commands, gui_handler, multi_line_label.clone(), multi_line_label_info @@ -492,12 +535,16 @@ impl GuiBuilder { multi_line_label.set_layer(layer)?; } UiInfoElement::MultiLineTextField(multi_line_text_field_info) => { - let multi_line_text_field = - MultiLineTextField::try_from(multi_line_text_field_info, gui_handler)?; + let multi_line_text_field = MultiLineTextField::try_from( + multi_line_text_field_info, + commands, + gui_handler, + )?; GuiBuilder::insert_id(ids, &multi_line_text_field_info.id, &multi_line_text_field)?; grid.attach( + commands, gui_handler, multi_line_text_field.clone(), multi_line_text_field_info @@ -520,6 +567,7 @@ impl GuiBuilder { Self::insert_id(ids, &text_field_info.id, &text_field)?; grid.attach( + commands, gui_handler, text_field.clone(), text_field_info @@ -542,6 +590,7 @@ impl GuiBuilder { Self::insert_id(ids, &icon_info.id, UiElement::Icon(Arc::downgrade(&icon)))?; grid.attach( + commands, gui_handler, icon.clone(), icon_info.x_slot.get().with_context(|| "x_slot of icon")?, @@ -558,6 +607,7 @@ impl GuiBuilder { Self::insert_id(ids, &progress_bar_info.id, &progress_bar)?; grid.attach( + commands, gui_handler, progress_bar.clone(), progress_bar_info @@ -580,6 +630,7 @@ impl GuiBuilder { Self::insert_id(ids, &grid_info.id, &sub_grid)?; grid.attach( + commands, gui_handler, sub_grid.clone(), grid_info.x_slot.get().with_context(|| "x_slot of grid")?, @@ -593,6 +644,7 @@ impl GuiBuilder { for child in grid_info.children.read().unwrap().iter() { Self::create_child( + commands, gui_handler, child, &sub_grid, diff --git a/src/builder/snippet.rs b/src/builder/snippet.rs index a79c7aa..39717f8 100644 --- a/src/builder/snippet.rs +++ b/src/builder/snippet.rs @@ -1,7 +1,7 @@ use std::{any::Any, collections::HashMap, sync::Arc}; use assetpath::AssetPath; -use ecs::World; +use ecs::Commands; use super::validator::{ buttoninfo::NeighbourInfo, @@ -18,27 +18,39 @@ pub struct GuiSnippet { } impl GuiSnippet { - pub fn new(gui_handler: &mut GuiHandler, path: &AssetPath) -> Result> { + pub fn new( + commands: &mut Commands, + gui_handler: &mut GuiHandler, + path: &AssetPath, + ) -> Result> { let validator = Validator::new( #[cfg(feature = "audio")] gui_handler, path, )?; - Self::_new(gui_handler, validator) + Self::_new(commands, gui_handler, validator) } - pub fn from_str(gui_handler: &mut GuiHandler, s: &str) -> Result> { + pub fn from_str( + commands: &mut Commands, + gui_handler: &mut GuiHandler, + s: &str, + ) -> Result> { let validator = Validator::from_str( #[cfg(feature = "audio")] gui_handler, s, )?; - Self::_new(gui_handler, validator) + Self::_new(commands, gui_handler, validator) } - fn _new(gui_handler: &mut GuiHandler, validator: Validator) -> Result> { + fn _new( + commands: &mut Commands, + gui_handler: &mut GuiHandler, + validator: Validator, + ) -> Result> { let root = validator.root(); let mut ids = HashMap::new(); @@ -57,7 +69,14 @@ impl GuiSnippet { GuiBuilder::insert_id(&mut ids, &grid_info.id, &grid)?; for child in grid_info.children.read().unwrap().iter() { - Self::create_child(gui_handler, child, &grid, &mut ids, &mut custom_neighbours)?; + Self::create_child( + commands, + gui_handler, + child, + &grid, + &mut ids, + &mut custom_neighbours, + )?; } GuiBuilder::connect_custom_neighbours(&ids, custom_neighbours)?; @@ -94,8 +113,13 @@ impl Visibility for GuiSnippet { self.grid.visible() } - fn set_visibility(&self, world: &mut World, visibility: bool) -> Result<()> { - self.grid.set_visibility(world, visibility) + fn set_visibility( + &self, + commands: &mut Commands, + gui_handler: &mut GuiHandler, + visibility: bool, + ) -> Result<()> { + self.grid.set_visibility(commands, gui_handler, visibility) } } @@ -148,7 +172,10 @@ impl Gridable for GuiSnippet { impl Functionality for GuiSnippet { fn set_click_callbacks( &self, - functions: Vec<(&str, Box Result<()> + Send + Sync>)>, + functions: Vec<( + &str, + Box Result<()> + Send + Sync>, + )>, ) -> Result<()> { for (function_name, callback) in functions { let suffix_less_function_name = handle_function_suffix(function_name); @@ -164,7 +191,7 @@ impl Functionality for GuiSnippet { &self, _functions: Vec<( &str, - Box Result<()> + Send + Sync>, + Box Result<()> + Send + Sync>, )>, ) -> Result<()> { Ok(()) @@ -174,7 +201,7 @@ impl Functionality for GuiSnippet { &self, callbacks: Vec<( &str, - Box Result<()> + Send + Sync>, + Box Result<()> + Send + Sync>, )>, ) -> Result<()> { for (function_name, callback) in callbacks { @@ -191,7 +218,11 @@ impl Functionality for GuiSnippet { &self, callbacks: Vec<( &str, - Box Result + Send + Sync>, + Box< + dyn Fn(&mut Commands, &mut GuiHandler, ControllerButton) -> Result + + Send + + Sync, + >, )>, ) -> Result<()> { for (function_name, callback) in callbacks { @@ -207,6 +238,7 @@ impl Functionality for GuiSnippet { impl GuiSnippet { fn create_child( + commands: &mut Commands, gui_handler: &mut GuiHandler, child: &UiInfoElement, grid: &Grid, @@ -220,6 +252,7 @@ impl GuiSnippet { GuiBuilder::insert_id(ids, &button_info.id, &button)?; grid.attach( + commands, gui_handler, button.clone(), button_info.x_slot.get()?, @@ -236,6 +269,7 @@ impl GuiSnippet { GuiBuilder::insert_id(ids, &label_info.id, &label)?; grid.attach( + commands, gui_handler, label, label_info.x_slot.get()?, @@ -246,11 +280,12 @@ impl GuiSnippet { } UiInfoElement::MultiLineLabel(multi_line_label_info) => { let multi_line_label = - MultiLineLabel::try_from(multi_line_label_info, gui_handler)?; + MultiLineLabel::try_from(multi_line_label_info, commands, gui_handler)?; GuiBuilder::insert_id(ids, &multi_line_label_info.id, &multi_line_label)?; grid.attach( + commands, gui_handler, multi_line_label, multi_line_label_info.x_slot.get()?, @@ -260,12 +295,16 @@ impl GuiSnippet { )?; } UiInfoElement::MultiLineTextField(multi_line_text_field_info) => { - let multi_line_text_field = - MultiLineTextField::try_from(multi_line_text_field_info, gui_handler)?; + let multi_line_text_field = MultiLineTextField::try_from( + multi_line_text_field_info, + commands, + gui_handler, + )?; GuiBuilder::insert_id(ids, &multi_line_text_field_info.id, &multi_line_text_field)?; grid.attach( + commands, gui_handler, multi_line_text_field, multi_line_text_field_info.x_slot.get()?, @@ -280,6 +319,7 @@ impl GuiSnippet { GuiBuilder::insert_id(ids, &text_field_info.id, &text_field)?; grid.attach( + commands, gui_handler, text_field, text_field_info.x_slot.get()?, @@ -294,6 +334,7 @@ impl GuiSnippet { GuiBuilder::insert_id(ids, &icon_info.id, UiElement::Icon(Arc::downgrade(&icon)))?; grid.attach( + commands, gui_handler, icon, icon_info.x_slot.get()?, @@ -308,6 +349,7 @@ impl GuiSnippet { GuiBuilder::insert_id(ids, &progress_bar_info.id, &progress_bar)?; grid.attach( + commands, gui_handler, progress_bar, progress_bar_info.x_slot.get()?, @@ -322,6 +364,7 @@ impl GuiSnippet { GuiBuilder::insert_id(ids, &grid_info.id, &sub_grid)?; grid.attach( + commands, gui_handler, sub_grid.clone(), grid_info.x_slot.get()?, @@ -331,7 +374,14 @@ impl GuiSnippet { )?; for child in grid_info.children.read().unwrap().iter() { - Self::create_child(gui_handler, child, &sub_grid, ids, neighbour_infos)?; + Self::create_child( + commands, + gui_handler, + child, + &sub_grid, + ids, + neighbour_infos, + )?; } } } diff --git a/src/elements/button.rs b/src/elements/button.rs index 4c2de5b..1760bbe 100644 --- a/src/elements/button.rs +++ b/src/elements/button.rs @@ -315,23 +315,32 @@ impl Button { pub fn set_callback(&self, callback: F) where - F: Fn(&mut Commands) -> Result<()> + Send + Sync + 'static, + F: Fn(&mut Commands, &mut GuiHandler) -> Result<()> + Send + Sync + 'static, { - self.click_executable - .set_callback(move |commands: &mut Commands, _: ()| callback(commands)); + self.click_executable.set_callback( + move |commands: &mut Commands, gui_handler: &mut GuiHandler, _: ()| { + callback(commands, gui_handler) + }, + ); } pub fn set_select_callback(&self, callback: F) where - F: Fn(&mut Commands, bool) -> Result<()> + Send + Sync + 'static, + F: Fn(&mut Commands, &mut GuiHandler, bool) -> Result<()> + Send + Sync + 'static, { - self.on_select_executable - .set_callback(move |commands: &mut Commands, select: bool| callback(commands, select)); + self.on_select_executable.set_callback( + move |commands: &mut Commands, gui_handler: &mut GuiHandler, select: bool| { + callback(commands, gui_handler, select) + }, + ); } pub fn set_custom_callback(&self, callback: F) where - F: Fn(&mut Commands, ControllerButton) -> Result + Send + Sync + 'static, + F: Fn(&mut Commands, &mut GuiHandler, ControllerButton) -> Result + + Send + + Sync + + 'static, { self.selectable.set_custom_callback(callback); } @@ -448,7 +457,12 @@ impl Visibility for Button { self.visible.load(SeqCst) } - fn set_visibility(&self, gui_handler: &mut GuiHandler, visibility: bool) -> Result<()> { + fn set_visibility( + &self, + _commands: &mut Commands, + gui_handler: &mut GuiHandler, + visibility: bool, + ) -> Result<()> { if visibility != self.visible.load(SeqCst) { self.visible.store(visibility, SeqCst); @@ -579,19 +593,18 @@ impl Button { fn create_selected_changed_callback(button: Arc