We are making an editor utility widget to control and modify some custom made BP assets and other custom UObjects.
So far so good, but the designers asked us to make a dropdown menu in the same vein as the unreal’s menus, with subcategories and other dropdowns appearing if the subcategory allow it.
Like if you go in the Window menu, you have the Level Editor category and inside the Cinematics that shows another dropdown menu with Camera Shake previewer, Sequencer etc etc.
At the moment, all we have is a very simple Combobox string that shows the name of some BP assets and when you select one, it sets that selection in another BP as a TSubclassOf variable, nothing too complicated and it’s working as intended, so the modification asked is purely “visual”
Now, I believe that the Editor menus are made with Slate and we are using Editor Utility Widget, so my first question is : is the change asked even possible to make or will we have to re do things entirely in Slate ?
(From what I saw, it’s a bit radically different and does not allow us to have a visual approach on how to design the window which would be a problem)
After some research, I saw that the class I’m looking for is the FMenuBuilder with Slate but then, would it be possible to create a menu with that class and then wrap it in a UWidget so I can use it in my Editor Utility Widget ?
After some more tweaking i finally got this result:
This is UMG Slider widget, integrated into the slate toolbar.
There is one HUGE problem with this solution: it crashes if i try to fill this menu on plugin startup and if i try to load another map.
Crash occurs because I create widget with World parent. In theory, if I’ll manage to parent it to something else (app or other UWidget or anything else), it will be perfectly working solution.
My current code looks like this:
const UBlueprint* Blueprint = Cast<UBlueprint>(UEditorAssetLibrary::LoadAsset(Reference));
if (!Blueprint) return;
//Gets widget class from the blueprint
TSubclassOf<UEditorUtilityWidget> const WidgetClass = Blueprint->GeneratedClass;
TSharedRef<SBorder> Window = SNew(SBorder);
TSharedRef<SWidget> SlateWidget = SNew(SHorizontalBox)
+SHorizontalBox::Slot()
.AutoWidth()
[
Window
];
if (SlateWidget.ToSharedPtr().IsValid())
{
FToolMenuEntry& Entry = Section.AddEntry(
FToolMenuEntry::InitWidget(TEXT("Name"),
SlateWidget,
LOCTEXT("Label", "Label"),
0,
0,
0)
);
Window->SetContent(GetSlateWidgetFromUMGClass(WidgetClass));
}
UToolMenus::Get()->RefreshAllWidgets();
Some logic may be redundant, so please be careful when referencing this code.
I’ll post an update if I’ll be able to solve the crash or find some workaround, but please tell me if you’ll be able to solve it sooner.