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}