mod buttons;
pub use buttons::{PointerButton, PointerButtons};
extern crate alloc;
use alloc::vec::Vec;
use core::num::NonZeroU64;
use dpi::{LogicalPosition, PhysicalPosition, PhysicalSize};
use keyboard_types::Modifiers;
use crate::ScrollDelta;
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct PointerId(NonZeroU64);
impl PointerId {
pub const PRIMARY: Self = Self(NonZeroU64::MIN);
#[inline(always)]
pub fn new(n: u64) -> Option<Self> {
NonZeroU64::new(n).map(PointerId)
}
#[inline(always)]
pub fn is_primary_pointer(self) -> bool {
self == Self::PRIMARY
}
#[inline(always)]
pub fn get_inner(self) -> NonZeroU64 {
self.0
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct PersistentDeviceId(NonZeroU64);
impl PersistentDeviceId {
#[inline(always)]
pub fn new(n: u64) -> Option<Self> {
NonZeroU64::new(n).map(PersistentDeviceId)
}
}
#[non_exhaustive]
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, PartialOrd, Ord)]
#[repr(u8)]
pub enum PointerType {
#[default]
Unknown,
Mouse,
Pen,
Touch,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub struct PointerInfo {
pub pointer_id: Option<PointerId>,
pub persistent_device_id: Option<PersistentDeviceId>,
pub pointer_type: PointerType,
}
impl PointerInfo {
#[inline(always)]
pub fn is_primary_pointer(&self) -> bool {
self.pointer_id.is_some_and(PointerId::is_primary_pointer)
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct PointerOrientation {
pub altitude: f32,
pub azimuth: f32,
}
impl Default for PointerOrientation {
fn default() -> Self {
Self {
altitude: core::f32::consts::FRAC_PI_2,
azimuth: core::f32::consts::FRAC_PI_2,
}
}
}
pub type ContactGeometry = PhysicalSize<f64>;
#[derive(Clone, Debug, PartialEq)]
pub struct PointerState {
pub time: u64,
pub position: PhysicalPosition<f64>,
pub buttons: PointerButtons,
pub modifiers: Modifiers,
pub count: u8,
pub contact_geometry: ContactGeometry,
pub orientation: PointerOrientation,
pub pressure: f32,
pub tangential_pressure: f32,
pub scale_factor: f64,
}
impl PointerState {
#[cfg(feature = "kurbo")]
pub fn logical_point(&self) -> kurbo::Point {
let log = self.position.to_logical(self.scale_factor);
kurbo::Point { x: log.x, y: log.y }
}
#[cfg(feature = "kurbo")]
pub fn physical_point(&self) -> kurbo::Point {
kurbo::Point {
x: self.position.x,
y: self.position.y,
}
}
pub fn logical_position(&self) -> LogicalPosition<f64> {
self.position.to_logical(self.scale_factor)
}
}
impl Default for PointerState {
fn default() -> Self {
Self {
time: 0,
position: PhysicalPosition::<f64>::default(),
buttons: PointerButtons::default(),
modifiers: Modifiers::default(),
count: 0,
contact_geometry: ContactGeometry {
width: 1.0,
height: 1.0,
},
orientation: PointerOrientation::default(),
pressure: 0.0,
tangential_pressure: 0.0,
scale_factor: 1.,
}
}
}
#[derive(Clone, Debug, PartialEq)]
pub struct PointerUpdate {
pub pointer: PointerInfo,
pub current: PointerState,
pub coalesced: Vec<PointerState>,
pub predicted: Vec<PointerState>,
}
impl PointerUpdate {
#[inline(always)]
pub fn is_primary_pointer(&self) -> bool {
self.pointer.is_primary_pointer()
}
}
#[derive(Clone, Debug)]
pub struct PointerButtonEvent {
pub button: Option<PointerButton>,
pub pointer: PointerInfo,
pub state: PointerState,
}
#[derive(Clone, Debug)]
pub struct PointerScrollEvent {
pub pointer: PointerInfo,
pub delta: ScrollDelta,
pub state: PointerState,
}
#[derive(Clone, Debug)]
pub enum PointerGesture {
Pinch(f32),
Rotate(f32),
}
#[derive(Clone, Debug)]
pub struct PointerGestureEvent {
pub pointer: PointerInfo,
pub gesture: PointerGesture,
pub state: PointerState,
}
#[derive(Clone, Debug)]
pub enum PointerEvent {
Down(PointerButtonEvent),
Up(PointerButtonEvent),
Move(PointerUpdate),
Cancel(PointerInfo),
Enter(PointerInfo),
Leave(PointerInfo),
Scroll(PointerScrollEvent),
Gesture(PointerGestureEvent),
}
impl PointerEvent {
#[inline(always)]
pub fn is_primary_pointer(&self) -> bool {
match self {
Self::Down(PointerButtonEvent { pointer, .. })
| Self::Up(PointerButtonEvent { pointer, .. })
| Self::Move(PointerUpdate { pointer, .. })
| Self::Cancel(pointer)
| Self::Enter(pointer)
| Self::Leave(pointer)
| Self::Scroll(PointerScrollEvent { pointer, .. })
| Self::Gesture(PointerGestureEvent { pointer, .. }) => pointer.is_primary_pointer(),
}
}
}