use static_assertions::assert_not_impl_all;
use std::{cell::Cell, marker::PhantomData, ptr::NonNull};
use crate::{bind, file::RwOps, Result, Sdl, SdlError};
pub mod gesture;
pub struct TouchFinger<'device> {
ptr: NonNull<bind::SDL_Finger>,
_phantom: PhantomData<&'device ()>,
}
impl std::fmt::Debug for TouchFinger<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("TouchFinger")
.field("id", &self.id())
.finish_non_exhaustive()
}
}
impl TouchFinger<'_> {
#[must_use]
pub fn id(&self) -> i64 {
unsafe { self.ptr.as_ref() }.id
}
#[must_use]
pub fn x(&self) -> f32 {
unsafe { self.ptr.as_ref() }.x
}
#[must_use]
pub fn y(&self) -> f32 {
unsafe { self.ptr.as_ref() }.y
}
#[must_use]
pub fn pressure(&self) -> f32 {
unsafe { self.ptr.as_ref() }.pressure
}
}
#[derive(Debug, Clone)]
pub struct TouchDevice(bind::SDL_TouchID, PhantomData<Cell<u8>>);
assert_not_impl_all!(TouchDevice: Send, Sync);
impl TouchDevice {
#[must_use]
pub fn all_devices() -> Vec<Self> {
let num = unsafe { bind::SDL_GetNumTouchDevices() };
(0..num)
.map(|index| {
let id = unsafe { bind::SDL_GetTouchDevice(index) };
Self(id, PhantomData)
})
.collect()
}
#[must_use]
pub fn record(&self) -> bool {
unsafe { bind::SDL_RecordGesture(self.0) == 1 }
}
#[must_use]
pub fn touch_fingers(&self) -> Vec<TouchFinger> {
let num = unsafe { bind::SDL_GetNumTouchFingers(self.0) };
(0..num)
.filter_map(|index| {
let ptr = unsafe { bind::SDL_GetTouchFinger(self.0, index) };
(!ptr.is_null()).then(|| TouchFinger {
ptr: NonNull::new(ptr).unwrap(),
_phantom: PhantomData,
})
})
.collect()
}
pub fn load_dollar_templates(&self, src: &RwOps) -> Result<usize> {
let ret = unsafe { bind::SDL_LoadDollarTemplates(self.0, src.ptr().as_ptr()) };
if ret <= 0 {
Err(SdlError::Others { msg: Sdl::error() })
} else {
Ok(ret as usize)
}
}
}