On a UMG Button, how to handle DragDrop functionality while retaining OnClicked functionality?

Thank you both for your quick replies. I ended up using something very similar to Zhi Kang Shao’s solution, but I read both answers and incorporated both of your input into mine. This is what worked for me.

The HUD/Grid widget, which is basically just a 12x12 UniformGridPanel of custom buttons:

311612-ue-forum-answer-grid.png

The UniformGridPanel had to be set to Visible in order for OnDrop to work. Also, the custom buttons are all Visible. Everything else is “Not Hit-Testable (Self Only)”.

The custom Button widget:

311613-ue-forum-answer-custom-button.png

Both the “Button” and “ButtonAppearance” widgets are actually Borders and not Buttons. “Button” is invisible and fills the entire available space so that it can accept mouse inputs. Also, note that it is listed as the last of the Overlay children so that it is “on top” of the ButtonAppearance and the inputs will all be received without getting blocked. Everything is set to Visible, though Button has its Render Opacity set to 0.0 to be invisible when rendered.

NOTE: I initially encountered a problem getting the buttons to render at all after I had changed them to both be Border widgets. It turns out that it was the Content Padding. If they are both set to 0.0 then nothing will render. One or the other needs a positive value in order for them to render properly. I used a value of 0.5 for the Button and kept the ButtonAppearance’s Content Padding at 0.0.

Inside the Custom Button widget, I needed a boolean variable “bIsPressed” for when the left mouse button had been pushed down (but not yet released) on the button, and also has not left the button’s area. It defaults to false, is set to true in OnMouseButtonDown, and is checked in OnMouseButtonUp, and if true, then a CustomOnClicked event is fired which takes the place of the regular event OnClicked. It is set to false in OnMouseEnter, OnMouseLeave, OnDragEnter, and OnDragLeave. All four of those imply that, since the mouse button was first pushed down, the cursor has since left the button’s area, and therefore will not count as a Click.

However, I did not need a “bIsDragging” variable like Zhi Kang Shao did, for whatever reasons. All I did was create a new BP class from DragDropOperation, which contained two variable references to my custom button class as SourceNode and DestinationNode. I created an instance of this operation from OnDragDetected:

NOTE: I had promoted the DraggedWidget (which doesn’t work yet, but… irrelevant) to a variable so that in OnDragCancelled/OnDrop I could destroy it. However, I was surprised to learn that you can’t destroy widgets, but only remove them from their parent widgets, and let the GC take care of it. So… I’m not sure if that is necessary; probably not.

OnDrop was the only mouse event that I didn’t handle inside the custom button, but rather in the HUD/Grid, where I just cast the operation input pin to my custom operation and did what I needed to with the data.

I could no longer using the OnHovered and OnUnhovered events for the button, since they don’t exist for a Border, but OnMouseEnter and OnMouseLeave do exist, and they served the exact same purpose.

Thank you again to both of you!

2 Likes