Fix drag-and-drop termination condition bug (#5452)
I introduced this in #5433. TL;DR: there are two termination conditions for drag-and-drop operations: - ESC - release mouse The former _must_ happen at frame start (to properly capture the keystroke). The latter _must_ happen at end-of-frame (to _not_ shadow the mouse release event from user code). This is now properly documented.
This commit is contained in:
parent
5384600fa2
commit
13352d6064
|
|
@ -27,31 +27,38 @@ impl DragAndDrop {
|
||||||
ctx.on_end_pass("drag_and_drop_end_pass", Arc::new(Self::end_pass));
|
ctx.on_end_pass("drag_and_drop_end_pass", Arc::new(Self::end_pass));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Interrupt drag-and-drop if the user presses the escape key.
|
||||||
|
///
|
||||||
|
/// This needs to happen at frame start so we can properly capture the escape key.
|
||||||
fn begin_pass(ctx: &Context) {
|
fn begin_pass(ctx: &Context) {
|
||||||
let has_any_payload = Self::has_any_payload(ctx);
|
let has_any_payload = Self::has_any_payload(ctx);
|
||||||
|
|
||||||
if has_any_payload {
|
if has_any_payload {
|
||||||
let abort_dnd = ctx.input_mut(|i| {
|
let abort_dnd_due_to_escape_key =
|
||||||
i.pointer.any_released()
|
ctx.input_mut(|i| i.consume_key(crate::Modifiers::NONE, crate::Key::Escape));
|
||||||
|| i.consume_key(crate::Modifiers::NONE, crate::Key::Escape)
|
|
||||||
});
|
|
||||||
|
|
||||||
if abort_dnd {
|
if abort_dnd_due_to_escape_key {
|
||||||
Self::clear_payload(ctx);
|
Self::clear_payload(ctx);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Interrupt drag-and-drop if the user releases the mouse button.
|
||||||
|
///
|
||||||
|
/// This is a catch-all safety net in case user code doesn't capture the drag payload itself.
|
||||||
|
/// This must happen at end-of-frame such that we don't shadow the mouse release event from user
|
||||||
|
/// code.
|
||||||
fn end_pass(ctx: &Context) {
|
fn end_pass(ctx: &Context) {
|
||||||
let mut is_dragging = false;
|
let has_any_payload = Self::has_any_payload(ctx);
|
||||||
|
|
||||||
ctx.data_mut(|data| {
|
if has_any_payload {
|
||||||
let state = data.get_temp_mut_or_default::<Self>(Id::NULL);
|
let abort_dnd_due_to_mouse_release = ctx.input_mut(|i| i.pointer.any_released());
|
||||||
is_dragging = state.payload.is_some();
|
|
||||||
});
|
|
||||||
|
|
||||||
if is_dragging {
|
if abort_dnd_due_to_mouse_release {
|
||||||
ctx.set_cursor_icon(CursorIcon::Grabbing);
|
Self::clear_payload(ctx);
|
||||||
|
} else {
|
||||||
|
ctx.set_cursor_icon(CursorIcon::Grabbing);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue