events.rs

  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}