use std::rc::Rc;
use incular_core::time::Instant;
use incular_core::{
DragStartBehavior, KeyboardEvent, Offset, PointerPhase, PointerSampleMetadata, TrackpadGesture,
};
use crate::focus::{FocusBehavior, FocusNode};
use crate::keyboard::{
ActionInvocationSubscription, ActionListenerSubscription, ErasedActionScope,
ErasedShortcutScope,
};
use crate::scale::{ScaleEndDetails, ScaleStartDetails, ScaleUpdateDetails};
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct PointerEvent {
pub pointer: u64,
pub position: Offset,
pub phase: PointerPhase,
pub time: Instant,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct RawPointerEvent {
pub pointer: u64,
pub device: u64,
pub kind: PointerDeviceKind,
pub buttons: u32,
pub button: Option<u32>,
pub sample: PointerSampleMetadata,
pub position: Offset,
pub phase: PointerPhase,
pub time: Instant,
pub delta: Offset,
pub local_position: Offset,
pub local_delta: Offset,
pub down: bool,
pub synthesized: bool,
pub scroll_delta: Offset,
}
impl RawPointerEvent {
#[must_use]
pub const fn new(
pointer: u64,
device: u64,
kind: PointerDeviceKind,
buttons: u32,
position: Offset,
phase: PointerPhase,
time: Instant,
) -> Self {
Self {
pointer,
device,
kind,
buttons,
button: None,
sample: PointerSampleMetadata::EMPTY,
position,
phase,
time,
delta: Offset::ZERO,
local_position: position,
local_delta: Offset::ZERO,
down: pointer_is_down(phase, buttons),
synthesized: false,
scroll_delta: Offset::ZERO,
}
}
#[must_use]
pub const fn with_button(mut self, button: Option<u32>) -> Self {
self.button = button;
self
}
#[must_use]
pub fn scroll(
pointer: u64,
device: u64,
kind: PointerDeviceKind,
position: Offset,
scroll_delta: Offset,
time: Instant,
) -> Self {
Self {
scroll_delta,
..Self::new(pointer, device, kind, 0, position, PointerPhase::Move, time)
}
}
#[must_use]
pub const fn with_sample(mut self, sample: PointerSampleMetadata) -> Self {
self.sample = sample;
self
}
#[must_use]
pub const fn legacy(self) -> PointerEvent {
PointerEvent {
pointer: self.pointer,
position: self.position,
phase: self.phase,
time: self.time,
}
}
}
impl From<PointerEvent> for RawPointerEvent {
fn from(event: PointerEvent) -> Self {
Self::new(
event.pointer,
0,
PointerDeviceKind::Mouse,
0,
event.position,
event.phase,
event.time,
)
}
}
const fn pointer_is_down(phase: PointerPhase, buttons: u32) -> bool {
match phase {
PointerPhase::Down => true,
PointerPhase::Move => buttons != 0,
PointerPhase::Up | PointerPhase::Cancel | PointerPhase::Enter | PointerPhase::Exit => false,
}
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
pub enum MouseCursor {
#[default]
Defer,
Basic,
Click,
Text,
Crosshair,
Grab,
Grabbing,
NotAllowed,
ResizeHorizontal,
ResizeVertical,
ResizeUpLeftDownRight,
ResizeUpRightDownLeft,
}
pub use incular_core::PointerDeviceKind;
#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct Velocity {
pub pixels_per_second: Offset,
}
impl Velocity {
pub const ZERO: Self = Self {
pixels_per_second: Offset::ZERO,
};
#[must_use]
pub const fn new(pixels_per_second: Offset) -> Self {
Self { pixels_per_second }
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct TapDownDetails {
pub global_position: Offset,
pub local_position: Offset,
pub kind: PointerDeviceKind,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct TapUpDetails {
pub global_position: Offset,
pub local_position: Offset,
pub kind: PointerDeviceKind,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct DragStartDetails {
pub source_time: Option<Instant>,
pub global_position: Offset,
pub local_position: Offset,
pub kind: PointerDeviceKind,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct DragDownDetails {
pub global_position: Offset,
pub local_position: Offset,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct LongPressStartDetails {
pub global_position: Offset,
pub local_position: Offset,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct LongPressMoveUpdateDetails {
pub global_position: Offset,
pub local_position: Offset,
pub offset_from_origin: Offset,
pub local_offset_from_origin: Offset,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct LongPressEndDetails {
pub global_position: Offset,
pub local_position: Offset,
pub velocity: Velocity,
}
#[derive(Clone, Default)]
pub struct GestureCallbacks {
pub on_tap: Option<Rc<dyn Fn()>>,
pub on_tap_down: Option<Rc<dyn Fn(TapDownDetails)>>,
pub on_tap_up: Option<Rc<dyn Fn(TapUpDetails)>>,
pub on_tap_cancel: Option<Rc<dyn Fn()>>,
pub on_double_tap: Option<Rc<dyn Fn()>>,
pub on_double_tap_down: Option<Rc<dyn Fn(TapDownDetails)>>,
pub on_double_tap_cancel: Option<Rc<dyn Fn()>>,
pub on_long_press: Option<Rc<dyn Fn()>>,
pub on_long_press_start: Option<Rc<dyn Fn(LongPressStartDetails)>>,
pub on_long_press_move_update: Option<Rc<dyn Fn(LongPressMoveUpdateDetails)>>,
pub on_long_press_up: Option<Rc<dyn Fn()>>,
pub on_long_press_end: Option<Rc<dyn Fn(LongPressEndDetails)>>,
pub on_pan_down: Option<Rc<dyn Fn(DragDownDetails)>>,
pub on_pan_start: Option<Rc<dyn Fn(DragStartDetails)>>,
pub on_pan_update: Option<Rc<dyn Fn(DragUpdateDetails)>>,
pub on_pan_end: Option<Rc<dyn Fn(DragEndDetails)>>,
pub on_pan_cancel: Option<Rc<dyn Fn()>>,
pub on_horizontal_drag_down: Option<Rc<dyn Fn(DragDownDetails)>>,
pub on_horizontal_drag_start: Option<Rc<dyn Fn(DragStartDetails)>>,
pub on_horizontal_drag_update: Option<Rc<dyn Fn(DragUpdateDetails)>>,
pub on_horizontal_drag_end: Option<Rc<dyn Fn(DragEndDetails)>>,
pub on_horizontal_drag_cancel: Option<Rc<dyn Fn()>>,
pub on_vertical_drag_down: Option<Rc<dyn Fn(DragDownDetails)>>,
pub on_vertical_drag_start: Option<Rc<dyn Fn(DragStartDetails)>>,
pub on_vertical_drag_update: Option<Rc<dyn Fn(DragUpdateDetails)>>,
pub on_vertical_drag_end: Option<Rc<dyn Fn(DragEndDetails)>>,
pub on_vertical_drag_cancel: Option<Rc<dyn Fn()>>,
pub on_scale_start: Option<Rc<dyn Fn(ScaleStartDetails)>>,
pub on_scale_update: Option<Rc<dyn Fn(ScaleUpdateDetails)>>,
pub on_scale_end: Option<Rc<dyn Fn(ScaleEndDetails)>>,
pub on_trackpad_gesture: Option<Rc<dyn Fn(TrackpadGesture)>>,
pub on_cancel: Option<Rc<dyn Fn()>>,
pub on_key: Option<Rc<dyn Fn(KeyboardEvent) -> bool>>,
pub on_key_down: Option<Rc<dyn Fn(KeyboardEvent)>>,
pub on_key_repeat: Option<Rc<dyn Fn(KeyboardEvent)>>,
pub on_key_up: Option<Rc<dyn Fn(KeyboardEvent)>>,
pub on_shortcut: Option<Rc<dyn Fn(KeyboardEvent) -> bool>>,
pub shortcut_scope: Option<Rc<ErasedShortcutScope>>,
pub action_scope: Option<Rc<ErasedActionScope>>,
pub action_listener: Option<Rc<ActionListenerSubscription>>,
pub action_invocation_listener: Option<Rc<ActionInvocationSubscription>>,
pub focus_node: Option<FocusNode>,
pub focus_behavior: Option<Rc<FocusBehavior>>,
pub autofocus: bool,
pub include_semantics: bool,
pub mouse_cursor: MouseCursor,
pub drag_start_behavior: DragStartBehavior,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum GestureAction {
Tap,
DoubleTap,
LongPress,
LongPressStart(LongPressStartDetails),
PanStart(DragStartDetails),
Pan(DragUpdateDetails),
PanEnd(DragEndDetails),
HorizontalDragStart(DragStartDetails),
HorizontalDrag(DragUpdateDetails),
HorizontalDragEnd(DragEndDetails),
VerticalDragStart(DragStartDetails),
VerticalDrag(DragUpdateDetails),
VerticalDragEnd(DragEndDetails),
ArenaAccepted {
pointer: u64,
},
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum GestureDecision {
Pending,
Accept(GestureAction),
Reject,
Cancelled,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct DragUpdateDetails {
pub source_time: Option<Instant>,
pub delta: Offset,
pub primary_delta: Option<f32>,
pub global_position: Offset,
pub local_position: Offset,
pub kind: PointerDeviceKind,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct DragEndDetails {
pub velocity: Velocity,
pub primary_velocity: Option<f32>,
pub global_position: Offset,
pub local_position: Offset,
}
#[derive(Clone, Default)]
pub struct DragCallbacks {
pub on_start: Option<Rc<dyn Fn(DragStartDetails)>>,
pub on_update: Option<Rc<dyn Fn(DragUpdateDetails)>>,
pub on_end: Option<Rc<dyn Fn(DragEndDetails)>>,
}