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