use crate::types::Point;
pub const PRECISE_THRESHOLD: f64 = 4.0;
pub const COARSE_THRESHOLD: f64 = 8.0;
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct Press {
pub at: Point,
pub threshold: f64,
}
impl Press {
pub const fn new(at: Point, threshold: f64) -> Self {
Self { at, threshold }
}
pub const fn from_pointer(at: Point, coarse: bool) -> Self {
Self::new(
at,
if coarse {
COARSE_THRESHOLD
} else {
PRECISE_THRESHOLD
},
)
}
pub fn is_drag(self, now: Point) -> bool {
self.at.distance(now) >= self.threshold
}
pub fn is_drag_in_world(self, moved: f64, zoom: f64) -> bool {
moved * zoom >= self.threshold
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn a_still_pointer_is_never_a_drag_and_a_travelled_one_always_is() {
let press = Press::from_pointer(Point::new(100.0, 100.0), false);
assert!(!press.is_drag(press.at));
assert!(!press.is_drag(Point::new(103.0, 100.0)));
assert!(press.is_drag(Point::new(104.0, 100.0)));
assert!(press.is_drag(Point::new(97.0, 97.0)));
}
#[test]
fn touch_is_allowed_more_wobble_than_a_mouse() {
let at = Point::new(0.0, 0.0);
let wobble = Point::new(6.0, 0.0);
assert!(Press::from_pointer(at, false).is_drag(wobble));
assert!(!Press::from_pointer(at, true).is_drag(wobble));
}
#[test]
fn the_threshold_means_screen_pixels_at_any_zoom() {
let press = Press::from_pointer(Point::new(0.0, 0.0), false);
assert!(!press.is_drag_in_world(3.0, 1.0));
assert!(press.is_drag_in_world(3.0, 2.0));
assert!(!press.is_drag_in_world(3.0, 0.5));
}
}