ptsd/interactions/
button.rs1use 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);
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)
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
80impl OnEvent for _Button {
81 fn on_event(&mut self, ctx: &mut Context, _sized: &SizedTree, event: Box<dyn Event>) -> Vec<Box<dyn Event>> {
82 if let Some(event::Button::Disable(disable)) = event.downcast_ref::<event::Button>() && self.4 {
83 self.disable(*disable);
84 } else if let Some(event) = event.downcast_ref::<event::Button>() && !self.2 {
85 match event {
86 event::Button::Hover(true) => self.1.display("hover"),
87 event::Button::Pressed(true) => {
88 self.1.display("pressed");
89 if !self.5 {
90 ctx.send(Request::Hardware(Hardware::Haptic));
91 (self.3)(ctx);
92 }
93 }
94 event::Button::Pressed(false) => {
95 println!("Button released");
96 if self.5 {
97 ctx.send(Request::Hardware(Hardware::Haptic));
98 (self.3)(ctx);
99 }
100 self.1.display("default");
101 },
102 event::Button::Disable(_) => {},
103 _ => self.1.display("default"),
104 }
105 }
106
107 vec![event]
108 }
109}
110
111impl std::fmt::Debug for _Button {
112 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
113 write!(f, "_Button")
114 }
115}
116