rich_sdl2_rust/event/touch/
gesture.rs

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