FReply SGraphPin::OnDrop( const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent ) { TSharedPtr<SGraphNode> NodeWidget = OwnerNodePtr.Pin(); bool bReadOnly = NodeWidget.IsValid() ? !NodeWidget->IsNodeEditable() : false; TSharedPtr<FDragDropOperation> Operation = DragDropEvent.GetOperation(); if (!Operation.IsValid() || bReadOnly) { return FReply::Unhandled(); } // Is someone dropping a connection onto this pin? if (Operation->IsOfType<FGraphEditorDragDropAction>()) { TSharedPtr<FGraphEditorDragDropAction> DragConnectionOp = StaticCastSharedPtr<FGraphEditorDragDropAction>(Operation); FVector2D NodeAddPosition = FVector2D::ZeroVector; TSharedPtr<SGraphNode> OwnerNode = OwnerNodePtr.Pin(); if (OwnerNode.IsValid()) { NodeAddPosition = OwnerNode->GetPosition() + MyGeometry.Position; //Don't have access to bounding information for node, using fixed offet that should work for most cases. const float FixedOffset = 200.0f; //Line it up vertically with pin NodeAddPosition.Y += MyGeometry.Size.Y; if(GetDirection() == EEdGraphPinDirection::EGPD_Input) { //left side just offset by fixed amount //@TODO: knowing the width of the node we are about to create would allow us to line this up more precisely, // but this information is not available currently NodeAddPosition.X -= FixedOffset; } else { //right side we need the width of the pin + fixed amount because our reference position is the upper left corner of pin(which is variable length) NodeAddPosition.X += MyGeometry.Size.X + FixedOffset; } } return DragConnectionOp->DroppedOnPin(DragDropEvent.GetScreenSpacePosition(), NodeAddPosition); } // handle dropping an asset on the pin else if (Operation->IsOfType<FAssetDragDropOp>() && NodeWidget.IsValid()) { UEdGraphNode* Node = NodeWidget->GetNodeObj(); if(Node != NULL && Node->GetSchema() != NULL) { TSharedPtr<FAssetDragDropOp> AssetOp = StaticCastSharedPtr<FAssetDragDropOp>(Operation); Node->GetSchema()->DroppedAssetsOnPin(AssetOp->AssetData, DragDropEvent.GetScreenSpacePosition(), GraphPinObj); } return FReply::Handled(); } return FReply::Unhandled(); }
void SGraphPin::OnDragEnter( const FGeometry& MyGeometry, const FDragDropEvent& DragDropEvent ) { TSharedPtr<FDragDropOperation> Operation = DragDropEvent.GetOperation(); if (!Operation.IsValid()) { return; } // Is someone dragging a connection? if (Operation->IsOfType<FGraphEditorDragDropAction>()) { // Ensure that the pin is valid before using it if(GraphPinObj != NULL && GraphPinObj->GetOuter() != NULL && GraphPinObj->GetOuter()->IsA(UEdGraphNode::StaticClass())) { // Inform the Drag and Drop operation that we are hovering over this pin. TSharedPtr<FGraphEditorDragDropAction> DragConnectionOp = StaticCastSharedPtr<FGraphEditorDragDropAction>(Operation); DragConnectionOp->SetHoveredPin(GraphPinObj); } // Pins treat being dragged over the same as being hovered outside of drag and drop if they know how to respond to the drag action. SBorder::OnMouseEnter( MyGeometry, DragDropEvent ); } else if (Operation->IsOfType<FAssetDragDropOp>()) { TSharedPtr<SGraphNode> NodeWidget = OwnerNodePtr.Pin(); if (NodeWidget.IsValid()) { UEdGraphNode* Node = NodeWidget->GetNodeObj(); if(Node != NULL && Node->GetSchema() != NULL) { TSharedPtr<FAssetDragDropOp> AssetOp = StaticCastSharedPtr<FAssetDragDropOp>(Operation); bool bOkIcon = false; FString TooltipText; Node->GetSchema()->GetAssetsPinHoverMessage(AssetOp->AssetData, GraphPinObj, TooltipText, bOkIcon); const FSlateBrush* TooltipIcon = bOkIcon ? FEditorStyle::GetBrush(TEXT("Graph.ConnectorFeedback.OK")) : FEditorStyle::GetBrush(TEXT("Graph.ConnectorFeedback.Error"));; AssetOp->SetToolTip(FText::FromString(TooltipText), TooltipIcon); } } } }
FReply FDragConnection::DroppedOnNode(FVector2D ScreenPosition, FVector2D GraphPosition) { bool bHandledPinDropOnNode = false; UEdGraphNode* HoveredNode = GetHoveredNode(); if (HoveredNode) { // Gather any source drag pins TArray<UEdGraphPin*> ValidSourcePins; ValidateGraphPinList(/*out*/ ValidSourcePins); if (ValidSourcePins.Num()) { for (UEdGraphPin* SourcePin : ValidSourcePins) { // Check for pin drop support FText ResponseText; if (SourcePin->GetOwningNode() != HoveredNode && SourcePin->GetSchema()->SupportsDropPinOnNode(HoveredNode, SourcePin->PinType, SourcePin->Direction, ResponseText)) { bHandledPinDropOnNode = true; // Find which pin name to use and drop the pin on the node FString PinName = SourcePin->PinFriendlyName.IsEmpty()? SourcePin->PinName : SourcePin->PinFriendlyName.ToString(); const FScopedTransaction Transaction( NSLOCTEXT("UnrealEd", "AddInParam", "Add In Parameter" ) ); UEdGraphPin* EdGraphPin = HoveredNode->GetSchema()->DropPinOnNode(GetHoveredNode(), PinName, SourcePin->PinType, SourcePin->Direction); if(EdGraphPin) { SourcePin->Modify(); EdGraphPin->Modify(); SourcePin->GetSchema()->TryCreateConnection(SourcePin, EdGraphPin); } } // If we have not handled the pin drop on node and there is an error message, do not let other actions occur. if(!bHandledPinDropOnNode && !ResponseText.IsEmpty()) { bHandledPinDropOnNode = true; } } } } return bHandledPinDropOnNode? FReply::Handled() : FReply::Unhandled(); }