events.rs

  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}