pax_runtime_api/events.rs
1//! Event payloads and cancellation wrappers passed to Pax event handlers.
2
3use super::*;
4
5// Unified events
6
7/// Event wrapper passed to Pax event handlers.
8///
9/// `Event<T>` carries the typed event payload and shared cancellation state,
10/// allowing handlers to call `prevent_default` where the active chassis supports it.
11#[derive(Clone)]
12pub struct Event<T> {
13 /// The event-specific payload, for example `Click` or `KeyDown`.
14 pub args: T,
15 // Shared cancellation state, so cloned event wrappers preserve `prevent_default`.
16 cancelled: Rc<Cell<bool>>,
17}
18
19impl<T: Clone + 'static> ImplToFromPaxAny for Event<T> {}
20
21impl<T> Event<T> {
22 /// Constructs an event wrapper around a raw payload.
23 pub fn new(args: T) -> Self {
24 Self {
25 args,
26 cancelled: Default::default(),
27 }
28 }
29
30 /// Cancels the platform default for this event, when the chassis supports cancellation.
31 pub fn prevent_default(&self) {
32 self.cancelled.set(true);
33 }
34
35 // Whether `prevent_default` has been called.
36 pub fn cancelled(&self) -> bool {
37 self.cancelled.get()
38 }
39}
40
41impl<T> Deref for Event<T> {
42 type Target = T;
43
44 fn deref(&self) -> &Self::Target {
45 &self.args
46 }
47}
48
49/// Scroll is the shared delta-based path for wheel scrolling, touch swipe gestures, and
50/// read-only native scroller position changes.
51/// Use `Wheel` or `TouchMove` when you need platform-specific details instead of the normalized
52/// delta stream.
53#[derive(Clone)]
54pub struct Scroll {
55 /// Horizontal scroll delta.
56 pub delta_x: f64,
57 /// Vertical scroll delta.
58 pub delta_y: f64,
59}
60
61// Touch Events
62
63/// Represents a single touch event.
64#[derive(Clone)]
65pub struct Touch {
66 /// The window-space x-coordinate of this touch point.
67 /// Use `NodeContext::local_point` to convert it into coordinates relative to a handler's node.
68 pub x: f64,
69 /// The window-space y-coordinate of this touch point.
70 /// Use `NodeContext::local_point` to convert it into coordinates relative to a handler's node.
71 pub y: f64,
72 /// Stable identifier for this touch across a touch sequence.
73 pub identifier: i64,
74 /// Horizontal delta since the previous touch update.
75 pub delta_x: f64,
76 /// Vertical delta since the previous touch update.
77 pub delta_y: f64,
78}
79
80impl From<&TouchMessage> for Touch {
81 fn from(value: &TouchMessage) -> Self {
82 Touch {
83 x: value.x,
84 y: value.y,
85 identifier: value.identifier,
86 delta_x: value.delta_x,
87 delta_y: value.delta_y,
88 }
89 }
90}
91
92/// A TouchStart occurs when the user touches an element.
93/// The contained `touches` represent a list of touch points. The hit node is captured for the
94/// touch identifier so subsequent move and end events keep routing to the same subtree.
95#[derive(Clone)]
96pub struct TouchStart {
97 /// Active touch points at the start of this touch sequence.
98 pub touches: Vec<Touch>,
99}
100
101/// A TouchMove occurs when the user moves while touching an element.
102/// The contained `touches` represent a list of touch points and the event targets the node captured
103/// at touch start, even when the point has moved outside its bounds.
104#[derive(Clone)]
105pub struct TouchMove {
106 /// Active touch points after this touch movement.
107 pub touches: Vec<Touch>,
108}
109
110/// A TouchEnd occurs when the user stops touching an element.
111/// The contained `touches` represent a list of touch points and the event targets, then releases,
112/// the node captured at touch start.
113#[derive(Clone)]
114pub struct TouchEnd {
115 /// Touch points that ended.
116 pub touches: Vec<Touch>,
117}
118
119/// A TouchCancel occurs when the platform aborts an active touch sequence before normal release,
120/// such as during a system interruption or host-level gesture cancellation.
121///
122/// The contained `touches` represent the cancelled touch points and the event targets, then
123/// releases, the node captured at touch start. Cancelled touches must not produce activation.
124/// A native Scroller that can observe its pan simultaneously with child touches keeps delivering
125/// move events and finishes the child sequence with `TouchEnd`; winning scroll arbitration alone
126/// does not cancel the touch.
127#[derive(Clone)]
128pub struct TouchCancel {
129 /// Touch points whose active sequence was cancelled.
130 pub touches: Vec<Touch>,
131}
132
133// Keyboard Events
134
135/// Common properties in keyboard events.
136#[derive(Clone)]
137pub struct KeyboardEventArgs {
138 /// Platform-normalized key string.
139 pub key: String,
140 /// Modifier keys active during the event.
141 pub modifiers: Vec<ModifierKey>,
142 /// Whether this event was generated by key-repeat.
143 pub is_repeat: bool,
144}
145
146/// User is pressing a key.
147#[derive(Clone)]
148pub struct KeyDown {
149 /// Common keyboard event data.
150 pub keyboard: KeyboardEventArgs,
151}
152
153/// A native text selection is beginning.
154#[derive(Clone)]
155pub struct SelectStart {}
156
157/// User has released a key.
158#[derive(Clone)]
159pub struct KeyUp {
160 /// Common keyboard event data.
161 pub keyboard: KeyboardEventArgs,
162}
163
164/// User presses a key that displays a character (alphanumeric or symbol).
165#[derive(Clone)]
166pub struct KeyPress {
167 /// Common keyboard event data.
168 pub keyboard: KeyboardEventArgs,
169}
170
171/// Window or component focused.
172#[derive(Clone)]
173pub struct Focus {}
174
175// Mouse Events
176
177/// Common properties in mouse-backed events and normalized activation events.
178#[derive(Clone)]
179pub struct MouseEventArgs {
180 /// The window-space x-coordinate of the event.
181 /// Use `NodeContext::local_point` to convert it into coordinates relative to a handler's node.
182 pub x: f64,
183 /// The window-space y-coordinate of the event.
184 /// Use `NodeContext::local_point` to convert it into coordinates relative to a handler's node.
185 pub y: f64,
186 /// Mouse button associated with the event.
187 pub button: MouseButton,
188 /// Modifier keys active during the event.
189 pub modifiers: Vec<ModifierKey>,
190}
191
192/// The variants of mouse buttons available on mouse-supporting platforms.
193#[derive(Clone, PartialEq)]
194pub enum MouseButton {
195 /// Primary mouse button.
196 Left,
197 /// Secondary mouse button.
198 Right,
199 /// Middle mouse button.
200 Middle,
201 /// Button not identified by the chassis.
202 Unknown,
203}
204
205impl From<MouseButtonMessage> for MouseButton {
206 fn from(value: MouseButtonMessage) -> Self {
207 match value {
208 MouseButtonMessage::Left => MouseButton::Left,
209 MouseButtonMessage::Right => MouseButton::Right,
210 MouseButtonMessage::Middle => MouseButton::Middle,
211 MouseButtonMessage::Unknown => MouseButton::Unknown,
212 }
213 }
214}
215
216/// The variants of modifier keys available on keyboard-supporting platforms.
217#[derive(Clone)]
218pub enum ModifierKey {
219 /// Shift key.
220 Shift,
221 /// Control key.
222 Control,
223 /// Alt or Option key.
224 Alt,
225 /// Command, Meta, or Windows key.
226 Command,
227}
228
229impl From<&ModifierKeyMessage> for ModifierKey {
230 fn from(value: &ModifierKeyMessage) -> Self {
231 match value {
232 ModifierKeyMessage::Shift => ModifierKey::Shift,
233 ModifierKeyMessage::Control => ModifierKey::Control,
234 ModifierKeyMessage::Alt => ModifierKey::Alt,
235 ModifierKeyMessage::Command => ModifierKey::Command,
236 }
237 }
238}
239
240/// User activates an element with a mouse click or single-touch tap.
241///
242/// `@click` and `@tap` handlers both receive `Event<Click>`. A touch tap is
243/// emitted after touch end and normalized with `button` set to
244/// `MouseButton::Left` and no modifiers.
245#[derive(Clone)]
246pub struct Click {
247 /// Common mouse event data.
248 pub mouse: MouseEventArgs,
249}
250
251/// User drops a file-like payload over an element.
252#[derive(Clone)]
253pub struct Drop {
254 /// The x-coordinate of the drop in the receiving node's local coordinate space.
255 pub x: f64,
256 /// The y-coordinate of the drop in the receiving node's local coordinate space.
257 pub y: f64,
258 /// File or payload name supplied by the platform.
259 pub name: String,
260 /// MIME type supplied by the platform.
261 pub mime_type: String,
262 /// Raw dropped payload bytes.
263 pub data: Vec<u8>,
264}
265
266/// User double-clicks a mouse button over an element.
267#[derive(Clone)]
268pub struct DoubleClick {
269 /// Common mouse event data.
270 pub mouse: MouseEventArgs,
271}
272
273/// User moves the mouse while it is over an element.
274#[derive(Clone)]
275pub struct MouseMove {
276 /// Common mouse event data.
277 pub mouse: MouseEventArgs,
278}
279
280/// User scrolls the mouse wheel over an element.
281#[derive(Clone)]
282pub struct Wheel {
283 /// The x-coordinate of the wheel event in the receiving node's local coordinate space.
284 pub x: f64,
285 /// The y-coordinate of the wheel event in the receiving node's local coordinate space.
286 pub y: f64,
287 /// Horizontal wheel delta.
288 pub delta_x: f64,
289 /// Vertical wheel delta.
290 pub delta_y: f64,
291 /// Modifier keys active during the event.
292 pub modifiers: Vec<ModifierKey>,
293}
294
295/// User checks or unchecks a checkbox.
296#[derive(Clone)]
297pub struct CheckboxChange {
298 /// The new checked state.
299 pub checked: bool,
300}
301
302/// User changes a slider's value.
303#[derive(Clone)]
304pub struct SliderChange {
305 /// The new slider value.
306 pub value: f64,
307}
308
309/// User types into a text input field.
310#[derive(Clone)]
311pub struct TextInput {
312 /// Text committed by the input event.
313 pub text: String,
314}
315
316/// User changes the text in a text input field.
317#[derive(Clone)]
318pub struct TextboxChange {
319 /// Current text after the change.
320 pub text: String,
321}
322
323/// Text input reported while the user edits a textbox.
324///
325/// On web, this follows the DOM `input` event. `TextboxChange` follows the
326/// DOM `change` event instead; commit timing depends on the platform control.
327#[derive(Clone)]
328pub struct TextboxInput {
329 /// Current text reported by the input event.
330 pub text: String,
331}
332
333/// User activates a native button by click or tap.
334#[derive(Clone)]
335pub struct ButtonClick {}
336
337/// Completion status for a native photo picker request.
338#[derive(Clone, PartialEq)]
339pub enum PhotoPickerStatus {
340 /// One or more photos were selected.
341 Selected,
342 /// The platform picker was dismissed without a selection.
343 Cancelled,
344 /// Camera or picker permission was denied or restricted.
345 PermissionDenied,
346 /// The requested source is not available on this platform/device.
347 Unavailable,
348 /// One or more candidate photos exceeded the configured byte limit.
349 SizeLimitExceeded,
350 /// The platform picker failed for another reason.
351 Failed,
352}
353
354impl From<&str> for PhotoPickerStatus {
355 fn from(value: &str) -> Self {
356 match value {
357 "selected" => Self::Selected,
358 "cancelled" => Self::Cancelled,
359 "permission_denied" => Self::PermissionDenied,
360 "unavailable" => Self::Unavailable,
361 "size_limit_exceeded" => Self::SizeLimitExceeded,
362 _ => Self::Failed,
363 }
364 }
365}
366
367/// Platform source used to produce a selected photo.
368#[derive(Clone, PartialEq)]
369pub enum PhotoPickerSourceKind {
370 /// Existing image from a photo library.
371 Library,
372 /// Existing image from the filesystem.
373 File,
374 /// Newly captured camera image.
375 Camera,
376 /// Source not recognized by this runtime version.
377 Other(String),
378}
379
380impl From<&str> for PhotoPickerSourceKind {
381 fn from(value: &str) -> Self {
382 match value {
383 "library" => Self::Library,
384 "file" => Self::File,
385 "camera" => Self::Camera,
386 other => Self::Other(other.to_string()),
387 }
388 }
389}
390
391/// One selected image returned by a native photo picker.
392#[derive(Clone)]
393pub struct PhotoPickerPhoto {
394 /// Stable temporary identifier for this selection.
395 pub temp_id: String,
396 /// File name supplied by the platform, when available.
397 pub file_name: Option<String>,
398 /// MIME type supplied or inferred by the platform.
399 pub mime_type: String,
400 /// Byte size of the selected asset.
401 pub byte_size: u64,
402 /// Image width in pixels, when available.
403 pub width: Option<u32>,
404 /// Image height in pixels, when available.
405 pub height: Option<u32>,
406 /// Source used for this image.
407 pub source_kind: PhotoPickerSourceKind,
408 /// Platform preview/read handle, such as an object URL or file URL.
409 pub handle: Option<String>,
410 /// Copied asset bytes when the chassis can provide them within configured limits.
411 pub data: Option<Vec<u8>>,
412}
413
414impl From<&PhotoPickerAssetArgs> for PhotoPickerPhoto {
415 fn from(value: &PhotoPickerAssetArgs) -> Self {
416 Self {
417 temp_id: value.temp_id.clone(),
418 file_name: value.file_name.clone(),
419 mime_type: value.mime_type.clone(),
420 byte_size: value.byte_size,
421 width: value.width,
422 height: value.height,
423 source_kind: PhotoPickerSourceKind::from(value.source_kind.as_str()),
424 handle: value.handle.clone(),
425 data: if value.data.is_empty() {
426 None
427 } else {
428 Some(value.data.clone())
429 },
430 }
431 }
432}
433
434/// Native photo picker completion event.
435#[derive(Clone)]
436pub struct PhotoPickerChange {
437 /// Picker node id that produced the result.
438 pub id: u32,
439 /// App-controlled request id, usually copied from the picker trigger value.
440 pub request_id: u64,
441 /// Completion status.
442 pub status: PhotoPickerStatus,
443 /// Human-readable platform message for errors or partial results.
444 pub message: Option<String>,
445 /// Selected photos, empty for cancellation, permission denial, or unavailable sources.
446 pub photos: Vec<PhotoPickerPhoto>,
447}
448
449impl From<&PhotoPickerInterruptArgs> for PhotoPickerChange {
450 fn from(value: &PhotoPickerInterruptArgs) -> Self {
451 Self {
452 id: value.id,
453 request_id: value.request_id,
454 status: PhotoPickerStatus::from(value.status.as_str()),
455 message: value.message.clone(),
456 photos: value.photos.iter().map(PhotoPickerPhoto::from).collect(),
457 }
458 }
459}
460
461/// User presses a mouse button over an element.
462#[derive(Clone)]
463pub struct MouseDown {
464 /// Common mouse event data.
465 pub mouse: MouseEventArgs,
466}
467
468/// User releases a mouse button over an element.
469#[derive(Clone)]
470pub struct MouseUp {
471 /// Common mouse event data.
472 pub mouse: MouseEventArgs,
473}
474
475/// User moves the mouse onto an element.
476#[derive(Clone)]
477pub struct MouseOver {}
478
479/// User moves the mouse away from an element.
480#[derive(Clone)]
481pub struct MouseOut {}
482
483/// User right-clicks an element to open the context menu.
484#[derive(Clone)]
485pub struct ContextMenu {
486 /// Common mouse event data.
487 pub mouse: MouseEventArgs,
488}