From 55a3ed38eaba0a7d73d69d1f9b8c60291824e0ac Mon Sep 17 00:00:00 2001 From: valadaptive Date: Fri, 27 Sep 2024 08:04:52 -0400 Subject: [PATCH 1/2] Update ScrollArea drag velocity when drag stopped Fixes #5174. The drag velocity was not being updated unless the cursor counted as "dragging", which only happens when it's in motion. This effectively guarantees that the drag velocity will never be zero, even if the cursor is not moving, and results in spurious scroll velocity being applied when the cursor is released. Instead, we update the velocity only when the drag is stopped, which is when the kinetic scrolling actually needs to begin. --- crates/egui/src/containers/scroll_area.rs | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) diff --git a/crates/egui/src/containers/scroll_area.rs b/crates/egui/src/containers/scroll_area.rs index ab7da8aff29..b7da4bf8528 100644 --- a/crates/egui/src/containers/scroll_area.rs +++ b/crates/egui/src/containers/scroll_area.rs @@ -621,20 +621,35 @@ impl ScrollArea { .interact_rect .map(|rect| ui.interact(rect, id.with("area"), Sense::drag())); - if content_response_option.map(|response| response.dragged()) == Some(true) { + if content_response_option + .as_ref() + .is_some_and(|response| response.dragged()) + { for d in 0..2 { if scroll_enabled[d] { ui.input(|input| { state.offset[d] -= input.pointer.delta()[d]; - state.vel[d] = input.pointer.velocity()[d]; }); state.scroll_stuck_to_end[d] = false; state.offset_target[d] = None; - } else { - state.vel[d] = 0.0; } } } else { + // Apply the cursor velocity to the scroll area when the user releases the drag. + if content_response_option + .as_ref() + .is_some_and(|response| response.drag_stopped()) + { + for d in 0..2 { + if scroll_enabled[d] { + ui.input(|input| { + state.vel[d] = input.pointer.velocity()[d]; + }); + } else { + state.vel[d] = 0.0; + } + } + } for d in 0..2 { // Kinetic scrolling let stop_speed = 20.0; // Pixels per second. From d063466e2f2b291c907595bd3ae8153f91ddcd20 Mon Sep 17 00:00:00 2001 From: valadaptive Date: Tue, 1 Oct 2024 14:46:13 -0400 Subject: [PATCH 2/2] Add and use Vec2b#to_vec2 --- crates/egui/src/containers/scroll_area.rs | 11 ++--------- crates/emath/src/vec2b.rs | 8 ++++++++ 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/crates/egui/src/containers/scroll_area.rs b/crates/egui/src/containers/scroll_area.rs index b7da4bf8528..3b3925c9dcd 100644 --- a/crates/egui/src/containers/scroll_area.rs +++ b/crates/egui/src/containers/scroll_area.rs @@ -640,15 +640,8 @@ impl ScrollArea { .as_ref() .is_some_and(|response| response.drag_stopped()) { - for d in 0..2 { - if scroll_enabled[d] { - ui.input(|input| { - state.vel[d] = input.pointer.velocity()[d]; - }); - } else { - state.vel[d] = 0.0; - } - } + state.vel = + scroll_enabled.to_vec2() * ui.input(|input| input.pointer.velocity()); } for d in 0..2 { // Kinetic scrolling diff --git a/crates/emath/src/vec2b.rs b/crates/emath/src/vec2b.rs index f241de64ed5..673f2959e0f 100644 --- a/crates/emath/src/vec2b.rs +++ b/crates/emath/src/vec2b.rs @@ -1,3 +1,5 @@ +use crate::Vec2; + /// Two bools, one for each axis (X and Y). #[derive(Copy, Clone, Debug, Default, PartialEq, Eq)] #[cfg_attr(feature = "serde", derive(serde::Deserialize, serde::Serialize))] @@ -43,6 +45,12 @@ impl Vec2b { y: self.y || other.y, } } + + /// Convert to a float `Vec2` where the components are 1.0 for `true` and 0.0 for `false`. + #[inline] + pub fn to_vec2(self) -> Vec2 { + Vec2::new(self.x.into(), self.y.into()) + } } impl From for Vec2b {