1#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
7pub enum MouseButton {
8 Left,
9 Right,
10 Middle,
11}
12
13#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
15pub enum ElementState {
16 Pressed,
17 Released,
18}
19
20#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
22pub struct Modifiers {
23 pub shift: bool,
24 pub ctrl: bool,
25 pub alt: bool,
26 pub meta: bool,
27}
28
29#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
31pub enum KeyCode {
32 Tab,
33 Enter,
34 Escape,
35 Space,
36 Backspace,
37 Delete,
38 ArrowLeft,
39 ArrowRight,
40 ArrowUp,
41 ArrowDown,
42 Home,
43 End,
44 PageUp,
45 PageDown,
46 KeyA,
47 KeyC,
48 KeyV,
49 KeyX,
50 KeyZ,
51 Other(u32),
53}
54
55#[derive(Debug, Clone, Copy, PartialEq, Eq)]
57pub enum EventResult {
58 Handled,
60 Ignored,
62}
63
64#[derive(Debug, Clone)]
66pub struct MouseClickEvent {
67 pub button: MouseButton,
68 pub state: ElementState,
69 pub x: f32,
70 pub y: f32,
71 pub click_count: u32,
72}
73
74#[derive(Debug, Clone)]
76pub struct KeyboardEvent {
77 pub key: KeyCode,
78 pub state: ElementState,
79 pub modifiers: Modifiers,
80 pub text: Option<String>,
81}
82
83#[derive(Debug, Clone)]
85pub struct MouseMoveEvent {
86 pub x: f32,
87 pub y: f32,
88}
89
90#[derive(Debug, Clone)]
92pub struct ScrollEvent {
93 pub x: f32,
94 pub y: f32,
95 pub delta_x: f32,
96 pub delta_y: f32,
97}
98
99pub trait EventHandler {
101 fn handle_mouse_click(&mut self, event: &MouseClickEvent) -> EventResult {
103 let _ = event;
104 EventResult::Ignored
105 }
106
107 fn handle_keyboard(&mut self, event: &KeyboardEvent) -> EventResult {
109 let _ = event;
110 EventResult::Ignored
111 }
112
113 fn handle_mouse_move(&mut self, event: &MouseMoveEvent) -> EventResult {
115 let _ = event;
116 EventResult::Ignored
117 }
118
119 fn handle_scroll(&mut self, event: &ScrollEvent) -> EventResult {
121 let _ = event;
122 EventResult::Ignored
123 }
124
125 fn is_focused(&self) -> bool;
127
128 fn set_focused(&mut self, focused: bool);
130
131 fn contains_point(&self, x: f32, y: f32) -> bool;
133}
134
135#[cfg(test)]
140mod tests {
141 use super::*;
142
143 #[test]
144 fn mouse_click_event_fields() {
145 let evt = MouseClickEvent {
146 button: MouseButton::Left,
147 state: ElementState::Pressed,
148 x: 10.0,
149 y: 20.0,
150 click_count: 2,
151 };
152 assert_eq!(evt.button, MouseButton::Left);
153 assert_eq!(evt.state, ElementState::Pressed);
154 assert!((evt.x - 10.0).abs() < f32::EPSILON);
155 assert!((evt.y - 20.0).abs() < f32::EPSILON);
156 assert_eq!(evt.click_count, 2);
157 }
158
159 #[test]
160 fn event_result_matching() {
161 let handled = EventResult::Handled;
162 let ignored = EventResult::Ignored;
163 assert_eq!(handled, EventResult::Handled);
164 assert_eq!(ignored, EventResult::Ignored);
165 assert_ne!(handled, ignored);
166 }
167
168 #[test]
169 fn modifiers_default_all_false() {
170 let m = Modifiers::default();
171 assert!(!m.shift);
172 assert!(!m.ctrl);
173 assert!(!m.alt);
174 assert!(!m.meta);
175 }
176
177 #[test]
178 fn key_code_variants() {
179 let keys = [
181 KeyCode::Tab,
182 KeyCode::Enter,
183 KeyCode::Escape,
184 KeyCode::Space,
185 KeyCode::Backspace,
186 KeyCode::Delete,
187 KeyCode::ArrowLeft,
188 KeyCode::ArrowRight,
189 KeyCode::ArrowUp,
190 KeyCode::ArrowDown,
191 KeyCode::Home,
192 KeyCode::End,
193 KeyCode::PageUp,
194 KeyCode::PageDown,
195 KeyCode::KeyA,
196 KeyCode::KeyC,
197 KeyCode::KeyV,
198 KeyCode::KeyX,
199 KeyCode::KeyZ,
200 KeyCode::Other(0),
201 ];
202 for (i, a) in keys.iter().enumerate() {
204 for (j, b) in keys.iter().enumerate() {
205 if i != j {
206 assert_ne!(a, b, "KeyCode variants at {i} and {j} should differ");
207 }
208 }
209 }
210 }
211
212 #[test]
213 fn keyboard_event_with_text() {
214 let evt = KeyboardEvent {
215 key: KeyCode::KeyA,
216 state: ElementState::Pressed,
217 modifiers: Modifiers {
218 shift: true,
219 ..Default::default()
220 },
221 text: Some("A".to_string()),
222 };
223 assert_eq!(evt.key, KeyCode::KeyA);
224 assert_eq!(evt.text.as_deref(), Some("A"));
225 assert!(evt.modifiers.shift);
226 }
227
228 #[test]
229 fn scroll_event_fields() {
230 let evt = ScrollEvent {
231 x: 5.0,
232 y: 6.0,
233 delta_x: -1.0,
234 delta_y: 3.5,
235 };
236 assert!((evt.delta_x - (-1.0)).abs() < f32::EPSILON);
237 assert!((evt.delta_y - 3.5).abs() < f32::EPSILON);
238 }
239}