1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
//! Gesture controller and events.
use std::marker::PhantomData;
use crate::{bind, file::RwOps, EnumInt, Result, Sdl, SdlError};
use super::TouchDevice;
/// A gesture controller by $1 gesture recognition system.
#[derive(Debug, Clone)]
pub struct Gesture(bind::SDL_GestureID);
impl Gesture {
/// Saves all gestures into `dst` and returns the numbers of succeed to write.
///
/// # Errors
///
/// Returns `Err` if failed to save all the template data.
pub fn save_dollar_template_all(dst: &RwOps) -> Result<usize> {
let ret = unsafe { bind::SDL_SaveAllDollarTemplates(dst.ptr().as_ptr()) };
if ret == 0 {
Err(SdlError::Others { msg: Sdl::error() })
} else {
Ok(ret as usize)
}
}
/// Saves gesture into `dst` and returns the numbers of succeed to write.
///
/// # Errors
///
/// Returns `Err` if failed to save a template data.
pub fn save_dollar_template(&self, dst: &RwOps) -> Result<usize> {
let ret = unsafe { bind::SDL_SaveDollarTemplate(self.0, dst.ptr().as_ptr()) };
if ret == 0 {
Err(SdlError::Others { msg: Sdl::error() })
} else {
Ok(ret as usize)
}
}
}
/// An event on recognized a gesture
#[derive(Debug, Clone)]
#[non_exhaustive]
pub enum GestureEvent {
/// The gesture was multi touches.
Multi {
/// When this event occurred.
timestamp: u32,
/// The rotating amount of fingers on the gesture.
delta_theta: f32,
/// The distance difference among fingers on the gesture.
delta_dist: f32,
/// The normalized x coord of the center on the gesture.
x: f32,
/// The normalized y coord of the center on the gesture.
y: f32,
/// The numbers of fingers on the gesture.
num_fingers: u16,
},
/// The gesture was recognized by $1.
Dollar {
/// When this event occurred.
timestamp: u32,
/// The touch device the gesture detected.
touch: TouchDevice,
/// The id of the nearest gesture.
gesture: Gesture,
/// The numbers of fingers on the gesture.
num_fingers: u32,
/// The error from the template.
error: f32,
/// The normalized x coord of the center on the gesture.
x: f32,
/// The normalized y coord of the center on the gesture.
y: f32,
},
/// The gesture was recorded for $1.
DollarRecord {
/// The touch device the gesture detected.
touch: TouchDevice,
/// The id of the nearest gesture.
gesture: Gesture,
},
}
impl From<bind::SDL_MultiGestureEvent> for GestureEvent {
fn from(raw: bind::SDL_MultiGestureEvent) -> Self {
Self::Multi {
timestamp: raw.timestamp,
delta_theta: raw.dTheta,
delta_dist: raw.dDist,
x: raw.x,
y: raw.y,
num_fingers: raw.numFingers,
}
}
}
impl From<bind::SDL_DollarGestureEvent> for GestureEvent {
fn from(raw: bind::SDL_DollarGestureEvent) -> Self {
match raw.type_ as EnumInt {
bind::SDL_DOLLARGESTURE => Self::Dollar {
timestamp: raw.timestamp,
touch: TouchDevice(raw.touchId, PhantomData),
gesture: Gesture(raw.gestureId),
num_fingers: raw.numFingers,
error: raw.error,
x: raw.x,
y: raw.y,
},
bind::SDL_DOLLARRECORD => Self::DollarRecord {
touch: TouchDevice(raw.touchId, PhantomData),
gesture: Gesture(raw.gestureId),
},
_ => unreachable!(),
}
}
}