258 lines
7.5 KiB
C++
258 lines
7.5 KiB
C++
// ©2023 Batty Bovine Productions, LLC. All Rights Reserved.
|
|
|
|
#include "ComboActionGraphEditorUtilities.h"
|
|
|
|
#include "ComboActionGraph.h"
|
|
#include "K2Node_Event.h"
|
|
|
|
#include "Ed/AssetEditor_ComboActionGraph.h"
|
|
#include "Ed/EdComboActionGraph.h"
|
|
#include "Ed/EdComboActionGraphNode.h"
|
|
#include "Kismet2/BlueprintEditorUtils.h"
|
|
#include "Kismet2/KismetEditorUtilities.h"
|
|
#include "Kismet2/SClassPickerDialog.h"
|
|
#include "Layout/AssetEditorTabs.h"
|
|
|
|
|
|
bool FComboActionGraphEditorUtilities::PickChildrenOfClass(const FText &TitleText, UClass *&OutChosenClass, UClass *Class)
|
|
{
|
|
// Create filter
|
|
TSharedPtr<FComboActionClassViewerFilter> Filter = MakeShareable(new FComboActionClassViewerFilter);
|
|
Filter->AllowedChildrenOfClasses.Add(Class);
|
|
|
|
// Fill in options
|
|
FClassViewerInitializationOptions Options;
|
|
Options.Mode = EClassViewerMode::ClassPicker;
|
|
Options.bShowUnloadedBlueprints = true;
|
|
Options.ClassFilters.Add(Filter.ToSharedRef());
|
|
|
|
Options.DisplayMode = EClassViewerDisplayMode::TreeView;
|
|
|
|
Options.bShowNoneOption = false;
|
|
Options.InitiallySelectedClass = Class;
|
|
|
|
Options.bExpandRootNodes = true;
|
|
Options.NameTypeToDisplay = EClassViewerNameTypeToDisplay::DisplayName;
|
|
|
|
return SClassPickerDialog::PickClass(TitleText, Options, OutChosenClass, Class);
|
|
}
|
|
|
|
bool FComboActionGraphEditorUtilities::OpenBlueprintEditor(UBlueprint *Blueprint, EComboActionBlueprintOpenType OpenType, FName FunctionNameToOpen, bool bForceFullEditor, bool bAddBlueprintFunctionIfItDoesNotExist)
|
|
{
|
|
if (!Blueprint)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
Blueprint->bForceFullEditor = bForceFullEditor;
|
|
|
|
// Find Function Graph
|
|
UObject *ObjectToFocusOn = nullptr;
|
|
if (OpenType != EComboActionBlueprintOpenType::None && FunctionNameToOpen != NAME_None)
|
|
{
|
|
UClass* Class = Blueprint->GeneratedClass;
|
|
check(Class);
|
|
|
|
if (OpenType == EComboActionBlueprintOpenType::Function)
|
|
{
|
|
ObjectToFocusOn = bAddBlueprintFunctionIfItDoesNotExist
|
|
? FComboActionGraphEditorUtilities::BlueprintGetOrAddFunction(Blueprint, FunctionNameToOpen, Class)
|
|
: FComboActionGraphEditorUtilities::BlueprintGetFunction(Blueprint, FunctionNameToOpen, Class);
|
|
}
|
|
else if (OpenType == EComboActionBlueprintOpenType::Event)
|
|
{
|
|
ObjectToFocusOn = bAddBlueprintFunctionIfItDoesNotExist
|
|
? FComboActionGraphEditorUtilities::BlueprintGetOrAddEvent(Blueprint, FunctionNameToOpen, Class)
|
|
: FComboActionGraphEditorUtilities::BlueprintGetEvent(Blueprint, FunctionNameToOpen, Class);
|
|
}
|
|
}
|
|
|
|
// Default to the last uber graph
|
|
if (ObjectToFocusOn == nullptr)
|
|
{
|
|
ObjectToFocusOn = Blueprint->GetLastEditedUberGraph();
|
|
}
|
|
if (ObjectToFocusOn)
|
|
{
|
|
FKismetEditorUtilities::BringKismetToFocusAttentionOnObject(ObjectToFocusOn);
|
|
return true;
|
|
}
|
|
|
|
return FComboActionGraphEditorUtilities::OpenEditorForAsset(Blueprint);
|
|
}
|
|
|
|
UEdGraph *FComboActionGraphEditorUtilities::BlueprintGetOrAddFunction(UBlueprint *Blueprint, FName FunctionName, UClass *FunctionClassSignature)
|
|
{
|
|
if (!Blueprint || Blueprint->BlueprintType != BPTYPE_Normal)
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
// Find existing function
|
|
if (UEdGraph *GraphFunction = BlueprintGetFunction(Blueprint, FunctionName, FunctionClassSignature))
|
|
{
|
|
return GraphFunction;
|
|
}
|
|
|
|
// Create a new function
|
|
UEdGraph *NewGraph = FBlueprintEditorUtils::CreateNewGraph(Blueprint, FunctionName, UEdGraph::StaticClass(), UEdGraphSchema_K2::StaticClass());
|
|
FBlueprintEditorUtils::AddFunctionGraph(Blueprint, NewGraph, /*bIsUserCreated=*/ false, FunctionClassSignature);
|
|
Blueprint->LastEditedDocuments.Add(NewGraph);
|
|
return NewGraph;
|
|
}
|
|
|
|
UEdGraph *FComboActionGraphEditorUtilities::BlueprintGetFunction(UBlueprint *Blueprint, FName FunctionName, UClass *FunctionClassSignature)
|
|
{
|
|
if (!Blueprint || Blueprint->BlueprintType != BPTYPE_Normal)
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
// Find existing function
|
|
for (UEdGraph *GraphFunction : Blueprint->FunctionGraphs)
|
|
{
|
|
if (FunctionName == GraphFunction->GetFName())
|
|
{
|
|
return GraphFunction;
|
|
}
|
|
}
|
|
|
|
// Find in the implemented Interfaces Graphs
|
|
for (const FBPInterfaceDescription &Interface : Blueprint->ImplementedInterfaces)
|
|
{
|
|
for (UEdGraph *GraphFunction : Interface.Graphs)
|
|
{
|
|
if (FunctionName == GraphFunction->GetFName())
|
|
{
|
|
return GraphFunction;
|
|
}
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
UK2Node_Event *FComboActionGraphEditorUtilities::BlueprintGetOrAddEvent(UBlueprint *Blueprint, FName EventName, UClass *EventClassSignature)
|
|
{
|
|
if (!Blueprint || Blueprint->BlueprintType != EBlueprintType::BPTYPE_Normal)
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
// Find existing event
|
|
if (UK2Node_Event *EventNode = FComboActionGraphEditorUtilities::BlueprintGetEvent(Blueprint, EventName, EventClassSignature))
|
|
{
|
|
return EventNode;
|
|
}
|
|
|
|
// Create a New Event
|
|
if (Blueprint->UbergraphPages.Num())
|
|
{
|
|
int32 NodePositionY = 0;
|
|
UK2Node_Event* NodeEvent = FKismetEditorUtilities::AddDefaultEventNode(
|
|
Blueprint,
|
|
Blueprint->UbergraphPages[0],
|
|
EventName,
|
|
EventClassSignature,
|
|
NodePositionY
|
|
);
|
|
NodeEvent->SetEnabledState(ENodeEnabledState::Enabled);
|
|
NodeEvent->NodeComment = "";
|
|
NodeEvent->bCommentBubbleVisible = false;
|
|
return NodeEvent;
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
UK2Node_Event *FComboActionGraphEditorUtilities::BlueprintGetEvent(UBlueprint *Blueprint, FName EventName, UClass *EventClassSignature)
|
|
{
|
|
if (!Blueprint || Blueprint->BlueprintType != EBlueprintType::BPTYPE_Normal)
|
|
{
|
|
return nullptr;
|
|
}
|
|
|
|
TArray<UK2Node_Event*> AllEvents;
|
|
FBlueprintEditorUtils::GetAllNodesOfClass<UK2Node_Event>(Blueprint, AllEvents);
|
|
for (UK2Node_Event *EventNode : AllEvents)
|
|
{
|
|
if (EventNode->bOverrideFunction && EventNode->EventReference.GetMemberName() == EventName)
|
|
{
|
|
return EventNode;
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
bool FComboActionGraphEditorUtilities::OpenEditorForAsset(const UObject* Asset)
|
|
{
|
|
if (!IsValid(Asset) || !GEditor)
|
|
{
|
|
return false;
|
|
}
|
|
|
|
return GEditor->GetEditorSubsystem<UAssetEditorSubsystem>()->OpenEditorForAsset(const_cast<UObject*>(Asset));
|
|
}
|
|
|
|
bool FComboActionGraphEditorUtilities::OpenEditorAndJumpToGraphNode(TWeakPtr<FAssetEditor_ComboActionGraph> DialogueEditorPtr, const UEdGraphNode *GraphNode, bool bFocusIfOpen)
|
|
{
|
|
if (!IsValid(GraphNode))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
if (!DialogueEditorPtr.IsValid())
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// Open if not already.
|
|
UComboActionGraph *Dialogue = FComboActionGraphEditorUtilities::GetActionFromGraphNode(GraphNode);
|
|
if (!FComboActionGraphEditorUtilities::OpenEditorForAsset(Dialogue))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// Could still fail focus on the graph node
|
|
if (IAssetEditorInstance *EditorInstance = FindEditorForAsset(Dialogue, bFocusIfOpen))
|
|
{
|
|
EditorInstance->FocusWindow(const_cast<UEdGraphNode*>(GraphNode));
|
|
|
|
UEdComboActionGraph *GraphEditor = Cast<UEdComboActionGraph>(Dialogue->EdGraph);
|
|
if (GraphEditor)
|
|
{
|
|
TSet<const UEdGraphNode*> SelectedNodes;
|
|
SelectedNodes.Add(GraphNode);
|
|
|
|
GraphEditor->SelectNodeSet(SelectedNodes);
|
|
DialogueEditorPtr.Pin()->JumpToNode(GraphNode);
|
|
}
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
UComboActionGraph *FComboActionGraphEditorUtilities::GetActionFromGraphNode(const UEdGraphNode *GraphNode)
|
|
{
|
|
if (const UEdComboActionGraphNode *ComboActionBaseNode = Cast<UEdComboActionGraphNode>(GraphNode))
|
|
{
|
|
return ComboActionBaseNode->GetEdComboActionGraph()->GetComboActionGraph();
|
|
}
|
|
if (const UEdComboActionGraph *ComboActionGraph = Cast<UEdComboActionGraph>(GraphNode->GetGraph()))
|
|
{
|
|
return Cast<UComboActionGraph>(ComboActionGraph->GetComboActionGraph());
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
IAssetEditorInstance *FComboActionGraphEditorUtilities::FindEditorForAsset(UObject* Asset, bool bFocusIfOpen)
|
|
{
|
|
if (!IsValid(Asset) || !GEditor)
|
|
{
|
|
return nullptr;
|
|
}
|
|
return GEditor->GetEditorSubsystem<UAssetEditorSubsystem>()->FindEditorForAsset(Asset, bFocusIfOpen);
|
|
}
|
|
|