4#include "Framework/MultiBox/MultiBoxBuilder.h"
5#include "UObject/UObjectIterator.h"
6#include "ScopedTransaction.h"
8#include "GraphEditorActions.h"
10#if ENGINE_MINOR_VERSION >= 24
21#define LOCTEXT_NAMESPACE "DlgDialogueGraphSchema"
48 if (InputNode == OutputNode)
65 if (!ContextMenuBuilder.FromPin)
71#if ENGINE_MINOR_VERSION >= 24
74 if (Context->Node && !Context->bIsDebugging)
77 FToolMenuSection& Section = Menu->AddSection(
"DialogueGraphSchemaNodeActions", LOCTEXT(
"NodeActionsMenuHeader",
"Node Actions"));
84 Super::GetContextMenuActions(Menu, Context);
92 const UEdGraphPin* InGraphPin,
93 FMenuBuilder* MenuBuilder,
97 if (InGraphNode && !bIsDebugging)
100 MenuBuilder->BeginSection(
"DialogueGraphSchemaNodeActions", LOCTEXT(
"NodeActionsMenuHeader",
"Node Actions"));
103 MenuBuilder->AddMenuEntry(FGraphEditorCommands::Get().
BreakNodeLinks);
105 MenuBuilder->EndSection();
109 Super::GetContextMenuActions(CurrentGraph, InGraphNode, InGraphPin, MenuBuilder, bIsDebugging);
116 check(Graph.Nodes.Num() == 0);
117 UDialogueGraph* DialogueGraph = CastChecked<UDialogueGraph>(&Graph);
130 return FPinConnectionResponse(CONNECT_RESPONSE_DISALLOW, LOCTEXT(
"ConnectionMovePinLinks",
"Move Pin Links Not implemented"));
135 return FPinConnectionResponse(CONNECT_RESPONSE_DISALLOW, LOCTEXT(
"ConnectionMovePinLinks",
"Copy Pin Links Not implemented"));
141 if (PinA->GetOwningNode() == PinB->GetOwningNode())
143 return FPinConnectionResponse(CONNECT_RESPONSE_DISALLOW, LOCTEXT(
"ConnectionSameNode",
"Both are on the same node"));
149 return FPinConnectionResponse(CONNECT_RESPONSE_DISALLOW, LOCTEXT(
"ConnectionLoop",
"Connection would cause loop"));
159 return FPinConnectionResponse(CONNECT_RESPONSE_DISALLOW, TEXT(
"Cannot wire an edge from this node because it does not accept output connection "));
165 return FPinConnectionResponse(CONNECT_RESPONSE_DISALLOW, TEXT(
"Cannot wire an edge to this node because it does not accept input connection "));
171 return FPinConnectionResponse(CONNECT_RESPONSE_DISALLOW, LOCTEXT(
"ConnectionAlreadyMade",
"Connection between nodes already made"));
174 const bool bPinAIsEdge = SourceNode->IsA(UDialogueGraphNode_Edge::StaticClass());
175 const bool bPinBIsEdge = TargetNode->IsA(UDialogueGraphNode_Edge::StaticClass());
177 if (bPinAIsEdge && bPinBIsEdge)
179 return FPinConnectionResponse(CONNECT_RESPONSE_DISALLOW, TEXT(
"Cannot wire an edge to an edge"));
186 return FPinConnectionResponse(CONNECT_RESPONSE_BREAK_OTHERS_A, TEXT(
"SHOULD NOT BE VISIBLE"));
190 return FPinConnectionResponse(CONNECT_RESPONSE_BREAK_OTHERS_B, TEXT(
"SHOULD NOT BE VISIBLE"));
195 if (!bPinAIsEdge && !bPinBIsEdge)
198 return FPinConnectionResponse(CONNECT_RESPONSE_MAKE_WITH_CONVERSION_NODE, TEXT(
"Create an Edge"));
201 return FPinConnectionResponse(CONNECT_RESPONSE_MAKE, FText::GetEmpty());
207 if (PinA->GetOwningNode() == PinB->GetOwningNode())
214 UEdGraphPin* FormerParentOutputPin =
nullptr;
231 UEdGraph* Graph = PinA->GetOwningNode()->GetGraph();
233 PinA->GetOwningNode()->Modify();
234 PinB->GetOwningNode()->Modify();
239 const bool bModified = Super::TryCreateConnection(PinA, PinB);
243 if (FormerParentOutputPin !=
nullptr)
245 FormerParentOutputPin->GetOwningNode()->PinConnectionListChanged(FormerParentOutputPin);
250 NodeB->
GetDialogue()->CompileDialogueNodesFromGraphNodes();
263 UEdGraph* Graph = NodeA->GetGraph();
267 FDialogueEditorUtilities::SpawnGraphNodeFromTemplate<UDialogueGraphNode_Edge>(
272 if (PinA->Direction == EGPD_Output)
288 NewEdge = GraphNode_Edge_DragDop->GetDialogueEdge();
293 GraphNode_Edge->PostEditChange();
295 Graph->NotifyGraphChanged();
308 UEdGraph* Graph = TargetNode.GetGraph();
312 verify(Graph->Modify());
313 verify(TargetNode.Modify());
316 Super::BreakNodeLinks(TargetNode);
321 GraphNode->CheckAll();
325 Dialogue->CompileDialogueNodesFromGraphNodes();
330 const FScopedTransaction Transaction(LOCTEXT(
"GraphEd_BreakPinLinks",
"Dialogue Editor: Break Pin Links"));
336 verify(Node->Modify());
337 verify(Graph->Modify());
341 Super::BreakPinLinks(TargetPin, bSendsNodeNotifcation);
344 if (
UDialogueGraphNode* GraphNode = Cast<UDialogueGraphNode>(TargetPin.GetOwningNode()))
346 GraphNode->CheckAll();
351 if (bSendsNodeNotifcation)
354 Dialogue->CompileDialogueNodesFromGraphNodes();
360 const FScopedTransaction Transaction(LOCTEXT(
"GraphEd_BreakSinglePinLink",
"Dialogue Editor: Break Pin Link"));
362 Super::BreakSinglePinLink(SourcePin, TargetPin);
381 const FScopedTransaction Transaction(LOCTEXT(
"GraphEd_BreakPinLink",
"Dialogue Editor: Break Pin Link"));
384 UEdGraph* Graph = FromNode->GetGraph();
388 verify(FromNode->Modify());
389 verify(ToNode->Modify());
390 verify(Graph->Modify());
394 FromPin->BreakLinkTo(ToPin);
397 FromNode->PinConnectionListChanged(FromPin);
398 ToNode->PinConnectionListChanged(ToPin);
399 if (bSendsNodeNotifcation)
401 FromNode->NodeConnectionListChanged();
402 ToNode->NodeConnectionListChanged();
408 GraphNode->CheckAll();
412 GraphNode->CheckAll();
417 if (bSendsNodeNotifcation)
419 Dialogue->CompileDialogueNodesFromGraphNodes();
426 if (ActionMenuBuilder.FromPin)
433 const FText MenuDescription = bIsManyNodesSelected ?
434 LOCTEXT(
"CreateCommentAction",
"Create Comment from Selection") : LOCTEXT(
"AddCommentAction",
"Add Comment...");
435 const FText ToolTip = LOCTEXT(
"CreateCommentToolTip",
"Creates a comment.");
436 constexpr int32 Grouping = 1;
440 ActionMenuBuilder.AddAction(NewAction);
445 if (ActionMenuBuilder.FromPin || !IsValid(CurrentGraph))
455 TArray<UDialogueGraphNode*> SelectedGraphNodes;
458 const FText MenuDescription =
459 LOCTEXT(
"ConvertSpeechNodesToSequenceNodeDesc",
"Converts selected Speech node(s) to a Speech Sequence Node");
460 const FText ToolTip =
461 LOCTEXT(
"ConvertSpeechNodesToSequenceNodeToolTip",
"Converts selected (compresses) linear Speech node(s) to a Speech Sequence Node");
463 TSharedPtr<FConvertSpeechNodesToSpeechSequence_DialogueGraphSchemaAction> NewAction(
472 ActionMenuBuilder.AddAction(NewAction);
480 FText ToolTip, MenuDesc;
483 if (ActionMenuBuilder.FromPin ==
nullptr)
486 ToolTip = LOCTEXT(
"NewDialogueNodeTooltip",
"Adds {Name} to the graph");
487 MenuDesc = LOCTEXT(
"NewDialogueNodeMenuDescription",
"{Name}");
489 else if (ActionMenuBuilder.FromPin->Direction == EGPD_Input)
492 ToolTip = LOCTEXT(
"NewDialogueNodeTooltip_FromInputPin",
"Adds {Name} to the graph as a parent to the current node");
493 MenuDesc = LOCTEXT(
"NewDialogueNodeMenuDescription_FromInputPin",
"Add {Name} parent");
498 check(ActionMenuBuilder.FromPin->Direction == EGPD_Output);
499 ToolTip = LOCTEXT(
"NewDialogueNodeTooltip_FromOutputPin",
"Adds {Name} to the graph as a child to the current node");
500 MenuDesc = LOCTEXT(
"NewDialogueNodeMenuDescription_FromOutputPin",
"Add {Name} child");
504 FFormatNamedArguments Arguments;
509 const UDlgNode* DialogueNode = DialogueNodeClass->GetDefaultObject<
UDlgNode>();
510 Arguments.Add(TEXT(
"Name"), FText::FromString(DialogueNode->GetNodeTypeString()));
514 Grouping++, DialogueNodeClass));
515 ActionMenuBuilder.AddAction(Action);
527 for (TObjectIterator<UClass> It; It; ++It)
529 if (It->IsChildOf(UDlgNode::StaticClass()) && !It->HasAnyClassFlags(CLASS_Abstract))
541#undef LOCTEXT_NAMESPACE
static UDialogueGraphNode_Edge * GetLastTargetGraphEdgeBeforeDrag(const UEdGraph *Graph)
static void SetLastTargetGraphEdgeBeforeDrag(const UEdGraph *Graph, UDialogueGraphNode_Edge *InEdge)
static bool CanConvertSpeechNodesToSpeechSequence(const TSet< UObject * > &SelectedNodes, TArray< UDialogueGraphNode * > &OutSelectedGraphNodes)
static const TSet< UObject * > GetSelectedNodes(const UEdGraph *Graph)
static UDlgDialogue * GetDialogueForGraph(const UEdGraph *Graph)
void LinkGraphNodesFromDialogue() const
void AutoPositionGraphNodes() const
void CreateGraphNodesFromDialogue()
virtual bool HasOutputConnectionToNode(const UEdGraphNode *TargetNode) const
virtual bool CanHaveInputConnections() const
UDlgDialogue * GetDialogue() const
virtual bool CanHaveOutputConnections() const
const FDlgEdge & GetDialogueEdge() const
void CreateConnections(UDialogueGraphNode *ParentNode, UDialogueGraphNode *ChildNode)
void SetDialogueEdge(const FDlgEdge &InEdge)
FIntPoint GetDefaultEdgePosition() const
void BreakSinglePinLink(UEdGraphPin *SourcePin, UEdGraphPin *TargetPin) const override
static const FText NODE_CATEGORY_Convert
void GetContextMenuActions(const UEdGraph *CurrentGraph, const UEdGraphNode *InGraphNode, const UEdGraphPin *InGraphPin, FMenuBuilder *MenuBuilder, bool bIsDebugging) const override
void BreakPinLinks(UEdGraphPin &TargetPin, bool bSendsNodeNotifcation) const override
static const FName PIN_CATEGORY_Output
void BreakNodeLinks(UEdGraphNode &TargetNode) const override
void GetCommentAction(FGraphActionMenuBuilder &ActionMenuBuilder, const UEdGraph *CurrentGraph=nullptr) const
const FPinConnectionResponse CanCreateConnection(const UEdGraphPin *PinA, const UEdGraphPin *PinB) const override
bool ShouldHidePinDefaultValue(UEdGraphPin *Pin) const override
void GetAllDialogueNodeActions(FGraphActionMenuBuilder &ActionMenuBuilder) const
static TArray< TSubclassOf< UDlgNode > > DialogueNodeClasses
bool TryCreateConnection(UEdGraphPin *PinA, UEdGraphPin *PinB) const override
static const FText NODE_CATEGORY_Graph
void GetPaletteActions(FGraphActionMenuBuilder &ActionMenuBuilder) const
void BreakLinkTo(UEdGraphPin *TargetPin, UEdGraphPin *ToPin, bool bSendsNodeNotifcation) const
void DroppedAssetsOnGraph(const TArray< FAssetData > &Assets, const FVector2D &GraphPosition, UEdGraph *Graph) const override
static void InitDialogueNodeClasses()
void GetConvertActions(FGraphActionMenuBuilder &ActionMenuBuilder, const UEdGraph *CurrentGraph) const
void GetGraphContextActions(FGraphContextMenuBuilder &ContextMenuBuilder) const override
FPinConnectionResponse CopyPinLinks(UEdGraphPin &CopyFromPin, UEdGraphPin &CopyToPin, bool bIsIntermediateCopy=false) const override
void CreateDefaultNodesForGraph(UEdGraph &Graph) const override
bool CreateAutomaticConversionNodeAndConnections(UEdGraphPin *PinA, UEdGraphPin *PinB) const override
bool ConnectionCausesLoop(const UEdGraphPin *InputPin, const UEdGraphPin *OutputPin) const
FPinConnectionResponse MovePinLinks(UEdGraphPin &MoveFromPin, UEdGraphPin &MoveToPin, bool bIsIntermediateMove=false, bool bNotifyLinkedNodes=false) const override
static bool bDialogueNodeClassesInitialized
void DroppedAssetsOnNode(const TArray< FAssetData > &Assets, const FVector2D &GraphPosition, UEdGraphNode *Node) const override
static const FName PIN_CATEGORY_Input
static const FText NODE_CATEGORY_Dialogue
int32 GetNodeSelectionCount(const UEdGraph *Graph) const override
UCLASS(BlueprintType, Meta = (DisplayThumbnail = "true"))
UCLASS(BlueprintType, Abstract, EditInlineNew, ClassGroup = "Dialogue")
int32 TargetIndex
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Dialogue|Edge", Meta = (ClampMin = -1))