Skip to main content

compose_rust/
input.rs

1//! What an event hands its handler, for the events whose payload is more than a value.
2//!
3//! These are the Host's types rather than an authoring layer's, because what they hold is
4//! decided by the wire: a key press and whether it was consumed, the paths a drop
5//! carried, the range a list asked for. Every runtime hands the same ones over.
6
7use crate::Key;
8use std::cell::Cell;
9use std::rc::Rc;
10
11/// A key-down event whose consumption state is shared with the Host boundary.
12#[derive(Clone, Debug)]
13pub struct KeyEvent {
14    key: Key,
15    shift_key: bool,
16    ctrl_key: bool,
17    alt_key: bool,
18    meta_key: bool,
19    repeat: bool,
20    code: u32,
21    text: String,
22    consumed: Rc<Cell<bool>>,
23}
24
25impl KeyEvent {
26    pub fn new(key: Key, shift_key: bool, ctrl_key: bool, alt_key: bool, meta_key: bool) -> Self {
27        Self {
28            key,
29            shift_key,
30            ctrl_key,
31            alt_key,
32            meta_key,
33            repeat: false,
34            code: 0,
35            text: String::new(),
36            consumed: Rc::new(Cell::new(false)),
37        }
38    }
39
40    /// Adds what the wire carries beyond the modifiers: whether a held key is repeating,
41    /// the physical key as a USB HID usage value, and the DOM `key` string.
42    pub fn with_details(mut self, repeat: bool, code: u32, text: &str) -> Self {
43        self.repeat = repeat;
44        self.code = code;
45        self.text = text.to_owned();
46        self
47    }
48
49    /// True when the event comes from a held key repeating.
50    pub fn repeat(&self) -> bool {
51        self.repeat
52    }
53
54    /// The physical key as a USB HID usage value, the same on every layout.
55    pub fn code(&self) -> u32 {
56        self.code
57    }
58
59    /// The DOM `key` string, such as `"ArrowDown"` or `"a"`.
60    pub fn text(&self) -> &str {
61        &self.text
62    }
63
64    pub fn key(&self) -> Key {
65        self.key
66    }
67
68    pub fn shift_key(&self) -> bool {
69        self.shift_key
70    }
71
72    pub fn ctrl_key(&self) -> bool {
73        self.ctrl_key
74    }
75
76    pub fn alt_key(&self) -> bool {
77        self.alt_key
78    }
79
80    pub fn meta_key(&self) -> bool {
81        self.meta_key
82    }
83
84    pub fn consume(&self) {
85        self.consumed.set(true);
86    }
87
88    pub fn consumed(&self) -> bool {
89        self.consumed.get()
90    }
91}
92
93/// The paths of the files a reader let go over a node.
94///
95/// Separated on the wire by a NUL, which is the one byte no path on any of the three
96/// desktops may contain. A newline would have been shorter to read and wrong: a file
97/// called "notes\nfor tuesday" is legal on two of them, and splitting on newlines would
98/// have turned one file into two.
99#[derive(Clone, Debug, PartialEq)]
100pub struct FileDrop {
101    paths: Vec<String>,
102}
103
104impl FileDrop {
105    /// Takes apart the one string the paths travelled in.
106    ///
107    /// Public because the separation is part of what this type promises, and a test that
108    /// could not build one could only check it through a window.
109    pub fn new(joined: &str) -> Self {
110        Self {
111            paths: joined
112                .split('\0')
113                .filter(|path| !path.is_empty())
114                .map(str::to_owned)
115                .collect(),
116        }
117    }
118
119    /// Every path that arrived, in the order the platform gave them.
120    pub fn paths(&self) -> &[String] {
121        &self.paths
122    }
123}
124
125/// A node's size motion came to rest: the size it settled at, in dp.
126///
127/// Delivered once for each change of size that runs to its end, after the last frame of
128/// the run, so a screen can wait for a collapse to finish before it takes the child out.
129/// A run that a newer target interrupts is not reported; the one that settles is. Under
130/// reduced motion the size changes in one frame and this arrives in that frame.
131#[derive(Clone, Copy, Debug, PartialEq)]
132pub struct MotionFinished {
133    pub width_dp: f32,
134    pub height_dp: f32,
135}
136
137/// The visible item range the Renderer asks the Host to materialise.
138#[derive(Clone, Copy, Debug, Eq, PartialEq)]
139pub struct RangeRequest {
140    start: u32,
141    count: u32,
142}
143
144impl RangeRequest {
145    pub fn new(start: u32, count: u32) -> Self {
146        Self { start, count }
147    }
148
149    pub fn start(&self) -> usize {
150        self.start as usize
151    }
152
153    pub fn count(&self) -> usize {
154        self.count as usize
155    }
156}
157
158/// Which kinds of pointer event a node subscribes to, as the bit mask the wire carries.
159///
160/// The bit of a kind is `1 << (tag - 1)`, so `Move` is 1 and `ContextMenu` is 128. A mask
161/// of zero subscribes to nothing, and a node with no subscription gets no pointer input
162/// at all, which is what keeps a screen of plain containers free of it.
163#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
164pub struct PointerKinds(pub u32);
165
166impl PointerKinds {
167    pub const NONE: Self = Self(0);
168    pub const MOVE: Self = Self::of(crate::schema::PointerKind::Move);
169    pub const ENTER: Self = Self::of(crate::schema::PointerKind::Enter);
170    pub const LEAVE: Self = Self::of(crate::schema::PointerKind::Leave);
171    pub const DOWN: Self = Self::of(crate::schema::PointerKind::Down);
172    pub const UP: Self = Self::of(crate::schema::PointerKind::Up);
173    pub const CANCEL: Self = Self::of(crate::schema::PointerKind::Cancel);
174    pub const WHEEL: Self = Self::of(crate::schema::PointerKind::Wheel);
175    pub const CONTEXT_MENU: Self = Self::of(crate::schema::PointerKind::ContextMenu);
176    /// Every kind.
177    pub const ALL: Self = Self(0xff);
178
179    /// The mask holding one kind.
180    pub const fn of(kind: crate::schema::PointerKind) -> Self {
181        Self(1 << (kind as u32 - 1))
182    }
183
184    /// This mask and `other` together.
185    pub const fn union(self, other: Self) -> Self {
186        Self(self.0 | other.0)
187    }
188
189    /// Whether `kind` is in the mask.
190    pub const fn contains(self, kind: crate::schema::PointerKind) -> bool {
191        self.0 & Self::of(kind).0 != 0
192    }
193
194    pub const fn bits(self) -> u32 {
195        self.0
196    }
197}
198
199impl std::ops::BitOr for PointerKinds {
200    type Output = Self;
201
202    fn bitor(self, other: Self) -> Self {
203        self.union(other)
204    }
205}
206
207/// The bit of each mouse button in `buttons` and `button`: the same numbers as the DOM's
208/// `buttons` and Compose's `PointerButtons`.
209pub mod pointer_button {
210    pub const PRIMARY: u32 = 1;
211    pub const SECONDARY: u32 = 2;
212    pub const TERTIARY: u32 = 4;
213    pub const BACK: u32 = 8;
214    pub const FORWARD: u32 = 16;
215}
216
217/// One pointer event handed to a handler, with its consumption state shared with the
218/// Host boundary like [`KeyEvent`]'s.
219///
220/// Calling [`PointerEvent::consume`] keeps the event from reaching an ancestor's handler
221/// and from doing what the Renderer would otherwise do with it: a consumed `Wheel` does not
222/// scroll, a consumed `ContextMenu` shows no menu.
223#[derive(Clone, Debug)]
224pub struct PointerEvent {
225    kind: crate::schema::PointerKind,
226    pointer_id: u32,
227    pointer_type: crate::schema::PointerType,
228    x: f32,
229    y: f32,
230    buttons: u32,
231    button: u32,
232    modifiers: u32,
233    click_count: u32,
234    delta_x: f32,
235    delta_y: f32,
236    delta_mode: crate::schema::WheelDeltaMode,
237    timestamp_nanos: u64,
238    consumed: Rc<Cell<bool>>,
239}
240
241impl PointerEvent {
242    #[allow(clippy::too_many_arguments)]
243    pub fn new(
244        kind: crate::schema::PointerKind,
245        pointer_id: u32,
246        pointer_type: crate::schema::PointerType,
247        x: f32,
248        y: f32,
249        buttons: u32,
250        button: u32,
251        modifiers: u32,
252        click_count: u32,
253        delta_x: f32,
254        delta_y: f32,
255        delta_mode: crate::schema::WheelDeltaMode,
256        timestamp_nanos: u64,
257    ) -> Self {
258        Self {
259            kind,
260            pointer_id,
261            pointer_type,
262            x,
263            y,
264            buttons,
265            button,
266            modifiers,
267            click_count,
268            delta_x,
269            delta_y,
270            delta_mode,
271            timestamp_nanos,
272            consumed: Rc::new(Cell::new(false)),
273        }
274    }
275
276    pub fn kind(&self) -> crate::schema::PointerKind {
277        self.kind
278    }
279
280    /// Names one finger, pen or mouse across its events. A mouse is 1.
281    pub fn pointer_id(&self) -> u32 {
282        self.pointer_id
283    }
284
285    pub fn pointer_type(&self) -> crate::schema::PointerType {
286        self.pointer_type
287    }
288
289    /// Distance from the node's left edge, in dp. Outside the node while it holds a capture.
290    pub fn x(&self) -> f32 {
291        self.x
292    }
293
294    /// Distance from the node's top edge, in dp.
295    pub fn y(&self) -> f32 {
296        self.y
297    }
298
299    /// The buttons held now, as a mask of [`pointer_button`] bits.
300    pub fn buttons(&self) -> u32 {
301        self.buttons
302    }
303
304    /// The button that caused this `Down` or `Up`, and 0 for any other kind.
305    pub fn button(&self) -> u32 {
306        self.button
307    }
308
309    pub fn shift_key(&self) -> bool {
310        self.modifiers & 1 != 0
311    }
312
313    pub fn ctrl_key(&self) -> bool {
314        self.modifiers & 2 != 0
315    }
316
317    pub fn alt_key(&self) -> bool {
318        self.modifiers & 4 != 0
319    }
320
321    pub fn meta_key(&self) -> bool {
322        self.modifiers & 8 != 0
323    }
324
325    /// Consecutive presses in the same place on a `Down` or `Up`: 1, 2, and so on.
326    pub fn click_count(&self) -> u32 {
327        self.click_count
328    }
329
330    /// Wheel travel, positive to the right. Zero for any other kind.
331    pub fn delta_x(&self) -> f32 {
332        self.delta_x
333    }
334
335    /// Wheel travel, positive downward.
336    pub fn delta_y(&self) -> f32 {
337        self.delta_y
338    }
339
340    pub fn delta_mode(&self) -> crate::schema::WheelDeltaMode {
341        self.delta_mode
342    }
343
344    /// When the OS produced the input, on the monotonic clock `render_frame` also uses.
345    pub fn timestamp_nanos(&self) -> u64 {
346        self.timestamp_nanos
347    }
348
349    pub fn consume(&self) {
350        self.consumed.set(true);
351    }
352
353    pub fn consumed(&self) -> bool {
354        self.consumed.get()
355    }
356}