How to cancel drag-and-drop with ESC key?

seems to be working fine for me now, since this update.

There is no notification on the source side that the drag has been cancelled. Whatever you normally do in mouseUp then you may need to do in a timer and check that the drag is still active.

Thanks, but how would you know? mouseDrag() etc. continues to get called.
Installing a timer instead of getting notified is a hack and implementing a check that drag has been canceled would mean to invent the wheel again. Isn’t this the reason to use a framework? Shouldn’t it transparently handle all standard situations?

I agree, you should be able to pass a lambda into startDragging that notifies you when the drag has finished. But even with that, mouseDrag will continue to get called because the mouse is still dragging. In your mouseDrag you should check dnd->isDragAndDropActive ();

… and I think thats wrong: If the drag action is canceled why would we see still see dragging actions? To which drag event would they belong to? Maybe some internal juce state actually noticed it already, but for the user it’s simply not canceled.

Uhm, I agree that the high-level “gesture” of the drag and drop managed with DragAndDropTarget/Container should be interrupted when ESC is pressed, but I don’t think that mouseDrag() should stop being called after ESC is pressed.

mouseDrag() is a callback for a low-level event, and while your finger is still pressed on the mouse button, it makes sense that mouseDrag() is called until you lift it, causing mouseUp().

With respect to low-level mouse event, ESC shouldn’t have any special treatment IMHO, just like nothing special happens if I press ENTER, an arrow key, backspace or whatever while mouseDrag()s are being triggered.

1 Like

Yeah mouseDrag() isn’t limited to classic drag and drop operations. It’d be great to stop/cancel a drag operation from DragAndDropContainer programatically when e.g. certain touch events occur.

I was thinking along the lines of @yfede considering mouseDrag() after the ESC event.
However, the mouseDrag don’t arrive from the moment you call startDrag. Instead they are redirected to the DragAndDropContainer, IIUC?
In that case it would be surprising if they start to reappear once you click ESC. The cursor is most likely no longer over that component, and you would need to catch that so it doesn’t start a new drag right away.
Instead I think the further mouseDrag should be silently ignored until the user releases the mouse button.

Why would it start dragging right away? The user needs to actively call startDrag(). There is simply no reason and no use-case to continue to send out mouseDrag() events after it has been canceled.

Are we talking about the same mouseDrag ie Component::mouseDrag?

When a mouse button is pressed inside a component, that component receives mouseDrag callbacks each time the mouse moves, even if the mouse strays outside the component’s bounds.

Yes, mouse drag callbacks should be made as long as the mouse is being dragged. This has nothing to do with a drag / drop operation, which may or may not be cancelled at any time.

2 Likes