use crate::geometry::PointF;
#[repr(transparent)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default)]
pub struct TouchId(pub u32);
impl TouchId {
#[inline]
pub const fn new(id: u32) -> Self {
Self(id)
}
pub const INVALID: Self = Self(u32::MAX);
#[inline]
pub const fn is_valid(&self) -> bool {
self.0 != u32::MAX
}
}
#[repr(u8)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Default, Hash)]
pub enum TouchPhase {
#[default]
Begin = 0,
Move = 1,
End = 2,
Cancel = 3,
}
impl TouchPhase {
#[inline]
pub fn from_u8(value: u8) -> Option<Self> {
match value {
0 => Some(Self::Begin),
1 => Some(Self::Move),
2 => Some(Self::End),
3 => Some(Self::Cancel),
_ => None,
}
}
#[inline]
pub const fn is_active(&self) -> bool {
matches!(self, Self::Begin | Self::Move)
}
#[inline]
pub const fn is_end(&self) -> bool {
matches!(self, Self::End | Self::Cancel)
}
}
#[repr(C)]
#[derive(Clone, Copy, Debug, Default)]
pub struct TouchPoint {
pub id: TouchId,
pub phase: TouchPhase,
pub position: PointF,
pub pressure: f32,
pub radius: f32,
}
impl TouchPoint {
#[inline]
pub const fn new(id: TouchId, phase: TouchPhase, position: PointF) -> Self {
Self {
id,
phase,
position,
pressure: 1.0,
radius: 0.0,
}
}
#[inline]
pub const fn with_pressure(mut self, pressure: f32) -> Self {
self.pressure = pressure;
self
}
#[inline]
pub const fn with_radius(mut self, radius: f32) -> Self {
self.radius = radius;
self
}
}
#[repr(u8)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum GestureType {
Tap = 0,
DoubleTap = 1,
LongPress = 2,
Swipe = 3,
Pinch = 4,
Rotate = 5,
Pan = 6,
}
impl GestureType {
#[inline]
pub fn from_u8(value: u8) -> Option<Self> {
match value {
0 => Some(Self::Tap),
1 => Some(Self::DoubleTap),
2 => Some(Self::LongPress),
3 => Some(Self::Swipe),
4 => Some(Self::Pinch),
5 => Some(Self::Rotate),
6 => Some(Self::Pan),
_ => None,
}
}
#[inline]
pub const fn name(&self) -> &'static str {
match self {
Self::Tap => "Tap",
Self::DoubleTap => "Double Tap",
Self::LongPress => "Long Press",
Self::Swipe => "Swipe",
Self::Pinch => "Pinch",
Self::Rotate => "Rotate",
Self::Pan => "Pan",
}
}
#[inline]
pub const fn min_touches(&self) -> usize {
match self {
Self::Tap | Self::DoubleTap | Self::LongPress | Self::Swipe | Self::Pan => 1,
Self::Pinch | Self::Rotate => 2,
}
}
}
#[repr(u8)]
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
pub enum SwipeDirection {
Up = 0,
Down = 1,
Left = 2,
Right = 3,
}
impl SwipeDirection {
#[inline]
pub fn from_u8(value: u8) -> Option<Self> {
match value {
0 => Some(Self::Up),
1 => Some(Self::Down),
2 => Some(Self::Left),
3 => Some(Self::Right),
_ => None,
}
}
#[inline]
pub const fn opposite(&self) -> Self {
match self {
Self::Up => Self::Down,
Self::Down => Self::Up,
Self::Left => Self::Right,
Self::Right => Self::Left,
}
}
#[inline]
pub const fn is_horizontal(&self) -> bool {
matches!(self, Self::Left | Self::Right)
}
#[inline]
pub const fn is_vertical(&self) -> bool {
matches!(self, Self::Up | Self::Down)
}
}