1use num_derive::{FromPrimitive, ToPrimitive};
5use num_traits::{FromPrimitive, ToPrimitive};
6
7#[derive(Debug, Copy, Clone, PartialEq, Eq, ToPrimitive, FromPrimitive)]
8pub enum TouchKind {
9 Press = 0,
10 Release,
11 Drag,
12}
13
14#[derive(Debug, Copy, Clone)]
15pub struct Touch {
16 pub kind: TouchKind,
17 pub id: usize,
18 pub x: usize,
19 pub y: usize,
20}
21
22impl Touch {
23 #[must_use]
24 pub fn translate_pos(&self, origin_x: usize, origin_y: usize) -> Touch {
25 Touch { x: self.x.saturating_sub(origin_x), y: self.y.saturating_sub(origin_y), ..*self }
26 }
27
28 #[must_use]
29 pub fn with_offset(&self, offset_x: i32, offset_y: i32) -> Touch {
30 Touch {
31 x: (self.x as i32).saturating_add(offset_x) as usize,
32 y: (self.y as i32).saturating_add(offset_y) as usize,
33 ..*self
34 }
35 }
36
37 pub fn is_within_area(&self, x: usize, y: usize, w: usize, h: usize) -> bool {
38 (self.x >= x && self.x < x + w) && (self.y >= y && self.y < y + h)
39 }
40
41 pub fn is_press(&self) -> bool { matches!(self.kind, TouchKind::Press) }
42
43 pub fn is_drag(&self) -> bool { matches!(self.kind, TouchKind::Drag) }
44
45 pub fn is_release(&self) -> bool { matches!(self.kind, TouchKind::Release) }
46
47 pub fn as_input_message(&self, msg_id: usize) -> xous::Message {
50 xous::Message::new_scalar(msg_id, self.kind.to_usize().expect("to u32"), self.id, self.x, self.y)
51 }
52
53 pub fn try_from_input_message(msg: &xous::Message) -> Option<Self> {
56 let scalar = msg.scalar_message()?;
57 let kind = TouchKind::from_usize(scalar.arg1)?;
58 let id = scalar.arg2;
59 let x = scalar.arg3;
60 let y = scalar.arg4;
61 Some(Touch { kind, id, x, y })
62 }
63
64 pub fn diff(&self, other: &Touch) -> (isize, isize) {
65 (self.x as isize - other.x as isize, self.y as isize - other.y as isize)
66 }
67
68 pub fn distance_to(&self, other: &Touch) -> f32 {
70 let (dx, dy) = self.diff(other);
71 (dx as f32 * dx as f32 + dy as f32 * dy as f32).sqrt()
72 }
73}