diff --git a/src/extensions/input_handling.rs b/src/extensions/input_handling.rs index 399bc0f..227d526 100644 --- a/src/extensions/input_handling.rs +++ b/src/extensions/input_handling.rs @@ -1,4 +1,4 @@ -use crate::{extensions::Extension, prelude::Handler}; +use crate::extensions::Extension; pub struct InputExtension; @@ -8,9 +8,7 @@ impl Extension for InputExtension { std::thread::spawn(move || loop { if let Ok(e) = crossterm::event::read() { for widget in screen.widgets.lock().unwrap().iter() { - if let Some(h) = widget.get::>() { - h.call(widget, &e); - } + widget.event(&e); } } }); diff --git a/src/extensions/mod.rs b/src/extensions/mod.rs index a2d98f6..d027629 100644 --- a/src/extensions/mod.rs +++ b/src/extensions/mod.rs @@ -58,3 +58,9 @@ impl Debug for Handler { write!(f, "Handler({})", type_name::()) } } + +impl<'a> dyn Event + 'a { + pub fn get(&self) -> Option<&T> { + self.as_any().downcast_ref() + } +} diff --git a/src/extensions/tick.rs b/src/extensions/tick.rs index 6334015..354814d 100644 --- a/src/extensions/tick.rs +++ b/src/extensions/tick.rs @@ -1,7 +1,6 @@ use std::{fmt::Debug, sync::Arc}; use crate::extensions::Extension; -use crate::extensions::Handler; use crate::{event, Screen}; pub struct TickExtension(pub u16); @@ -16,9 +15,7 @@ impl Extension for TickExtension { let mut tick = 0; loop { for w in screen.widgets.lock().unwrap().iter() { - if let Some(on_tick) = w.get::>() { - on_tick.call(&w, &TickEvent(tick)) - } + w.event(&TickEvent(tick)); } tick += 1; std::thread::sleep(std::time::Duration::from_millis(rate_dur)); diff --git a/src/widget.rs b/src/widget.rs index 8b12285..f8f3fa1 100644 --- a/src/widget.rs +++ b/src/widget.rs @@ -12,7 +12,11 @@ use std::{ sync::{Arc, Mutex, MutexGuard}, }; -use crate::{render_scope::RenderScope, state::DependencyHandler}; +use crate::{ + prelude::{Event, Handler}, + render_scope::RenderScope, + state::DependencyHandler, +}; /// A trait object for any renderable UI element. pub type BoxedElement = Box; @@ -37,6 +41,9 @@ pub trait Element: Send + Sync { #[allow(unused)] fn draw_child(&self, element: &Arc) {} + #[allow(unused)] + fn event(&mut self, event: &dyn Event) {} + /// Returns a type-erased reference to this object. fn as_any(&self) -> &dyn Any; @@ -223,6 +230,21 @@ impl Widget { } self } + + pub fn event(self: &Arc, e: &E) { + if let Some(wrapper) = self.get::>() { + wrapper.call(self, e); + } + + match &**self { + Widget::Dynamic(w) => { + w.get_elem().event(e); + } + Widget::Static(w) => { + w.get_elem().event(e); + } + } + } } impl StaticWidget {