Best way to customize drag and drop?

When the user drags an object out of my list, I’m putting together a fancy drag image. But when the mouse goes over my tree view I want the big drag image to disappear and the cursor just to change, because otherwise the big drag image covers up the destination tree view.

I’m already providing hilighting in the tree to show the user where the item will be dropped, in the form of a rectangular glowing outline.

The problem is, how do I hook into the drag and drop code to cleanly change the image during the drag, from the item that wants to change behavior?

Ah, that’s not something I ever added hooks for… It’d require a fair bit of under-the-hood hackery, I’d imagine.

Would you be open to some of my ideas for implementing this?

I’m thinking, a really quick and unobtrusive way to accomplish this would be to add a new abstract interface, like:

class DragAndDropAppearanceListener
  virtual void onDragAndDropImageHook (Image& image) { }

During the drag and drop tracking, we could use dynamic_cast on the Component under the mouse, to test for this interface. If we get nullptr, everything works the way it did before.

If we see this interface, then we give the class an opportunity to push a new image onto a “stack”. When the cursor moves off the component, or when the drag finishes, we pop the stack / destroy the stack. The drag image displayed is always the image on top of the stack.

Something like this. Anyway the overall goal is to do this quickly and cleanly without affecting many places. What do you think?

Yeah, I guess having a stack makes sense. I don’t think I’d want to clutter things up with yet another callback interface though - maybe just a new method in DragAndDropContainer that lets you push/pop a new drag image, and you could call that from the existing callback as necessary.

So the DragAndDropTarget, in its callback during the drag would retrieve the parent DragAndDropContainer and call some function on it?

Yes, that’s probably how I’d approach it.

Okay, I will work something up in a separate branch and you can have a look-see.