-
Notifications
You must be signed in to change notification settings - Fork 1.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Better distinction of dragged vs clicked #547
Comments
I think it would make sense if egui would not report In /// If the pointer moves more than this, it is no longer a click (but maybe a drag)
const MAX_CLICK_DIST: f32 = 6.0;
/// The new pointer press must come within this many seconds from previous pointer release
const MAX_CLICK_DELAY: f64 = 0.3; We should probably not consider it a drag until the mouse has moved that many pixels or have been down for that many seconds. |
I see, and actually, my simple workaround is not great after some more testing. If you need very fine dragging you almost never find the sweet spot. I think the most intuitive would be the time the mouse has been down. A very small delay until you can start dragging is less problematic, but I would still expose it through a builder parameter as one might still want the super responsive drag response and not care about actual clicks. |
Related change: a76b816 (don't register as click if the pointer has been pressed for too long) |
Just a note for anyone else who needs a solution to this, I started from the example code here https://github.com/emilk/egui/blob/master/crates/egui_demo_lib/src/demo/drag_and_drop.rs Most of this is duplicating the functionality in egui of setting has_moved_too_much_for_a_click, but it isn't publicly exposed. The other issue is that the logic in egui can only start on a drag on the same frame as when the mouse goes down, so we have to set that manually too. Modified: // Check for drags:
let mut allow_check_for_drag = false;
ui.input(|input| {
if let Some(press_origin) = input.pointer.press_origin() {
if let Some(latest_pos) = input.pointer.latest_pos() {
if press_origin.distance(latest_pos) > 6.0 {
allow_check_for_drag = true;
}
}
}
});
if allow_check_for_drag && response.hovered() {
ui.memory_mut(|mem| mem.set_dragged_id(id));
} |
Hello,
First of all, I'd like to point out how amazing the library is. It does most of what one would expect from an immediate-mode GUI and can easily handle new cases/features. Thanks for all the time passed on working on this!
Now on my issue, which might actually not be an issue but intended. When using
dragged()
on a Response of a widget to detect a change, I noticed that clicking on a widget also seems to count as dragged. At least on anegui::DragValue
. Is this intended? In my case, I want to allow the user to change the field (by clicking and entering a custom value) without triggering a change, if not explicitly dragged. A workaround that works well for me uses an epsilon value to differentiate between a simple click or a "real" drag action, something like:if response.drag_delta().max_elem() > 1e-5 { do_something(); }
. Also note that(response.dragged() && !response.clicked())
does not result in not detecting a change when clicked (which definitely looks like a bug).Should this approach be the default behaviour when checking for
dragged()
, or are there specific use cases where a simple click should count as a drag event? My choice of epsilon is, of course, completely arbitrary, and I suppose there are better choices.Best,
Philippe
The text was updated successfully, but these errors were encountered: