Skip to main content

ptsd/interactions/
button.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 Button(Stack, emitters::Button<_Button>);
11impl OnEvent for Button {}
12impl Button {
13    pub fn new(
14        default: impl Drawable + 'static,
15        hover: Option<impl Drawable + 'static>,
16        pressed: Option<impl Drawable + 'static>,
17        disabled: Option<impl Drawable + 'static>,
18        callback: impl FnMut(&mut Context) + Clone + 'static,
19        disableable: bool,
20    ) -> Self {
21        let button = _Button::new(default, hover, pressed, disabled, callback, disableable, false);
22        Self(Stack::default(), emitters::Button::new(button))
23    }
24
25    pub fn new_triggers_on_release(
26        default: impl Drawable + 'static,
27        hover: Option<impl Drawable + 'static>,
28        pressed: Option<impl Drawable + 'static>,
29        disabled: Option<impl Drawable + 'static>,
30        callback: impl FnMut(&mut Context) + Clone + 'static,
31        disableable: bool,
32    ) -> Self {
33        let button = _Button::new(default, hover, pressed, disabled, callback, disableable, true);
34        Self(Stack::default(), emitters::Button::new(button))
35    }
36}
37
38impl std::ops::Deref for Button {
39    type Target = _Button;
40    fn deref(&self) -> &Self::Target {&self.1.1}
41}
42
43impl std::ops::DerefMut for Button {
44    fn deref_mut(&mut self) -> &mut Self::Target {&mut self.1.1}
45}
46
47#[derive(Component, Clone)]
48pub struct _Button(Stack, Enum<Box<dyn Drawable>>, #[skip] bool, #[skip] Box<dyn Callback>, #[skip] bool, #[skip] bool, #[skip] bool);
49
50impl _Button {
51    pub fn new(
52        default: impl Drawable + 'static,
53        hover: Option<impl Drawable + 'static>,
54        pressed: Option<impl Drawable + 'static>,
55        disabled: Option<impl Drawable + 'static>,
56        callback: impl FnMut(&mut Context) + Clone + 'static,
57        disableable: bool,
58        triggers_on_release: bool,
59    ) -> Self {
60        let mut items: Vec<(String, Box<dyn Drawable>)> = Vec::new();
61        items.push(("default".to_string(), Box::new(default)));
62        if let Some(h) = hover { items.push(("hover".to_string(), Box::new(h))) }
63        if let Some(p) = pressed { items.push(("pressed".to_string(), Box::new(p))) }
64        if let Some(d) = disabled { items.push(("disabled".to_string(), Box::new(d))) }
65        _Button(Stack::default(), Enum::new(items, "default".to_string()), false, Box::new(callback), disableable, triggers_on_release, false)
66    }
67
68    pub fn disable(&mut self, disable: bool) {
69        if self.2 != disable {
70            self.2 = disable;
71
72            match self.2 {
73                true => self.1.display("disabled"),
74                false => self.1.display("default")
75            }
76        }
77    }
78
79    pub fn on_click(&mut self) -> &mut Box<dyn Callback> {&mut self.3}
80}
81
82impl OnEvent for _Button {
83    fn on_event(&mut self, ctx: &mut Context, _sized: &SizedTree, event: Box<dyn Event>) -> Vec<Box<dyn Event>> {
84        if let Some(event) = event.downcast_ref::<event::Button>() {
85            if let event::Button::Disable(disable) = event {
86                if self.4 { self.disable(*disable);} 
87            } else if !self.2 {
88                match event {
89                    event::Button::Hover(true) if !self.6 => self.1.display("hover"),
90                    event::Button::Pressed(true) => {
91                        self.6 = true;
92                        self.1.display("pressed");
93                        if !self.5 {
94                            ctx.send(Request::Hardware(Hardware::Haptic));
95                            (self.3)(ctx);
96                        }
97                    }
98                    event::Button::Pressed(false) => {
99                        self.6 = false;
100                        if self.5 {
101                            ctx.send(Request::Hardware(Hardware::Haptic));
102                            (self.3)(ctx);
103                        }
104                        self.1.display("default");
105                    },
106                    event::Button::Hover(false) if !self.6 => {
107                        self.1.display("default");
108                    }
109                    // event::Button::Disable(_) => {},
110                    _ => {} //self.1.display("default"),
111                }
112            }
113        }
114
115        vec![event]
116    }
117}
118
119impl std::fmt::Debug for _Button {
120    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
121        write!(f, "_Button")
122    }
123}
124