Skip to main content

repose_core/
input.rs

1use crate::Vec2;
2use std::cell::Cell;
3use std::rc::Rc;
4
5#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
6pub struct PointerId(pub u64);
7
8#[derive(Clone, Copy, Debug, PartialEq, Eq)]
9pub enum PointerKind {
10    Mouse,
11    Touch,
12    Pen,
13}
14
15#[derive(Clone, Copy, Debug)]
16pub enum PointerButton {
17    Primary,   // Left mouse, touch
18    Secondary, // Right mouse
19    Tertiary,  // Middle mouse
20}
21
22#[derive(Clone, Copy, Debug, PartialEq, Eq)]
23pub enum PointerEventPass {
24    /// Top-down pass: ancestor -> descendant. Allows ancestors to preview or
25    /// intercept events before descendants see them.
26    Initial,
27    /// Bottom-up pass: descendant -> ancestor. The primary pass where gesture
28    /// handlers react to and consume events. A child that consumes its event
29    /// prevents the parent from reacting (Compose's requireUnconsumed).
30    Main,
31    /// Top-down pass: ancestor -> descendant. Allows descendants to learn
32    /// about events consumed by ancestors during the Main pass.
33    Final,
34}
35
36#[derive(Clone, Copy, Debug)]
37pub enum PointerEventKind {
38    Down(PointerButton),
39    Up(PointerButton),
40    Move,
41    Cancel,
42    Enter,
43    Leave,
44}
45
46#[derive(Clone, Debug)]
47pub struct PointerEvent {
48    pub id: PointerId,
49    pub kind: PointerKind,
50    pub event: PointerEventKind,
51    /// Position relative to `origin` (hit-region top-left), in physical px.
52    pub position: Vec2,
53    /// Top-left of the hit region this event is being delivered to (physical px).
54    pub origin: Vec2,
55    pub pressure: f32,
56    pub modifiers: Modifiers,
57    /// Shared consumed state -> every clone of this event points to the same
58    /// Cell. Calling `consume()` on any clone marks it consumed for all clones.
59    pub consumed: Rc<Cell<bool>>,
60}
61
62impl PointerEvent {
63    pub fn new(
64        id: PointerId,
65        kind: PointerKind,
66        event: PointerEventKind,
67        position: Vec2,
68        pressure: f32,
69        modifiers: Modifiers,
70    ) -> Self {
71        Self {
72            id,
73            kind,
74            event,
75            position,
76            origin: Vec2::ZERO,
77            pressure,
78            modifiers,
79            consumed: Rc::new(Cell::new(false)),
80        }
81    }
82
83    /// Absolute position in window/surface physical pixels.
84    pub fn position_in_window(&self) -> Vec2 {
85        self.position + self.origin
86    }
87
88    /// Mark this event as consumed. Once consumed, subsequent handlers in the
89    /// same pass should skip processing it (equivalent to Compose's
90    /// `PointerInputChange.consume()`).
91    pub fn consume(&self) {
92        self.consumed.set(true);
93    }
94
95    /// Returns `true` if `consume()` was called on this event or any clone of it.
96    pub fn is_consumed(&self) -> bool {
97        self.consumed.get()
98    }
99}
100
101#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
102pub struct Modifiers {
103    pub shift: bool,
104    pub ctrl: bool,
105    pub alt: bool,
106    pub meta: bool,    // Cmd on Mac, Win key on Windows
107    pub command: bool, // egui like (Cmd on macOS, Ctrl elsewhere)
108}
109
110#[derive(Clone, Debug, PartialEq, Eq, Hash)]
111pub enum Key {
112    Character(char),
113    Enter,
114    Tab,
115    Backspace,
116    Delete,
117    Insert,
118    Escape,
119    ArrowLeft,
120    ArrowRight,
121    ArrowUp,
122    ArrowDown,
123    Home,
124    End,
125    PageUp,
126    PageDown,
127    Space,
128    F(u8), // F1-F12
129    Unknown,
130}
131
132#[derive(Clone, Copy, Debug, PartialEq, Eq)]
133pub enum KeyEventType {
134    /// Key pressed down.
135    Down,
136    /// Key released.
137    Up,
138    /// Unknown or unsupported event type.
139    Unknown,
140}
141
142#[derive(Clone, Debug)]
143pub struct KeyEvent {
144    pub key: Key,
145    pub modifiers: Modifiers,
146    pub is_repeat: bool,
147    /// Whether this is a key-down or key-up event.
148    pub event_type: KeyEventType,
149    /// UTF-16 code point for character keys, or 0 for non-characters.
150    /// Matches Compose's `utf16CodePoint`.
151    pub utf16_code_point: u16,
152}
153
154#[derive(Clone, Debug)]
155pub struct TextInputEvent {
156    pub text: String,
157}
158
159#[derive(Clone, Debug)]
160pub enum ImeEvent {
161    /// IME composition started
162    Start,
163    /// Composition text updated
164    Update {
165        text: String,
166        cursor: Option<(usize, usize)>, // (start, end) of composition range
167    },
168    /// Composition committed (finalized)
169    Commit(String),
170    /// Composition cancelled
171    Cancel,
172}
173
174#[derive(Clone, Debug)]
175pub enum InputEvent {
176    Pointer(PointerEvent),
177    Key(KeyEvent),
178    Text(TextInputEvent),
179    Ime(ImeEvent),
180}