Skip to main content

frust_core/event/
pointer.rs

1//! Pointer, cursor, scroll and scale vocabulary: what a hit-tested event carries.
2
3use kurbo::Point;
4
5/// Which button a pointer event carries; touch and pen contacts report `Primary`.
6#[derive(Clone, Copy, Debug, PartialEq, Eq)]
7pub enum PointerButton {
8    Primary,
9    Secondary,
10    Middle,
11}
12
13/// A gesture's phase: `Down`, zero or more `Move`s, then `Up` or `Cancel` (the platform stole
14/// the gesture). Both terminal phases release capture.
15#[derive(Clone, Copy, Debug, PartialEq, Eq)]
16pub enum PointerPhase {
17    Down,
18    Move,
19    Up,
20    Cancel,
21}
22
23/// One pointer event: three fields — phase, position, button — and no pointer-kind axis.
24/// `position` is logical pixels in the receiving widget's local space.
25#[derive(Clone, Copy, Debug, PartialEq)]
26pub struct PointerEvent {
27    pub phase: PointerPhase,
28    pub position: Point,
29    pub button: PointerButton,
30}
31
32/// The kind of device a pointer contact comes from — one half of a [`PointerId`].
33#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
34pub enum PointerSource {
35    Mouse,
36    Touch,
37}
38
39/// A contact's identity: its source plus the shell's slot (`0` is the gesture's first contact;
40/// the mouse only has `0`). It rides beside a [`PointerEvent`], never inside it; see
41/// [`InputEvent::PointerContact`](crate::event::InputEvent::PointerContact) for the contract.
42#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
43pub struct PointerId {
44    pub source: PointerSource,
45    pub slot: u32,
46}
47
48impl PointerId {
49    /// The mouse: the identity a bare `InputEvent::Pointer` carries.
50    pub const MOUSE: PointerId = PointerId {
51        source: PointerSource::Mouse,
52        slot: 0,
53    };
54
55    /// The touch contact in `slot` (`0` for the gesture's first finger).
56    pub const fn touch(slot: u32) -> PointerId {
57        PointerId {
58            source: PointerSource::Touch,
59            slot,
60        }
61    }
62}
63
64/// The platform-neutral cursor a widget requests through `EventCtx::set_cursor`; only a desktop
65/// shell honours it. `#[non_exhaustive]`: an out-of-tree `match` degrades an unknown variant to
66/// [`CursorIcon::Default`].
67#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
68#[non_exhaustive]
69pub enum CursorIcon {
70    /// The host arrow; what a pass in which no widget asked resolves to.
71    #[default]
72    Default,
73    /// The clickable hand.
74    Pointer,
75    Text,
76    Grab,
77    Grabbing,
78    ColResize,
79    RowResize,
80    /// A refused action: a disabled control, or a drop target rejecting the drag.
81    NotAllowed,
82}
83
84/// A scroll amount `(x, y)`: `Lines` from a mouse wheel, `Pixels` (logical) from a precision
85/// trackpad or touch.
86#[derive(Clone, Copy, Debug, PartialEq)]
87pub enum ScrollDelta {
88    Lines(f64, f64),
89    Pixels(f64, f64),
90}
91
92/// A scale gesture's phase. No `Cancel`: every shipped source reports a clean bracket, or a lone
93/// `Update` for a notch wheel.
94#[derive(Clone, Copy, Debug, PartialEq, Eq)]
95pub enum ScalePhase {
96    Begin,
97    Update,
98    End,
99}
100
101/// A pinch/zoom event — [`InputEvent::Scroll`](crate::event::InputEvent::Scroll)'s hit-tested
102/// sibling, carrying a multiplicative delta and a focal point.
103#[derive(Clone, Copy, Debug, PartialEq)]
104pub struct ScaleEvent {
105    pub phase: ScalePhase,
106    /// This event's multiplicative change, not a running total: `1.0` is a no-op.
107    pub scale_delta: f64,
108    /// The fixed point of the zoom, in local logical space; translated like a pointer position.
109    pub focal: Point,
110    /// Rate of scale change per second; `0.0` from every shipped source, which reports none.
111    pub velocity: f64,
112}