ptsd/interactions/
text_input.rs1use prism::event::{self, OnEvent, Event};
2use prism::drawable::{Drawable, Component, SizedTree};
3use prism::display::Enum;
4use prism::layout::{Stack, Size, Offset, Padding};
5use prism::{emitters, Context, Request, Hardware};
6use crate::interfaces::ShowKeyboard;
7#[derive(Component, Clone, Debug)]
10pub struct InputField(Stack, emitters::Selectable<emitters::TextInput<_InputField>>);
11impl OnEvent for InputField {}
12impl InputField {
13 pub fn new(
14 default: impl Drawable + 'static,
15 focus: impl Drawable + 'static,
16 hover: Option<impl Drawable + 'static>,
17 error: Option<impl Drawable + 'static>,
18 content: impl Drawable + 'static,
19 height: f32,
20 ) -> Self {
21 let text_input = _InputField::new(default, focus, hover, error, content, height);
22 Self(Stack::default(), emitters::TextInput::new(text_input, true))
23 }
24}
25
26impl std::ops::Deref for InputField {
27 type Target = _InputField;
28 fn deref(&self) -> &Self::Target {&self.1.1.1}
29}
30
31impl std::ops::DerefMut for InputField {
32 fn deref_mut(&mut self) -> &mut Self::Target {&mut self.1.1.1}
33}
34
35#[derive(Debug, Component, Clone)]
36pub struct _InputField(Stack, Enum<Box<dyn Drawable>>, pub Box<dyn Drawable>, #[skip] pub bool);
37
38impl _InputField {
39 pub fn new(
40 default: impl Drawable + 'static,
41 focus: impl Drawable + 'static,
42 hover: Option<impl Drawable + 'static>,
43 error: Option<impl Drawable + 'static>,
44 content: impl Drawable + 'static,
45 height: f32,
46 ) -> Self {
47 let height = Size::custom(move |h: Vec<(f32, f32)>| (h[1].0.max(height), h[1].1.max(height)));
48 let layout = Stack(Offset::Start, Offset::Start, Size::Fit, height, Padding::default());
49
50 let mut items: Vec<(String, Box<dyn Drawable>)> = Vec::new();
51 items.push(("default".to_string(), Box::new(default)));
52 items.push(("focus".to_string(), Box::new(focus)));
53 if let Some(h) = hover { items.push(("hover".to_string(), Box::new(h))) }
54 if let Some(e) = error { items.push(("error".to_string(), Box::new(e))) }
55
56 _InputField(layout, Enum::new(items, "default".to_string()), Box::new(content), false)
57 }
58
59 pub fn error(&mut self, error: bool) {
60 if self.3 != error {
61 self.3 = error;
62
63 match self.3 {
64 true => self.1.display("error"),
65 false => self.1.display("default")
66 }
67 }
68 }
69}
70
71impl OnEvent for _InputField {
72 fn on_event(&mut self, ctx: &mut Context, _sized: &SizedTree, event: Box<dyn Event>) -> Vec<Box<dyn Event>> {
73 if let Some(e) = event.downcast_ref::<event::TextInput>() {
74 match e {
75 event::TextInput::Hover(true) if !self.3 => self.1.display("hover"),
76 event::TextInput::Focused(true) => {
77 ctx.send(Request::Event(Box::new(ShowKeyboard(true))));
78 ctx.send(Request::Hardware(Hardware::Haptic));
79 self.1.display("focus");
80 },
81 event::TextInput::Focused(false) => {
82 self.1.display(if self.3 {"error"} else {"default"});
84 },
85 _ => self.1.display("default"),
86 }
87 }
88
89 vec![event]
90 }
91}