If mouse moves too much, don't register it as a click

This commit is contained in:
Emil Ernerfeldt 2020-05-23 12:00:03 +02:00
parent b30c49f409
commit 4bea65595c
4 changed files with 28 additions and 10 deletions

View file

@ -410,7 +410,7 @@ fn resize_hover(
right = (rect.right() - mouse_pos.x).abs() <= side_interact_radius; right = (rect.right() - mouse_pos.x).abs() <= side_interact_radius;
bottom = (rect.bottom() - mouse_pos.y).abs() <= side_interact_radius; bottom = (rect.bottom() - mouse_pos.y).abs() <= side_interact_radius;
if rect.right_bottom().dist(mouse_pos) < corner_interact_radius { if rect.right_bottom().distance(mouse_pos) < corner_interact_radius {
right = true; right = true;
bottom = true; bottom = true;
} }
@ -419,15 +419,15 @@ fn resize_hover(
left = (rect.left() - mouse_pos.x).abs() <= side_interact_radius; left = (rect.left() - mouse_pos.x).abs() <= side_interact_radius;
top = (rect.top() - mouse_pos.y).abs() <= side_interact_radius; top = (rect.top() - mouse_pos.y).abs() <= side_interact_radius;
if rect.right_top().dist(mouse_pos) < corner_interact_radius { if rect.right_top().distance(mouse_pos) < corner_interact_radius {
right = true; right = true;
top = true; top = true;
} }
if rect.left_top().dist(mouse_pos) < corner_interact_radius { if rect.left_top().distance(mouse_pos) < corner_interact_radius {
left = true; left = true;
top = true; top = true;
} }
if rect.left_bottom().dist(mouse_pos) < corner_interact_radius { if rect.left_bottom().distance(mouse_pos) < corner_interact_radius {
left = true; left = true;
bottom = true; bottom = true;
} }

View file

@ -248,7 +248,7 @@ impl Context {
/// If the given Id is not unique, an error will be printed at the given position. /// If the given Id is not unique, an error will be printed at the given position.
pub fn register_unique_id(&self, id: Id, source_name: impl std::fmt::Debug, pos: Pos2) -> Id { pub fn register_unique_id(&self, id: Id, source_name: impl std::fmt::Debug, pos: Pos2) -> Id {
if let Some(clash_pos) = self.used_ids.lock().insert(id, pos) { if let Some(clash_pos) = self.used_ids.lock().insert(id, pos) {
if clash_pos.dist(pos) < 4.0 { if clash_pos.distance(pos) < 4.0 {
self.show_error( self.show_error(
pos, pos,
&format!("use of non-unique ID {:?} (name clash?)", source_name), &format!("use of non-unique ID {:?} (name clash?)", source_name),
@ -325,7 +325,7 @@ impl Context {
InteractInfo { InteractInfo {
rect, rect,
hovered, hovered,
clicked: hovered && active, clicked: hovered && active && self.input().mouse.could_be_click,
active, active,
} }
} else if self.input.mouse.down { } else if self.input.mouse.down {

View file

@ -84,6 +84,10 @@ pub struct MouseInput {
/// Where did the current click/drag originate? /// Where did the current click/drag originate?
pub press_origin: Option<Pos2>, pub press_origin: Option<Pos2>,
/// If the mouse is down, will it register as a click when released?
/// Set to true on mouse down, set to false when mouse moves too much.
pub could_be_click: bool,
/// How much the mouse moved compared to last frame, in points. /// How much the mouse moved compared to last frame, in points.
pub delta: Vec2, pub delta: Vec2,
@ -103,6 +107,7 @@ impl Default for MouseInput {
released: false, released: false,
pos: None, pos: None,
press_origin: None, press_origin: None,
could_be_click: false,
delta: Vec2::zero(), delta: Vec2::zero(),
velocity: Vec2::zero(), velocity: Vec2::zero(),
pos_tracker: MovementTracker::new(1000, 0.1), pos_tracker: MovementTracker::new(1000, 0.1),
@ -177,12 +182,23 @@ impl MouseInput {
let pressed = !self.down && new.mouse_down; let pressed = !self.down && new.mouse_down;
let mut press_origin = self.press_origin; let mut press_origin = self.press_origin;
let mut could_be_click = self.could_be_click;
if pressed { if pressed {
press_origin = new.mouse_pos; press_origin = new.mouse_pos;
could_be_click = true;
} else if !self.down || self.pos.is_none() { } else if !self.down || self.pos.is_none() {
press_origin = None; press_origin = None;
} }
if let (Some(press_origin), Some(mouse_pos)) = (new.mouse_pos, press_origin) {
// If mouse moves more than this, it is no longer a click (but maybe a drag)
const MAX_CLICK_DIST: f32 = 6.0;
could_be_click &= press_origin.distance(mouse_pos) < MAX_CLICK_DIST;
} else {
could_be_click = false;
}
if let Some(mouse_pos) = new.mouse_pos { if let Some(mouse_pos) = new.mouse_pos {
self.pos_tracker.add(new.time, mouse_pos); self.pos_tracker.add(new.time, mouse_pos);
} else { } else {
@ -199,6 +215,7 @@ impl MouseInput {
released: self.down && !new.mouse_down, released: self.down && !new.mouse_down,
pos: new.mouse_pos, pos: new.mouse_pos,
press_origin, press_origin,
could_be_click,
delta, delta,
velocity, velocity,
pos_tracker: self.pos_tracker, pos_tracker: self.pos_tracker,
@ -266,6 +283,7 @@ impl MouseInput {
ui.add(label!("released: {}", self.released)); ui.add(label!("released: {}", self.released));
ui.add(label!("pos: {:?}", self.pos)); ui.add(label!("pos: {:?}", self.pos));
ui.add(label!("press_origin: {:?}", self.press_origin)); ui.add(label!("press_origin: {:?}", self.press_origin));
ui.add(label!("could_be_click: {}", self.could_be_click));
ui.add(label!("delta: {:?}", self.delta)); ui.add(label!("delta: {:?}", self.delta));
ui.add(label!( ui.add(label!(
"velocity: [{:3.0} {:3.0}] points/sec", "velocity: [{:3.0} {:3.0}] points/sec",

View file

@ -53,11 +53,11 @@ impl Vec2 {
self.x * self.x + self.y * self.y self.x * self.x + self.y * self.y
} }
pub fn dist(a: Self, b: Self) -> f32 { pub fn distance(a: Self, b: Self) -> f32 {
(a - b).length() (a - b).length()
} }
pub fn dist_sq(a: Self, b: Self) -> f32 { pub fn distance_sq(a: Self, b: Self) -> f32 {
(a - b).length_sq() (a - b).length_sq()
} }
@ -231,11 +231,11 @@ impl Pos2 {
} }
} }
pub fn dist(self: Self, other: Self) -> f32 { pub fn distance(self: Self, other: Self) -> f32 {
(self - other).length() (self - other).length()
} }
pub fn dist_sq(self: Self, other: Self) -> f32 { pub fn distance_sq(self: Self, other: Self) -> f32 {
(self - other).length_sq() (self - other).length_sq()
} }