Skip to main content

ptsd/interactions/
selectable.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 crate::utils::Callback;
8
9#[derive(Component, Debug, Clone)]
10pub struct Selectable(Stack, emitters::Selectable<_Selectable>);
11impl OnEvent for Selectable {}
12impl Selectable {
13    pub fn new(
14        default: impl Drawable + 'static,
15        selected: impl Drawable + 'static,
16        is_selected: bool,
17        can_deselect: bool,
18        on_click: impl FnMut(&mut Context) + Clone + 'static,
19        group_id: uuid::Uuid,
20    ) -> Self {
21        let selectable = _Selectable::new(default, selected, is_selected, can_deselect, on_click);
22        Self(Stack::default(), emitters::Selectable::new(selectable, group_id))
23    }
24
25    pub fn is_selected(&self) -> bool {self.1.1.4}
26}
27
28impl std::ops::Deref for Selectable {
29    type Target = _Selectable;
30    fn deref(&self) -> &Self::Target {&self.1.1}
31}
32
33impl std::ops::DerefMut for Selectable {
34    fn deref_mut(&mut self) -> &mut Self::Target {&mut self.1.1}
35}
36
37#[derive(Component, Clone)]
38pub struct _Selectable(Stack, Enum<Box<dyn Drawable>>, #[skip] Box<dyn Callback>, #[skip] bool, #[skip] bool);
39
40impl _Selectable {
41    pub fn new(
42        default: impl Drawable + 'static,
43        selected: impl Drawable + 'static,
44        is_selected: bool,
45        can_deselect: bool,
46        on_click: impl FnMut(&mut Context) + Clone + 'static
47    ) -> Self {
48        let start = if is_selected {"selected"} else {"default"};
49        _Selectable(Stack::default(), Enum::new(vec![
50            ("default".to_string(), Box::new(default)),
51            ("selected".to_string(), Box::new(selected)),
52        ], start.to_string()), Box::new(on_click), can_deselect, is_selected)
53    }
54}
55
56impl OnEvent for _Selectable {
57    fn on_event(&mut self, ctx: &mut Context, _sized: &SizedTree, event: Box<dyn Event>) -> Vec<Box<dyn Event>> {
58        if let Some(event::Selectable::Selected(b)) = event.downcast_ref::<event::Selectable>() {
59            match b {
60                false => {
61                    self.1.display("default");
62                    self.4 = false;
63                }
64                true => {
65                    if self.3 && &self.1.current() == "selected" {
66                        // already selected 
67                        self.1.display("default");
68                        self.4 = false;
69                        ctx.send(Request::Hardware(Hardware::Haptic));
70                        (self.2)(ctx);
71                    } else {
72                        self.1.display("selected");
73                        self.4 = true;
74                        ctx.send(Request::Hardware(Hardware::Haptic));
75                        (self.2)(ctx);
76                    }
77                }
78            }
79        }
80        vec![event]
81    }
82}
83
84impl std::fmt::Debug for _Selectable {
85    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
86        write!(f, "_Selectable")
87    }
88}