Seregon/StratoSDK

StratoSDK is a framework with a declarative approach similar to Flutter/React, written and designed entirely for Rust.

Rust/27.3 KB/No license
crates/strato-core/src/event.rs
StratoSDK / crates / strato-core / src / event.rs
1//! Event handling system for StratoUI
2 
3use glam::Vec2;
4use std::any::Any;
5use std::fmt::Debug;
6use std::sync::Arc;
7 
8/// Result of event handling
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub enum EventResult {
11 /// Event was handled, stop propagation
12 Handled,
13 /// Event was not handled, continue propagation
14 Ignored,
15}
16 
17/// Mouse button types
18#[derive(Debug, Clone, Copy, PartialEq, Eq)]
19pub enum MouseButton {
20 Left,
21 Right,
22 Middle,
23 Other(u16),
24}
25 
26/// Keyboard key codes
27#[derive(Debug, Clone, Copy, PartialEq, Eq)]
28pub enum KeyCode {
29 // Letters
30 A,
31 B,
32 C,
33 D,
34 E,
35 F,
36 G,
37 H,
38 I,
39 J,
40 K,
41 L,
42 M,
43 N,
44 O,
45 P,
46 Q,
47 R,
48 S,
49 T,
50 U,
51 V,
52 W,
53 X,
54 Y,
55 Z,
56 // Numbers
57 Num0,
58 Num1,
59 Num2,
60 Num3,
61 Num4,
62 Num5,
63 Num6,
64 Num7,
65 Num8,
66 Num9,
67 // Function keys
68 F1,
69 F2,
70 F3,
71 F4,
72 F5,
73 F6,
74 F7,
75 F8,
76 F9,
77 F10,
78 F11,
79 F12,
80 // Control keys
81 Enter,
82 Escape,
83 Backspace,
84 Tab,
85 Space,
86 Left,
87 Right,
88 Up,
89 Down,
90 Shift,
91 Control,
92 Alt,
93 Super,
94 // Special
95 Delete,
96 Insert,
97 Home,
98 End,
99 PageUp,
100 PageDown,
101}
102 
103/// High-level key event for text input and navigation
104#[derive(Debug, Clone, PartialEq)]
105pub enum KeyEvent {
106 /// Character input
107 Char(char),
108 /// Backspace key
109 Backspace,
110 /// Delete key
111 Delete,
112 /// Enter key
113 Enter,
114 /// Left arrow
115 Left,
116 /// Right arrow
117 Right,
118 /// Up arrow
119 Up,
120 /// Down arrow
121 Down,
122 /// Home key
123 Home,
124 /// End key
125 End,
126 /// Tab key
127 Tab,
128 /// Escape key
129 Escape,
130}
131 
132/// Keyboard modifiers
133#[derive(Debug, Clone, Copy, Default)]
134pub struct Modifiers {
135 pub shift: bool,
136 pub control: bool,
137 pub alt: bool,
138 pub super_key: bool,
139}
140 
141/// Mouse event data
142#[derive(Debug, Clone)]
143pub struct MouseEvent {
144 pub position: Vec2,
145 pub button: Option<MouseButton>,
146 pub modifiers: Modifiers,
147 pub delta: Vec2,
148}
149 
150/// Keyboard event data
151#[derive(Debug, Clone)]
152pub struct KeyboardEvent {
153 pub key_code: KeyCode,
154 pub modifiers: Modifiers,
155 pub is_repeat: bool,
156 pub text: Option<String>,
157}
158 
159/// Window event data
160#[derive(Debug, Clone)]
161pub enum WindowEvent {
162 Resize { width: u32, height: u32 },
163 Move { x: i32, y: i32 },
164 Focus(bool),
165 Close,
166 Minimize,
167 Maximize,
168}
169 
170/// Touch event data
171#[derive(Debug, Clone)]
172pub struct TouchEvent {
173 pub id: u64,
174 pub position: Vec2,
175 pub force: Option<f32>,
176}
177 
178/// Main event type
179#[derive(Debug, Clone)]
180pub enum Event {
181 /// Mouse button pressed
182 MouseDown(MouseEvent),
183 /// Mouse button released
184 MouseUp(MouseEvent),
185 /// Mouse moved
186 MouseMove(MouseEvent),
187 /// Mouse wheel scrolled
188 MouseWheel { delta: Vec2, modifiers: Modifiers },
189 /// Mouse entered widget
190 MouseEnter,
191 /// Mouse left widget
192 MouseExit,
193 
194 /// Key pressed
195 KeyDown(KeyboardEvent),
196 /// Key released
197 KeyUp(KeyboardEvent),
198 /// Text input
199 TextInput(String),
200 
201 /// Window event
202 Window(WindowEvent),
203 
204 /// Touch started
205 TouchStart(TouchEvent),
206 /// Touch moved
207 TouchMove(TouchEvent),
208 /// Touch ended
209 TouchEnd(TouchEvent),
210 /// Touch cancelled
211 TouchCancel(TouchEvent),
212 
213 /// Custom user event
214 Custom(Arc<dyn Any + Send + Sync>),
215}
216 
217/// Event handler trait
218pub trait EventHandler: Send + Sync {
219 /// Handle an event
220 fn handle(&mut self, event: &Event) -> EventResult;
221 
222 /// Check if handler can handle this event type
223 fn can_handle(&self, _event: &Event) -> bool {
224 true
225 }
226}
227 
228/// Event dispatcher with priority and filtering
229pub struct EventDispatcher {
230 handlers: Vec<(Box<dyn EventHandler>, i32)>, // (handler, priority)
231 event_filters: Vec<Box<dyn Fn(&Event) -> bool + Send + Sync>>,
232}
233 
234impl EventDispatcher {
235 /// Create a new event dispatcher
236 pub fn new() -> Self {
237 Self {
238 handlers: Vec::new(),
239 event_filters: Vec::new(),
240 }
241 }
242 
243 /// Add a handler with priority (higher priority = processed first)
244 pub fn add_handler_with_priority(&mut self, handler: Box<dyn EventHandler>, priority: i32) {
245 self.handlers.push((handler, priority));
246 // Sort by priority (descending)
247 self.handlers.sort_by(|a, b| b.1.cmp(&a.1));
248 }
249 
250 /// Add a handler with default priority (0)
251 pub fn add_handler(&mut self, handler: Box<dyn EventHandler>) {
252 self.add_handler_with_priority(handler, 0);
253 }
254 
255 /// Add an event filter
256 pub fn add_filter<F>(&mut self, filter: F)
257 where
258 F: Fn(&Event) -> bool + Send + Sync + 'static,
259 {
260 self.event_filters.push(Box::new(filter));
261 }
262 
263 /// Dispatch an event to all handlers
264 pub fn dispatch(&mut self, event: &Event) -> EventResult {
265 // Apply filters first
266 for filter in &self.event_filters {
267 if !filter(event) {
268 return EventResult::Ignored;
269 }
270 }
271 
272 // Dispatch to handlers in priority order
273 for (handler, _) in &mut self.handlers {
274 if handler.can_handle(event) {
275 if handler.handle(event) == EventResult::Handled {
276 return EventResult::Handled;
277 }
278 }
279 }
280 EventResult::Ignored
281 }
282 
283 /// Remove all handlers
284 pub fn clear_handlers(&mut self) {
285 self.handlers.clear();
286 }
287 
288 /// Remove all filters
289 pub fn clear_filters(&mut self) {
290 self.event_filters.clear();
291 }
292}
293 
294impl Default for EventDispatcher {
295 fn default() -> Self {
296 Self::new()
297 }
298}
299 
300#[cfg(test)]
301mod tests {
302 use super::*;
303 
304 struct TestHandler {
305 handled_count: usize,
306 }
307 
308 impl EventHandler for TestHandler {
309 fn handle(&mut self, _event: &Event) -> EventResult {
310 self.handled_count += 1;
311 EventResult::Handled
312 }
313 }
314 
315 #[test]
316 fn test_event_dispatcher() {
317 let mut dispatcher = EventDispatcher::new();
318 dispatcher.add_handler(Box::new(TestHandler { handled_count: 0 }));
319 
320 let event = Event::MouseEnter;
321 let result = dispatcher.dispatch(&event);
322 assert_eq!(result, EventResult::Handled);
323 }
324}
325