ComboInput/Source/ComboInputEditor/Private/Ed/SEdComboActionGraphEdge.cpp

132 lines
4.5 KiB
C++

#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<UObject*, TSharedRef<SNode>>& NodeToWidgetLookup) const
{
UEdComboActionGraphEdge *EdgeNode = CastChecked<UEdComboActionGraphEdge>(GraphNode);
FGeometry StartGeom;
FGeometry EndGeom;
UEdComboActionGraphNode *Start = EdgeNode->GetStartNode();
UEdComboActionGraphNode *End = EdgeNode->GetEndNode();
if (Start != nullptr && End != nullptr)
{
const TSharedRef<SNode> *pFromWidget = NodeToWidgetLookup.Find(Start);
const TSharedRef<SNode> *pToWidget = NodeToWidgetLookup.Find(End);
if (pFromWidget != nullptr && pToWidget != nullptr)
{
const TSharedRef<SNode>& FromWidget = *pFromWidget;
const TSharedRef<SNode>& 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 <size of node>
// towards the PrevStateNode and +1 is 1 <size of node> towards the NextStateNode.
const float MutliNodeSpace = 0.2f; // Space between multiple transition nodes (in units of <size of node> )
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