diff --git a/src/elements/callback_builder.rs b/src/elements/callback_builder.rs new file mode 100644 index 0000000..b097d1a --- /dev/null +++ b/src/elements/callback_builder.rs @@ -0,0 +1,55 @@ +use std::any::Any; + +use anyhow::Result; + +use super::ControllerButton; + +macro_rules! callbacks { + ($name:ident, $($cb:tt)*) => { + #[derive(Default)] + pub struct $name<'a> { + callbacks: Vec<(&'a str, Box)>, + } + + impl<'a> $name<'a> { + pub fn add(mut self, name: &'a str, callback: impl $($cb)* + 'static)->Self { + self.callbacks.push((name, Box::new(callback))); + self + } + } + + impl<'a> Into)>> for $name<'a> { + fn into(self) -> Vec<(&'a str, Box)> { + self.callbacks + } + } + }; +} + +callbacks!(ClickCallbacks, Fn() -> Result<()> + Send + Sync); +callbacks!(SelectCallbacks, Fn(bool) -> anyhow::Result<()> + Send + Sync); +callbacks!(CustomCallbacks, Fn(ControllerButton) -> anyhow::Result + Send + Sync); +callbacks!(VecCallbacks, Fn(&dyn Any) -> Result<()> + Send + Sync); + +#[test] +fn test_click_callback_builder() { + struct Test; + + impl Test { + fn set_click_callbacks( + &self, + _callbacks: Vec<(&str, Box Result<()> + Send + Sync>)>, + ) -> Result<()> { + Ok(()) + } + } + + let t = Test; + + let cbs = ClickCallbacks::default().add("test", || { + println!("hello world!"); + Ok(()) + }); + + t.set_click_callbacks(cbs.into()).unwrap(); +} diff --git a/src/elements/mod.rs b/src/elements/mod.rs index e68fcaa..6b8e4c1 100644 --- a/src/elements/mod.rs +++ b/src/elements/mod.rs @@ -22,6 +22,7 @@ pub mod uielement; pub mod traits; +mod callback_builder; pub mod prelude; pub(crate) struct TextableWrapper { diff --git a/src/elements/prelude.rs b/src/elements/prelude.rs index 1a55eb9..72773a3 100644 --- a/src/elements/prelude.rs +++ b/src/elements/prelude.rs @@ -1,5 +1,6 @@ pub use super::{ button::{Button, ButtonBuilder, ButtonSelectMode}, + callback_builder::*, fill_type::FillTypeInfo, grid::Grid, icon::Icon,