Click and Drag&drop

I’m trying to make an inventory slot widget that can be clicked to open an item info screen or dragged and dropped to move the item around the inventory. I was able to use the DetectDragIfPressed() in MouseButtonDown to drag, but when I attempt to add the click functionality, it doesn’t seem like there’s a way to do both. I’m not using default buttons and I’ve been trying this in Blueprint (with the widget) and C++ (with a parent of the widget - still a UUserWidget). I’m in Unreal Engine 5.5.4.

My thought process is: OnMouseButtonDown will record the mouse position, OnMouseMove will keep checking if the current position’s distance to the original position is greater than a threshold amount (5-10), if it is - its a drag and to start drag logic (but i can’t call DetectDragIfPressed late, has to be OnMouseButtonDown), and then OnMouseButtonUp if it was not a drag then it was a click and to handle click logic (opening the item info widget).

I’ve been experiencing issues when trying to use DetectDragIfPressed, since the same implies that it will “Detect” the drag, but it simply says its a drag right away anyways if the given key matches.

2 Likes

Still no luck. I’ve also been checking out countless inventory tutorials, but none of them get past a simple drag and drop - usually they just do a tooltip or some kind of hover over info box. What I’m wanting needs the slot to be clicked and a separate widget comes up with item information, and if dragged then it’d be the normal item moving. I’ve started building out my own, but I would have to handle the drag and drop operations without using Slate/UMG built-in functions.

While I have to mention that using built-in buttons would probably be easier, here are some notes:

  • the only check DetectDragIfPressed performs is whether the provided key is pressed or not, the name is a bit misleading, it’s meant to be used to conditionally construct a FEventReply (it literally doesn’t do anything else, there are no “consequences” of calling this)
  • consider using OnMouseButtonUp for the info screen instead, that way you can trivially perform dragging (= drag while pressed, with some thresholds to check whether the mouse is actually moving)

I’m currently making a custom widget to handle the click and drag&drop functions. It doesn’t seem like the default UMG drag & drop allows anything other than just the dragging and dropping (no clicking).

It is, but this doesn’t change the problems of the click/drag&drop

Yes, but you’d have to call this in MouseButtonDown, but you wouldn’t know if it was a drag at that moment - which is why once you call it, Slate handles detecting if its a drag (I’m not sure how, because it seems like its always a drag once its called)

To handle if it was a click, the click logic is OnMouseButtonUp since that is when the click is completed and if the drag threshold was not passed, it was a click.. But for drag logic, its a simple boolean whether it passed the threshold in OnMouseMove (for my custom logic, otherwise Slate would handle it) - but my custom logic would also require capturing the mouse for movement outside the widget (which also breaks the DetectDragIfPressed built-in functions)

Ah ok, I misread, you’re already using Up for click, that’s fine then.

To repeat myself, Slate doesn’t do anything else in that function other than checking whether the key is pressed or not. The function is solely used for creating a “drag” FEventReply to pass to other functions and whatnot. I can copy you the code if you’d like. :smiley:

To rephrase my suggestion from earlier, always returning a drag on OnMouseButtonDown should be fine, but just wait for a threshold to be reached to actually start moving the item around. As for the “capturing the movement outside the widget”, you may want to set “Capture Mouse” on the FEventReply during OnMouseButtonDown before you return it.

I don’t know why this didn’t click earlier, but thank you.
For any future me’s: The answer was

(That function being DetectDragIfPressed)
This is important because Slate will just reply saying that it will take care of it later, so you’re still free to have things going on. Just set a boolean after it detects drag, then OnMouseButtonUp, you check if that boolean is true or not.

Here’s my Blueprints that work now, I used OnPreviewMouseButtonDown but will switch it to OnMouseButtonDown since generally preview shouldn’t be used. Also, I had to add handling to OnMouseButtonDoubleClick to act like an OnMouseButtonDown again, since I don’t want a double click feature.


Overriding OnDragDetected to set a boolean and create a drag drop operation (Where it says Create WB Preview Slot Widget)

And OnMouseButtonUp just checks if those booleans were set and then does the click/drag&drop logic.

THANK YOU KEMICHAR, I’ve been stuck on this for over a month when the solution was so simple.

1 Like