C++ plugin UI delegate functions

Hi

I’m trying to set a delegate function for the OnClicked() attribute of an SButton. And have that function modify a member variable. I’ve begun with the editor mode plugin wizard to set up my c++ files.

In my .h I have

class FVASFVPluginEdModeToolkit : public FModeToolkit
{
public:
	FVASFVPluginEdModeToolkit();

private:
	float completePercent = 0.0f;
};

and in .cpp I have

FVASFVPluginEdModeToolkit::FVASFVPluginEdModeToolkit()
{
	struct Locals
	{
		FReply OnNewVolumeManagerButtonClick()
		{
			UE_LOG(VASFVLog, Warning, TEXT("OnNewVolumeManagerButtonClick"));
			completePercent += 0.5f;
			return FReply::Handled();
		}
	}
	
	SAssignNew(ToolkitWidget, SBorder)
	...
	+ SVerticalBox::Slot()
		[
			SNew(SButton)
			.Text(FText::FromString("New Volume Manager"))
			//.OnClicked_Static(&Locals::OnNewVolumeManagerButtonClick)
		]
	]; //END UI
	
}

In the constructor of the plugin, I can set up functions in the Locals struct which can be set as the OnClicked_Static() attribute of an SButton. But as soon as I try to modify a member variable of the plugin in that function I get the compilation error “a nonstatic member reference must be relative to a specific object”.

I think I understand this is because:

.OnClicked_Static(&Locals::OnNewVolumeManagerButtonClick)

would actually call the class function, which should be only static? Whereas I want to be calling the function of my object, and modifying its member variables.

I’ve tried changing to:

.OnClicked(&Locals::OnNewVolumeManagerButtonClick)

but I get the compilation error “no instance of overloaded function “SButton::FArguments::OnClicked” matches the argument list”

My question is how can I have a delegate function run when an SButton is clicked, and how can that function modify a member variable of the plugin? I haven’t found any tutorials on plugin UIs.

Thanks for reading

Your function is not static you would need to ■■■ “static” before FReply in function decleration and it seems it suppose to not be static considering you modifying inner varable.

For non-static functions you need to point to object instance on which function will be called in, sale since this is local struct you should add a class namespace to function pointer (but im not sure)

.OnClicked(X,&Locals::OnNewVolumeManagerButtonClick)

X need to be pointer to struct object, if you declere your struct without “*” like this:

Locals X;

You need to add “&” to turn it in to pointer:

.OnClicked(&X,&Locals::OnNewVolumeManagerButtonClick)

If this does not work do this:

.OnClicked(&X,&FVASFVPluginEdModeToolkit::Locals::OnNewVolumeManagerButtonClick)

I’m not sure if TAttributes bindings can work with structs.

Speaking of which you setup seems to be very wierd, you making struct inside constructor? where object of struct? this struct will die once constructor is done, so you might have ferther problems later on.

By looks of it you seem to want to create anonymous function, if that the case there easier way to do so:

.OnClicked_Lambda([&](){
             UE_LOG(VASFVLog, Warning, TEXT("OnNewVolumeManagerButtonClick"));
             completePercent += 0.5f;
             return FReply::Handled();
})
1 Like

Hi, thanks for helping out!

Ah that makes sense. Yeah I don’t want a static function. I really don’t want the function to die once the constructor is done. Should I instead define a class member function outside of the constructor, and put it’s definition in the header file?

How could I then link that class function to the button’s OnClicked attribute?

Thanks!

.OnClicked(this,&FVASFVPluginEdModeToolkit::OnNewVolumeManagerButtonClick)

and “this” ofcorse is a object of a class, if you set attribute in class it self use “this”

Hey thanks!
I couldn’t get that to work with .OnClicked but .OnClicked_Raw seems to work perfectly!