From c2c700899ddf53b6af37bdc735fc872d0576f882 Mon Sep 17 00:00:00 2001 From: Lucas Colombo Date: Wed, 18 Sep 2024 02:38:37 -0300 Subject: [PATCH] =?UTF-8?q?feat(cli):=20=E2=9C=A8=20tui:=20extend=20is=5Fa?= =?UTF-8?q?ctive=20usage?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/cli/tui/framework/app.rs | 30 +++++++---- lib/cli/tui/framework/component.rs | 81 ++++++++++++++++++++---------- lib/cli/tui/mod.rs | 2 +- 3 files changed, 76 insertions(+), 37 deletions(-) diff --git a/lib/cli/tui/framework/app.rs b/lib/cli/tui/framework/app.rs index 9f441db..fad6db9 100644 --- a/lib/cli/tui/framework/app.rs +++ b/lib/cli/tui/framework/app.rs @@ -105,8 +105,10 @@ impl App { let mut actions = Vec::new(); for component in self.components.iter_mut() { - let component_actions = component.handle_events(Some(e.clone()))?; - actions.extend(component_actions); + if component.is_active() { + let component_actions = component.handle_events(Some(e.clone()))?; + actions.extend(component_actions); + } } for action in actions { @@ -129,9 +131,11 @@ impl App { let mut errors = Vec::new(); tui.draw(|f| { for component in self.components.iter_mut() { - let r = component.draw(f, f.area()); - if let Err(e) = r { - errors.push(format!("Failed to draw: {:?}", e)); + if component.is_active() { + let r = component.draw(f, f.area()); + if let Err(e) = r { + errors.push(format!("Failed to draw: {:?}", e)); + } } } })?; @@ -143,9 +147,11 @@ impl App { let mut errors = Vec::new(); tui.draw(|f| { for component in self.components.iter_mut() { - let r = component.draw(f, f.area()); - if let Err(e) = r { - errors.push(format!("Failed to draw: {:?}", e)); + if component.is_active() { + let r = component.draw(f, f.area()); + if let Err(e) = r { + errors.push(format!("Failed to draw: {:?}", e)); + } } } })?; @@ -157,13 +163,17 @@ impl App { } for component in self.components.iter_mut() { - component.update(a.clone())?; + if component.is_active() { + component.update(a.clone())?; + } } } else { // unrecognized action, might be a custom component action // send it to all components as a raw string for component in self.components.iter_mut() { - let _ = component.receive_message(action.clone()); + if component.is_active() { + let _ = component.receive_message(action.clone()); + } } } } diff --git a/lib/cli/tui/framework/component.rs b/lib/cli/tui/framework/component.rs index 6546d9c..0305629 100644 --- a/lib/cli/tui/framework/component.rs +++ b/lib/cli/tui/framework/component.rs @@ -76,29 +76,35 @@ pub trait Component: Downcast { /// /// * `Result>` - An action to be processed or none. fn handle_events(&mut self, event: Option) -> Result> { - let mut actions = vec![]; + if self.is_active() { + let mut actions = vec![]; - let action = match event { - Some(Event::Key(key_event)) => self.handle_key_events(key_event)?, - Some(Event::Mouse(mouse_event)) => self.handle_mouse_events(mouse_event)?, - Some(Event::Tick) => self.handle_tick_event()?, - Some(Event::Render) => self.handle_frame_event()?, - Some(Event::Paste(ref event)) => self.handle_paste_event(event.clone())?, - _ => None, - }; + let action = match event { + Some(Event::Key(key_event)) => self.handle_key_events(key_event)?, + Some(Event::Mouse(mouse_event)) => self.handle_mouse_events(mouse_event)?, + Some(Event::Tick) => self.handle_tick_event()?, + Some(Event::Render) => self.handle_frame_event()?, + Some(Event::Paste(ref event)) => self.handle_paste_event(event.clone())?, + _ => None, + }; - if let Some(action) = action { - actions.push(action); - } - - if let Some(children) = self.get_children() { - for child in children.values_mut() { - let child_actions = child.handle_events(event.clone())?; - actions.extend(child_actions); + if let Some(action) = action { + actions.push(action); } - } - Ok(actions) + if let Some(children) = self.get_children() { + for child in children.values_mut() { + if child.is_active() { + let child_actions = child.handle_events(event.clone())?; + actions.extend(child_actions); + } + } + } + + Ok(actions) + } else { + Ok(vec![]) + } } /// Handle key events and produce actions if necessary. @@ -288,7 +294,9 @@ pub trait Component: Downcast { /// /// # Arguments /// * `active` - The active state of the component. - fn set_active(&mut self, _active: bool) {} + fn set_active(&mut self, active: bool) { + set_active_on_children(self, active); + } } impl_downcast!(Component); @@ -299,9 +307,13 @@ impl_downcast!(Component); /// created to allow to easily override the default `update` method of a component implementation /// and still be able to call the children's `update` method. pub fn update_children(this: &mut T, action: Action) -> Result<()> { - if let Some(children) = this.get_children() { - for child in children.values_mut() { - child.update(action.clone())?; + if this.is_active() { + if let Some(children) = this.get_children() { + for child in children.values_mut() { + if child.is_active() { + child.update(action.clone())?; + } + } } } @@ -317,15 +329,32 @@ pub fn pass_message_to_children( this: &mut T, message: String, ) -> Result<()> { - if let Some(children) = this.get_children() { - for child in children.values_mut() { - child.receive_message(message.clone())?; + if this.is_active() { + if let Some(children) = this.get_children() { + for child in children.values_mut() { + if child.is_active() { + child.receive_message(message.clone())?; + } + } } } Ok(()) } +/// Set active/inactive to the children of a component. +/// +/// This helper function is used to set active/inactive to the children of a component. It was +/// created to allow to easily implement the default `set_active` method of a component +/// implementation and be able to call the children's `set_active` method. +pub fn set_active_on_children(this: &mut T, active: bool) { + if let Some(children) = this.get_children() { + for child in children.values_mut() { + child.set_active(active); + } + } +} + /// Initialize the children of a component. /// /// This helper function is used to initialize the children of a component. It was created to diff --git a/lib/cli/tui/mod.rs b/lib/cli/tui/mod.rs index f07777c..e4c3f67 100644 --- a/lib/cli/tui/mod.rs +++ b/lib/cli/tui/mod.rs @@ -20,7 +20,7 @@ pub mod utils { pub mod component { pub use super::super::framework::component::{ child_downcast, child_downcast_mut, init_children, pass_action_handler_to_children, - pass_message_to_children, update_children, + pass_message_to_children, set_active_on_children, update_children, }; }