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