In the previous articles, we have seen how we can define editor widgets with blueprints and how define an editor widget from C++. But, while we have seen the basics of the creation of such widgets, we have not studied how we can build a widget from C++, i.e. selecting the components to display and writing the logic behind. This tutorial will present you how it can be done, by doing something similar to the tutorial with blueprints, but using C++.

To start, we will start by creating a class which extend EditorUtilityWidget in a plugin (the previous tutorial describes the steps to do so).
Once it’s done, we are ready to build the widget from C++.

Defining the class attributes and functions

In this example, we will create an Editor Widget in C++ which will contain a button: when clicked, a message will be print on the screen.

So, to begin we will create a property to contain the message to be displayed on the screen, like this:


UPROPERTY(EditAnywhere, BlueprintReadWrite)
FText Message;

We set this property as editable, so it can be edited in the widget blueprint which will extend this class.

And a function to print the message on the screen:


UFUNCTION(BlueprintCallable)
void PrintText();

Defined like this:


void UMyEditorWidgetClass::PrintText()
{
	DEBUG_TEXT(*this->Message.ToString())
}

With:


#define DEBUG_TEXT(x, ...) if(GEngine){GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Red, FString::Printf(x, __VA_ARGS__));}

Defining the components

We want to create a button that when clicked will call the PrintText() function. To edit the components of the widget, we will override the NativePreConstruct() method and we will construct our widget there. It could also work by overriding NativeConstruct but this way we will be able to preview the widget with the widget blueprint. The rules of construction are the same than for any UMG widget written in C++, so if you are familiar with C++ UMG widgets, there’s nothing new. This is what it will looks like:


void UMyEditorWidgetClass::NativePreConstruct()
{
	Super::NativePreConstruct();

	// The default root widget is a canvas panel
	UWidget* RootWidget = GetRootWidget();
	UCanvasPanel* CanvasPanel = static_cast(RootWidget);

	// Here we create a text block
	UTextBlock* TextBlock = NewObject();
	TextBlock->SetText(FText::FromString("Hello World"));

	// Then a button which contains the text block
	UButton* Button = NewObject();
	Button->SetContent(TextBlock);
	Button->OnClicked.AddDynamic(this, &UMyEditorWidgetClass::PrintText);

	CanvasPanel->AddChildToCanvas(Button);
}

There nothing about styling, setting the text size or anything else, so it will be ugly, but at least it shows the basics.

Testing everything

Now, that everything is written, we can test it to see how it works. So, we need to create an Editor Widget Blueprint which extends this class.

Once it’s done, in the blueprint Graph, we will have this (to set the C++ class as the parent class):

And if we open just after the Designer view, we will have this:

We can now do a right click on the asset and click on Run Editor Utility Widget. The widget will then be displayed. It will look like the one which was defined in the article about Editor Widget Blueprints, except this one is entirely defined in C++.

Conclusion

In this tutorial, we have seen how an Editor Widget Blueprint can be defined using C++. Obviously, if we don’t have the need to use C++ functions, it’s usually better to make everything with the blueprint editor, but sometimes we don’t have the choice (for instance if we want to make system calls in the editor widget, or build it according to results from an external library). It was possible, before the 4.22, to define editor widgets using C++. But what is great with 4.22 is that now, we can make this editor widgets in C++ and extend them with the UMG designer and the blueprint graph editor. It allows us to benefits from the power of C++ and the usability of the UMG designer.

This article concludes (for the moment) the short serie of articles about the 4.22 Editor Widgets. But 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.