#include "SEdComboActionGraphEdge.h" #include "ConnectionDrawingPolicy.h" #include "SGraphPanel.h" #include "Ed/EdComboActionGraphEdge.h" #include "Ed/EdComboActionGraphNode.h" #include "Widgets/Images/SImage.h" #define LOCTEXT_NAMESPACE "SEdComboActionGraphEdge" void SEdComboActionGraphEdge::Construct(const FArguments &InArgs, UEdComboActionGraphEdge *InNode) { this->GraphNode = InNode; this->UpdateGraphNode(); } bool SEdComboActionGraphEdge::RequiresSecondPassLayout() const { return true; } void SEdComboActionGraphEdge::PerformSecondPassLayout(const TMap>& NodeToWidgetLookup) const { UEdComboActionGraphEdge *EdgeNode = CastChecked(GraphNode); FGeometry StartGeom; FGeometry EndGeom; UEdComboActionGraphNode *Start = EdgeNode->GetStartNode(); UEdComboActionGraphNode *End = EdgeNode->GetEndNode(); if (Start != nullptr && End != nullptr) { const TSharedRef *pFromWidget = NodeToWidgetLookup.Find(Start); const TSharedRef *pToWidget = NodeToWidgetLookup.Find(End); if (pFromWidget != nullptr && pToWidget != nullptr) { const TSharedRef& FromWidget = *pFromWidget; const TSharedRef& ToWidget = *pToWidget; StartGeom = FGeometry(FVector2D(Start->NodePosX, Start->NodePosY), FVector2D::ZeroVector, FromWidget->GetDesiredSize(), 1.0f); EndGeom = FGeometry(FVector2D(End->NodePosX, End->NodePosY), FVector2D::ZeroVector, ToWidget->GetDesiredSize(), 1.0f); } } PositionBetweenTwoNodesWithOffset(StartGeom, EndGeom, 0, 1); } void SEdComboActionGraphEdge::UpdateGraphNode() { InputPins.Empty(); OutputPins.Empty(); RightNodeBox.Reset(); LeftNodeBox.Reset(); this->ContentScale.Bind( this, &SGraphNode::GetContentScale ); this->GetOrAddSlot( ENodeZone::Center ) .HAlign(HAlign_Center) .VAlign(VAlign_Center) [ SNew(SOverlay) /*+ SOverlay::Slot() [ SNew(SImage) .Image(FAppStyle::GetBrush("Graph.TransitionNode.ColorSpill")) .ColorAndOpacity(this, &SEdComboActionGraphEdge::GetEdgeColor) ]*/ + SOverlay::Slot() [ SNew(SImage) .Image(FAppStyle::GetBrush("GraphEditor.RefPinIcon")) .ColorAndOpacity(this, &SEdComboActionGraphEdge::GetEdgeColor) ] ]; } void SEdComboActionGraphEdge::PositionBetweenTwoNodesWithOffset(const FGeometry& StartGeom, const FGeometry& EndGeom, int32 NodeIndex, int32 MaxNodes) const { // 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); // Position ourselves halfway along the connecting line between the nodes, elevated away perpendicular to the direction of the line const float Height = 30.0f; const FVector2D DesiredNodeSize = GetDesiredSize(); FVector2D DeltaPos(EndAnchorPoint - StartAnchorPoint); if (DeltaPos.IsNearlyZero()) { DeltaPos = FVector2D(10.0f, 0.0f); } const FVector2D Normal = FVector2D(DeltaPos.Y, -DeltaPos.X).GetSafeNormal(); const FVector2D NewCenter = StartAnchorPoint + (0.5f * DeltaPos) + (Height * Normal); FVector2D DeltaNormal = DeltaPos.GetSafeNormal(); // Calculate node offset in the case of multiple transitions between the same two nodes // MultiNodeOffset: the offset where 0 is the centre of the transition, -1 is 1 // towards the PrevStateNode and +1 is 1 towards the NextStateNode. const float MutliNodeSpace = 0.2f; // Space between multiple transition nodes (in units of ) const float MultiNodeStep = (1.f + MutliNodeSpace); //Step between node centres (Size of node + size of node spacer) const float MultiNodeStart = -((MaxNodes - 1) * MultiNodeStep) / 2.f; const float MultiNodeOffset = MultiNodeStart + (NodeIndex * MultiNodeStep); // Now we need to adjust the new center by the node size, zoom factor and multi node offset const FVector2D NewCorner = NewCenter - (0.5f * DesiredNodeSize) + (DeltaNormal * MultiNodeOffset * DesiredNodeSize.Size()); GraphNode->NodePosX = NewCorner.X; GraphNode->NodePosY = NewCorner.Y; } FSlateColor SEdComboActionGraphEdge::GetEdgeColor() const { return FLinearColor(0.9f, 0.9f, 0.9f, 1.0f); } #undef LOCTEXT_NAMESPACE