use {Event, Input, Motion};
#[derive(Copy, Clone, Deserialize, Serialize, PartialEq, Debug)]
pub enum Touch {
Start,
Move,
End,
Cancel,
}
#[derive(Copy, Clone, Deserialize, Serialize, PartialEq, Debug)]
pub struct TouchArgs {
pub device: i64,
pub id: i64,
pub x: f64,
pub y: f64,
pub z: f64,
pub px: f64,
pub py: f64,
pub pz: f64,
pub is_3d: bool,
pub touch: Touch,
}
impl TouchArgs {
pub fn new(device: i64, id: i64, pos: [f64; 2], pressure: f64, touch: Touch) -> TouchArgs {
TouchArgs {
device: device,
id: id,
x: pos[0],
y: pos[1],
z: 0.0,
is_3d: false,
px: 0.0,
py: 0.0,
pz: pressure,
touch: touch,
}
}
pub fn new_3d(device: i64,
id: i64,
pos: [f64; 3],
pressure: [f64; 3],
touch: Touch)
-> TouchArgs {
TouchArgs {
device: device,
id: id,
x: pos[0],
y: pos[1],
z: pos[2],
is_3d: true,
px: pressure[0],
py: pressure[1],
pz: pressure[2],
touch: touch,
}
}
pub fn position(&self) -> [f64; 2] {
[self.x, self.y]
}
pub fn position_3d(&self) -> [f64; 3] {
[self.x, self.y, self.z]
}
pub fn pressure(&self) -> f64 {
(self.px * self.px + self.py * self.py + self.pz * self.pz).sqrt()
}
pub fn pressure_3d(&self) -> [f64; 3] {
[self.px, self.py, self.pz]
}
}
pub trait TouchEvent: Sized {
fn from_touch_args(args: &TouchArgs, old_event: &Self) -> Option<Self>;
fn touch<U, F>(&self, f: F) -> Option<U> where F: FnMut(&TouchArgs) -> U;
fn touch_args(&self) -> Option<TouchArgs> {
self.touch(|args| args.clone())
}
}
impl TouchEvent for Event {
fn from_touch_args(args: &TouchArgs, _old_event: &Self) -> Option<Self> {
Some(Event::Input(Input::Move(Motion::Touch(*args))))
}
fn touch<U, F>(&self, mut f: F) -> Option<U>
where F: FnMut(&TouchArgs) -> U
{
match *self {
Event::Input(Input::Move(Motion::Touch(ref args))) => Some(f(args)),
_ => None,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_input_touch() {
let pos = [0.0; 2];
let e: Event = TouchArgs::new(0, 0, pos, 1.0, Touch::Start).into();
let a: Option<Event> =
TouchEvent::from_touch_args(&TouchArgs::new(0, 0, pos, 1.0, Touch::Start), &e);
let b: Option<Event> = a.clone()
.unwrap()
.touch(|t| {
TouchEvent::from_touch_args(&TouchArgs::new(t.device,
t.id,
t.position(),
t.pressure(),
Touch::Start),
a.as_ref().unwrap())
})
.unwrap();
assert_eq!(a, b);
}
#[test]
fn test_input_touch_3d() {
use super::super::Event;
let pos = [0.0; 3];
let pressure = [0.0, 0.0, 1.0];
let e: Event = TouchArgs::new_3d(0, 0, pos, pressure, Touch::Start).into();
let a: Option<Event> =
TouchEvent::from_touch_args(&TouchArgs::new_3d(0, 0, pos, pressure, Touch::Start), &e);
let b: Option<Event> = a.clone()
.unwrap()
.touch(|t| {
TouchEvent::from_touch_args(&TouchArgs::new_3d(t.device,
t.id,
t.position_3d(),
t.pressure_3d(),
Touch::Start),
a.as_ref().unwrap())
})
.unwrap();
assert_eq!(a, b);
}
}