ratatui_kit/hooks/
use_input.rs1use std::{cell::Cell, rc::Rc};
12
13use crossterm::event::Event;
14use ratatui::layout::Rect;
15
16use super::{Hook, Hooks};
17use crate::{
18 SystemContext, UseContext,
19 input::{CurrentLayer, EventOptions, EventPriority, EventResult, EventScope, InputLayer},
20};
21
22mod private {
23 pub trait Sealed {}
24 impl Sealed for crate::hooks::Hooks<'_, '_> {}
25}
26
27pub trait UseInputLayer: private::Sealed {
28 fn use_input_layer(&mut self, open: bool, blocks_lower: bool) -> InputLayer;
33}
34
35pub trait UseEventHandler: private::Sealed {
36 fn use_event_handler<F>(&mut self, scope: EventScope, priority: EventPriority, f: F)
39 where
40 F: FnMut(Event) -> EventResult + 'static;
41
42 fn use_event_handler_with_options<F>(
44 &mut self,
45 scope: EventScope,
46 priority: EventPriority,
47 options: EventOptions,
48 f: F,
49 ) where
50 F: FnMut(Event) -> EventResult + 'static;
51}
52
53struct UseInputLayerImpl;
55impl Hook for UseInputLayerImpl {}
56
57impl UseInputLayer for Hooks<'_, '_> {
58 fn use_input_layer(&mut self, open: bool, blocks_lower: bool) -> InputLayer {
59 self.use_hook(|| UseInputLayerImpl); let mut sys = self.use_context_mut::<SystemContext>();
62 sys.input.push_layer(open, blocks_lower)
63 }
64}
65
66struct UseEventHandlerImpl {
69 area: Rc<Cell<Rect>>,
70}
71
72impl Hook for UseEventHandlerImpl {
73 fn pre_component_draw(&mut self, drawer: &mut crate::ComponentDrawer) {
74 self.area.set(drawer.area);
75 }
76}
77
78impl UseEventHandler for Hooks<'_, '_> {
79 fn use_event_handler<F>(&mut self, scope: EventScope, priority: EventPriority, f: F)
80 where
81 F: FnMut(Event) -> EventResult + 'static,
82 {
83 self.use_event_handler_with_options(scope, priority, EventOptions::default(), f);
84 }
85
86 fn use_event_handler_with_options<F>(
87 &mut self,
88 scope: EventScope,
89 priority: EventPriority,
90 options: EventOptions,
91 f: F,
92 ) where
93 F: FnMut(Event) -> EventResult + 'static,
94 {
95 let area = {
97 let hook = self.use_hook(|| UseEventHandlerImpl {
98 area: Rc::new(Cell::new(Rect::default())),
99 });
100 hook.area.clone()
101 };
102
103 let layer = match scope {
105 EventScope::Global => None,
106 EventScope::Layer(h) => Some(h.id),
107 EventScope::Current => {
108 let id = self
109 .try_use_context::<CurrentLayer>()
110 .map(|c| c.0)
111 .unwrap_or_else(|| self.use_context::<SystemContext>().input.root_layer());
112 Some(id)
113 }
114 };
115
116 let mut sys = self.use_context_mut::<SystemContext>();
118 sys.input
119 .register_handler(layer, priority, options, area, Box::new(f));
120 }
121}