1use rustc_hash::FxHashMap;
6
7pub type EventType = u32;
9
10pub mod event_types {
12 use super::EventType;
13
14 pub const POINTER_DOWN: EventType = 1;
15 pub const POINTER_UP: EventType = 2;
16 pub const POINTER_MOVE: EventType = 3;
17 pub const POINTER_ENTER: EventType = 4;
18 pub const POINTER_LEAVE: EventType = 5;
19 pub const DRAG: EventType = 6;
21 pub const DRAG_END: EventType = 7;
23 pub const FOCUS: EventType = 10;
24 pub const BLUR: EventType = 11;
25 pub const KEY_DOWN: EventType = 20;
26 pub const KEY_UP: EventType = 21;
27 pub const TEXT_INPUT: EventType = 22;
29 pub const SCROLL: EventType = 30;
30 pub const SCROLL_END: EventType = 31;
32 pub const PINCH: EventType = 32;
34 pub const RESIZE: EventType = 40;
35
36 pub const WINDOW_FOCUS: EventType = 50;
38 pub const WINDOW_BLUR: EventType = 51;
39
40 pub const MOUNT: EventType = 60;
42 pub const UNMOUNT: EventType = 61;
43
44 pub const CUT: EventType = 70;
46 pub const COPY: EventType = 71;
47 pub const PASTE: EventType = 72;
48
49 pub const SELECT_ALL: EventType = 80;
51}
52
53#[derive(Clone, Debug)]
55pub struct Event {
56 pub event_type: EventType,
57 pub target: u64, pub data: EventData,
59 pub timestamp: u64,
60 pub propagation_stopped: bool,
61}
62
63#[derive(Clone, Debug)]
65pub enum EventData {
66 Pointer {
67 x: f32,
68 y: f32,
69 button: u8,
70 pressure: f32,
71 },
72 Key {
73 key: KeyCode,
75 modifiers: Modifiers,
77 repeat: bool,
79 },
80 TextInput {
82 text: String,
84 },
85 Clipboard {
87 text: String,
89 },
90 Scroll {
91 delta_x: f32,
92 delta_y: f32,
93 },
94 Resize {
95 width: u32,
96 height: u32,
97 },
98 None,
99}
100
101#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)]
103pub struct KeyCode(pub u32);
104
105impl KeyCode {
106 pub const A: KeyCode = KeyCode(0x41);
108 pub const B: KeyCode = KeyCode(0x42);
109 pub const C: KeyCode = KeyCode(0x43);
110 pub const D: KeyCode = KeyCode(0x44);
111 pub const E: KeyCode = KeyCode(0x45);
112 pub const F: KeyCode = KeyCode(0x46);
113 pub const G: KeyCode = KeyCode(0x47);
114 pub const H: KeyCode = KeyCode(0x48);
115 pub const I: KeyCode = KeyCode(0x49);
116 pub const J: KeyCode = KeyCode(0x4A);
117 pub const K: KeyCode = KeyCode(0x4B);
118 pub const L: KeyCode = KeyCode(0x4C);
119 pub const M: KeyCode = KeyCode(0x4D);
120 pub const N: KeyCode = KeyCode(0x4E);
121 pub const O: KeyCode = KeyCode(0x4F);
122 pub const P: KeyCode = KeyCode(0x50);
123 pub const Q: KeyCode = KeyCode(0x51);
124 pub const R: KeyCode = KeyCode(0x52);
125 pub const S: KeyCode = KeyCode(0x53);
126 pub const T: KeyCode = KeyCode(0x54);
127 pub const U: KeyCode = KeyCode(0x55);
128 pub const V: KeyCode = KeyCode(0x56);
129 pub const W: KeyCode = KeyCode(0x57);
130 pub const X: KeyCode = KeyCode(0x58);
131 pub const Y: KeyCode = KeyCode(0x59);
132 pub const Z: KeyCode = KeyCode(0x5A);
133
134 pub const KEY_0: KeyCode = KeyCode(0x30);
136 pub const KEY_1: KeyCode = KeyCode(0x31);
137 pub const KEY_2: KeyCode = KeyCode(0x32);
138 pub const KEY_3: KeyCode = KeyCode(0x33);
139 pub const KEY_4: KeyCode = KeyCode(0x34);
140 pub const KEY_5: KeyCode = KeyCode(0x35);
141 pub const KEY_6: KeyCode = KeyCode(0x36);
142 pub const KEY_7: KeyCode = KeyCode(0x37);
143 pub const KEY_8: KeyCode = KeyCode(0x38);
144 pub const KEY_9: KeyCode = KeyCode(0x39);
145
146 pub const BACKSPACE: KeyCode = KeyCode(0x08);
148 pub const TAB: KeyCode = KeyCode(0x09);
149 pub const ENTER: KeyCode = KeyCode(0x0D);
150 pub const ESCAPE: KeyCode = KeyCode(0x1B);
151 pub const SPACE: KeyCode = KeyCode(0x20);
152 pub const DELETE: KeyCode = KeyCode(0x7F);
153
154 pub const LEFT: KeyCode = KeyCode(0x25);
156 pub const UP: KeyCode = KeyCode(0x26);
157 pub const RIGHT: KeyCode = KeyCode(0x27);
158 pub const DOWN: KeyCode = KeyCode(0x28);
159
160 pub const HOME: KeyCode = KeyCode(0x24);
162 pub const END: KeyCode = KeyCode(0x23);
163 pub const PAGE_UP: KeyCode = KeyCode(0x21);
164 pub const PAGE_DOWN: KeyCode = KeyCode(0x22);
165
166 pub const UNKNOWN: KeyCode = KeyCode(0);
168}
169
170#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
172pub struct Modifiers {
173 bits: u8,
174}
175
176impl Modifiers {
177 pub const NONE: Modifiers = Modifiers { bits: 0 };
178 pub const SHIFT: u8 = 0b0001;
179 pub const CTRL: u8 = 0b0010;
180 pub const ALT: u8 = 0b0100;
181 pub const META: u8 = 0b1000; pub const fn new(shift: bool, ctrl: bool, alt: bool, meta: bool) -> Self {
185 let mut bits = 0;
186 if shift {
187 bits |= Self::SHIFT;
188 }
189 if ctrl {
190 bits |= Self::CTRL;
191 }
192 if alt {
193 bits |= Self::ALT;
194 }
195 if meta {
196 bits |= Self::META;
197 }
198 Self { bits }
199 }
200
201 pub const fn from_bits(bits: u8) -> Self {
203 Self { bits }
204 }
205
206 pub const fn shift(&self) -> bool {
208 self.bits & Self::SHIFT != 0
209 }
210
211 pub const fn ctrl(&self) -> bool {
213 self.bits & Self::CTRL != 0
214 }
215
216 pub const fn alt(&self) -> bool {
218 self.bits & Self::ALT != 0
219 }
220
221 pub const fn meta(&self) -> bool {
223 self.bits & Self::META != 0
224 }
225
226 pub const fn any(&self) -> bool {
228 self.bits != 0
229 }
230
231 #[cfg(target_os = "macos")]
233 pub const fn command(&self) -> bool {
234 self.meta()
235 }
236
237 #[cfg(not(target_os = "macos"))]
239 pub const fn command(&self) -> bool {
240 self.ctrl()
241 }
242}
243
244impl Event {
245 pub fn stop_propagation(&mut self) {
246 self.propagation_stopped = true;
247 }
248}
249
250pub type EventHandler = Box<dyn Fn(&Event) + Send + Sync>;
252
253pub struct EventDispatcher {
255 handlers: FxHashMap<(u64, EventType), Vec<EventHandler>>,
256}
257
258impl EventDispatcher {
259 pub fn new() -> Self {
260 Self {
261 handlers: FxHashMap::default(),
262 }
263 }
264
265 pub fn register<F>(&mut self, widget_id: u64, event_type: EventType, handler: F)
267 where
268 F: Fn(&Event) + Send + Sync + 'static,
269 {
270 self.handlers
271 .entry((widget_id, event_type))
272 .or_default()
273 .push(Box::new(handler));
274 }
275
276 pub fn dispatch(&self, event: &mut Event) {
278 if let Some(handlers) = self.handlers.get(&(event.target, event.event_type)) {
279 for handler in handlers {
280 if event.propagation_stopped {
281 break;
282 }
283 handler(event);
284 }
285 }
286 }
287}
288
289impl Default for EventDispatcher {
290 fn default() -> Self {
291 Self::new()
292 }
293}