kobo_core/device/
touch.rs1pub const SWIPE_MIN_DX: f32 = 80.0;
9pub const SWIPE_MAX_MS: u128 = 500;
10pub const DOUBLE_TAP_MAX_PRESS_MS: u128 = 300;
11pub const DOUBLE_TAP_WINDOW_MS: u128 = 400;
12
13#[derive(Clone, Copy)]
15pub struct TouchConfig {
16 pub switch_xy: bool,
17 pub mirrored_x: bool,
18 pub mirrored_y: bool,
19 pub raw_x_max: i32,
20 pub raw_y_max: i32,
21 pub screen_w: i32,
22 pub screen_h: i32,
23}
24
25pub fn to_display(rx: i32, ry: i32, cfg: &TouchConfig) -> (f32, f32) {
27 let (mut x, mut y) = if cfg.switch_xy { (ry, rx) } else { (rx, ry) };
28
29 if cfg.mirrored_x {
30 let max = if cfg.switch_xy {
31 cfg.raw_y_max
32 } else {
33 cfg.raw_x_max
34 };
35 x = max - x;
36 }
37 if cfg.mirrored_y {
38 let max = if cfg.switch_xy {
39 cfg.raw_x_max
40 } else {
41 cfg.raw_y_max
42 };
43 y = max - y;
44 }
45
46 (x as f32, y as f32)
47}
48
49#[allow(dead_code)]
50pub fn is_swipe(swipe_dx: f32, swipe_dy: f32, dt_ms: u128) -> bool {
51 swipe_dx.abs() > SWIPE_MIN_DX && dt_ms < SWIPE_MAX_MS && swipe_dx.abs() > swipe_dy.abs()
52}
53
54pub fn is_double_tap(dt_ms: u128, since_prev_tap_ms: u128) -> bool {
55 dt_ms < DOUBLE_TAP_MAX_PRESS_MS && since_prev_tap_ms < DOUBLE_TAP_WINDOW_MS
56}
57
58#[cfg(test)]
59mod tests {
60 use super::*;
61
62 fn libra_cfg() -> TouchConfig {
64 TouchConfig {
65 switch_xy: true,
66 mirrored_x: true,
67 mirrored_y: false,
68 raw_x_max: 1447,
69 raw_y_max: 1071,
70 screen_w: 1072,
71 screen_h: 1448,
72 }
73 }
74
75 fn plain_cfg() -> TouchConfig {
77 TouchConfig {
78 switch_xy: false,
79 mirrored_x: false,
80 mirrored_y: false,
81 raw_x_max: 1071,
82 raw_y_max: 1447,
83 screen_w: 1072,
84 screen_h: 1448,
85 }
86 }
87
88 #[test]
89 fn libra_left_edge_maps_small_x() {
90 let cfg = libra_cfg();
91 let (dx, _) = to_display(736, 1035, &cfg);
92 assert!(
93 dx < 100.0,
94 "left-edge tap must map to small display_x, got {dx}"
95 );
96 }
97
98 #[test]
99 fn libra_right_edge_maps_large_x() {
100 let cfg = libra_cfg();
101 let (dx, _) = to_display(693, 36, &cfg);
102 assert!(
103 dx > 970.0,
104 "right-edge tap must map to large display_x, got {dx}"
105 );
106 }
107
108 #[test]
109 fn plain_passes_through() {
110 let cfg = plain_cfg();
111 let (dx, dy) = to_display(100, 200, &cfg);
112 assert_eq!(dx, 100.0);
113 assert_eq!(dy, 200.0);
114 }
115
116 #[test]
117 fn plain_mirrored_x() {
118 let mut cfg = plain_cfg();
119 cfg.mirrored_x = true;
120 let (dx, _) = to_display(0, 0, &cfg);
121 assert_eq!(dx, cfg.raw_x_max as f32);
122 }
123
124 #[test]
125 fn is_swipe_detects_fast_horizontal_flick() {
126 assert!(is_swipe(200.0, 5.0, 120));
127 assert!(is_swipe(-250.0, 40.0, 200));
128 }
129
130 #[test]
131 fn is_swipe_rejects_small_or_slow_or_vertical() {
132 assert!(!is_swipe(20.0, 5.0, 300));
133 assert!(!is_swipe(200.0, 5.0, 600));
134 assert!(!is_swipe(100.0, 300.0, 100));
135 }
136
137 #[test]
138 fn is_double_tap_within_window() {
139 assert!(is_double_tap(150, 200));
140 assert!(!is_double_tap(400, 200));
141 assert!(!is_double_tap(150, 500));
142 }
143}