euv_ui/hook/use_keyboard/
impl.rs1use super::*;
2
3impl UseKeyboard {
5 pub(crate) fn new() -> Self {
11 Self {
12 pressed: Signal::create(String::new()),
13 teardown: Rc::new(RefCell::new(None)),
14 }
15 }
16
17 pub fn current_key(&self) -> String {
23 self.get_pressed().get()
24 }
25
26 pub fn is_pressed(&self, key: &str) -> bool {
36 self.get_pressed().get() == key
37 }
38
39 pub(crate) fn attach(&self) {
44 #[cfg(target_arch = "wasm32")]
45 {
46 let Some(window) = browser_window() else {
47 return;
48 };
49 let pressed: Signal<String> = self.get_pressed();
50 let on_down: Closure<dyn FnMut(Event)> =
51 Closure::wrap(Box::new(move |event: Event| {
52 let Ok(keyboard) = event.dyn_into::<KeyboardEvent>() else {
53 return;
54 };
55 pressed.set(keyboard.key());
56 }));
57 let on_up: Closure<dyn FnMut(Event)> = Closure::wrap(Box::new(move |event: Event| {
58 let Ok(keyboard) = event.dyn_into::<KeyboardEvent>() else {
59 return;
60 };
61 let released: String = keyboard.key();
62 if pressed.get() == released {
63 pressed.set(String::new());
64 }
65 }));
66 if window
67 .add_event_listener_with_callback(EVENT_KEYDOWN, on_down.as_ref().unchecked_ref())
68 .is_err()
69 {
70 return;
71 }
72 if window
73 .add_event_listener_with_callback(EVENT_KEYUP, on_up.as_ref().unchecked_ref())
74 .is_err()
75 {
76 return;
77 }
78 *self.get_teardown().borrow_mut() = Some(Box::new(move || {
79 let _: Result<(), JsValue> = window.remove_event_listener_with_callback(
80 EVENT_KEYDOWN,
81 on_down.as_ref().unchecked_ref(),
82 );
83 let _: Result<(), JsValue> = window.remove_event_listener_with_callback(
84 EVENT_KEYUP,
85 on_up.as_ref().unchecked_ref(),
86 );
87 }));
88 }
89 }
90
91 pub(crate) fn detach(&self) {
93 let taken: Option<Box<dyn Fn()>> = self.get_teardown().borrow_mut().take();
94 if let Some(teardown) = taken {
95 teardown();
96 }
97 }
98}