Skip to main content

ptsd/interactions/
toggle.rs

1use prism::event::{self, OnEvent, Event};
2use prism::drawable::{Drawable, Component, SizedTree};
3use prism::display::Enum;
4use prism::layout::Stack;
5use prism::{emitters, Context, Request, Hardware};
6
7use std::sync::{Arc, Mutex};
8
9#[derive(Component, Clone, Debug)]
10pub struct Toggle(Stack, emitters::Button<_Toggle>);
11impl OnEvent for Toggle {}
12impl Toggle {
13    pub fn new(
14        on: impl Drawable + 'static,
15        off: impl Drawable + 'static,
16        is_selected: bool,
17        on_click: impl FnMut(&mut Context, bool) + Send + Sync + 'static,
18    ) -> Self {
19        let toggle = _Toggle::new(on, off, is_selected, on_click);
20        Self(Stack::default(), emitters::Button::new(toggle))
21    }
22}
23
24impl std::ops::Deref for Toggle {
25    type Target = _Toggle;
26    fn deref(&self) -> &Self::Target {&self.1.1}
27}
28
29impl std::ops::DerefMut for Toggle {
30    fn deref_mut(&mut self) -> &mut Self::Target {&mut self.1.1}
31}
32
33#[derive(Component, Clone)]
34pub struct _Toggle(Stack, Enum<Box<dyn Drawable>>, #[skip] bool, #[skip] ToggleCallback);
35
36impl _Toggle {
37    pub fn new(
38        on: impl Drawable + 'static,
39        off: impl Drawable + 'static,
40        is_selected: bool,
41        on_click: impl FnMut(&mut Context, bool) + Send + Sync + 'static,
42    ) -> Self {
43        let start = if is_selected {"on"} else {"off"};
44        _Toggle(Stack::default(), 
45            Enum::new(vec![("on".to_string(), Box::new(on)), ("off".to_string(), Box::new(off))], start.to_string()), 
46            !is_selected, Arc::new(Mutex::new(on_click))
47        )
48    }
49}
50
51impl OnEvent for _Toggle {
52    fn on_event(&mut self, ctx: &mut Context, _sized: &SizedTree, event: Box<dyn Event>) -> Vec<Box<dyn Event>> {
53        if let Some(event::Button::Pressed(true)) = event.downcast_ref::<event::Button>() {
54            self.2 = !self.2;
55            ctx.send(Request::Hardware(Hardware::Haptic));
56            if let Ok(mut cb) = self.3.lock() { (cb)(ctx, !self.2); }
57            match self.2 {
58                false => self.1.display("on"),
59                true => self.1.display("off"),
60            }
61        }
62        Vec::new()
63    }
64}
65
66impl std::fmt::Debug for _Toggle {
67    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
68        write!(f, "_Toggle")
69    }
70}
71
72
73type ToggleCallback = Arc<Mutex<dyn FnMut(&mut Context, bool) + Send + Sync + 'static>>;