1use crate::{
2 point, Bounds, DispatchPhase, FocusHandle, Keystroke, Modifiers, Pixels, Point, ViewContext,
3};
4use smallvec::SmallVec;
5use std::{any::Any, ops::Deref};
6
7#[derive(Clone, Debug, Eq, PartialEq)]
8pub struct KeyDownEvent {
9 pub keystroke: Keystroke,
10 pub is_held: bool,
11}
12
13#[derive(Clone, Debug)]
14pub struct KeyUpEvent {
15 pub keystroke: Keystroke,
16}
17
18#[derive(Clone, Debug, Default)]
19pub struct ModifiersChangedEvent {
20 pub modifiers: Modifiers,
21}
22
23impl Deref for ModifiersChangedEvent {
24 type Target = Modifiers;
25
26 fn deref(&self) -> &Self::Target {
27 &self.modifiers
28 }
29}
30
31/// The phase of a touch motion event.
32/// Based on the winit enum of the same name.
33#[derive(Clone, Copy, Debug)]
34pub enum TouchPhase {
35 Started,
36 Moved,
37 Ended,
38}
39
40#[derive(Clone, Debug, Default)]
41pub struct MouseDownEvent {
42 pub button: MouseButton,
43 pub position: Point<Pixels>,
44 pub modifiers: Modifiers,
45 pub click_count: usize,
46}
47
48#[derive(Clone, Debug, Default)]
49pub struct MouseUpEvent {
50 pub button: MouseButton,
51 pub position: Point<Pixels>,
52 pub modifiers: Modifiers,
53 pub click_count: usize,
54}
55
56#[derive(Clone, Debug, Default)]
57pub struct MouseClickEvent {
58 pub down: MouseDownEvent,
59 pub up: MouseUpEvent,
60}
61
62#[derive(Hash, PartialEq, Eq, Copy, Clone, Debug)]
63pub enum MouseButton {
64 Left,
65 Right,
66 Middle,
67 Navigate(NavigationDirection),
68}
69
70impl MouseButton {
71 pub fn all() -> Vec<Self> {
72 vec![
73 MouseButton::Left,
74 MouseButton::Right,
75 MouseButton::Middle,
76 MouseButton::Navigate(NavigationDirection::Back),
77 MouseButton::Navigate(NavigationDirection::Forward),
78 ]
79 }
80}
81
82impl Default for MouseButton {
83 fn default() -> Self {
84 Self::Left
85 }
86}
87
88#[derive(Hash, PartialEq, Eq, Copy, Clone, Debug)]
89pub enum NavigationDirection {
90 Back,
91 Forward,
92}
93
94impl Default for NavigationDirection {
95 fn default() -> Self {
96 Self::Back
97 }
98}
99
100#[derive(Clone, Debug, Default)]
101pub struct MouseMoveEvent {
102 pub position: Point<Pixels>,
103 pub pressed_button: Option<MouseButton>,
104 pub modifiers: Modifiers,
105}
106
107#[derive(Clone, Debug)]
108pub struct ScrollWheelEvent {
109 pub position: Point<Pixels>,
110 pub delta: ScrollDelta,
111 pub modifiers: Modifiers,
112 pub touch_phase: TouchPhase,
113}
114
115impl Deref for ScrollWheelEvent {
116 type Target = Modifiers;
117
118 fn deref(&self) -> &Self::Target {
119 &self.modifiers
120 }
121}
122
123#[derive(Clone, Copy, Debug)]
124pub enum ScrollDelta {
125 Pixels(Point<Pixels>),
126 Lines(Point<f32>),
127}
128
129impl Default for ScrollDelta {
130 fn default() -> Self {
131 Self::Lines(Default::default())
132 }
133}
134
135impl ScrollDelta {
136 pub fn precise(&self) -> bool {
137 match self {
138 ScrollDelta::Pixels(_) => true,
139 ScrollDelta::Lines(_) => false,
140 }
141 }
142
143 pub fn pixel_delta(&self, line_height: Pixels) -> Point<Pixels> {
144 match self {
145 ScrollDelta::Pixels(delta) => *delta,
146 ScrollDelta::Lines(delta) => point(line_height * delta.x, line_height * delta.y),
147 }
148 }
149}
150
151#[derive(Clone, Debug, Default)]
152pub struct MouseExitEvent {
153 pub position: Point<Pixels>,
154 pub pressed_button: Option<MouseButton>,
155 pub modifiers: Modifiers,
156}
157
158impl Deref for MouseExitEvent {
159 type Target = Modifiers;
160
161 fn deref(&self) -> &Self::Target {
162 &self.modifiers
163 }
164}
165
166#[derive(Clone, Debug)]
167pub enum InputEvent {
168 KeyDown(KeyDownEvent),
169 KeyUp(KeyUpEvent),
170 ModifiersChanged(ModifiersChangedEvent),
171 MouseDown(MouseDownEvent),
172 MouseUp(MouseUpEvent),
173 MouseMoved(MouseMoveEvent),
174 MouseExited(MouseExitEvent),
175 ScrollWheel(ScrollWheelEvent),
176}
177
178impl InputEvent {
179 pub fn position(&self) -> Option<Point<Pixels>> {
180 match self {
181 InputEvent::KeyDown { .. } => None,
182 InputEvent::KeyUp { .. } => None,
183 InputEvent::ModifiersChanged { .. } => None,
184 InputEvent::MouseDown(event) => Some(event.position),
185 InputEvent::MouseUp(event) => Some(event.position),
186 InputEvent::MouseMoved(event) => Some(event.position),
187 InputEvent::MouseExited(event) => Some(event.position),
188 InputEvent::ScrollWheel(event) => Some(event.position),
189 }
190 }
191
192 pub fn mouse_event<'a>(&'a self) -> Option<&'a dyn Any> {
193 match self {
194 InputEvent::KeyDown { .. } => None,
195 InputEvent::KeyUp { .. } => None,
196 InputEvent::ModifiersChanged { .. } => None,
197 InputEvent::MouseDown(event) => Some(event),
198 InputEvent::MouseUp(event) => Some(event),
199 InputEvent::MouseMoved(event) => Some(event),
200 InputEvent::MouseExited(event) => Some(event),
201 InputEvent::ScrollWheel(event) => Some(event),
202 }
203 }
204
205 pub fn keyboard_event<'a>(&'a self) -> Option<&'a dyn Any> {
206 match self {
207 InputEvent::KeyDown(event) => Some(event),
208 InputEvent::KeyUp(event) => Some(event),
209 InputEvent::ModifiersChanged(event) => Some(event),
210 InputEvent::MouseDown(_) => None,
211 InputEvent::MouseUp(_) => None,
212 InputEvent::MouseMoved(_) => None,
213 InputEvent::MouseExited(_) => None,
214 InputEvent::ScrollWheel(_) => None,
215 }
216 }
217}
218
219pub struct FocusEvent {
220 pub blurred: Option<FocusHandle>,
221 pub focused: Option<FocusHandle>,
222}
223
224pub type MouseDownListener<V> = Box<
225 dyn Fn(&mut V, &MouseDownEvent, &Bounds<Pixels>, DispatchPhase, &mut ViewContext<V>)
226 + Send
227 + Sync
228 + 'static,
229>;
230pub type MouseUpListener<V> = Box<
231 dyn Fn(&mut V, &MouseUpEvent, &Bounds<Pixels>, DispatchPhase, &mut ViewContext<V>)
232 + Send
233 + Sync
234 + 'static,
235>;
236pub type MouseClickListener<V> =
237 Box<dyn Fn(&mut V, &MouseClickEvent, &mut ViewContext<V>) + Send + Sync + 'static>;
238
239pub type MouseMoveListener<V> = Box<
240 dyn Fn(&mut V, &MouseMoveEvent, &Bounds<Pixels>, DispatchPhase, &mut ViewContext<V>)
241 + Send
242 + Sync
243 + 'static,
244>;
245
246pub type ScrollWheelListener<V> = Box<
247 dyn Fn(&mut V, &ScrollWheelEvent, &Bounds<Pixels>, DispatchPhase, &mut ViewContext<V>)
248 + Send
249 + Sync
250 + 'static,
251>;
252
253pub type KeyDownListener<V> =
254 Box<dyn Fn(&mut V, &KeyDownEvent, DispatchPhase, &mut ViewContext<V>) + Send + Sync + 'static>;
255
256pub type KeyUpListener<V> =
257 Box<dyn Fn(&mut V, &KeyUpEvent, DispatchPhase, &mut ViewContext<V>) + Send + Sync + 'static>;
258
259pub type FocusListener<V> =
260 Box<dyn Fn(&mut V, &FocusEvent, &mut ViewContext<V>) + Send + Sync + 'static>;
261
262pub struct EventListeners<V: 'static> {
263 pub mouse_down: SmallVec<[MouseDownListener<V>; 2]>,
264 pub mouse_up: SmallVec<[MouseUpListener<V>; 2]>,
265 pub mouse_click: SmallVec<[MouseClickListener<V>; 2]>,
266 pub mouse_move: SmallVec<[MouseMoveListener<V>; 2]>,
267 pub scroll_wheel: SmallVec<[ScrollWheelListener<V>; 2]>,
268 pub key_down: SmallVec<[KeyDownListener<V>; 2]>,
269 pub key_up: SmallVec<[KeyUpListener<V>; 2]>,
270 pub focus: SmallVec<[FocusListener<V>; 2]>,
271}
272
273impl<V> Default for EventListeners<V> {
274 fn default() -> Self {
275 Self {
276 mouse_down: SmallVec::new(),
277 mouse_up: SmallVec::new(),
278 mouse_click: SmallVec::new(),
279 mouse_move: SmallVec::new(),
280 scroll_wheel: SmallVec::new(),
281 key_down: SmallVec::new(),
282 key_up: SmallVec::new(),
283 focus: SmallVec::new(),
284 }
285 }
286}