Trying to add a combo graph editor.
This commit is contained in:
@@ -27,7 +27,8 @@ public class ComboInputEditor : ModuleRules
|
||||
"CoreUObject",
|
||||
"AssetTools",
|
||||
"SlateCore",
|
||||
"Projects"
|
||||
"Projects",
|
||||
"GraphEditor"
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
@@ -0,0 +1,434 @@
|
||||
// ©2023 Batty Bovine Productions, LLC. All Rights Reserved.
|
||||
|
||||
#include "ComboActionGraphSchema.h"
|
||||
|
||||
#include "ComboActionGraph.h"
|
||||
#include "FConnectionDrawingPolicy_ComboActionGraph.h"
|
||||
#include "GraphEditorActions.h"
|
||||
|
||||
#include "Ed/EdComboActionGraphEdge.h"
|
||||
#include "Ed/EdComboActionGraphNode.h"
|
||||
#include "Framework/Commands/GenericCommands.h"
|
||||
#include "Nodes/ComboActionGraphEdge.h"
|
||||
#include "Nodes/ComboActionGraphNode.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "ComboActionGraph"
|
||||
|
||||
|
||||
UEdGraphNode *FAssetSchemaAction_ComboActionGraphSchema_NewNode::PerformAction(UEdGraph *ParentGraph, UEdGraphPin *FromPin, const FVector2D Location, bool bSelectNewNode)
|
||||
{
|
||||
UEdGraphNode *ResultNode = nullptr;
|
||||
|
||||
if (NodeTemplate != nullptr)
|
||||
{
|
||||
const FScopedTransaction Transaction(LOCTEXT("ComboActionGraphEditorNewNode", "Combo Action Graph Editor: New Node"));
|
||||
ParentGraph->Modify();
|
||||
if (FromPin != nullptr)
|
||||
FromPin->Modify();
|
||||
|
||||
NodeTemplate->Rename(nullptr, ParentGraph);
|
||||
ParentGraph->AddNode(NodeTemplate, true, bSelectNewNode);
|
||||
|
||||
NodeTemplate->CreateNewGuid();
|
||||
NodeTemplate->PostPlacedNewNode();
|
||||
NodeTemplate->AllocateDefaultPins();
|
||||
NodeTemplate->AutowireNewNode(FromPin);
|
||||
|
||||
NodeTemplate->NodePosX = Location.X;
|
||||
NodeTemplate->NodePosY = Location.Y;
|
||||
|
||||
NodeTemplate->ComboActionGraphNode->SetFlags(EObjectFlags::RF_Transactional);
|
||||
NodeTemplate->SetFlags(EObjectFlags::RF_Transactional);
|
||||
|
||||
ResultNode = NodeTemplate;
|
||||
}
|
||||
|
||||
return ResultNode;
|
||||
}
|
||||
|
||||
void FAssetSchemaAction_ComboActionGraphSchema_NewNode::AddReferencedObjects(FReferenceCollector &Collector)
|
||||
{
|
||||
FEdGraphSchemaAction::AddReferencedObjects(Collector);
|
||||
Collector.AddReferencedObject(NodeTemplate);
|
||||
}
|
||||
|
||||
UEdGraphNode *FAssetSchemaAction_ComboActionGraphSchema_NewEdge::PerformAction(UEdGraph *ParentGraph, UEdGraphPin *FromPin, const FVector2D Location, bool bSelectNewNode)
|
||||
{
|
||||
UEdGraphNode *ResultNode = nullptr;
|
||||
|
||||
if (NodeTemplate != nullptr)
|
||||
{
|
||||
const FScopedTransaction Transaction(LOCTEXT("ComboActionGraphEditorNewEdge", "Combo Action Graph Editor: New Edge"));
|
||||
ParentGraph->Modify();
|
||||
if (FromPin != nullptr)
|
||||
FromPin->Modify();
|
||||
|
||||
NodeTemplate->Rename(nullptr, ParentGraph);
|
||||
ParentGraph->AddNode(NodeTemplate, true, bSelectNewNode);
|
||||
|
||||
NodeTemplate->CreateNewGuid();
|
||||
NodeTemplate->PostPlacedNewNode();
|
||||
NodeTemplate->AllocateDefaultPins();
|
||||
NodeTemplate->AutowireNewNode(FromPin);
|
||||
|
||||
NodeTemplate->NodePosX = Location.X;
|
||||
NodeTemplate->NodePosY = Location.Y;
|
||||
|
||||
NodeTemplate->ComboActionGraphEdge->SetFlags(EObjectFlags::RF_Transactional);
|
||||
NodeTemplate->SetFlags(EObjectFlags::RF_Transactional);
|
||||
|
||||
ResultNode = NodeTemplate;
|
||||
}
|
||||
|
||||
return ResultNode;
|
||||
}
|
||||
|
||||
void FAssetSchemaAction_ComboActionGraphSchema_NewEdge::AddReferencedObjects(FReferenceCollector &Collector)
|
||||
{
|
||||
FEdGraphSchemaAction::AddReferencedObjects(Collector);
|
||||
Collector.AddReferencedObject(NodeTemplate);
|
||||
}
|
||||
|
||||
|
||||
void UComboActionGraphSchema::GetBreakLinkToSubMenuActions(UToolMenu *Menu, UEdGraphPin *InGraphPin)
|
||||
{
|
||||
// Make sure we have a unique name for every entry in the list
|
||||
TMap<FString, uint32> LinkTitleCount;
|
||||
|
||||
FToolMenuSection &Section = Menu->FindOrAddSection("ComboActionGraphAssetGraphSchemaPinActions");
|
||||
|
||||
// Add all the links we could break from
|
||||
for (TArray<class UEdGraphPin*>::TConstIterator Links(InGraphPin->LinkedTo); Links; ++Links)
|
||||
{
|
||||
UEdGraphPin* Pin = *Links;
|
||||
FString TitleString = Pin->GetOwningNode()->GetNodeTitle(ENodeTitleType::ListView).ToString();
|
||||
FText Title = FText::FromString(TitleString);
|
||||
if (Pin->PinName != TEXT(""))
|
||||
{
|
||||
TitleString = FString::Printf(TEXT("%s (%s)"), *TitleString, *Pin->PinName.ToString());
|
||||
|
||||
// Add name of connection if possible
|
||||
FFormatNamedArguments Args;
|
||||
Args.Add(TEXT("NodeTitle"), Title);
|
||||
Args.Add(TEXT("PinName"), Pin->GetDisplayName());
|
||||
Title = FText::Format(LOCTEXT("BreakDescPin", "{NodeTitle} ({PinName})"), Args);
|
||||
}
|
||||
|
||||
uint32& Count = LinkTitleCount.FindOrAdd(TitleString);
|
||||
|
||||
FText Description;
|
||||
FFormatNamedArguments Args;
|
||||
Args.Add(TEXT("NodeTitle"), Title);
|
||||
Args.Add(TEXT("NumberOfNodes"), Count);
|
||||
|
||||
if (Count == 0)
|
||||
{
|
||||
Description = FText::Format(LOCTEXT("BreakDesc", "Break link to {NodeTitle}"), Args);
|
||||
}
|
||||
else
|
||||
{
|
||||
Description = FText::Format(LOCTEXT("BreakDescMulti", "Break link to {NodeTitle} ({NumberOfNodes})"), Args);
|
||||
}
|
||||
++Count;
|
||||
|
||||
Section.AddMenuEntry(NAME_None, Description, Description, FSlateIcon(), FUIAction(
|
||||
FExecuteAction::CreateUObject(this, &UComboActionGraphSchema::BreakSinglePinLink, const_cast<UEdGraphPin*>(InGraphPin), *Links)));
|
||||
}
|
||||
}
|
||||
|
||||
void UComboActionGraphSchema::GetGraphContextActions(FGraphContextMenuBuilder &ContextMenuBuilder) const
|
||||
{
|
||||
UComboActionGraph *Graph = CastChecked<UComboActionGraph>(ContextMenuBuilder.CurrentGraph->GetOuter());
|
||||
|
||||
if (Graph->NodeType == nullptr)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const bool bNoParent = (ContextMenuBuilder.FromPin == NULL);
|
||||
|
||||
FText AddToolTip = LOCTEXT("NewMoutneaDialogueGraphNodeTooltip", "Add Dialogue Node here");
|
||||
|
||||
TSet<TSubclassOf<UComboActionGraphNode>> Visited;
|
||||
|
||||
FText Desc = Graph->NodeType.GetDefaultObject()->ContextMenuName;
|
||||
FText NodeCategory = Graph->NodeType.GetDefaultObject()->GetNodeCategory();
|
||||
|
||||
if (Desc.IsEmpty())
|
||||
{
|
||||
FString Title = Graph->NodeType->GetName();
|
||||
Title.RemoveFromEnd("_C");
|
||||
Desc = FText::FromString(Title);
|
||||
}
|
||||
|
||||
if (!Graph->NodeType->HasAnyClassFlags(CLASS_Abstract))
|
||||
{
|
||||
TSharedPtr<FAssetSchemaAction_ComboActionGraphSchema_NewNode> NewNodeAction(new FAssetSchemaAction_ComboActionGraphSchema_NewNode(NodeCategory, Desc, AddToolTip, 0));
|
||||
NewNodeAction->NodeTemplate = NewObject<UEdComboActionGraphNode>(ContextMenuBuilder.OwnerOfTemporaries);
|
||||
NewNodeAction->NodeTemplate->ComboActionGraphNode = NewObject<UComboActionGraphNode>(NewNodeAction->NodeTemplate, Graph->NodeType);
|
||||
NewNodeAction->NodeTemplate->ComboActionGraphNode->Graph = Graph;
|
||||
ContextMenuBuilder.AddAction(NewNodeAction);
|
||||
|
||||
Visited.Add(Graph->NodeType);
|
||||
}
|
||||
|
||||
for (TObjectIterator<UClass> It; It; ++It)
|
||||
{
|
||||
if (It->IsChildOf(Graph->NodeType) && !It->HasAnyClassFlags(CLASS_Abstract) && !Visited.Contains(*It))
|
||||
{
|
||||
TSubclassOf<UComboActionGraphNode> NodeType = *It;
|
||||
|
||||
if (It->GetName().StartsWith("REINST") || It->GetName().StartsWith("SKEL"))
|
||||
continue;
|
||||
|
||||
if (!Graph->GetClass()->IsChildOf(NodeType.GetDefaultObject()->CompatibleGraphType))
|
||||
continue;
|
||||
|
||||
if (!NodeType.GetDefaultObject()->bAllowManualCreate)
|
||||
continue;
|
||||
|
||||
Desc = NodeType.GetDefaultObject()->ContextMenuName;
|
||||
AddToolTip = NodeType.GetDefaultObject()->GetDescription();
|
||||
|
||||
NodeCategory = NodeType.GetDefaultObject()->GetNodeCategory();
|
||||
|
||||
if (Desc.IsEmpty())
|
||||
{
|
||||
FString Title = NodeType->GetName();
|
||||
Title.RemoveFromEnd("_C");
|
||||
Desc = FText::FromString(Title);
|
||||
}
|
||||
|
||||
TSharedPtr<FAssetSchemaAction_ComboActionGraphSchema_NewNode> Action(new FAssetSchemaAction_ComboActionGraphSchema_NewNode(NodeCategory, Desc, AddToolTip, 0));
|
||||
Action->NodeTemplate = NewObject<UEdComboActionGraphNode>(ContextMenuBuilder.OwnerOfTemporaries);
|
||||
Action->NodeTemplate->ComboActionGraphNode = NewObject<UComboActionGraphNode>(Action->NodeTemplate, NodeType);
|
||||
Action->NodeTemplate->ComboActionGraphNode->Graph = Graph;
|
||||
ContextMenuBuilder.AddAction(Action);
|
||||
|
||||
Visited.Add(NodeType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UComboActionGraphSchema::GetContextMenuActions(UToolMenu* Menu, UGraphNodeContextMenuContext* Context) const
|
||||
{
|
||||
if (Context->Pin)
|
||||
{
|
||||
{
|
||||
FToolMenuSection& Section = Menu->AddSection("ComboActionGraphAssetGraphSchemaNodeActions", LOCTEXT("PinActionsMenuHeader", "Pin Actions"));
|
||||
// Only display the 'Break Links' option if there is a link to break!
|
||||
if (Context->Pin->LinkedTo.Num() > 0)
|
||||
{
|
||||
Section.AddMenuEntry(FGraphEditorCommands::Get().BreakPinLinks);
|
||||
|
||||
// add sub menu for break link to
|
||||
if (Context->Pin->LinkedTo.Num() > 1)
|
||||
{
|
||||
Section.AddSubMenu(
|
||||
"BreakLinkTo",
|
||||
LOCTEXT("BreakLinkTo", "Break Link To..."),
|
||||
LOCTEXT("BreakSpecificLinks", "Break a specific link..."),
|
||||
FNewToolMenuDelegate::CreateUObject((UComboActionGraphSchema *const)this, &UComboActionGraphSchema::GetBreakLinkToSubMenuActions, const_cast<UEdGraphPin*>(Context->Pin)));
|
||||
}
|
||||
else
|
||||
{
|
||||
((UComboActionGraphSchema *const)this)->GetBreakLinkToSubMenuActions(Menu, const_cast<UEdGraphPin*>(Context->Pin));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (Context->Node)
|
||||
{
|
||||
{
|
||||
FToolMenuSection& Section = Menu->AddSection("ComboActionGraphAssetGraphSchemaNodeActions", LOCTEXT("ClassActionsMenuHeader", "Node Actions"));
|
||||
Section.AddSeparator(FName(TEXT("Main Options")));
|
||||
Section.AddMenuEntry(FGenericCommands::Get().Rename);
|
||||
Section.AddSeparator(FName(TEXT("Other Options")));
|
||||
Section.AddMenuEntry(FGenericCommands::Get().Delete);
|
||||
Section.AddMenuEntry(FGenericCommands::Get().Cut);
|
||||
Section.AddMenuEntry(FGenericCommands::Get().Copy);
|
||||
Section.AddMenuEntry(FGenericCommands::Get().Duplicate);
|
||||
|
||||
Section.AddMenuEntry(FGraphEditorCommands::Get().BreakNodeLinks);
|
||||
}
|
||||
}
|
||||
|
||||
Super::GetContextMenuActions(Menu, Context);
|
||||
}
|
||||
|
||||
const FPinConnectionResponse UComboActionGraphSchema::CanCreateConnection(const UEdGraphPin* A, const UEdGraphPin* B) const
|
||||
{
|
||||
// Make sure the pins are not on the same node
|
||||
if (A->GetOwningNode() == B->GetOwningNode())
|
||||
{
|
||||
return FPinConnectionResponse(CONNECT_RESPONSE_DISALLOW, LOCTEXT("PinErrorSameNode", "Both are on the same node"));
|
||||
}
|
||||
|
||||
// Compare the directions
|
||||
if ((A->Direction == EGPD_Input) && (B->Direction == EGPD_Input))
|
||||
{
|
||||
return FPinConnectionResponse(CONNECT_RESPONSE_DISALLOW, LOCTEXT("PinErrorInput", "Can't connect input node to input node"));
|
||||
}
|
||||
else if ((A->Direction == EGPD_Output) && (B->Direction == EGPD_Output))
|
||||
{
|
||||
return FPinConnectionResponse(CONNECT_RESPONSE_DISALLOW, LOCTEXT("PinErrorOutput", "Can't connect output node to output node"));
|
||||
}
|
||||
|
||||
// check for cycles
|
||||
FComboActionNodeVisitorCycleChecker CycleChecker;
|
||||
if (!CycleChecker.CheckForLoop(A->GetOwningNode(), B->GetOwningNode()))
|
||||
{
|
||||
return FPinConnectionResponse(CONNECT_RESPONSE_DISALLOW, LOCTEXT("PinErrorCycle", "Can't create a graph cycle"));
|
||||
}
|
||||
if (!CycleChecker.CheckForLoop(B->GetOwningNode(), A->GetOwningNode()))
|
||||
{
|
||||
return FPinConnectionResponse(CONNECT_RESPONSE_DISALLOW, LOCTEXT("PinErrorCycle", "Can't create a graph cycle"));
|
||||
}
|
||||
|
||||
UEdComboActionGraphNode* EdNode_A = Cast<UEdComboActionGraphNode>(A->GetOwningNode());
|
||||
UEdComboActionGraphNode* EdNode_B = Cast<UEdComboActionGraphNode>(B->GetOwningNode());
|
||||
|
||||
if (EdNode_A == nullptr || EdNode_B == nullptr)
|
||||
{
|
||||
return FPinConnectionResponse(CONNECT_RESPONSE_DISALLOW, LOCTEXT("PinError", "Not a valid UComboActionGraphEdNode"));
|
||||
}
|
||||
|
||||
FText ErrorMessage;
|
||||
if (A->Direction == EGPD_Input)
|
||||
{
|
||||
if (!EdNode_A->ComboActionGraphNode->CanCreateConnection(EdNode_B->ComboActionGraphNode, EGPD_Input, ErrorMessage))
|
||||
{
|
||||
return FPinConnectionResponse(CONNECT_RESPONSE_DISALLOW, ErrorMessage);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!EdNode_B->ComboActionGraphNode->CanCreateConnection(EdNode_A->ComboActionGraphNode, EGPD_Output, ErrorMessage))
|
||||
{
|
||||
return FPinConnectionResponse(CONNECT_RESPONSE_DISALLOW, ErrorMessage);
|
||||
}
|
||||
}
|
||||
|
||||
if (EdNode_A->ComboActionGraphNode->GetGraph()->bEdgeEnabled)
|
||||
{
|
||||
return FPinConnectionResponse(CONNECT_RESPONSE_MAKE_WITH_CONVERSION_NODE, LOCTEXT("PinConnect", "Connect nodes with edge"));
|
||||
}
|
||||
else
|
||||
{
|
||||
return FPinConnectionResponse(CONNECT_RESPONSE_MAKE, LOCTEXT("PinConnect", "Connect nodes"));
|
||||
}
|
||||
}
|
||||
|
||||
bool UComboActionGraphSchema::CreateAutomaticConversionNodeAndConnections(UEdGraphPin* A, UEdGraphPin* B) const
|
||||
{
|
||||
UEdComboActionGraphNode *NodeA = Cast<UEdComboActionGraphNode>(A->GetOwningNode());
|
||||
UEdComboActionGraphNode *NodeB = Cast<UEdComboActionGraphNode>(B->GetOwningNode());
|
||||
|
||||
if (NodeA == nullptr || NodeB == nullptr)
|
||||
return false;
|
||||
|
||||
if (NodeA->GetInputPin() == nullptr || NodeA->GetOutputPin() == nullptr || NodeB->GetInputPin() == nullptr || NodeB->GetOutputPin() == nullptr)
|
||||
return false;
|
||||
|
||||
UComboActionGraph* Graph = NodeA->ComboActionGraphNode->GetGraph();
|
||||
|
||||
FVector2D InitPos((NodeA->NodePosX + NodeB->NodePosX) / 2, (NodeA->NodePosY + NodeB->NodePosY) / 2);
|
||||
|
||||
FAssetSchemaAction_ComboActionGraphSchema_NewEdge Action;
|
||||
Action.NodeTemplate = NewObject<UEdComboActionGraphEdge>(NodeA->GetGraph());
|
||||
Action.NodeTemplate->SetEdge(NewObject<UComboActionGraphEdge>(Action.NodeTemplate, Graph->EdgeType));
|
||||
UEdComboActionGraphEdge *EdgeNode = Cast<UEdComboActionGraphEdge>(Action.PerformAction(NodeA->GetGraph(), nullptr, InitPos, false));
|
||||
|
||||
if (A->Direction == EEdGraphPinDirection::EGPD_Output)
|
||||
{
|
||||
EdgeNode->CreateConnections(NodeA, NodeB);
|
||||
}
|
||||
else
|
||||
{
|
||||
EdgeNode->CreateConnections(NodeB, NodeA);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
FConnectionDrawingPolicy *UComboActionGraphSchema::CreateConnectionDrawingPolicy(int32 InBackLayerID, int32 InFrontLayerID, float InZoomFactor, const FSlateRect& InClippingRect, FSlateWindowElementList& InDrawElements, UEdGraph* InGraphObj) const
|
||||
{
|
||||
/*
|
||||
if (const UMounteaDialogueGraphEditorSettings* MounteaDialogueGraphEditorSettings = GetMutableDefault<UMounteaDialogueGraphEditorSettings>())
|
||||
{
|
||||
if (MounteaDialogueGraphEditorSettings->AllowAdvancedWiring())
|
||||
{
|
||||
return new FConnectionDrawingPolicy_AdvancedMounteaDialogueGraph(InBackLayerID, InFrontLayerID, InZoomFactor, InClippingRect, InDrawElements, InGraphObj);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
return new FConnectionDrawingPolicy_ComboActionGraph(InBackLayerID, InFrontLayerID, InZoomFactor, InClippingRect, InDrawElements, InGraphObj);
|
||||
}
|
||||
|
||||
FLinearColor UComboActionGraphSchema::GetPinTypeColor(const FEdGraphPinType& PinType) const
|
||||
{
|
||||
return FColor::White;
|
||||
}
|
||||
|
||||
void UComboActionGraphSchema::BreakNodeLinks(UEdGraphNode& TargetNode) const
|
||||
{
|
||||
const FScopedTransaction Transaction(NSLOCTEXT("UnrealEd", "GraphEd_BreakNodeLinks", "Break Node Links"));
|
||||
|
||||
Super::BreakNodeLinks(TargetNode);
|
||||
}
|
||||
|
||||
void UComboActionGraphSchema::BreakPinLinks(UEdGraphPin& TargetPin, bool bSendsNodeNotifcation) const
|
||||
{
|
||||
const FScopedTransaction Transaction(NSLOCTEXT("UnrealEd", "GraphEd_BreakPinLinks", "Break Pin Links"));
|
||||
|
||||
Super::BreakPinLinks(TargetPin, bSendsNodeNotifcation);
|
||||
}
|
||||
|
||||
void UComboActionGraphSchema::BreakSinglePinLink(UEdGraphPin* SourcePin, UEdGraphPin* TargetPin) const
|
||||
{
|
||||
const FScopedTransaction Transaction(NSLOCTEXT("UnrealEd", "GraphEd_BreakSinglePinLink", "Break Pin Link"));
|
||||
|
||||
Super::BreakSinglePinLink(SourcePin, TargetPin);
|
||||
}
|
||||
|
||||
UEdGraphPin *UComboActionGraphSchema::DropPinOnNode(UEdGraphNode* InTargetNode, const FName& InSourcePinName, const FEdGraphPinType& InSourcePinType, EEdGraphPinDirection InSourcePinDirection) const
|
||||
{
|
||||
UEdComboActionGraphNode* EdNode = Cast<UEdComboActionGraphNode>(InTargetNode);
|
||||
switch (InSourcePinDirection)
|
||||
{
|
||||
case EEdGraphPinDirection::EGPD_Input:
|
||||
return EdNode->GetOutputPin();
|
||||
case EEdGraphPinDirection::EGPD_Output:
|
||||
return EdNode->GetInputPin();
|
||||
default:
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool UComboActionGraphSchema::SupportsDropPinOnNode(UEdGraphNode* InTargetNode, const FEdGraphPinType& InSourcePinType, EEdGraphPinDirection InSourcePinDirection, FText& OutErrorMessage) const
|
||||
{
|
||||
return Cast<UEdComboActionGraphNode>(InTargetNode) != nullptr;
|
||||
}
|
||||
|
||||
bool UComboActionGraphSchema::IsCacheVisualizationOutOfDate(int32 InVisualizationCacheID) const
|
||||
{
|
||||
return CurrentCacheRefreshID != InVisualizationCacheID;
|
||||
}
|
||||
|
||||
int32 UComboActionGraphSchema::GetCurrentVisualizationCacheID() const
|
||||
{
|
||||
return CurrentCacheRefreshID;
|
||||
}
|
||||
|
||||
void UComboActionGraphSchema::ForceVisualizationCacheClear() const
|
||||
{
|
||||
CurrentCacheRefreshID++;
|
||||
}
|
||||
|
||||
void UComboActionGraphSchema::CreateDefaultNodesForGraph(UEdGraph& Graph) const
|
||||
{
|
||||
Super::CreateDefaultNodesForGraph(Graph);
|
||||
}
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
@@ -0,0 +1,164 @@
|
||||
// ©2023 Batty Bovine Productions, LLC. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
|
||||
#include "ComboActionGraphSchema.generated.h"
|
||||
|
||||
|
||||
class FComboActionNodeVisitorCycleChecker
|
||||
{
|
||||
public:
|
||||
/** Check whether a loop in the graph would be caused by linking the passed-in nodes */
|
||||
bool CheckForLoop(UEdGraphNode *StartNode, UEdGraphNode *EndNode)
|
||||
{
|
||||
VisitedNodes.Add(StartNode);
|
||||
|
||||
if (!QuiCheckDirectConnections(StartNode, EndNode))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return TraverseInputNodesToRoot(EndNode);
|
||||
}
|
||||
|
||||
private:
|
||||
bool TraverseInputNodesToRoot(UEdGraphNode *Node)
|
||||
{
|
||||
VisitedNodes.Add(Node);
|
||||
|
||||
for (int32 PinIndex = 0; PinIndex < Node->Pins.Num(); ++PinIndex)
|
||||
{
|
||||
UEdGraphPin *MyPin = Node->Pins[PinIndex];
|
||||
|
||||
if (MyPin->Direction == EGPD_Output)
|
||||
{
|
||||
for (int32 LinkedPinIndex = 0; LinkedPinIndex < MyPin->LinkedTo.Num(); ++LinkedPinIndex)
|
||||
{
|
||||
UEdGraphPin *OtherPin = MyPin->LinkedTo[LinkedPinIndex];
|
||||
if (OtherPin)
|
||||
{
|
||||
UEdGraphNode *OtherNode = OtherPin->GetOwningNode();
|
||||
if (VisitedNodes.Contains(OtherNode))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
return TraverseInputNodesToRoot(OtherNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool QuiCheckDirectConnections(UEdGraphNode *A, UEdGraphNode *B)
|
||||
{
|
||||
for (auto Itr : B->Pins)
|
||||
{
|
||||
if (A->Pins.Contains(Itr))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto Itr : A->Pins)
|
||||
{
|
||||
if (B->Pins.Contains(Itr))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
TSet<UEdGraphNode *> VisitedNodes;
|
||||
};
|
||||
|
||||
/** Action to add a node to the graph */
|
||||
USTRUCT()
|
||||
struct FAssetSchemaAction_ComboActionGraphSchema_NewNode : public FEdGraphSchemaAction
|
||||
{
|
||||
GENERATED_BODY();
|
||||
|
||||
public:
|
||||
FAssetSchemaAction_ComboActionGraphSchema_NewNode() : NodeTemplate(nullptr){}
|
||||
|
||||
FAssetSchemaAction_ComboActionGraphSchema_NewNode(const FText &InNodeCategory, const FText &InMenuDesc, const FText &InToolTip, const int32 InGrouping)
|
||||
: FEdGraphSchemaAction(InNodeCategory, InMenuDesc, InToolTip, InGrouping), NodeTemplate(nullptr){}
|
||||
|
||||
virtual UEdGraphNode *PerformAction(class UEdGraph *ParentGraph, UEdGraphPin *FromPin, const FVector2D Location, bool bSelectNewNode = true) override;
|
||||
virtual void AddReferencedObjects(FReferenceCollector &Collector) override;
|
||||
|
||||
class UEdComboActionGraphNode *NodeTemplate;
|
||||
};
|
||||
|
||||
USTRUCT()
|
||||
struct FAssetSchemaAction_ComboActionGraphSchema_NewEdge : public FEdGraphSchemaAction
|
||||
{
|
||||
GENERATED_BODY();
|
||||
|
||||
public:
|
||||
FAssetSchemaAction_ComboActionGraphSchema_NewEdge() : NodeTemplate(nullptr)
|
||||
{}
|
||||
|
||||
FAssetSchemaAction_ComboActionGraphSchema_NewEdge(const FText &InNodeCategory, const FText &InMenuDesc, const FText &InToolTip, const int32 InGrouping)
|
||||
: FEdGraphSchemaAction(InNodeCategory, InMenuDesc, InToolTip, InGrouping), NodeTemplate(nullptr)
|
||||
{}
|
||||
|
||||
virtual UEdGraphNode *PerformAction(class UEdGraph *ParentGraph, UEdGraphPin *FromPin, const FVector2D Location, bool bSelectNewNode = true) override;
|
||||
virtual void AddReferencedObjects(FReferenceCollector &Collector) override;
|
||||
|
||||
class UEdComboActionGraphEdge *NodeTemplate;
|
||||
};
|
||||
|
||||
|
||||
UCLASS(MinimalAPI)
|
||||
class UComboActionGraphSchema : public UEdGraphSchema
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
void GetBreakLinkToSubMenuActions(class UToolMenu* Menu, class UEdGraphPin* InGraphPin);
|
||||
|
||||
virtual EGraphType GetGraphType(const UEdGraph* TestEdGraph) const override { return EGraphType::GT_StateMachine; }
|
||||
|
||||
virtual void GetGraphContextActions(FGraphContextMenuBuilder& ContextMenuBuilder) const override;
|
||||
|
||||
virtual void GetContextMenuActions(class UToolMenu* Menu, class UGraphNodeContextMenuContext* Context) const override;
|
||||
|
||||
virtual const FPinConnectionResponse CanCreateConnection(const UEdGraphPin* A, const UEdGraphPin* B) const override;
|
||||
|
||||
virtual bool CreateAutomaticConversionNodeAndConnections(UEdGraphPin* A, UEdGraphPin* B) const override;
|
||||
|
||||
virtual class FConnectionDrawingPolicy* CreateConnectionDrawingPolicy(int32 InBackLayerID, int32 InFrontLayerID, float InZoomFactor, const FSlateRect& InClippingRect, class FSlateWindowElementList& InDrawElements, class UEdGraph* InGraphObj) const override;
|
||||
|
||||
virtual FLinearColor GetPinTypeColor(const FEdGraphPinType& PinType) const override;
|
||||
|
||||
virtual void BreakNodeLinks(UEdGraphNode& TargetNode) const override;
|
||||
|
||||
virtual void BreakPinLinks(UEdGraphPin& TargetPin, bool bSendsNodeNotifcation) const override;
|
||||
|
||||
virtual void BreakSinglePinLink(UEdGraphPin* SourcePin, UEdGraphPin* TargetPin) const override;
|
||||
|
||||
virtual UEdGraphPin* DropPinOnNode(UEdGraphNode* InTargetNode, const FName& InSourcePinName, const FEdGraphPinType& InSourcePinType, EEdGraphPinDirection InSourcePinDirection) const override;
|
||||
|
||||
virtual bool SupportsDropPinOnNode(UEdGraphNode* InTargetNode, const FEdGraphPinType& InSourcePinType, EEdGraphPinDirection InSourcePinDirection, FText& OutErrorMessage) const override;
|
||||
|
||||
virtual bool IsCacheVisualizationOutOfDate(int32 InVisualizationCacheID) const override;
|
||||
|
||||
virtual int32 GetCurrentVisualizationCacheID() const override;
|
||||
|
||||
virtual void ForceVisualizationCacheClear() const override;
|
||||
|
||||
virtual void CreateDefaultNodesForGraph(UEdGraph& Graph) const override;
|
||||
|
||||
private:
|
||||
|
||||
static int32 CurrentCacheRefreshID;
|
||||
};
|
||||
@@ -0,0 +1,209 @@
|
||||
// ©2023 Batty Bovine Productions, LLC. All Rights Reserved.
|
||||
|
||||
#include "Ed/EdComboActionGraph.h"
|
||||
|
||||
#include "Ed/EdComboActionGraphEdge.h"
|
||||
#include "Ed/EdComboActionGraphNode.h"
|
||||
#include "ComboActionGraph.h"
|
||||
#include "Nodes/ComboActionGraphNode.h"
|
||||
#include "Nodes/ComboActionGraphEdge.h"
|
||||
//#include "Helpers/MounteaDialogueGraphEditorHelpers.h"
|
||||
//#include "Helpers/MounteaDialogueGraphEditorUtilities.h"
|
||||
//#include "Helpers/MounteaDialogueSystemEditorBFC.h"
|
||||
|
||||
DEFINE_LOG_CATEGORY(LogEdComboActionGraph);
|
||||
|
||||
|
||||
void UEdComboActionGraph::RebuildComboActionGraph()
|
||||
{
|
||||
UE_LOG(LogEdComboActionGraph, Warning, TEXT("UEdComboActionGraph::RebuildComboActionGraph has been called"));
|
||||
|
||||
UComboActionGraph *Graph = GetComboActionGraph();
|
||||
|
||||
Clear();
|
||||
|
||||
for (int i = 0; i < Nodes.Num(); ++i)
|
||||
{
|
||||
if (UEdComboActionGraphNode *EdNode = Cast<UEdComboActionGraphNode>(Nodes[i]))
|
||||
{
|
||||
if (EdNode->ComboActionGraphNode == nullptr)
|
||||
continue;
|
||||
|
||||
UComboActionGraphNode *ComboActionGraphNode = EdNode->ComboActionGraphNode;
|
||||
|
||||
NodeMap.Add(ComboActionGraphNode, EdNode);
|
||||
|
||||
Graph->AllNodes.Add(ComboActionGraphNode);
|
||||
|
||||
//EdNode->SetDialogueNodeIndex( Graph->AllNodes.Find(EdNode->ComboActionGraphNode) );
|
||||
|
||||
for (int PinIdx = 0; PinIdx < EdNode->Pins.Num(); ++PinIdx)
|
||||
{
|
||||
UEdGraphPin* Pin = EdNode->Pins[PinIdx];
|
||||
|
||||
if (Pin->Direction != EEdGraphPinDirection::EGPD_Output)
|
||||
continue;
|
||||
|
||||
for (int LinkToIdx = 0; LinkToIdx < Pin->LinkedTo.Num(); ++LinkToIdx)
|
||||
{
|
||||
UComboActionGraphNode *ChildNode = nullptr;
|
||||
if (UEdComboActionGraphNode *EdNode_Child = Cast<UEdComboActionGraphNode>(Pin->LinkedTo[LinkToIdx]->GetOwningNode()))
|
||||
{
|
||||
ChildNode = EdNode_Child->ComboActionGraphNode;
|
||||
}
|
||||
else if (UEdComboActionGraphEdge *EdNode_Edge = Cast<UEdComboActionGraphEdge>(Pin->LinkedTo[LinkToIdx]->GetOwningNode()))
|
||||
{
|
||||
UEdComboActionGraphNode *Child = EdNode_Edge->GetEndNode();;
|
||||
if (Child != nullptr)
|
||||
{
|
||||
ChildNode = Child->ComboActionGraphNode;
|
||||
}
|
||||
}
|
||||
|
||||
if (ChildNode != nullptr)
|
||||
{
|
||||
ComboActionGraphNode->ChildrenNodes.Add(ChildNode);
|
||||
|
||||
ChildNode->ParentNodes.Add(ComboActionGraphNode);
|
||||
}
|
||||
else
|
||||
{
|
||||
UE_LOG(LogEdComboActionGraph, Error, TEXT("[RebuildComboActionGraph] Can't find child node"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (UEdComboActionGraphEdge *EdgeNode = Cast<UEdComboActionGraphEdge>(Nodes[i]))
|
||||
{
|
||||
UEdComboActionGraphNode *StartNode = EdgeNode->GetStartNode();
|
||||
UEdComboActionGraphNode *EndNode = EdgeNode->GetEndNode();
|
||||
UComboActionGraphEdge *Edge = EdgeNode->ComboActionGraphEdge;
|
||||
|
||||
if (StartNode == nullptr || EndNode == nullptr || Edge == nullptr)
|
||||
{
|
||||
UE_LOG(LogEdComboActionGraph, Error, TEXT("[RebuildMounteaDialogueGraph] Add edge failed."));
|
||||
continue;
|
||||
}
|
||||
|
||||
EdgeMap.Add(Edge, EdgeNode);
|
||||
|
||||
Edge->Graph = Graph;
|
||||
Edge->Rename(nullptr, Graph, REN_DontCreateRedirectors | REN_DoNotDirty);
|
||||
Edge->StartNode = StartNode->ComboActionGraphNode;
|
||||
Edge->EndNode = EndNode->ComboActionGraphNode;
|
||||
Edge->StartNode->Edges.Add(Edge->EndNode, Edge);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < Graph->AllNodes.Num(); ++i)
|
||||
{
|
||||
UComboActionGraphNode *Node = Graph->AllNodes[i];
|
||||
if (Node->ParentNodes.Num() == 0)
|
||||
{
|
||||
Graph->RootNodes.Add(Node);
|
||||
|
||||
SortNodes(Node);
|
||||
}
|
||||
|
||||
Node->Graph = Graph;
|
||||
Node->Rename(nullptr, Graph, REN_DontCreateRedirectors | REN_DoNotDirty);
|
||||
}
|
||||
|
||||
Graph->RootNodes.Sort([&](const UComboActionGraphNode &L, const UComboActionGraphNode &R)
|
||||
{
|
||||
UEdComboActionGraphNode* EdNode_LNode = NodeMap[&L];
|
||||
UEdComboActionGraphNode* EdNode_RNode = NodeMap[&R];
|
||||
return EdNode_LNode->NodePosX < EdNode_RNode->NodePosX;
|
||||
});
|
||||
}
|
||||
|
||||
UComboActionGraph *UEdComboActionGraph::GetComboActionGraph() const
|
||||
{
|
||||
return CastChecked<UComboActionGraph>(GetOuter());
|
||||
}
|
||||
|
||||
bool UEdComboActionGraph::Modify(bool bAlwaysMarkDirty)
|
||||
{
|
||||
bool Rtn = Super::Modify(bAlwaysMarkDirty);
|
||||
|
||||
this->GetComboActionGraph()->Modify();
|
||||
|
||||
for (int32 i = 0; i < Nodes.Num(); ++i)
|
||||
{
|
||||
Nodes[i]->Modify();
|
||||
}
|
||||
|
||||
return Rtn;
|
||||
}
|
||||
|
||||
void UEdComboActionGraph::PostEditUndo()
|
||||
{
|
||||
NotifyGraphChanged();
|
||||
|
||||
Super::PostEditUndo();
|
||||
}
|
||||
|
||||
//void UEdComboActionGraph::SetDialogueEditorPtr(TWeakPtr<FAssetEditor_MounteaDialogueGraph> NewPtr)
|
||||
//{
|
||||
// DialogueEditorPtr = NewPtr;
|
||||
//}
|
||||
|
||||
//bool UEdComboActionGraph::JumpToNode(const UMounteaDialogueGraphNode* Node)
|
||||
//{
|
||||
// return FComboActionGraphEditorUtilities::OpenEditorAndJumpToGraphNode(DialogueEditorPtr, *NodeMap.Find(Node));
|
||||
//}
|
||||
|
||||
void UEdComboActionGraph::Clear()
|
||||
{
|
||||
UComboActionGraph *Graph = this->GetComboActionGraph();
|
||||
|
||||
Graph->ClearGraph();
|
||||
this->NodeMap.Reset();
|
||||
this->EdgeMap.Reset();
|
||||
|
||||
for (int i = 0; i < this->Nodes.Num(); ++i)
|
||||
{
|
||||
if (UEdComboActionGraphNode *EdNode = Cast<UEdComboActionGraphNode>(Nodes[i]))
|
||||
{
|
||||
UComboActionGraphNode *MounteaDialogueGraphNode = EdNode->ComboActionGraphNode;
|
||||
MounteaDialogueGraphNode->ParentNodes.Reset();
|
||||
MounteaDialogueGraphNode->ChildrenNodes.Reset();
|
||||
MounteaDialogueGraphNode->Edges.Reset();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UEdComboActionGraph::SortNodes(UComboActionGraphNode *RootNode)
|
||||
{
|
||||
int Level = 0;
|
||||
TArray<UComboActionGraphNode*> CurrLevelNodes = { RootNode };
|
||||
TArray<UComboActionGraphNode*> NextLevelNodes;
|
||||
|
||||
while (CurrLevelNodes.Num() != 0)
|
||||
{
|
||||
int32 LevelWidth = 0;
|
||||
for (int i = 0; i < CurrLevelNodes.Num(); ++i)
|
||||
{
|
||||
UComboActionGraphNode *Node = CurrLevelNodes[i];
|
||||
|
||||
auto Comp = [&](const UComboActionGraphNode &L, const UComboActionGraphNode &R)
|
||||
{
|
||||
UEdComboActionGraphNode *EdNode_LNode = NodeMap[&L];
|
||||
UEdComboActionGraphNode *EdNode_RNode = NodeMap[&R];
|
||||
return EdNode_LNode->NodePosX < EdNode_RNode->NodePosX;
|
||||
};
|
||||
|
||||
Node->ChildrenNodes.Sort(Comp);
|
||||
Node->ParentNodes.Sort(Comp);
|
||||
|
||||
for (int j = 0; j < Node->ChildrenNodes.Num(); ++j)
|
||||
{
|
||||
NextLevelNodes.Add(Node->ChildrenNodes[j]);
|
||||
}
|
||||
}
|
||||
|
||||
CurrLevelNodes = NextLevelNodes;
|
||||
NextLevelNodes.Reset();
|
||||
++Level;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
// ©2023 Batty Bovine Productions, LLC. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "EdGraph/EdGraph.h"
|
||||
|
||||
#include "EdComboActionGraph.generated.h"
|
||||
|
||||
DECLARE_LOG_CATEGORY_EXTERN(LogEdComboActionGraph, Log, All);
|
||||
|
||||
|
||||
UCLASS()
|
||||
class COMBOINPUT_API UEdComboActionGraph : public UEdGraph
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
virtual void RebuildComboActionGraph();
|
||||
|
||||
UComboActionGraph *GetComboActionGraph() const;
|
||||
|
||||
virtual bool Modify(bool bAlwaysMarkDirty) override;
|
||||
virtual void PostEditUndo() override;
|
||||
|
||||
//TWeakPtr<FAssetEditor_ComboActionGraph> GetDialogueEditorPtr() const { return DialogueEditorPtr; }
|
||||
//void SetDialogueEditorPtr(TWeakPtr<FAssetEditor_ComboActionGraph> NewPtr);
|
||||
//void ResetDialogueEditorPtr() { DialogueEditorPtr.Reset(); }
|
||||
|
||||
//bool JumpToNode(const class UComboActionGraphNode *Node);
|
||||
|
||||
public:
|
||||
|
||||
UPROPERTY(Transient)
|
||||
TMap<class UComboActionGraphNode*, class UEdComboActionGraphNode*> NodeMap;
|
||||
|
||||
UPROPERTY(Transient)
|
||||
TMap<class UComboActionGraphEdge*, class UEdComboActionGraphEdge*> EdgeMap;
|
||||
|
||||
protected:
|
||||
|
||||
void Clear();
|
||||
void SortNodes(UComboActionGraphNode *RootNode);
|
||||
|
||||
private:
|
||||
|
||||
/** Pointer back to the Dialogue editor that owns us */
|
||||
//TWeakPtr<FAssetEditor_ComboActionGraph> DialogueEditorPtr;
|
||||
};
|
||||
@@ -0,0 +1,83 @@
|
||||
// ©2023 Batty Bovine Productions, LLC. All Rights Reserved.
|
||||
|
||||
#include "EdComboActionGraphEdge.h"
|
||||
|
||||
#include "EdComboActionGraphNode.h"
|
||||
#include "Nodes/ComboActionGraphEdge.h"
|
||||
|
||||
|
||||
void UEdComboActionGraphEdge::SetEdge(UComboActionGraphEdge *Edge)
|
||||
{
|
||||
this->ComboActionGraphEdge = Edge;
|
||||
}
|
||||
|
||||
void UEdComboActionGraphEdge::AllocateDefaultPins()
|
||||
{
|
||||
UEdGraphPin* Inputs = this->CreatePin(EGPD_Input, TEXT("Edge"), FName(), TEXT("In"));
|
||||
Inputs->bHidden = true;
|
||||
UEdGraphPin* Outputs = this->CreatePin(EGPD_Output, TEXT("Edge"), FName(), TEXT("Out"));
|
||||
Outputs->bHidden = true;
|
||||
}
|
||||
|
||||
FText UEdComboActionGraphEdge::GetNodeTitle(ENodeTitleType::Type TitleType) const
|
||||
{
|
||||
return Super::GetNodeTitle(TitleType);
|
||||
}
|
||||
|
||||
void UEdComboActionGraphEdge::PinConnectionListChanged(UEdGraphPin *Pin)
|
||||
{
|
||||
if (Pin->LinkedTo.Num() == 0)
|
||||
{
|
||||
// Commit suicide; transitions must always have an input and output connection
|
||||
Modify();
|
||||
|
||||
// Our parent graph will have our graph in SubGraphs so needs to be modified to record that.
|
||||
if (UEdGraph *ParentGraph = GetGraph())
|
||||
{
|
||||
ParentGraph->Modify();
|
||||
}
|
||||
|
||||
DestroyNode();
|
||||
}
|
||||
}
|
||||
|
||||
void UEdComboActionGraphEdge::PrepareForCopying()
|
||||
{
|
||||
this->ComboActionGraphEdge->Rename(nullptr, this, REN_DontCreateRedirectors | REN_DoNotDirty);
|
||||
}
|
||||
|
||||
void UEdComboActionGraphEdge::CreateConnections(UEdComboActionGraphNode *Start, UEdComboActionGraphNode *End)
|
||||
{
|
||||
Pins[0]->Modify();
|
||||
Pins[0]->LinkedTo.Empty();
|
||||
|
||||
Start->GetOutputPin()->Modify();
|
||||
Pins[0]->MakeLinkTo(Start->GetOutputPin());
|
||||
|
||||
// This to next
|
||||
Pins[1]->Modify();
|
||||
Pins[1]->LinkedTo.Empty();
|
||||
|
||||
End->GetInputPin()->Modify();
|
||||
Pins[1]->MakeLinkTo(End->GetInputPin());
|
||||
}
|
||||
|
||||
UEdComboActionGraphNode *UEdComboActionGraphEdge::GetStartNode()
|
||||
{
|
||||
if (Pins[0]->LinkedTo.Num() > 0)
|
||||
{
|
||||
return Cast<UEdComboActionGraphNode>(Pins[0]->LinkedTo[0]->GetOwningNode());
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
UEdComboActionGraphNode *UEdComboActionGraphEdge::GetEndNode()
|
||||
{
|
||||
if (Pins[1]->LinkedTo.Num() > 0)
|
||||
{
|
||||
return Cast<UEdComboActionGraphNode>(Pins[1]->LinkedTo[0]->GetOwningNode());
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
// ©2023 Batty Bovine Productions, LLC. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "EdGraph/EdGraphNode.h"
|
||||
|
||||
#include "EdComboActionGraphEdge.generated.h"
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS(MinimalAPI)
|
||||
class UEdComboActionGraphEdge : public UEdGraphNode
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UPROPERTY()
|
||||
class UEdGraph *Graph;
|
||||
|
||||
UPROPERTY(VisibleAnywhere, Instanced, Category="Combo Action Graph")
|
||||
class UComboActionGraphEdge *ComboActionGraphEdge;
|
||||
|
||||
public:
|
||||
|
||||
void SetEdge(class UComboActionGraphEdge *Edge);
|
||||
|
||||
virtual void AllocateDefaultPins() override;
|
||||
|
||||
virtual FText GetNodeTitle(ENodeTitleType::Type TitleType) const override;
|
||||
|
||||
virtual void PinConnectionListChanged(UEdGraphPin *Pin) override;
|
||||
|
||||
virtual void PrepareForCopying() override;
|
||||
|
||||
virtual UEdGraphPin *GetInputPin() const { return Pins[0]; }
|
||||
virtual UEdGraphPin *GetOutputPin() const { return Pins[1]; }
|
||||
|
||||
void CreateConnections(class UEdComboActionGraphNode *Start, class UEdComboActionGraphNode* End);
|
||||
|
||||
class UEdComboActionGraphNode *GetStartNode();
|
||||
class UEdComboActionGraphNode *GetEndNode();
|
||||
};
|
||||
@@ -0,0 +1,169 @@
|
||||
// ©2023 Batty Bovine Productions, LLC. All Rights Reserved.
|
||||
|
||||
#include "EdComboActionGraphNode.h"
|
||||
|
||||
#include "Ed/EdComboActionGraph.h"
|
||||
#include "Helpers/ComboActionEditorBFC.h"
|
||||
#include "Nodes/ComboActionGraphNode.h"
|
||||
#include "Settings/ComboActionGraphEditorSettings.h"
|
||||
#include "Settings/FComboActionGraphEditorStyle.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "UEdComboActionGraphNode"
|
||||
|
||||
DEFINE_LOG_CATEGORY(LogEdComboActionGraphNode);
|
||||
|
||||
|
||||
UEdComboActionGraphNode::UEdComboActionGraphNode()
|
||||
{
|
||||
bCanRenameNode = true;
|
||||
|
||||
bAllowCopy = true;
|
||||
bAllowDelete = true;
|
||||
bAllowDuplicate = true;
|
||||
bAllowPaste = true;
|
||||
}
|
||||
|
||||
UEdComboActionGraph *UEdComboActionGraphNode::GetEdComboActionGraph() const
|
||||
{
|
||||
return Cast<UEdComboActionGraph>(this->GetGraph());
|
||||
};
|
||||
|
||||
void UEdComboActionGraphNode::AllocateDefaultPins()
|
||||
{
|
||||
if (this->ComboActionGraphNode == nullptr)
|
||||
{
|
||||
UE_LOG(LogEdComboActionGraphNode, Error, TEXT("[AllocateDefaultPins] Cannot find Owning Graph Node!"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (this->ComboActionGraphNode->bAllowInputNodes)
|
||||
{
|
||||
this->CreatePin(EGPD_Input, "MultipleNodes", FName(), TEXT("In"));
|
||||
}
|
||||
|
||||
if (this->ComboActionGraphNode->bAllowOutputNodes)
|
||||
{
|
||||
this->CreatePin(EGPD_Output, "MultipleNodes", FName(), TEXT("Out"));
|
||||
}
|
||||
}
|
||||
|
||||
FText UEdComboActionGraphNode::GetNodeTitle(ENodeTitleType::Type TitleType) const
|
||||
{
|
||||
return UComboActionEditorBFC::GetNodeTitle(this->ComboActionGraphNode);
|
||||
}
|
||||
|
||||
void UEdComboActionGraphNode::PrepareForCopying()
|
||||
{
|
||||
this->ComboActionGraphNode->Rename(nullptr, this, REN_DontCreateRedirectors | REN_DoNotDirty);
|
||||
}
|
||||
|
||||
void UEdComboActionGraphNode::AutowireNewNode(UEdGraphPin* FromPin)
|
||||
{
|
||||
Super::AutowireNewNode(FromPin);
|
||||
|
||||
if (FromPin != nullptr)
|
||||
{
|
||||
if (GetSchema()->TryCreateConnection(FromPin, GetInputPin()))
|
||||
{
|
||||
FromPin->GetOwningNode()->NodeConnectionListChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FLinearColor UEdComboActionGraphNode::GetBackgroundColor() const
|
||||
{
|
||||
// Getting Node colour based on the Settings if any found, otherwise use this logic
|
||||
if (UComboActionGraphEditorSettings *GraphEditorSettings = GetMutableDefault<UComboActionGraphEditorSettings>())
|
||||
{
|
||||
FLinearColor ReturnColour;
|
||||
if (GraphEditorSettings->FindNodeBackgroundColourOverride(this->ComboActionGraphNode->GetClass(), ReturnColour))
|
||||
{
|
||||
return ReturnColour;
|
||||
}
|
||||
}
|
||||
|
||||
return this->ComboActionGraphNode ? this->ComboActionGraphNode->GetBackgroundColor() : FLinearColor::Black;
|
||||
}
|
||||
|
||||
UEdGraphPin* UEdComboActionGraphNode::GetInputPin() const
|
||||
{
|
||||
return Pins[0];
|
||||
}
|
||||
|
||||
UEdGraphPin* UEdComboActionGraphNode::GetOutputPin() const
|
||||
{
|
||||
if (Pins.IsValidIndex(1))
|
||||
{
|
||||
return Pins[1];
|
||||
}
|
||||
|
||||
return Pins[0];
|
||||
}
|
||||
|
||||
bool UEdComboActionGraphNode::CanUserDeleteNode() const
|
||||
{
|
||||
if(!Super::CanUserDeleteNode())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this->ComboActionGraphNode)
|
||||
{
|
||||
return this->ComboActionGraphNode->bAllowDelete;
|
||||
}
|
||||
return bAllowDelete;
|
||||
}
|
||||
|
||||
bool UEdComboActionGraphNode::CanDuplicateNode() const
|
||||
{
|
||||
if(!Super::CanUserDeleteNode())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this->ComboActionGraphNode)
|
||||
{
|
||||
return this->ComboActionGraphNode->bAllowCopy;
|
||||
}
|
||||
|
||||
return bAllowCopy;
|
||||
}
|
||||
|
||||
bool UEdComboActionGraphNode::CanUserPasteNodes() const
|
||||
{
|
||||
if (this->ComboActionGraphNode)
|
||||
{
|
||||
return this->ComboActionGraphNode->bAllowPaste;
|
||||
}
|
||||
|
||||
return bAllowPaste;
|
||||
}
|
||||
|
||||
FText UEdComboActionGraphNode::GetTooltipText() const
|
||||
{
|
||||
if (this->ComboActionGraphNode)
|
||||
{
|
||||
return this->ComboActionGraphNode->GetNodeTooltipText();
|
||||
}
|
||||
|
||||
return NSLOCTEXT("UEdComboActionGraphNode", "DefaultToolTip", "Mountea Dialogue Node");
|
||||
}
|
||||
|
||||
FSlateIcon UEdComboActionGraphNode::GetIconAndTint(FLinearColor& OutColor) const
|
||||
{
|
||||
static const FSlateIcon Icon = FSlateIcon(FComboActionGraphEditorStyle::GetAppStyleSetName(), "MDSStyleSet.Node.Icon.small");
|
||||
OutColor = this->ComboActionGraphNode->GetBackgroundColor();
|
||||
return Icon;
|
||||
}
|
||||
|
||||
void UEdComboActionGraphNode::PostEditUndo()
|
||||
{
|
||||
Super::PostEditUndo();
|
||||
}
|
||||
|
||||
void UEdComboActionGraphNode::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
|
||||
{
|
||||
Super::PostEditChangeProperty(PropertyChangedEvent);
|
||||
}
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
@@ -0,0 +1,60 @@
|
||||
// ©2023 Batty Bovine Productions, LLC. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
|
||||
#include "SEdComboActionGraphNode.h"
|
||||
#include "EdGraph/EdGraphNode.h"
|
||||
|
||||
#include "EdComboActionGraphNode.generated.h"
|
||||
|
||||
DECLARE_LOG_CATEGORY_EXTERN(LogEdComboActionGraphNode, Log, All);
|
||||
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
UCLASS(MinimalAPI)
|
||||
class UEdComboActionGraphNode : public UEdGraphNode
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UEdComboActionGraphNode();
|
||||
|
||||
class UEdComboActionGraph *GetEdComboActionGraph() const;
|
||||
|
||||
virtual void AllocateDefaultPins() override;
|
||||
virtual FText GetNodeTitle(ENodeTitleType::Type TitleType) const override;
|
||||
virtual void PrepareForCopying() override;
|
||||
virtual void AutowireNewNode(UEdGraphPin *FromPin) override;
|
||||
|
||||
virtual FLinearColor GetBackgroundColor() const;
|
||||
virtual UEdGraphPin *GetInputPin() const;
|
||||
virtual UEdGraphPin *GetOutputPin() const;
|
||||
|
||||
virtual bool CanUserDeleteNode() const override;
|
||||
virtual bool CanDuplicateNode() const override;
|
||||
|
||||
virtual bool CanUserPasteNodes() const;
|
||||
|
||||
virtual FText GetTooltipText() const override;
|
||||
virtual FSlateIcon GetIconAndTint(FLinearColor &OutColor) const override;
|
||||
|
||||
#if WITH_EDITOR
|
||||
virtual void PostEditUndo() override;
|
||||
virtual void PostEditChangeProperty(FPropertyChangedEvent &PropertyChangedEvent) override;
|
||||
#endif
|
||||
|
||||
UPROPERTY(VisibleAnywhere, Instanced, Category="Combo Action Graph")
|
||||
class UComboActionGraphNode *ComboActionGraphNode;
|
||||
|
||||
SEdComboActionGraphNode *SEdNode;
|
||||
|
||||
private:
|
||||
bool bAllowCopy;
|
||||
bool bAllowDelete;
|
||||
bool bAllowDuplicate;
|
||||
bool bAllowPaste;
|
||||
};
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,89 @@
|
||||
// ©2023 Batty Bovine Productions, LLC. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
|
||||
#include "SGraphNode.h"
|
||||
#include "Settings\ComboActionGraphEditorSettings.h"
|
||||
|
||||
|
||||
class SEdComboActionGraphNode : public SGraphNode
|
||||
{
|
||||
public:
|
||||
SLATE_BEGIN_ARGS(SEdComboActionGraphNode) {}
|
||||
SLATE_END_ARGS()
|
||||
|
||||
void Construct(const FArguments &InArgs, class UEdComboActionGraphNode *InNode);
|
||||
|
||||
virtual void OnMouseEnter(const FGeometry &MyGeometry, const FPointerEvent &MouseEvent) override;
|
||||
virtual void OnMouseLeave(const FPointerEvent &MouseEvent) override;
|
||||
|
||||
const FSlateBrush *GetIndexBrush() const;
|
||||
|
||||
virtual void UpdateGraphNode() override;
|
||||
virtual void CreatePinWidgets() override;
|
||||
virtual void AddPin(const TSharedRef<SGraphPin> &PinToAdd) override;
|
||||
virtual bool IsNameReadOnly() const override;
|
||||
|
||||
void OnNameTextCommitted(const FText &InText, ETextCommit::Type CommitInfo);
|
||||
|
||||
virtual const FSlateBrush *GetNodeTypeBrush () const;
|
||||
virtual const FSlateBrush *GetTextNodeTypeBrush () const;
|
||||
virtual FSlateColor GetBorderBackgroundColor() const;
|
||||
virtual FSlateColor GetBorderFrontColor() const;
|
||||
virtual FSlateColor GetNodeTitleBackgroundColor() const;
|
||||
virtual FSlateColor GetDecoratorsBackgroundColor() const;
|
||||
|
||||
virtual FSlateColor GetPinsDockColor() const;
|
||||
|
||||
virtual EVisibility GetDragOverMarkerVisibility() const;
|
||||
|
||||
virtual const FSlateBrush *GetNameIcon() const;
|
||||
|
||||
virtual const FSlateBrush *GetInheritsImageBrush() const;
|
||||
virtual FSlateColor GetInheritsImageTint() const;
|
||||
|
||||
const FSlateBrush *GetBulletPointImageBrush() const;
|
||||
|
||||
virtual FText GetIndexOverlayTooltipText() const;
|
||||
virtual FText GetIndexText() const;
|
||||
EVisibility GetIndexSlotVisibility() const;
|
||||
FVector2D GetIndexSlotOffset() const;
|
||||
FVector2D GetIndexSlotSize() const;
|
||||
|
||||
virtual void OnIndexHoverStateChanged(bool bArg) const;
|
||||
virtual FSlateColor GetOverlayWidgetBackgroundColor(bool bArg) const;
|
||||
|
||||
bool HasGraphDecorators() const;
|
||||
bool HasNodeDecorators() const;
|
||||
|
||||
virtual FText GetDecoratorsText() const;
|
||||
virtual FText GetNumberOfDecorators() const;
|
||||
virtual FText GetDecoratorsInheritanceText() const;
|
||||
|
||||
EVisibility ShowImplementsOnlySlot_Unified() const;
|
||||
EVisibility ShowInheritsDecoratorsSlot_Unified() const;
|
||||
EVisibility ShowImplementsOnlySlot_Stack() const;
|
||||
EVisibility ShowInheritsDecoratorsSlot_Stack() const;
|
||||
EVisibility ShowAllDecorators() const;
|
||||
EVisibility ShowDecoratorsBottomPadding() const;
|
||||
|
||||
FSlateColor GetImplementsRowColor() const;
|
||||
FSlateColor GetBulletPointsImagePointColor() const;
|
||||
|
||||
virtual EComboActionDecoratorsInfoStyle GetDecoratorsStyle() const;
|
||||
EVisibility GetStackVisibility() const;
|
||||
EVisibility GetUnifiedVisibility() const;
|
||||
|
||||
FText GetTooltipText() const;
|
||||
|
||||
protected:
|
||||
TSharedPtr<SBorder> NodeBody;
|
||||
TSharedPtr<SHorizontalBox> OutputPinBox;
|
||||
|
||||
class UComboActionGraphEditorSettings *GraphEditorSettings = nullptr;
|
||||
|
||||
FLinearColor NodeInnerColor;
|
||||
FLinearColor PinsDockColor;
|
||||
};
|
||||
@@ -0,0 +1,36 @@
|
||||
// ©2023 Batty Bovine Productions, LLC. All Rights Reserved.
|
||||
|
||||
#include "SEdComboActionGraphNodeIndex.h"
|
||||
|
||||
#include "Settings/FComboActionGraphEditorStyle.h"
|
||||
|
||||
|
||||
void SEdComboActionGraphNodeIndex::Construct(const FArguments &InArgs)
|
||||
{
|
||||
const FSlateBrush* CircleBrush = FComboActionGraphEditorStyle::GetBrush(TEXT("MDSStyleSet.Node.IndexCircle"));
|
||||
ChildSlot
|
||||
[
|
||||
SNew(SOverlay)
|
||||
+SOverlay::Slot()
|
||||
.HAlign(HAlign_Fill)
|
||||
.VAlign(VAlign_Fill)
|
||||
[
|
||||
// Add a dummy box here to make sure the widget doesnt get smaller than the brush
|
||||
SNew(SBox)
|
||||
.WidthOverride(CircleBrush->ImageSize.X)
|
||||
.HeightOverride(CircleBrush->ImageSize.Y)
|
||||
]
|
||||
|
||||
+SOverlay::Slot()
|
||||
.HAlign(HAlign_Fill)
|
||||
.VAlign(VAlign_Fill)
|
||||
[
|
||||
SNew(SBorder)
|
||||
.BorderImage(CircleBrush)
|
||||
.BorderBackgroundColor(this, &SEdComboActionGraphNodeIndex::GetBackgroundColor)
|
||||
.Padding(FMargin(4.0f))
|
||||
.VAlign(VAlign_Center)
|
||||
.HAlign(HAlign_Center)
|
||||
]
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// ©2023 Batty Bovine Productions, LLC. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Widgets/DeclarativeSyntaxSupport.h"
|
||||
#include "Widgets/SCompoundWidget.h"
|
||||
|
||||
class SEdComboActionGraphNodeIndex : public SCompoundWidget
|
||||
{
|
||||
public:
|
||||
/** Delegate event fired when the hover state of this widget changes */
|
||||
DECLARE_DELEGATE_OneParam(FOnHoverStateChanged, bool /* bHovered */);
|
||||
|
||||
/** Delegate used to receive the background color of the node, depending on hover state and state of other siblings */
|
||||
DECLARE_DELEGATE_RetVal_OneParam(FSlateColor, FOnGetBackgroundColor, bool /* bHovered */);
|
||||
|
||||
SLATE_BEGIN_ARGS(SEdComboActionGraphNodeIndex) {}
|
||||
SLATE_ATTRIBUTE(TSharedPtr<SWidget>, OverlayBody)
|
||||
|
||||
// Events
|
||||
SLATE_EVENT(FOnHoverStateChanged, OnHoverStateChanged)
|
||||
SLATE_EVENT(FOnGetBackgroundColor, OnGetBackgroundColor)
|
||||
SLATE_END_ARGS()
|
||||
|
||||
void Construct(const FArguments &InArgs);
|
||||
|
||||
/** Get the color we use to display the rounded border */
|
||||
FSlateColor GetBackgroundColor() const { return FSlateColor::UseForeground(); }
|
||||
|
||||
private:
|
||||
/** The OverlayBody used for this widget*/
|
||||
TSharedPtr<SWidget> OverlayBody;
|
||||
};
|
||||
@@ -0,0 +1,208 @@
|
||||
// ©2023 Batty Bovine Productions, LLC. All Rights Reserved.
|
||||
|
||||
#include "FConnectionDrawingPolicy_ComboActionGraph.h"
|
||||
|
||||
#include "Ed/EdComboActionGraphEdge.h"
|
||||
#include "Ed/EdComboActionGraphNode.h"
|
||||
#include "Settings/ComboActionGraphEditorSettings.h"
|
||||
#include "Settings/FComboActionGraphEditorStyle.h"
|
||||
|
||||
DEFINE_LOG_CATEGORY(LogConnectionDrawingPolicy_ComboActionGraph);
|
||||
|
||||
|
||||
FConnectionDrawingPolicy_ComboActionGraph::FConnectionDrawingPolicy_ComboActionGraph(int32 InBackLayerID, int32 InFrontLayerID, float ZoomFactor, const FSlateRect &InClippingRect, FSlateWindowElementList &InDrawElements, UEdGraph *InGraphObj)
|
||||
: FKismetConnectionDrawingPolicy(InBackLayerID, InFrontLayerID, ZoomFactor, InClippingRect, InDrawElements, InGraphObj)
|
||||
, GraphObj(InGraphObj)
|
||||
{
|
||||
if (const UComboActionGraphEditorSettings* GraphEditorSettings = GetMutableDefault<UComboActionGraphEditorSettings>())
|
||||
{
|
||||
switch (GraphEditorSettings->GetArrowType())
|
||||
{
|
||||
case EComboActionArrowType::SimpleArrow:
|
||||
ArrowImage = FComboActionGraphEditorStyle::GetBrush(TEXT("MDSStyleSet.Graph.SimpleArrow"));
|
||||
break;
|
||||
case EComboActionArrowType::HollowArrow:
|
||||
ArrowImage = FComboActionGraphEditorStyle::GetBrush(TEXT("MDSStyleSet.Graph.HollowArrow"));
|
||||
break;
|
||||
case EComboActionArrowType::FancyArrow:
|
||||
ArrowImage = FComboActionGraphEditorStyle::GetBrush(TEXT("MDSStyleSet.Graph.FancyArrow"));
|
||||
break;
|
||||
case EComboActionArrowType::Bubble:
|
||||
ArrowImage = FComboActionGraphEditorStyle::GetBrush(TEXT("MDSStyleSet.Graph.Bubble"));
|
||||
break;
|
||||
case EComboActionArrowType::None:
|
||||
default:
|
||||
ArrowImage = nullptr;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ArrowImage = FAppStyle::GetBrush( TEXT("GenericPlay") );
|
||||
}
|
||||
|
||||
ArrowRadius = ArrowImage ? ArrowImage->ImageSize * ZoomFactor * 0.5f : FVector2D(0.f);
|
||||
MidpointImage = nullptr;
|
||||
MidpointRadius = FVector2D::ZeroVector;
|
||||
HoverDeemphasisDarkFraction = 0.8f;
|
||||
|
||||
BubbleImage = FAppStyle::GetBrush( TEXT("Graph.Arrow") );
|
||||
}
|
||||
|
||||
void FConnectionDrawingPolicy_ComboActionGraph::DetermineWiringStyle(UEdGraphPin *OutputPin, UEdGraphPin *InputPin, FConnectionParams &Params)
|
||||
{
|
||||
Params.AssociatedPin1 = OutputPin;
|
||||
Params.AssociatedPin2 = InputPin;
|
||||
|
||||
const UComboActionGraphEditorSettings *MounteaDialogueGraphEditorSettings = GetDefault<UComboActionGraphEditorSettings>();
|
||||
if (MounteaDialogueGraphEditorSettings)
|
||||
{
|
||||
Params.WireThickness = MounteaDialogueGraphEditorSettings->GetWireWidth();
|
||||
}
|
||||
else
|
||||
{
|
||||
Params.WireThickness = 1.f;
|
||||
}
|
||||
|
||||
const bool bDeemphasizeUnhoveredPins = HoveredPins.Num() > 0;
|
||||
if (bDeemphasizeUnhoveredPins)
|
||||
{
|
||||
ApplyHoverDeemphasis(OutputPin, InputPin, /*inout*/ Params.WireThickness, /*inout*/ Params.WireColor);
|
||||
}
|
||||
}
|
||||
|
||||
void FConnectionDrawingPolicy_ComboActionGraph::Draw(TMap<TSharedRef<SWidget>, FArrangedWidget> &InPinGeometries, FArrangedChildren &ArrangedNodes)
|
||||
{
|
||||
// Build an acceleration structure to quickly find geometry for the nodes
|
||||
NodeWidgetMap.Empty();
|
||||
for (int32 NodeIndex = 0; NodeIndex < ArrangedNodes.Num(); ++NodeIndex)
|
||||
{
|
||||
FArrangedWidget& CurWidget = ArrangedNodes[NodeIndex];
|
||||
TSharedRef<SGraphNode> ChildNode = StaticCastSharedRef<SGraphNode>(CurWidget.Widget);
|
||||
NodeWidgetMap.Add(ChildNode->GetNodeObj(), NodeIndex);
|
||||
}
|
||||
|
||||
// Now draw
|
||||
FConnectionDrawingPolicy::Draw(InPinGeometries, ArrangedNodes);
|
||||
}
|
||||
|
||||
void FConnectionDrawingPolicy_ComboActionGraph::DrawSplineWithArrow(const FGeometry &StartGeom, const FGeometry &EndGeom, const FConnectionParams &Params)
|
||||
{
|
||||
// Get a reasonable seed point (halfway between the boxes)
|
||||
const FVector2D StartCenter = FGeometryHelper::CenterOf(StartGeom);
|
||||
const FVector2D EndCenter = FGeometryHelper::CenterOf(EndGeom);
|
||||
const FVector2D SeedPoint = (StartCenter + EndCenter) * 0.5f;
|
||||
|
||||
// Find the (approximate) closest points between the two boxes
|
||||
const FVector2D StartAnchorPoint = FGeometryHelper::FindClosestPointOnGeom(StartGeom, SeedPoint);
|
||||
const FVector2D EndAnchorPoint = FGeometryHelper::FindClosestPointOnGeom(EndGeom, SeedPoint);
|
||||
|
||||
this->DrawSplineWithArrow(StartAnchorPoint, EndAnchorPoint, Params);
|
||||
}
|
||||
|
||||
void FConnectionDrawingPolicy_ComboActionGraph::DrawSplineWithArrow(const FVector2D &StartPoint, const FVector2D &EndPoint, const FConnectionParams &Params)
|
||||
{
|
||||
// bUserFlag1 indicates that we need to reverse the direction of connection (used by debugger)
|
||||
const FVector2D &P0 = Params.bUserFlag1 ? EndPoint : StartPoint;
|
||||
const FVector2D &P1 = Params.bUserFlag1 ? StartPoint : EndPoint;
|
||||
|
||||
UE_LOG(LogConnectionDrawingPolicy_ComboActionGraph, Verbose, TEXT("%s I %s"), *P0.ToString(), *P1.ToString());
|
||||
|
||||
FConnectionParams NewParams = Params;
|
||||
//NewParams.bDrawBubbles = true;
|
||||
|
||||
if (const UComboActionGraphEditorSettings *MounteaDialogueGraphEditorSettings = GetMutableDefault<UComboActionGraphEditorSettings>())
|
||||
{
|
||||
NewParams.WireThickness = MounteaDialogueGraphEditorSettings->GetWireWidth();
|
||||
}
|
||||
|
||||
Internal_DrawLineWithArrow(P0, P1, NewParams);
|
||||
}
|
||||
|
||||
void FConnectionDrawingPolicy_ComboActionGraph::DrawPreviewConnector(const FGeometry &PinGeometry, const FVector2D &StartPoint, const FVector2D &EndPoint, UEdGraphPin* Pin)
|
||||
{
|
||||
FConnectionParams Params;
|
||||
DetermineWiringStyle(Pin, nullptr, /*inout*/ Params);
|
||||
|
||||
if (Pin->Direction == EEdGraphPinDirection::EGPD_Output)
|
||||
{
|
||||
DrawSplineWithArrow(FGeometryHelper::FindClosestPointOnGeom(PinGeometry, EndPoint), EndPoint, Params);
|
||||
}
|
||||
else
|
||||
{
|
||||
DrawSplineWithArrow(FGeometryHelper::FindClosestPointOnGeom(PinGeometry, StartPoint), StartPoint, Params);
|
||||
}
|
||||
}
|
||||
|
||||
FVector2D FConnectionDrawingPolicy_ComboActionGraph::ComputeSplineTangent(const FVector2D &Start, const FVector2D &End) const
|
||||
{
|
||||
const FVector2D Delta = End - Start;
|
||||
const FVector2D NormDelta = Delta.GetSafeNormal();
|
||||
|
||||
return NormDelta;
|
||||
}
|
||||
|
||||
void FConnectionDrawingPolicy_ComboActionGraph::DetermineLinkGeometry(FArrangedChildren &ArrangedNodes, TSharedRef<SWidget> &OutputPinWidget, UEdGraphPin *OutputPin, UEdGraphPin *InputPin, FArrangedWidget *&StartWidgetGeometry, FArrangedWidget *&EndWidgetGeometry)
|
||||
{
|
||||
if (UEdComboActionGraphEdge *EdgeNode = Cast<UEdComboActionGraphEdge>(InputPin->GetOwningNode()))
|
||||
{
|
||||
UEdComboActionGraphNode* Start = EdgeNode->GetStartNode();
|
||||
UEdComboActionGraphNode* End = EdgeNode->GetEndNode();
|
||||
if (Start != nullptr && End != nullptr)
|
||||
{
|
||||
int32* StartNodeIndex = NodeWidgetMap.Find(Start);
|
||||
int32* EndNodeIndex = NodeWidgetMap.Find(End);
|
||||
if (StartNodeIndex != nullptr && EndNodeIndex != nullptr)
|
||||
{
|
||||
StartWidgetGeometry = &(ArrangedNodes[*StartNodeIndex]);
|
||||
EndWidgetGeometry = &(ArrangedNodes[*EndNodeIndex]);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
StartWidgetGeometry = PinGeometries->Find(OutputPinWidget);
|
||||
|
||||
if (TSharedPtr<SGraphPin>* pTargetWidget = PinToPinWidgetMap.Find(InputPin))
|
||||
{
|
||||
TSharedRef<SGraphPin> InputWidget = (*pTargetWidget).ToSharedRef();
|
||||
EndWidgetGeometry = PinGeometries->Find(InputWidget);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void FConnectionDrawingPolicy_ComboActionGraph::Internal_DrawLineWithArrow(const FVector2D &StartAnchorPoint, const FVector2D &EndAnchorPoint, const FConnectionParams &Params)
|
||||
{
|
||||
const float LineSeparationAmount = 4.5f;
|
||||
|
||||
const FVector2D DeltaPos = EndAnchorPoint - StartAnchorPoint;
|
||||
const FVector2D UnitDelta = DeltaPos.GetSafeNormal();
|
||||
const FVector2D Normal = FVector2D(DeltaPos.Y, -DeltaPos.X).GetSafeNormal();
|
||||
|
||||
// Come up with the final start/end points
|
||||
const FVector2D DirectionBias = Normal * LineSeparationAmount;
|
||||
const FVector2D LengthBias = ArrowRadius.X * UnitDelta;
|
||||
const FVector2D StartPoint = StartAnchorPoint + DirectionBias + LengthBias;
|
||||
const FVector2D EndPoint = EndAnchorPoint + DirectionBias - LengthBias;
|
||||
|
||||
// Draw a line/spline
|
||||
DrawConnection(WireLayerID, StartPoint, EndPoint, Params);
|
||||
|
||||
// Draw the arrow
|
||||
if (ArrowImage)
|
||||
{
|
||||
const FVector2D ArrowDrawPos = EndPoint - ArrowRadius;
|
||||
const float AngleInRadians = FMath::Atan2(DeltaPos.Y, DeltaPos.X);
|
||||
|
||||
FSlateDrawElement::MakeRotatedBox(
|
||||
DrawElementsList,
|
||||
ArrowLayerID,
|
||||
FPaintGeometry(ArrowDrawPos, ArrowImage->ImageSize * ZoomFactor, ZoomFactor),
|
||||
ArrowImage,
|
||||
ESlateDrawEffect::None,
|
||||
AngleInRadians,
|
||||
TOptional<FVector2D>(),
|
||||
FSlateDrawElement::RelativeToElement,
|
||||
Params.WireColor
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
// ©2023 Batty Bovine Productions, LLC. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "BlueprintConnectionDrawingPolicy.h"
|
||||
#include "ConnectionDrawingPolicy.h"
|
||||
|
||||
DECLARE_LOG_CATEGORY_EXTERN(LogConnectionDrawingPolicy_ComboActionGraph, Log, All);
|
||||
|
||||
|
||||
class FConnectionDrawingPolicy_ComboActionGraph : public FKismetConnectionDrawingPolicy
|
||||
{
|
||||
|
||||
public:
|
||||
FConnectionDrawingPolicy_ComboActionGraph(int32 InBackLayerID, int32 InFrontLayerID, float ZoomFactor, const FSlateRect& InClippingRect, FSlateWindowElementList& InDrawElements, UEdGraph* InGraphObj);
|
||||
virtual ~FConnectionDrawingPolicy_ComboActionGraph() {};
|
||||
|
||||
// FConnectionDrawingPolicy interface
|
||||
virtual void DetermineWiringStyle(UEdGraphPin* OutputPin, UEdGraphPin* InputPin, /*inout*/ FConnectionParams& Params) override;
|
||||
virtual void Draw(TMap<TSharedRef<SWidget>, FArrangedWidget>& InPinGeometries, FArrangedChildren& ArrangedNodes) override;
|
||||
virtual void DrawSplineWithArrow(const FGeometry& StartGeom, const FGeometry& EndGeom, const FConnectionParams& Params) override;
|
||||
virtual void DrawSplineWithArrow(const FVector2D& StartPoint, const FVector2D& EndPoint, const FConnectionParams& Params) override;
|
||||
virtual void DrawPreviewConnector(const FGeometry& PinGeometry, const FVector2D& StartPoint, const FVector2D& EndPoint, UEdGraphPin* Pin) override;
|
||||
virtual FVector2D ComputeSplineTangent(const FVector2D& Start, const FVector2D& End) const override;
|
||||
virtual void DetermineLinkGeometry(FArrangedChildren& ArrangedNodes, TSharedRef<SWidget>& OutputPinWidget, UEdGraphPin* OutputPin, UEdGraphPin* InputPin, FArrangedWidget*& StartWidgetGeometry, FArrangedWidget*& EndWidgetGeometry) override;
|
||||
// End of FConnectionDrawingPolicy interface
|
||||
|
||||
protected:
|
||||
void Internal_DrawLineWithArrow(const FVector2D& StartAnchorPoint, const FVector2D& EndAnchorPoint, const FConnectionParams& Params);
|
||||
|
||||
protected:
|
||||
UEdGraph *GraphObj;
|
||||
TMap<UEdGraphNode*, int32> NodeWidgetMap;
|
||||
|
||||
};
|
||||
@@ -0,0 +1,86 @@
|
||||
// ©2023 Batty Bovine Productions, LLC. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
|
||||
#include "Ed/EdComboActionGraphNode.h"
|
||||
#include "Kismet/BlueprintFunctionLibrary.h"
|
||||
#include "Nodes/ComboActionGraphNode.h"
|
||||
#include "Nodes/ComboActionGraphNode_ActionNodeBase.h"
|
||||
#include "Settings/ComboActionGraphEditorSettings.h"
|
||||
|
||||
#include "ComboActionEditorBFC.generated.h"
|
||||
|
||||
|
||||
/**
|
||||
* Editor Only helper functions.
|
||||
*/
|
||||
UCLASS()
|
||||
class UComboActionEditorBFC : public UBlueprintFunctionLibrary
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
|
||||
#if WITH_EDITOR
|
||||
static FText GetNodeTitle(UComboActionGraphNode *Node)
|
||||
{
|
||||
if (!Node) return FText::FromString("Invalid Node");
|
||||
|
||||
const UComboActionGraphEditorSettings *Settings = GetDefault<UComboActionGraphEditorSettings>();
|
||||
if (Settings)
|
||||
{
|
||||
if (Settings->ShowAutomaticNames())
|
||||
{
|
||||
if (const UComboActionGraphNode_ActionNodeBase *DialogueNodeBase = Cast<UComboActionGraphNode_ActionNodeBase>(Node))
|
||||
{
|
||||
if (DialogueNodeBase->GetDataTable())
|
||||
{
|
||||
FString ReturnString;
|
||||
DialogueNodeBase->GetRowName().ToString(ReturnString);
|
||||
|
||||
return FText::FromString(ReturnString);
|
||||
}
|
||||
}
|
||||
|
||||
return Node->GetInternalName();
|
||||
}
|
||||
}
|
||||
|
||||
return Node->GetNodeTitle();
|
||||
}
|
||||
|
||||
static EComboActionNodeTheme GetNodeTheme()
|
||||
{
|
||||
const UComboActionGraphEditorSettings *Settings = GetDefault<UComboActionGraphEditorSettings>();
|
||||
if (Settings != nullptr)
|
||||
{
|
||||
return Settings->GetNodeTheme();
|
||||
}
|
||||
|
||||
return EComboActionNodeTheme::DarkTheme;
|
||||
}
|
||||
|
||||
static void TriggerPreviewRefresh(TArray<UObject*> NodeObjects)
|
||||
{
|
||||
for (auto Itr : NodeObjects)
|
||||
{
|
||||
UEdComboActionGraphNode *SelectedNode = Cast<UEdComboActionGraphNode>(Itr);
|
||||
if (!SelectedNode || !SelectedNode->ComboActionGraphNode)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
UComboActionGraphNode_ActionNodeBase *DialogueNodeBase = Cast<UComboActionGraphNode_ActionNodeBase>(SelectedNode->ComboActionGraphNode);
|
||||
if (!DialogueNodeBase)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
DialogueNodeBase->UpdatePreviews();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
};
|
||||
@@ -0,0 +1,92 @@
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
|
||||
namespace ComboActionGraphColors
|
||||
{
|
||||
namespace NodeBody
|
||||
{
|
||||
constexpr FLinearColor Default(0.1f, 0.1f, 0.1f);
|
||||
constexpr FLinearColor Root(0.5f, 0.5f, 0.5f, 0.1f);
|
||||
constexpr FLinearColor Error(1.0f, 0.0f, 0.0f);
|
||||
}
|
||||
|
||||
namespace DecoratorsBody
|
||||
{
|
||||
constexpr FLinearColor Default(0.1f, 0.1f, 0.1f);
|
||||
}
|
||||
|
||||
namespace NodeBorder
|
||||
{
|
||||
constexpr FLinearColor Inactive(0.08f, 0.08f, 0.08f);
|
||||
constexpr FLinearColor Root(0.2f, 0.2f, 0.2f, 0.2f);
|
||||
constexpr FLinearColor Selected(1.00f, 0.08f, 0.08f);
|
||||
constexpr FLinearColor ActiveDebugging(1.0f, 1.0f, 0.0f);
|
||||
constexpr FLinearColor InactiveDebugging(0.4f, 0.4f, 0.0f);
|
||||
constexpr FLinearColor HighlightAbortRange0(0.0f, 0.22f, 0.4f);
|
||||
constexpr FLinearColor HighlightAbortRange1(0.0f, 0.4f, 0.22f);
|
||||
constexpr FLinearColor Disconnected(0.f, 0.f, 0.f);
|
||||
constexpr FLinearColor BrokenWithParent(1.f, 0.f, 1.f);
|
||||
constexpr FLinearColor QuickFind(0.f, 0.8f, 0.f);
|
||||
}
|
||||
|
||||
namespace Pin
|
||||
{
|
||||
constexpr FLinearColor Diff(0.9f, 0.2f, 0.15f);
|
||||
constexpr FLinearColor Hover(1.0f, 0.7f, 0.0f);
|
||||
constexpr FLinearColor Default(0.02f, 0.02f, 0.02f);
|
||||
constexpr FLinearColor SingleNode(0.02f, 0.02f, 0.02f);
|
||||
}
|
||||
|
||||
namespace Connection
|
||||
{
|
||||
constexpr FLinearColor Default(1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
namespace Action
|
||||
{
|
||||
constexpr FLinearColor DragMarker(1.0f, 1.0f, 0.2f);
|
||||
}
|
||||
|
||||
namespace Overlay
|
||||
{
|
||||
constexpr FLinearColor LightTheme(1.f, 1.f, 1.f, 0.45f);
|
||||
constexpr FLinearColor DarkTheme(0.f, 0.f, 0.f, 0.9f);
|
||||
}
|
||||
|
||||
namespace PinsDock
|
||||
{
|
||||
constexpr FLinearColor DarkTheme(0.075f, 0.075f, 0.075f, 1.f);
|
||||
constexpr FLinearColor LightTheme(0.075f, 0.075f, 0.075f, 1.f);
|
||||
}
|
||||
|
||||
namespace ValidationGraph
|
||||
{
|
||||
constexpr FLinearColor LightTheme(0.1f, 0.1f, 0.1f, 1.f);
|
||||
constexpr FLinearColor DarkTheme(0.05f, 0.05f, 0.05f, 1.f);
|
||||
}
|
||||
|
||||
namespace IndexBorder
|
||||
{
|
||||
constexpr FLinearColor NormalState(0.05f, 0.05f, 0.05f, 1.f);
|
||||
constexpr FLinearColor HoveredState(0.05f, 0.05f, 0.05f, 1.f);
|
||||
}
|
||||
|
||||
namespace BulletPointsColors
|
||||
{
|
||||
constexpr FLinearColor Normal(0.8f, 0.8f, 0.8f, 1.f);
|
||||
constexpr FLinearColor Disabled(0.8f, 0.8f, 0.8f, 0.2f);
|
||||
}
|
||||
|
||||
namespace TextColors
|
||||
{
|
||||
constexpr FLinearColor Normal(0.8f, 0.8f, 0.8f, 1.f);
|
||||
constexpr FLinearColor Disabled(0.8f, 0.8f, 0.8f, 0.2f);
|
||||
}
|
||||
|
||||
namespace Previews
|
||||
{
|
||||
constexpr FLinearColor Normal(0.8f, 0.8f, 0.8f, 0.05f);
|
||||
constexpr FLinearColor Invalid(0.8f, 0.8f, 0.8f, 0.2f);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
// ©2023 Batty Bovine Productions, LLC. All Rights Reserved.
|
||||
|
||||
#include "ComboActionGraphEditorSettings.h"
|
||||
|
||||
#define LOCTEXT_NAMESPACE "ComboActionGraphEditorSettings"
|
||||
|
||||
|
||||
UComboActionGraphEditorSettings::UComboActionGraphEditorSettings()
|
||||
{
|
||||
NodeType = EComboActionNodeType::SoftCorners;
|
||||
NodeTheme = EComboActionNodeTheme::DarkTheme;
|
||||
ArrowType = EComboActionArrowType::HollowArrow;
|
||||
|
||||
CategoryName = TEXT("Combo Input");
|
||||
SectionName = TEXT("Combo Input (Editor)");
|
||||
|
||||
AutoLayoutStrategy = EComboActionAutoLayoutStrategyType::Tree;
|
||||
|
||||
bFirstPassOnly = false;
|
||||
bRandomInit = false;
|
||||
OptimalDistance = 100.f;
|
||||
MaxIteration = 50;
|
||||
InitTemperature = 10.f;
|
||||
CoolDownRate = 10.f;
|
||||
|
||||
WireWidth = 0.8f;
|
||||
//WireStyle = EWiringStyle::EWS_Simple;
|
||||
//BubbleDrawRule = EBubbleDrawRule::EBDR_OnSelected;
|
||||
|
||||
bAllowRenameNodes = true;
|
||||
bDisplayAutomaticNames = false;
|
||||
|
||||
bShowDetailedInfo_InheritsDecorators = true;
|
||||
bShowDetailedInfo_NumDecorators = true;
|
||||
DecoratorsInfoStyle = EComboActionDecoratorsInfoStyle::Unified;
|
||||
|
||||
bAllowNativeDecoratorsEdit = false;
|
||||
}
|
||||
|
||||
#undef LOCTEXT_NAMESPACE
|
||||
@@ -0,0 +1,292 @@
|
||||
// ©2023 Batty Bovine Productions, LLC. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Engine/DeveloperSettings.h"
|
||||
|
||||
#include "ComboActionGraphEditorSettings.generated.h"
|
||||
|
||||
|
||||
#pragma region Enums
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EComboActionAutoLayoutStrategyType : uint8
|
||||
{
|
||||
Tree UMETA(DisplayName="Tree"),
|
||||
ForceDirected UMETA(DisplayName="Force Directed"),
|
||||
|
||||
Default UMETA(Hidden)
|
||||
};
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EComboActionWiringStyle : uint8
|
||||
{
|
||||
Vanilla UMETA(DisplayName="Vanilla"),
|
||||
Simple UMETA(DisplayName="90° Angle"),
|
||||
Complex UMETA(DisplayName="45° Angle"),
|
||||
|
||||
Default UMETA(Hidden)
|
||||
};
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EComboActionBubbleDrawRule : uint8
|
||||
{
|
||||
Always UMETA(DisplayName="Always"),
|
||||
OnSelected UMETA(DisplayName="When Selected")
|
||||
};
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EComboActionNodeTheme : uint8
|
||||
{
|
||||
DarkTheme UMETA(DisplayName="Dark Theme"),
|
||||
LightTheme UMETA(DisplayName="Light Theme")
|
||||
};
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EComboActionDecoratorsInfoStyle : uint8
|
||||
{
|
||||
Stack UMETA(DisplayName="Stack"),
|
||||
Unified UMETA(DisplayName="Unified")
|
||||
};
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EComboActionNodeType : uint8
|
||||
{
|
||||
SoftCorners UMETA(DisplayName="Soft Corners"),
|
||||
HardCorners UMETA(DisplayName="Hard Corners")
|
||||
};
|
||||
|
||||
UENUM(BlueprintType)
|
||||
enum class EComboActionArrowType : uint8
|
||||
{
|
||||
SimpleArrow UMETA(DisplayName="Simple Arrow"),
|
||||
HollowArrow UMETA(DisplayName="Hollow Arrow"),
|
||||
FancyArrow UMETA(DisplayName="Fancy Arrow"),
|
||||
Bubble UMETA(DisplayName="Bubble"),
|
||||
None UMETA(DisplayName="Nothing")
|
||||
};
|
||||
|
||||
#pragma endregion
|
||||
|
||||
/**
|
||||
* Combo Action Graph global settings.
|
||||
*/
|
||||
UCLASS(config = MounteaSettings)
|
||||
class COMBOINPUT_API UComboActionGraphEditorSettings : public UDeveloperSettings
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
public:
|
||||
UComboActionGraphEditorSettings();
|
||||
|
||||
private:
|
||||
|
||||
#pragma region GraphNodes
|
||||
|
||||
UPROPERTY(config, EditDefaultsOnly, Category = "NodesSettings")
|
||||
EComboActionNodeType NodeType;
|
||||
|
||||
UPROPERTY(config, EditDefaultsOnly, Category = "NodesSettings")
|
||||
EComboActionNodeTheme NodeTheme;
|
||||
|
||||
UPROPERTY(config, EditDefaultsOnly, Category = "NodesSettings|DecoratorsInfo")
|
||||
uint8 bShowDetailedInfo_NumDecorators : 1;
|
||||
|
||||
UPROPERTY(config, EditDefaultsOnly, Category = "NodesSettings|DecoratorsInfo")
|
||||
uint8 bShowDetailedInfo_InheritsDecorators : 1;
|
||||
|
||||
UPROPERTY(config, EditDefaultsOnly, Category = "NodesSettings")
|
||||
EComboActionDecoratorsInfoStyle DecoratorsInfoStyle;
|
||||
|
||||
UPROPERTY(config, EditDefaultsOnly, Category = "NodesSettings")
|
||||
bool bDisplayAutomaticNames;
|
||||
|
||||
UPROPERTY(config, EditDefaultsOnly, Category = "NodesSettings")
|
||||
bool bAllowRenameNodes;
|
||||
|
||||
/**
|
||||
* Select a Node Class and specify Override Colour for this Node type.
|
||||
* Only non-abstract classes are allowed!
|
||||
*/
|
||||
UPROPERTY(config, EditDefaultsOnly, Category = "NodesSettings", meta=(ShowTreeView))
|
||||
TMap<TSoftClassPtr<class UComboActionGraphNode>, FLinearColor> OverrideNodeBackgroundColours;
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region GraphDecorators
|
||||
|
||||
// Enables 'Edit' button for Native Code Decorators
|
||||
UPROPERTY(config, EditDefaultsOnly, Category = "NodesSettings")
|
||||
bool bAllowNativeDecoratorsEdit;
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region GraphWiring
|
||||
|
||||
UPROPERTY(config, EditDefaultsOnly, Category = "NodeWiring", meta=(UIMin=0.1f, ClampMin=0.1f, UIMax=1.5f, ClampMax=1.5f))
|
||||
float WireWidth;
|
||||
|
||||
UPROPERTY(config, EditDefaultsOnly, Category = "NodeWiring") //, meta=(ConfigRestartRequired=true))
|
||||
EComboActionArrowType ArrowType;
|
||||
|
||||
/* Advanced Wiring doesn't work now
|
||||
|
||||
UPROPERTY(config, EditDefaultsOnly, Category = "NodeWiring", AdvancedDisplay, meta=(ToolTip="Work in Progress!"))
|
||||
bool bUseAdvancedWiring;
|
||||
|
||||
UPROPERTY(config, EditDefaultsOnly, Category = "NodeWiring", AdvancedDisplay, meta=(ToolTip="Work in Progress!", EditCondition="bUseAdvancedWiring"))
|
||||
EWiringStyle WireStyle;
|
||||
|
||||
UPROPERTY(config, EditDefaultsOnly, Category = "NodeWiring", AdvancedDisplay, meta=(ToolTip="Work in Progress!", EditCondition="bUseAdvancedWiring"))
|
||||
uint32 HorizontalOffset = 16;
|
||||
|
||||
UPROPERTY(config, EditDefaultsOnly, Category = "NodeWiring", AdvancedDisplay, meta=(ToolTip="Work in Progress!", EditCondition="bUseAdvancedWiring"))
|
||||
EBubbleDrawRule BubbleDrawRule;
|
||||
|
||||
UPROPERTY(config, EditDefaultsOnly, Category = "NodeWiring", AdvancedDisplay, meta=(ToolTip="Work in Progress!", EditCondition="bUseAdvancedWiring"))
|
||||
int32 BubbleZoomThreshold;
|
||||
|
||||
// Space between bubbles on the wires. Default: 20.0
|
||||
UPROPERTY(config, EditDefaultsOnly, Category = "NodeWiring", AdvancedDisplay, meta = (ClampMin = "10.0", ToolTip="Work in Progress!", EditCondition="bUseAdvancedWiring"))
|
||||
float BubbleSpace = 20.0f;
|
||||
|
||||
UPROPERTY(config, EditDefaultsOnly, Category = "NodeWiring", AdvancedDisplay, meta = (ClampMin = "10.0", ToolTip="Work in Progress!", EditCondition="bUseAdvancedWiring"))
|
||||
float BubbleSize = 2.0f;
|
||||
|
||||
UPROPERTY(config, EditDefaultsOnly, Category = "NodeWiring", AdvancedDisplay, meta = (ClampMin = "10.0", ToolTip="Work in Progress!", EditCondition="bUseAdvancedWiring"))
|
||||
float BubbleSpeed = 2.0f;
|
||||
|
||||
// Disable the offset for pins. Default: false
|
||||
UPROPERTY(config, EditDefaultsOnly, Category = "NodeWiring", AdvancedDisplay, meta=(ToolTip="Work in Progress!", EditCondition="bUseAdvancedWiring"))
|
||||
bool DisablePinOffset = false;
|
||||
|
||||
// Fix default zoomed-out wire displacement. Default: true
|
||||
UPROPERTY(config, EditDefaultsOnly, Category = "NodeWiring", AdvancedDisplay, meta=(ToolTip="Work in Progress!", EditCondition="bUseAdvancedWiring"))
|
||||
bool FixZoomDisplacement = true;
|
||||
|
||||
*/
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region GraphArrange
|
||||
|
||||
UPROPERTY(config, EditDefaultsOnly, Category = "AutoArrange")
|
||||
float OptimalDistance;
|
||||
|
||||
UPROPERTY(config, EditDefaultsOnly, AdvancedDisplay, Category = "AutoArrange")
|
||||
EComboActionAutoLayoutStrategyType AutoLayoutStrategy;
|
||||
|
||||
UPROPERTY(config, EditDefaultsOnly, AdvancedDisplay, Category = "AutoArrange")
|
||||
int32 MaxIteration;
|
||||
|
||||
UPROPERTY(config, EditDefaultsOnly, AdvancedDisplay, Category = "AutoArrange")
|
||||
bool bFirstPassOnly;
|
||||
|
||||
UPROPERTY(config, EditDefaultsOnly, AdvancedDisplay, Category = "AutoArrange")
|
||||
bool bRandomInit;
|
||||
|
||||
UPROPERTY(config, EditDefaultsOnly, AdvancedDisplay, Category = "AutoArrange")
|
||||
float InitTemperature;
|
||||
|
||||
UPROPERTY(config, EditDefaultsOnly, AdvancedDisplay, Category = "AutoArrange")
|
||||
float CoolDownRate;
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#if WITH_EDITOR
|
||||
virtual FText GetSectionText() const override
|
||||
{
|
||||
return NSLOCTEXT("ComboActionGraphEditorSystem", "ComboActionGraphEditorSection", "Combo Action Graph (Editor)");
|
||||
}
|
||||
|
||||
virtual FText GetSectionDescription() const override
|
||||
{
|
||||
return NSLOCTEXT("ComboActionGraphEditorSystem", "ComboActionGraphEditorDescription", "Default values for Mountea Plugins (Editor).");
|
||||
}
|
||||
|
||||
virtual FName GetContainerName() const override
|
||||
{
|
||||
return "Project";
|
||||
}
|
||||
#endif
|
||||
|
||||
public:
|
||||
|
||||
#pragma region GraphNodes_Getters
|
||||
|
||||
EComboActionNodeTheme GetNodeTheme() const { return NodeTheme; }
|
||||
EComboActionNodeType GetNodeType() const { return NodeType; }
|
||||
bool ShowDetailedInfo_NumDecorators() const { return bShowDetailedInfo_NumDecorators; }
|
||||
bool ShowDetailedInfo_InheritsDecorators() const { return bShowDetailedInfo_InheritsDecorators; }
|
||||
bool ShowAutomaticNames() const { return bDisplayAutomaticNames; }
|
||||
EComboActionDecoratorsInfoStyle GetDecoratorsStyle() const { return DecoratorsInfoStyle; }
|
||||
bool AllowRenameNodes() const { return bAllowRenameNodes; }
|
||||
|
||||
bool FindNodeBackgroundColourOverride(const TSoftClassPtr<class UComboActionGraphNode> NodeClass, FLinearColor& BackgroundColour)
|
||||
{
|
||||
if (OverrideNodeBackgroundColours.Contains(NodeClass))
|
||||
{
|
||||
BackgroundColour = *OverrideNodeBackgroundColours.Find(NodeClass);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region GraphDecorators_Getters
|
||||
|
||||
bool IsNativeDecoratorsEditAllowed() const { return bAllowNativeDecoratorsEdit; }
|
||||
|
||||
#pragma endregion
|
||||
|
||||
|
||||
#pragma region GraphWiring_Getters
|
||||
|
||||
float GetWireWidth() const { return this->WireWidth; }
|
||||
|
||||
EComboActionArrowType GetArrowType() const { return this->ArrowType; }
|
||||
|
||||
/*
|
||||
bool AllowAdvancedWiring() const
|
||||
{ return bUseAdvancedWiring; };
|
||||
|
||||
EWiringStyle GetWireStyle() const
|
||||
{ return WireStyle; };
|
||||
|
||||
int32 GetHorizontalOffset() const
|
||||
{ return HorizontalOffset; };
|
||||
|
||||
EBubbleDrawRule GetBubbleDrawRule() const
|
||||
{ return BubbleDrawRule; };
|
||||
|
||||
int32 GetBubbleZoomThreshold() const
|
||||
{ return BubbleZoomThreshold; };
|
||||
|
||||
float GetBubbleSpace() const
|
||||
{ return BubbleSpace; };
|
||||
|
||||
float GetBubbleSpeed() const
|
||||
{ return BubbleSpeed; };
|
||||
|
||||
float GetBubbleSize() const
|
||||
{ return BubbleSize; };
|
||||
*/
|
||||
#pragma endregion
|
||||
|
||||
|
||||
#pragma region GraphArrange_Getters
|
||||
|
||||
EComboActionAutoLayoutStrategyType GetAutoLayoutStrategy() const { return this->AutoLayoutStrategy; }
|
||||
float GetOptimalDistance() const { return this->OptimalDistance; }
|
||||
int32 GetMaxIteration() const { return this->MaxIteration; }
|
||||
bool IsFirstPassOnly() const { return this->bFirstPassOnly; }
|
||||
bool IsRandomInit() const { return this->bRandomInit; }
|
||||
float GetInitTemperature() const { return this->InitTemperature; }
|
||||
float GetCoolDownRate() const { return this->CoolDownRate; }
|
||||
|
||||
#pragma endregion
|
||||
};
|
||||
|
||||
@@ -0,0 +1,138 @@
|
||||
// Copyright Dominik Pavlicek 2023. All Rights Reserved.
|
||||
|
||||
#include "FComboActionGraphEditorStyle.h"
|
||||
|
||||
#include "Interfaces/IPluginManager.h"
|
||||
#include "Misc/Paths.h"
|
||||
#include "Styling/SlateStyleRegistry.h"
|
||||
|
||||
#define IMAGE_BRUSH(RelativePath, ...) FSlateImageBrush(StyleSet->RootToContentDir(RelativePath, TEXT(".png")), __VA_ARGS__)
|
||||
#define BOX_BRUSH(RelativePath, ...) FSlateBoxBrush(StyleSet->RootToContentDir(RelativePath, TEXT(".png")), __VA_ARGS__)
|
||||
#define DEFAULT_FONT(...) FCoreStyle::GetDefaultFontStyle(__VA_ARGS__)
|
||||
|
||||
|
||||
TSharedPtr<FSlateStyleSet> FComboActionGraphEditorStyle::StyleSet = nullptr;
|
||||
|
||||
void FComboActionGraphEditorStyle::Initialize()
|
||||
{
|
||||
if (!StyleSet.IsValid() )
|
||||
{
|
||||
Create();
|
||||
FSlateStyleRegistry::RegisterSlateStyle(*StyleSet.Get());
|
||||
}
|
||||
}
|
||||
|
||||
void FComboActionGraphEditorStyle::Shutdown()
|
||||
{
|
||||
FSlateStyleRegistry::UnRegisterSlateStyle(*StyleSet.Get());
|
||||
ensure(StyleSet.IsUnique());
|
||||
StyleSet.Reset();
|
||||
}
|
||||
|
||||
void FComboActionGraphEditorStyle::Create()
|
||||
{
|
||||
const FVector2D Icon12x12(12.0f, 12.0f);
|
||||
const FVector2D Icon16x16(16.0f, 16.0f);
|
||||
const FVector2D Icon40x40(40.0f, 40.0f);
|
||||
const FVector2D Icon64x64(64.0f, 64.0f);
|
||||
const FVector2D Icon128x128(128.f, 128.f);
|
||||
const FVector2D Icon200x70(200.f, 70.f);
|
||||
|
||||
StyleSet = MakeShareable(new FSlateStyleSet(GetAppStyleSetName()));
|
||||
StyleSet->SetContentRoot(IPluginManager::Get().FindPlugin("ComboInput")->GetBaseDir() / TEXT("Resources"));
|
||||
StyleSet->SetCoreContentRoot(IPluginManager::Get().FindPlugin("ComboInput")->GetBaseDir() / TEXT("Content"));
|
||||
|
||||
StyleSet->Set("MDSStyleSet.AutoArrange.small", new IMAGE_BRUSH(TEXT("AutoArrangeIcon"), Icon16x16));
|
||||
StyleSet->Set("MDSStyleSet.AutoArrange", new IMAGE_BRUSH(TEXT("AutoArrangeIcon"), Icon40x40));
|
||||
StyleSet->Set("MDSStyleSet.AutoArrange.large", new IMAGE_BRUSH(TEXT("AutoArrangeIcon"), Icon64x64));
|
||||
|
||||
StyleSet->Set("MDSStyleSet.GraphSettings.small", new IMAGE_BRUSH(TEXT("GraphSettings"), Icon16x16));
|
||||
StyleSet->Set("MDSStyleSet.GraphSettings", new IMAGE_BRUSH(TEXT("GraphSettings"), Icon40x40));
|
||||
StyleSet->Set("MDSStyleSet.GraphSettings.large", new IMAGE_BRUSH(TEXT("GraphSettings"), Icon64x64));
|
||||
|
||||
StyleSet->Set("MDSStyleSet.ValidateGraph.small", new IMAGE_BRUSH(TEXT("ValidateGraph"), Icon16x16));
|
||||
StyleSet->Set("MDSStyleSet.ValidateGraph", new IMAGE_BRUSH(TEXT("ValidateGraph"), Icon40x40));
|
||||
StyleSet->Set("MDSStyleSet.ValidateGraph.large", new IMAGE_BRUSH(TEXT("ValidateGraph"), Icon64x64));
|
||||
|
||||
StyleSet->Set("MDSStyleSet.Graph.NodeOverlay", new BOX_BRUSH( TEXT("NodeOverlay"), FMargin(8.0f/64.0f, 3.0f/32.0f, 0, 0) ));
|
||||
StyleSet->Set("MDSStyleSet.Graph.PinDocksOverlay", new BOX_BRUSH( TEXT("PinDocksOverlay"), FMargin(8.0f/64.0f, 3.0f/32.0f, 0, 0) ));
|
||||
|
||||
StyleSet->Set("MDSStyleSet.Graph.SimpleArrow", new IMAGE_BRUSH(TEXT("SimpleArrow"), Icon16x16));
|
||||
StyleSet->Set("MDSStyleSet.Graph.HollowArrow", new IMAGE_BRUSH(TEXT("HollowArrow"), Icon16x16));
|
||||
StyleSet->Set("MDSStyleSet.Graph.FancyArrow", new IMAGE_BRUSH(TEXT("FancyArrow"), Icon16x16));
|
||||
StyleSet->Set("MDSStyleSet.Graph.Bubble", new IMAGE_BRUSH(TEXT("Bubble"), Icon16x16));
|
||||
|
||||
StyleSet->Set("MDSStyleSet.Node.SoftEdges", new BOX_BRUSH( TEXT("NodeSoftCorners") , FMargin(16.f/64.f, 25.f/64.f, 16.f/64.f, 16.f/64.f) ));
|
||||
StyleSet->Set("MDSStyleSet.Node.HardEdges", new BOX_BRUSH( TEXT("NodeHardCorners") , FMargin(16.f/64.f, 25.f/64.f, 16.f/64.f, 16.f/64.f) ));
|
||||
|
||||
StyleSet->Set("MDSStyleSet.Node.TextSoftEdges", new BOX_BRUSH( TEXT("TextSoftCorners") , FMargin(16.f/64.f, 25.f/64.f, 16.f/64.f, 16.f/64.f) ));
|
||||
StyleSet->Set("MDSStyleSet.Node.TextHardEdges", new BOX_BRUSH( TEXT("TextHardCorners") , FMargin(16.f/64.f, 25.f/64.f, 16.f/64.f, 16.f/64.f) ));
|
||||
|
||||
StyleSet->Set("MDSStyleSet.Node.IndexCircle", new IMAGE_BRUSH(TEXT("IndexIcon"), Icon16x16));
|
||||
|
||||
StyleSet->Set("MDSStyleSet.Icon.OK", new IMAGE_BRUSH(TEXT("OKIcon"), Icon16x16));
|
||||
StyleSet->Set("MDSStyleSet.Icon.Error", new IMAGE_BRUSH(TEXT("ErroIcon"), Icon16x16));
|
||||
StyleSet->Set("MDSStyleSet.Icon.BulletPoint", new IMAGE_BRUSH(TEXT("CircleBox"), Icon16x16));
|
||||
|
||||
StyleSet->Set("MDSStyleSet.Graph.CornerImage", new IMAGE_BRUSH(TEXT("Icon128"), Icon128x128));
|
||||
|
||||
StyleSet->Set("MDSStyleSet.Icon.Browse", new IMAGE_BRUSH(TEXT("BrowseIcon"), Icon12x12));
|
||||
StyleSet->Set("MDSStyleSet.Icon.Edit", new IMAGE_BRUSH(TEXT("EditIcon"), Icon12x12));
|
||||
|
||||
StyleSet->Set("MDSStyleSet.Buttons.Documentation", new IMAGE_BRUSH(TEXT("Documentation"), Icon200x70));
|
||||
StyleSet->Set("MDSStyleSet.Buttons.Documentation.small", new IMAGE_BRUSH(TEXT("DocumentationIcon"), Icon12x12));
|
||||
|
||||
StyleSet->Set("MDSStyleSet.Node.Icon.large", new IMAGE_BRUSH(TEXT("DialogueNodeIcon"), Icon64x64));
|
||||
StyleSet->Set("MDSStyleSet.Node.Icon", new IMAGE_BRUSH(TEXT("DialogueNodeIcon"), Icon16x16));
|
||||
StyleSet->Set("MDSStyleSet.Node.Icon.small", new IMAGE_BRUSH(TEXT("DialogueNodeIcon"), Icon12x12));
|
||||
|
||||
StyleSet->Set("MDSStyleSet.Icon.Close", new IMAGE_BRUSH(TEXT("CloseIcon"), Icon12x12));
|
||||
StyleSet->Set("MDSStyleSet.Icon.SupportDiscord", new IMAGE_BRUSH(TEXT("DiscordIcon"), Icon12x12));
|
||||
StyleSet->Set("MDSStyleSet.Icon.HeartIcon", new IMAGE_BRUSH(TEXT("HeartIcon"), Icon12x12));
|
||||
StyleSet->Set("MDSStyleSet.Icon.UBIcon", new IMAGE_BRUSH(TEXT("UnrealBucketIcon"), Icon12x12));
|
||||
StyleSet->Set("MDSStyleSet.Icon.MoneyIcon", new IMAGE_BRUSH(TEXT("MoneyIcon"), Icon12x12));
|
||||
|
||||
const FButtonStyle MounteaButtonStyle = FButtonStyle()
|
||||
.SetNormal(BOX_BRUSH("RoundedSelection_16x", 4.0f / 16.0f, FLinearColor(1, 1, 1, 0.1f)))
|
||||
.SetHovered(BOX_BRUSH("RoundedSelection_16x", 4.0f / 16.0f, FLinearColor(1, .55f, 0, 0.2f)))
|
||||
.SetPressed(BOX_BRUSH("RoundedSelection_16x", 4.0f / 16.0f, FLinearColor(1, .55f, 0, 0.4f)));
|
||||
|
||||
StyleSet->Set("MDSStyleSet.Buttons.Style", MounteaButtonStyle);
|
||||
|
||||
{
|
||||
const FScrollBarStyle ScrollBar = GetWidgetStyle<FScrollBarStyle>( "ScrollBar" );
|
||||
|
||||
FTextBlockStyle NormalText = FTextBlockStyle()
|
||||
.SetFont(DEFAULT_FONT("Regular", FCoreStyle::RegularTextSize))
|
||||
.SetColorAndOpacity(FSlateColor::UseForeground())
|
||||
.SetShadowOffset(FVector2D::ZeroVector)
|
||||
.SetShadowColorAndOpacity(FLinearColor::Black)
|
||||
.SetHighlightColor( FLinearColor( 0.02f, 0.3f, 0.0f ) )
|
||||
.SetHighlightShape( BOX_BRUSH( "TextBlockHighlightShape", FMargin(3.f/8.f) ) );
|
||||
|
||||
FTextBlockStyle NodeTitle = FTextBlockStyle(NormalText)
|
||||
.SetFont( DEFAULT_FONT( "Bold", 14 ) )
|
||||
.SetColorAndOpacity( FLinearColor(230.0f/255.0f,230.0f/255.0f,230.0f/255.0f) )
|
||||
.SetShadowOffset( FVector2D( 2,2 ) )
|
||||
.SetShadowColorAndOpacity( FLinearColor(0.f,0.f,0.f, 0.7f) );
|
||||
StyleSet->Set( "MDSStyleSet.NodeTitle", NodeTitle );
|
||||
|
||||
FEditableTextBoxStyle NodeTitleEditableText = FEditableTextBoxStyle()
|
||||
.SetFont(NormalText.Font)
|
||||
.SetBackgroundImageNormal( BOX_BRUSH( "TextBox", FMargin(4.0f/16.0f) ) )
|
||||
.SetBackgroundImageHovered( BOX_BRUSH( "TextBox_Hovered", FMargin(4.0f/16.0f) ) )
|
||||
.SetBackgroundImageFocused( BOX_BRUSH( "TextBox_Hovered", FMargin(4.0f/16.0f) ) )
|
||||
.SetBackgroundImageReadOnly( BOX_BRUSH( "TextBox_ReadOnly", FMargin(4.0f/16.0f) ) )
|
||||
.SetScrollBarStyle( ScrollBar );
|
||||
StyleSet->Set( "MDSStyleSet.NodeTitleEditableText", NodeTitleEditableText );
|
||||
|
||||
StyleSet->Set( "MDSStyleSet.NodeTitleInlineEditableText", FInlineEditableTextBlockStyle()
|
||||
.SetTextStyle(NodeTitle)
|
||||
.SetEditableTextBoxStyle(NodeTitleEditableText)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#undef DEFAULT_FONT
|
||||
#undef BOX_BRUSH
|
||||
#undef IMAGE_BRUSH
|
||||
@@ -0,0 +1,40 @@
|
||||
// Copyright Dominik Pavlicek 2023. All Rights Reserved.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "CoreMinimal.h"
|
||||
#include "Styling/SlateStyle.h"
|
||||
|
||||
|
||||
class FComboActionGraphEditorStyle
|
||||
{
|
||||
public:
|
||||
|
||||
static void Create();
|
||||
static void Initialize();
|
||||
static void Shutdown();
|
||||
static ISlateStyle &Get()
|
||||
{
|
||||
return *(StyleSet.Get());
|
||||
}
|
||||
|
||||
static const FSlateBrush *GetBrush(FName PropertyName, const ANSICHAR *Specifier = NULL)
|
||||
{
|
||||
return StyleSet->GetBrush(PropertyName, Specifier);
|
||||
};
|
||||
|
||||
static const FName &GetAppStyleSetName()
|
||||
{
|
||||
static FName StyleSetName(TEXT("ComboActionGraphEditorStyle"));
|
||||
return StyleSetName;
|
||||
};
|
||||
|
||||
template< class T >
|
||||
static const T &GetWidgetStyle( FName PropertyName, const ANSICHAR *Specifier = NULL )
|
||||
{
|
||||
return StyleSet->GetWidgetStyle< T >( PropertyName, Specifier );
|
||||
}
|
||||
|
||||
private:
|
||||
static TSharedPtr<FSlateStyleSet> StyleSet;
|
||||
};
|
||||
Reference in New Issue
Block a user