UEdGraphNode* FEdGraphSchemaAction_K2NewNode::CreateNode(class UEdGraph* ParentGraph, UEdGraphPin* FromPin, const FVector2D Location, class UK2Node* NodeTemplate, bool bSelectNewNode/* = true*/) { // Smart pointer that handles fixup after potential node reconstruction FWeakGraphPinPtr FromPinPtr = FromPin; // Duplicate template node to create new node UEdGraphNode* ResultNode = DuplicateObject<UK2Node>(NodeTemplate, ParentGraph); ResultNode->SetFlags(RF_Transactional); ParentGraph->AddNode(ResultNode, true, bSelectNewNode); ResultNode->CreateNewGuid(); ResultNode->PostPlacedNewNode(); ResultNode->AllocateDefaultPins(); // For input pins, new node will generally overlap node being dragged off // Work out if we want to visually push away from connected node int32 XLocation = Location.X; if (FromPinPtr.IsValid() && FromPinPtr->Direction == EGPD_Input) { UEdGraphNode* PinNode = FromPinPtr->GetOwningNode(); const float XDelta = FMath::Abs(PinNode->NodePosX - Location.X); if (XDelta < NodeDistance) { // Set location to edge of current node minus the max move distance // to force node to push off from connect node enough to give selection handle XLocation = PinNode->NodePosX - NodeDistance; } } ResultNode->NodePosX = XLocation; ResultNode->NodePosY = Location.Y; ResultNode->SnapToGrid(SNAP_GRID); // make sure to auto-wire after we position the new node (in case the // auto-wire creates a conversion node to put between them) ResultNode->AutowireNewNode(FromPinPtr); // Update Analytics for the new nodes FBlueprintEditorUtils::AnalyticsTrackNewNode( ResultNode ); // NOTE: At this point the node may have been reconstructed, depending on node type! return ResultNode; }
UEdGraphNode* FEdGraphSchemaAction_NewNode::CreateNode(class UEdGraph* ParentGraph, UEdGraphPin* FromPin, const FVector2D Location, class UEdGraphNode* NodeTemplate) { // Duplicate template node to create new node UEdGraphNode* ResultNode = NULL; #if WITH_EDITOR ResultNode = DuplicateObject<UEdGraphNode>(NodeTemplate, ParentGraph); ResultNode->SetFlags(RF_Transactional); ParentGraph->AddNode(ResultNode, true); ResultNode->CreateNewGuid(); ResultNode->PostPlacedNewNode(); ResultNode->AllocateDefaultPins(); ResultNode->AutowireNewNode(FromPin); // For input pins, new node will generally overlap node being dragged off // Work out if we want to visually push away from connected node int32 XLocation = Location.X; if (FromPin && FromPin->Direction == EGPD_Input) { UEdGraphNode* PinNode = FromPin->GetOwningNode(); const float XDelta = FMath::Abs(PinNode->NodePosX - Location.X); if (XDelta < NodeDistance) { // Set location to edge of current node minus the max move distance // to force node to push off from connect node enough to give selection handle XLocation = PinNode->NodePosX - NodeDistance; } } ResultNode->NodePosX = XLocation; ResultNode->NodePosY = Location.Y; ResultNode->SnapToGrid(SNAP_GRID); #endif // WITH_EDITOR return ResultNode; }
void FSoundCueEditor::PasteNodesHere(const FVector2D& Location) { // Undo/Redo support const FScopedTransaction Transaction( NSLOCTEXT("UnrealEd", "SoundCueEditorPaste", "Paste Sound Cue Node") ); SoundCue->GetGraph()->Modify(); SoundCue->Modify(); // Clear the selection set (newly pasted stuff will be selected) SoundCueGraphEditor->ClearSelectionSet(); // Grab the text to paste from the clipboard. FString TextToImport; FPlatformMisc::ClipboardPaste(TextToImport); // Import the nodes TSet<UEdGraphNode*> PastedNodes; FEdGraphUtilities::ImportNodesFromText(SoundCue->GetGraph(), TextToImport, /*out*/ PastedNodes); //Average position of nodes so we can move them while still maintaining relative distances to each other FVector2D AvgNodePosition(0.0f,0.0f); for (TSet<UEdGraphNode*>::TIterator It(PastedNodes); It; ++It) { UEdGraphNode* Node = *It; AvgNodePosition.X += Node->NodePosX; AvgNodePosition.Y += Node->NodePosY; } if ( PastedNodes.Num() > 0 ) { float InvNumNodes = 1.0f/float(PastedNodes.Num()); AvgNodePosition.X *= InvNumNodes; AvgNodePosition.Y *= InvNumNodes; } for (TSet<UEdGraphNode*>::TIterator It(PastedNodes); It; ++It) { UEdGraphNode* Node = *It; if (USoundCueGraphNode* SoundGraphNode = Cast<USoundCueGraphNode>(Node)) { SoundCue->AllNodes.Add(SoundGraphNode->SoundNode); } // Select the newly pasted stuff SoundCueGraphEditor->SetNodeSelection(Node, true); Node->NodePosX = (Node->NodePosX - AvgNodePosition.X) + Location.X ; Node->NodePosY = (Node->NodePosY - AvgNodePosition.Y) + Location.Y ; Node->SnapToGrid(SNodePanel::GetSnapGridSize()); // Give new node a different Guid from the old one Node->CreateNewGuid(); } // Force new pasted SoundNodes to have same connections as graph nodes SoundCue->CompileSoundNodesFromGraphNodes(); // Update UI SoundCueGraphEditor->NotifyGraphChanged(); SoundCue->PostEditChange(); SoundCue->MarkPackageDirty(); }
void FNiagaraEditor::PasteNodesHere(const FVector2D& Location) { TSharedPtr<SGraphEditor> CurrentGraphEditor = NodeGraphEditorPtr.Pin(); if (!CurrentGraphEditor.IsValid()) { return; } // Undo/Redo support const FScopedTransaction Transaction(FGenericCommands::Get().Paste->GetDescription()); UEdGraph* EdGraph = Cast<UEdGraph>(CurrentGraphEditor->GetCurrentGraph()); EdGraph->Modify(); const FGraphPanelSelectionSet SelectedNodes = CurrentGraphEditor->GetSelectedNodes(); // Clear the selection set (newly pasted stuff will be selected) CurrentGraphEditor->ClearSelectionSet(); // Grab the text to paste from the clipboard. FString TextToImport; FPlatformMisc::ClipboardPaste(TextToImport); // Import the nodes TSet<UEdGraphNode*> PastedNodes; FEdGraphUtilities::ImportNodesFromText(EdGraph, TextToImport, /*out*/ PastedNodes); //Average position of nodes so we can move them while still maintaining relative distances to each other FVector2D AvgNodePosition(0.0f, 0.0f); for (TSet<UEdGraphNode*>::TIterator It(PastedNodes); It; ++It) { UEdGraphNode* Node = (*It); if (Node) { AvgNodePosition.X += Node->NodePosX; AvgNodePosition.Y += Node->NodePosY; } } if (PastedNodes.Num() > 0) { float InvNumNodes = 1.0f / float(PastedNodes.Num()); AvgNodePosition.X *= InvNumNodes; AvgNodePosition.Y *= InvNumNodes; } for (TSet<UEdGraphNode*>::TIterator It(PastedNodes); It; ++It) { UEdGraphNode* PasteNode = (*It); if (PasteNode) { // Select the newly pasted stuff CurrentGraphEditor->SetNodeSelection(PasteNode, true); PasteNode->NodePosX = (PasteNode->NodePosX - AvgNodePosition.X) + Location.X; PasteNode->NodePosY = (PasteNode->NodePosY - AvgNodePosition.Y) + Location.Y; PasteNode->SnapToGrid(16); // Give new node a different Guid from the old one PasteNode->CreateNewGuid(); } } // Update UI CurrentGraphEditor->NotifyGraphChanged(); UObject* GraphOwner = EdGraph->GetOuter(); if (GraphOwner) { GraphOwner->PostEditChange(); GraphOwner->MarkPackageDirty(); } }