Editor Utility Widgets are one of the new feature of the Unreal Engine since 4.22. It allows users to define editor widgets using the UMG designer. We already covered this topic previously, so if you want to start with Editor Utility Widgets, you may want to check this article, this one and this one.

In this article, we will answer to a question we can have when using the Editor Utility Widgets: how can we programmatically start an Editor Utility Widget?

If you are wondering how an Editor Utility Widget can start another Editor Utility Widget, this article will explain you how to do it.

In the previous articles, the only way to start the Editor Utility Widget was to perform a right-click on it and select Run Editor Utility Widget. But it’s also possible to start it programmatically using C++ and blueprints.

Starting an Editor Utility Widget from C++

First of all, this is an editor only function, so we will need to create a new editor plugin (everything is explained for this in the previous article about Editor Utility Widgets in C++).

For this plugin, we will require several dependencies, so the following section must be added to the Build.cs:


PrivateDependencyModuleNames.AddRange(
	new string[]
	{
		"CoreUObject",
		"Engine",
		"Slate",
		"SlateCore",
                "UnrealEd",
                "Blutility",
                "UMG",
                "UMGEditor"
		// ... add private dependencies that you statically link with here ...	
	}
	);

Then, in this plugin, we will create a UBlueprintFunctionLibrary. Actually, it can be any class, but we will only need to create a static function allowing us to start the Editor Utility Widget, so a UBlueprintFunctionLibrary is enough.

The header of this class will give something like this:


#include "CoreMinimal.h"
#include "Editor/Blutility/Classes/EditorUtilityWidget.h"
#include "Runtime/Engine/Classes/Kismet/BlueprintFunctionLibrary.h

#include "EditorWidgetFunctionLibrary.generated.h"

UCLASS(BlueprintType)
class CPPEDITORWIDGET_API UEditorWidgetFunctionLibrary : public UBlueprintFunctionLibrary
{
	GENERATED_BODY()

public:
	UFUNCTION(BlueprintCallable)
		static void StartWidget(UWidgetBlueprint* Blueprint);
};

The important points to note here are the presence of a StartWidget static function taking as parameter a UWidgetBlueprint object. We may also note the required includes.

The corresponding part in the cpp file with the implementation of the function will be like this:


#include "EditorWidgetFunctionLibrary.h"

#include "Editor/UMGEditor/Public/WidgetBlueprint.h"
#include "Editor/LevelEditor/Public/LevelEditor.h"
#include "Runtime/Core/Public/Modules/ModuleManager.h"
#include "Editor/Blutility/Public/IBlutilityModule.h"
#include "Editor/Blutility/Classes/EditorUtilityWidgetBlueprint.h"

void UEditorWidgetFunctionLibrary::StartWidget(UWidgetBlueprint* Blueprint)
{
	if (Blueprint->GeneratedClass->IsChildOf(UEditorUtilityWidget::StaticClass()))
	{
		const UEditorUtilityWidget* CDO = Blueprint->GeneratedClass->GetDefaultObject();
		if (CDO->ShouldAutoRunDefaultAction())
		{
			// This is an instant-run blueprint, just execute it
			UEditorUtilityWidget* Instance = NewObject(GetTransientPackage(), Blueprint->GeneratedClass);
			Instance->ExecuteDefaultAction();
		}
		else
		{
			FName RegistrationName = FName(*(Blueprint->GetPathName() + TEXT("_ActiveTab")));
			FText DisplayName = FText::FromString(Blueprint->GetName());
			FLevelEditorModule& LevelEditorModule = FModuleManager::GetModuleChecked(TEXT("LevelEditor"));
			TSharedPtr LevelEditorTabManager = LevelEditorModule.GetLevelEditorTabManager();
			TSharedRef NewDockTab = LevelEditorTabManager->InvokeTab(RegistrationName);
		}
	}
}

For information, this function is extracted from FAssetTypeActions_EditorUtilityWidgetBlueprint::ExecuteRun(FWeakBlueprintPointerArray InObjects) in AssetTypeActions_EditorUtilityWidgetBlueprint.h.

Once this code copied in the plugin, we have everything required to start an Editor Widget Utility from C++. We just need to call StartWidget with a reference on the UWidgetBlueprint we want to start.

Usage in blueprints

The function previously defined is exposed to blueprints (marked as BlueprintCallable), this means the plugin we created allow us to programmatically start Editor Utility Widgets using blueprints. Indeed, the StartWidget function is callable from other Editor Utility Widgets, so now an Editor Utility Widget can start another widget.

And it’s straightforward:

Here we just created a simple Editor Utility Widget with only one button, and on the click on this button we want to spawn another widget. And, the previous figure shows all we need to do to implement this.

Conclusion

This article presents how we can programmatically start an Editor Utility Widget using either C++ or blueprints (but with the creation of a C++ plugin being mandatory).

And just so you know, this article is actually a request from a reader willing to know how to programmatically start an Editor Widget Blueprint (right now there’s still a lack of documentation and ressources about Editor Utility Widgets). If you’re interrested in more articles about this, or if you want to request an article about a specific topic, you can follow us and contact us on Twitter and Facebook.