use crate::{Offset, Size};
#[derive(Clone, Copy, Debug, Default, PartialEq, PartialOrd)]
pub struct NormalizedPressure(f32);
impl NormalizedPressure {
#[must_use]
pub fn new(value: f64) -> Option<Self> {
value
.is_finite()
.then(|| Self(value.clamp(0.0, 1.0) as f32))
}
#[must_use]
pub fn from_range(value: f64, maximum: f64) -> Option<Self> {
(value.is_finite() && maximum.is_finite() && maximum > 0.0)
.then(|| Self((value / maximum).clamp(0.0, 1.0) as f32))
}
#[must_use]
pub const fn get(self) -> f32 {
self.0
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct StylusOrientation {
pub altitude: f32,
pub azimuth: f32,
}
impl StylusOrientation {
#[must_use]
pub fn from_tilt_degrees(tilt_x: f64, tilt_y: f64) -> Option<Self> {
if !tilt_x.is_finite()
|| !tilt_y.is_finite()
|| !(-90.0..=90.0).contains(&tilt_x)
|| !(-90.0..=90.0).contains(&tilt_y)
{
return None;
}
let x = tilt_x.to_radians().tan();
let y = tilt_y.to_radians().tan();
if !x.is_finite() || !y.is_finite() {
return None;
}
let altitude = 1.0_f64.atan2(x.hypot(y));
let azimuth = y.atan2(x).rem_euclid(std::f64::consts::TAU);
Some(Self {
altitude: altitude as f32,
azimuth: azimuth as f32,
})
}
}
#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct StylusMetadata {
pub orientation: Option<StylusOrientation>,
pub barrel_button: bool,
}
#[derive(Clone, Copy, Debug, Default, PartialEq)]
pub struct PointerSampleMetadata {
pub pressure: Option<NormalizedPressure>,
pub stylus: Option<StylusMetadata>,
}
impl PointerSampleMetadata {
pub const EMPTY: Self = Self {
pressure: None,
stylus: None,
};
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum TrackpadGesturePhase {
Started,
Updated,
Ended,
Cancelled,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum TrackpadGestureKind {
Pinch,
Rotation,
Pan,
SmartMagnify,
Pressure,
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum TrackpadGesture {
Pinch {
device: u64,
phase: TrackpadGesturePhase,
magnification_delta: f32,
},
Rotation {
device: u64,
phase: TrackpadGesturePhase,
delta_radians: f32,
},
Pan {
device: u64,
phase: TrackpadGesturePhase,
delta: Offset,
},
SmartMagnify {
device: u64,
},
Pressure {
device: u64,
pressure: NormalizedPressure,
stage: i64,
},
}
impl TrackpadGesture {
#[must_use]
pub const fn device(self) -> u64 {
match self {
Self::Pinch { device, .. }
| Self::Rotation { device, .. }
| Self::Pan { device, .. }
| Self::SmartMagnify { device }
| Self::Pressure { device, .. } => device,
}
}
#[must_use]
pub const fn kind(self) -> TrackpadGestureKind {
match self {
Self::Pinch { .. } => TrackpadGestureKind::Pinch,
Self::Rotation { .. } => TrackpadGestureKind::Rotation,
Self::Pan { .. } => TrackpadGestureKind::Pan,
Self::SmartMagnify { .. } => TrackpadGestureKind::SmartMagnify,
Self::Pressure { .. } => TrackpadGestureKind::Pressure,
}
}
#[must_use]
pub const fn phase(self) -> Option<TrackpadGesturePhase> {
match self {
Self::Pinch { phase, .. } | Self::Rotation { phase, .. } | Self::Pan { phase, .. } => {
Some(phase)
}
Self::SmartMagnify { .. } | Self::Pressure { .. } => None,
}
}
}
pub use keyboard_types::{Code, Key, KeyState, KeyboardEvent, Location, Modifiers, NamedKey};
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum PointerPhase {
Enter,
Move,
Down,
Up,
Cancel,
Exit,
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
pub enum PointerDeviceKind {
#[default]
Mouse,
Touch,
Stylus,
InvertedStylus,
Trackpad,
Unknown,
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
pub enum DragStartBehavior {
#[default]
Start,
Down,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum WindowResizeDirection {
East,
North,
NorthEast,
NorthWest,
South,
SouthEast,
SouthWest,
West,
}
pub const PRIMARY_POINTER_BUTTON: u32 = 1 << 0;
pub const SECONDARY_POINTER_BUTTON: u32 = 1 << 1;
pub const TERTIARY_POINTER_BUTTON: u32 = 1 << 2;
pub const BACK_POINTER_BUTTON: u32 = 1 << 3;
pub const FORWARD_POINTER_BUTTON: u32 = 1 << 4;
#[must_use]
pub const fn additional_pointer_button_mask(index: u16) -> Option<u32> {
let bit = 5_u32 + index as u32;
if bit < u32::BITS {
Some(1_u32 << bit)
} else {
None
}
}
#[derive(Clone, Debug, PartialEq, Eq)]
pub enum ImeEvent {
Preedit {
text: String,
selection: Option<(usize, usize)>,
},
Commit(String),
End,
}
#[derive(Clone, Debug, PartialEq)]
pub enum InputEvent {
Pointer {
phase: PointerPhase,
position: Offset,
},
PointerWithId {
pointer: u64,
phase: PointerPhase,
position: Offset,
},
PointerWithMetadata {
pointer: u64,
device: u64,
kind: PointerDeviceKind,
buttons: u32,
button: Option<u32>,
sample: PointerSampleMetadata,
phase: PointerPhase,
position: Offset,
},
TrackpadGesture(TrackpadGesture),
Scroll {
delta: Offset,
},
Key(KeyboardEvent),
Text(String),
Ime(ImeEvent),
WindowResized {
size: Size,
scale_factor: f64,
},
}