benui
(benui)
April 22, 2016, 1:34pm
1
I would like to make a plugin to add some actions to the Node Actions list for all nodes.
For example I thought it might be cool to add a “swap inputs” function to the right-click Node Actions menu.
I’ve found the function GetContextMenuActions in the engine that seems to populate the list for each node type, but how can I get my plugin to wrap/override this function?
fpwong
(fpwong)
June 3, 2017, 9:41am
2
+1 for this, would like to know how to extend an engine class from a plugin.
zosiu
(zosiu)
September 20, 2022, 6:24pm
3
It can be done through GraphEditorModule
, here’s an example on how to add your own extender:
#pragma once
#include "CoreMinimal.h"
class FExtender;
class FUICommandList;
class UEdGraph;
class UEdGraphNode;
class UEdGraphPin;
class FYourExtension
{
public:
void Install();
void Uninstall();
private:
static TSharedRef<FExtender> HandleOnExtendGraphEditorContextMenu(
const TSharedRef<FUICommandList> CommandList,
const UEdGraph* Graph,
const UEdGraphNode* Node,
const UEdGraphPin* Pin,
bool bIsConst);
static void HandleOnExtendContextMenu(FMenuBuilder& MenuBuilder);
};
#include "YourExtension.h"
#include "GraphEditorModule.h"
// #include "EdGraph/EdGraph.h"
// #include "EdGraph/EdGraphNode.h"
// #include "EdGraph/EdGraphPin.h"
#define LOCTEXT_NAMESPACE "Editor.YourExtension"
DEFINE_LOG_CATEGORY_STATIC(LogYourExtension, Log, All);
const FName GraphEditorModuleName(TEXT("GraphEditor"));
void FYourExtension::Install()
{
auto& GraphEditorModule = FModuleManager::LoadModuleChecked<FGraphEditorModule>(GraphEditorModuleName);
GraphEditorModule.GetAllGraphEditorContextMenuExtender().Add(
FGraphEditorModule::FGraphEditorMenuExtender_SelectedNode::CreateStatic(
&FYourExtension::HandleOnExtendGraphEditorContextMenu));
}
TSharedRef<FExtender> FYourExtension::HandleOnExtendGraphEditorContextMenu(
const TSharedRef<FUICommandList> CommandList,
const UEdGraph* Graph,
const UEdGraphNode* Node,
const UEdGraphPin* Pin,
bool bIsConst)
{
TSharedRef<FExtender> Extender = MakeShared<FExtender>();
// you'll have to check the extension points for the specific node you are interested in, this one works for blueprint nodes for example
const FName ExtensionHook(TEXT("EdGraphSchemaNodeActions"));
Extender->AddMenuExtension(
ExtensionHook,
EExtensionHook::Before,
CommandList,
FMenuExtensionDelegate::CreateStatic(&FYourExtension::HandleOnExtendContextMenu));
return Extender;
}
void FYourExtension::HandleOnExtendContextMenu(FMenuBuilder& MenuBuilder)
{
MenuBuilder.BeginSection(NAME_None, LOCTEXT("SectionName", "YourSection"));
MenuBuilder.AddMenuEntry(
LOCTEXT("ActionLocKey", "your action"),
LOCTEXT("ActionTooltipLockKey", "tooltip for your action"),
FSlateIcon(),
FUIAction(FExecuteAction::CreateLambda([]() {
// do your thing
})));
MenuBuilder.EndSection();
}
void FYourExtension::Uninstall()
{
if (auto GraphEditorModule = FModuleManager::GetModulePtr<FGraphEditorModule>(GraphEditorModuleName))
{
GraphEditorModule->GetAllGraphEditorContextMenuExtender().RemoveAll(
[](const FGraphEditorModule::FGraphEditorMenuExtender_SelectedNode& Delegate) {
return (Delegate.TryGetBoundFunctionName() == GET_FUNCTION_NAME_CHECKED(FYourExtension, HandleOnExtendGraphEditorContextMenu));
});
}
}
#undef LOCTEXT_NAMESPACE