Editor Utility Widget- How to detect drag and drop operation in Level Editor Viewport?

Hello,

I’m trying to build a tool that displays a large number of items in a List Entry View inside an Editor Utility Widget. I want to be able to drag an item from the list and drop it into the Level Editor Viewport so that the corresponding actor is spawned at the mouse location.

The drag operation is already working, and the spawn logic is implemented as well. But I don’t know how to do the drop operation in the Level Editor Viewport.

For instance, I’ve tried with “on drag cancelled”. But the issue is, obviously, this event can be triggered from anywhere in any viewport or even widget. And the actor would then always be spawned at the same location in the word.

I would love to get some help on the matter.
Thanks!

The Level Editor viewport does not expose drag-drop events directly to EUW Blueprints. You must handle drag-drop events inside the Level Editor Viewport widget or an editor viewport extension, which requires C++, and also override drag-drop events in the editor viewport widget.

Hello,
I suspected it was the case indeed. So here I am, trying to learn C++.
I’m not sure to go far in that process (might be a very advanced stuff to do), but at least I would have tried anyway.

Take a look at Scriptable Tools. There are quite a lot of interesting features there, and you might find a solution.

I did not know about that! Looks interresting!
I’ll keep on learning more about C++ while I have some motivation (this is so tedious and cumbersome compared to Blueprint omg) but I’ll keep that in mind.
Thanks for pointing me this tool out!

Could not resist, and I’ve taken a look at it.
It looks really good! I might have a single issue; do you know how to call an Editor Utility Blueprint (or an Editor Scriptable) from an Editor Utility Widget?

Please describe exactly which blueprint you want to call up, send me a picture, and I’ll do my best to help you.

Hey, that’s very kind of you!
It happens I managed to find a way to make it work! (basically, select an actor/something from an editor utility widget and then being able to spawn that same actor/something in the world.)

I made a video about it since I found no other ressources talking about it and I figured it could interest some people.

I could have not figured this out without your help and you mentioning the Scriptable Tools, thanks a lot!

Glad to hear you managed to find a solution! I’ve been struggling with C++ in Unreal on my own for about a year now, and it’s both extremely challenging and really interesting. If you run into any issues, feel free to message me privately—I’ll do my best to help.

I managed to do this in one of my projects. The thing that was the “aha-moment” for me was that you’ll notice that drag-cancelled events are called no matter where the mouse is on the screen, it doesn’t need to be over a widget, unlike the drop-event.

I used this to my advantage and wrote some C++ helper functions to detect if the mouse is inside the editor viewport when the cancellation happened, and spawned an actor at the mouse cursor. The issue though is that it only checks if the cursor is literally within the bounds of the viewport and nothing else. Which means that the drop functionality “goes through” windows that are on top of the viewport. But that’s a shortcoming I’m ok with.

This was the code I came up with to check the mouse cursor:

bool UFrameworkEditorSubsystem::IsCursorInsideViewport(UObject* WorldContextObject)
{
    FVector2D TopLeftCoords = GEditor->GetActiveViewport()->ViewportToVirtualDesktopPixel(FVector2D(0,0));
    FVector2D BottomRightCoords = GEditor->GetActiveViewport()->ViewportToVirtualDesktopPixel(FVector2D(1,1));
    
    FVector2D MousePosition = UWidgetLayoutLibrary::GetMousePositionOnViewport(WorldContextObject);
    
    if (MousePosition.X > TopLeftCoords.X && MousePosition.Y > TopLeftCoords.Y)
    {
       if (MousePosition.X < BottomRightCoords.X && MousePosition.Y < BottomRightCoords.Y)
       {
          return true;
       }
    }
    
    return false;
}

(post deleted by author)

It’s good to know it’s possible to do that in C++, but I don’t know anything about it. I don’t think you can do that in BP right now since the properties/functions “getActiveViewport” don’t seem to be exposed in BP.

Thanks for the heads up anyway!

Yeah, it’s not possible in blueprints. GEditor is hidden (I think), and by extension all its members. If you decide to go for C++ in the future, know that it’s pretty simple to do.