ptsd/interactions/
selectable.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 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 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}