///|
/// Pointer interaction phase. `Move`/`Down`/`Up`/`Cancel` are produced by host
/// backends from raw input. `Exit` is a synthetic, runtime-only phase: the
/// runtime emits it to the previously hovered element when the pointer leaves
/// its bounds (host backends never produce it). Views use it to clear hover
/// state that they otherwise could not, because a normal `Move` outside the
/// element is never delivered to it by hit-testing.
#derive(Eq, Debug, ToJson)
pub(all) enum PointerPhase {
Move
Down
Up
Cancel
Exit
}
///|
pub extend PointerPhase with Debug::{to_repr}
///|
pub extend PointerPhase with Eq::{not_equal, equal}
///|
pub extend PointerPhase with ToJson::{to_json}
///|
/// `id` distinguishes simultaneous pointers. `0` is the primary stream: mouse,
/// pen, trackpad, and any host that does not report a finger identity. Secondary
/// fingers carry the host's own finger id, so a view can tell a two-finger
/// gesture apart from two independent one-finger drags.
///
/// `pressure` is normalized to `0.0..=1.0`. `1.0` means "the host gives no
/// pressure signal", which is the value for mouse and touchpad input on every
/// platform MoUI currently supports; views must treat it as a full press rather
/// than checking for `> 0.0`.
#derive(Eq, Debug, ToJson)
pub(all) struct PointerEvent {
position : Point
phase : PointerPhase
button : Int32
wheel_delta : Point
modifiers : KeyModifiers
id : Int32
pressure : Double
}
///|
pub extend PointerEvent with Debug::{to_repr}
///|
pub extend PointerEvent with Eq::{not_equal, equal}
///|
pub extend PointerEvent with ToJson::{to_json}
///|
#derive(Eq, Debug, ToJson)
pub(all) struct KeyModifiers {
shift : Bool
control : Bool
alt : Bool
meta : Bool
}
///|
pub extend KeyModifiers with Debug::{to_repr}
///|
pub extend KeyModifiers with Eq::{not_equal, equal}
///|
pub extend KeyModifiers with ToJson::{to_json}
///|
#derive(Eq, Debug, ToJson)
pub(all) struct KeyboardEvent {
key : String
text : String?
pressed : Bool
repeat : Bool
modifiers : KeyModifiers
}
///|
pub extend KeyboardEvent with Debug::{to_repr}
///|
pub extend KeyboardEvent with Eq::{not_equal, equal}
///|
pub extend KeyboardEvent with ToJson::{to_json}
///|
#derive(Eq, Debug, ToJson)
pub(all) struct TextRange {
start : Int32
end : Int32
}
///|
pub extend TextRange with Debug::{to_repr}
///|
pub extend TextRange with Eq::{not_equal, equal}
///|
pub extend TextRange with ToJson::{to_json}
///|
#derive(Eq, Debug, ToJson)
struct CompositionUpdate {
text : String
cursor : TextRange?
}
///|
pub extend CompositionUpdate with Debug::{to_repr}
///|
pub extend CompositionUpdate with Eq::{not_equal, equal}
///|
pub extend CompositionUpdate with ToJson::{to_json}
///|
#derive(Eq, Debug, ToJson)
pub(all) enum TextInputEvent {
InsertText(String)
ReplaceText(TextRange, String)
SetSelection(TextRange)
CompositionStart
CompositionUpdate(CompositionUpdate)
CompositionEnd(String)
DeleteRange(TextRange)
DeleteSurrounding(Int32, Int32)
}
///|
pub extend TextInputEvent with Debug::{to_repr}
///|
pub extend TextInputEvent with Eq::{not_equal, equal}
///|
pub extend TextInputEvent with ToJson::{to_json}
///|
#derive(Eq, Debug, ToJson)
pub(all) enum DragDropPhase {
Entered
Moved
Dropped
Left
}
///|
pub extend DragDropPhase with Debug::{to_repr}
///|
pub extend DragDropPhase with Eq::{not_equal, equal}
///|
pub extend DragDropPhase with ToJson::{to_json}
///|
#derive(Eq, Debug, ToJson)
pub(all) struct DragDropEvent {
phase : DragDropPhase
paths : Array[String]
position : Point?
}
///|
pub extend DragDropEvent with Debug::{to_repr}
///|
pub extend DragDropEvent with Eq::{not_equal, equal}
///|
pub extend DragDropEvent with ToJson::{to_json}
///|
#derive(Eq, Debug, ToJson)
pub(all) enum RedrawReason {
Initial
Input
Resize
Explicit
}
///|
pub extend RedrawReason with Debug::{to_repr}
///|
pub extend RedrawReason with Eq::{not_equal, equal}
///|
pub extend RedrawReason with ToJson::{to_json}
///|
#derive(Eq, Debug, ToJson)
pub(all) enum GestureKind {
Pinch
Rotate
Pan
DoubleTap
Pressure
}
///|
pub extend GestureKind with Debug::{to_repr}
///|
pub extend GestureKind with Eq::{not_equal, equal}
///|
pub extend GestureKind with ToJson::{to_json}
///|
/// OS-recognized gesture stream phase: trackpads and system recognizers
/// deliver `Started` / `Moved` / `Ended`; an instantaneous gesture such as a
/// double tap arrives as `Started` with no follow-up.
#derive(Eq, Debug, ToJson)
pub(all) enum GesturePhase {
Started
Moved
Ended
}
///|
pub extend GesturePhase with Debug::{to_repr}
///|
pub extend GesturePhase with Eq::{not_equal, equal}
///|
pub extend GesturePhase with ToJson::{to_json}
///|
/// One OS-recognized gesture sample (a trackpad pinch, rotation, pan,
/// double-tap, or pressure change). The host recognizer has already done the
/// multi-finger work, so the event carries per-sample deltas rather than a
/// touch stream; fields that do not belong to the kind stay at their zero
/// value instead of growing a variant per kind.
///
/// Gestures carry no position: the runtime targets the content under the last
/// known primary pointer, so a trackpad pinch zooms what the cursor is over.
#derive(Eq, Debug, ToJson)
pub(all) struct GestureEvent {
kind : GestureKind
phase : GesturePhase
/// `Pinch`: additive magnification fraction since the last sample
/// (0.05 = 5% zoom in, -0.05 = zoom out). Zero for every other kind.
scale_delta : Double
/// `Rotate`: radians since the last sample. Zero for every other kind.
rotation_delta : Double
/// `Pan`: translation in logical pixels since the last sample. Zero for
/// every other kind.
pan_delta : Point
/// `Pressure`: normalized force (0..1). Zero for every other kind.
pressure : Double
/// `Pressure`: platform pressure stage. Zero for every other kind.
pressure_stage : Int32
}
///|
pub extend GestureEvent with Debug::{to_repr}
///|
pub extend GestureEvent with Eq::{not_equal, equal}
///|
pub extend GestureEvent with ToJson::{to_json}
///|
pub fn GestureEvent::new(
kind~ : GestureKind,
phase~ : GesturePhase,
scale_delta~ : Double = 0.0,
rotation_delta~ : Double = 0.0,
pan_delta~ : Point = Point::new(x=0.0, y=0.0),
pressure~ : Double = 0.0,
pressure_stage~ : Int32 = 0,
) -> GestureEvent {
{
kind,
phase,
scale_delta,
rotation_delta,
pan_delta,
pressure,
pressure_stage,
}
}
///|
#derive(Eq, Debug, ToJson)
pub(all) enum AppEvent {
FrameTick(Frame)
Pointer(PointerEvent)
Keyboard(KeyboardEvent)
TextInput(TextInputEvent)
DragDrop(DragDropEvent)
PlatformView(String, PlatformViewEvent)
Resize(Size)
Redraw(RedrawReason)
Gesture(GestureEvent)
CloseRequested
}
///|
pub extend AppEvent with Debug::{to_repr}
///|
pub extend AppEvent with Eq::{not_equal, equal}
///|
pub extend AppEvent with ToJson::{to_json}
///|
pub fn PointerEvent::new(
position~ : Point,
phase~ : PointerPhase,
button~ : Int32 = 0,
wheel_delta~ : Point = Point::new(x=0.0, y=0.0),
modifiers~ : KeyModifiers = KeyModifiers::none(),
id~ : Int32 = 0,
pressure~ : Double = 1.0,
) -> PointerEvent {
{ position, phase, button, wheel_delta, modifiers, id, pressure, }
}
///|
pub fn KeyModifiers::none() -> KeyModifiers {
{ shift: false, control: false, alt: false, meta: false, }
}
///|
pub fn KeyModifiers::new(
shift~ : Bool = false,
control~ : Bool = false,
alt~ : Bool = false,
meta~ : Bool = false,
) -> KeyModifiers {
{ shift, control, alt, meta, }
}
///|
pub fn KeyboardEvent::new(
key~ : String,
pressed~ : Bool = true,
text~ : String? = None,
repeat~ : Bool = false,
modifiers~ : KeyModifiers = KeyModifiers::none(),
) -> KeyboardEvent {
{ key, text, pressed, repeat, modifiers, }
}
///|
pub fn TextRange::new(start~ : Int32, end~ : Int32) -> TextRange {
{ start, end, }
}
///|
pub fn TextRange::collapsed(index : Int32) -> TextRange {
{ start: index, end: index, }
}
///|
pub fn TextRange::normalized(self : TextRange) -> TextRange {
if self.start <= self.end {
self
} else {
{ start: self.end, end: self.start, }
}
}
///|
pub fn TextRange::is_collapsed(self : TextRange) -> Bool {
self.start == self.end
}
///|
pub fn CompositionUpdate::new(
text~ : String,
cursor~ : TextRange? = None,
) -> CompositionUpdate {
{ text, cursor, }
}
///|
pub fn CompositionUpdate::text(self : CompositionUpdate) -> String {
self.text
}
///|
pub fn CompositionUpdate::cursor(self : CompositionUpdate) -> TextRange? {
self.cursor
}
///|
pub fn DragDropEvent::new(
phase~ : DragDropPhase,
paths~ : Array[String] = [],
position~ : Point? = None,
) -> DragDropEvent {
{ phase, paths, position, }
}