events.rs

  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}