// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "Containers/Array.h" #include "Containers/Map.h" #include "Containers/Set.h" #include "CoreMinimal.h" #include "EdGraph/EdGraphNode.h" #include "EdGraph/EdGraphPin.h" #include "GraphEditorSettings.h" #include "GraphSplineOverlapResult.h" #include "HAL/Platform.h" #include "Layout/ArrangedWidget.h" #include "Logging/LogMacros.h" #include "Math/Color.h" #include "Math/Vector2D.h" #include "SGraphPin.h" #include "Templates/SharedPointer.h" #include "Widgets/SWidget.h" class FArrangedChildren; class FArrangedWidget; class FSlateRect; class FSlateWindowElementList; class SGraphPin; class SWidget; class UGraphEditorSettings; struct FGeometry; struct FSlateBrush; template class FInterpCurve; ///////////////////////////////////////////////////// GRAPHEDITOR_API DECLARE_LOG_CATEGORY_EXTERN(LogConnectionDrawingPolicy, Log, All); ///////////////////////////////////////////////////// // FGeometryHelper class GRAPHEDITOR_API FGeometryHelper { public: static UE::Slate::FDeprecateVector2DResult VerticalMiddleLeftOf(const FGeometry& SomeGeometry); static UE::Slate::FDeprecateVector2DResult VerticalMiddleRightOf(const FGeometry& SomeGeometry); static UE::Slate::FDeprecateVector2DResult CenterOf(const FGeometry& SomeGeometry); UE_DEPRECATED(5.6, "Use Array of FVector2f instead of FVector2D for slate positions") static void ConvertToPoints(const FGeometry& Geom, TArray& Points); static void ConvertToPoints(const FGeometry& Geom, TArray& Points); /** Find the point on line segment from LineStart to LineEnd which is closest to Point */ static UE::Slate::FDeprecateVector2DResult FindClosestPointOnLine(const UE::Slate::FDeprecateVector2DParameter& LineStart, const UE::Slate::FDeprecateVector2DParameter& LineEnd, const UE::Slate::FDeprecateVector2DParameter& TestPoint); static UE::Slate::FDeprecateVector2DResult FindClosestPointOnGeom(const FGeometry& Geom, const UE::Slate::FDeprecateVector2DParameter& TestPoint); }; ///////////////////////////////////////////////////// // FConnectionParameters struct GRAPHEDITOR_API FConnectionParams { FLinearColor WireColor; UEdGraphPin* AssociatedPin1; UEdGraphPin* AssociatedPin2; float WireThickness; bool bDrawBubbles; bool bUserFlag1; bool bUserFlag2; EEdGraphPinDirection StartDirection; EEdGraphPinDirection EndDirection; FDeprecateSlateVector2D StartTangent; FDeprecateSlateVector2D EndTangent; FConnectionParams() : WireColor(FLinearColor::White) , AssociatedPin1(nullptr) , AssociatedPin2(nullptr) , WireThickness(1.5f) , bDrawBubbles(false) , bUserFlag1(false) , bUserFlag2(false) , StartDirection(EGPD_Output) , EndDirection(EGPD_Input) , StartTangent(FVector2f::ZeroVector) , EndTangent(FVector2f::ZeroVector) { } }; #define END_DEPRECATED_VIRTUAL_FN ///////////////////////////////////////////////////// // FConnectionDrawingPolicy // This class draws the connections for an UEdGraph composed of pins and nodes class GRAPHEDITOR_API FConnectionDrawingPolicy { protected: int32 WireLayerID; int32 ArrowLayerID; const FSlateBrush* ArrowImage; const FSlateBrush* MidpointImage; const FSlateBrush* BubbleImage; const UGraphEditorSettings* Settings; public: FDeprecateSlateVector2D ArrowRadius; FDeprecateSlateVector2D MidpointRadius; FGraphSplineOverlapResult SplineOverlapResult; /** Handle for a currently relinked connection. */ struct FRelinkConnection { UEdGraphPin* SourcePin; UEdGraphPin* TargetPin; }; protected: float ZoomFactor; float HoverDeemphasisDarkFraction; const FSlateRect& ClippingRect; FSlateWindowElementList& DrawElementsList; TMap< UEdGraphPin*, TSharedPtr > PinToPinWidgetMap; TSet< FEdGraphPinReference > HoveredPins; TMap, FArrangedWidget>* PinGeometries; double LastHoverTimeEvent; FDeprecateSlateVector2D LocalMousePosition; /** List of currently relinked connections. */ TArray RelinkConnections; /** Selected nodes in the graph panel. */ TArray SelectedGraphNodes; public: virtual ~FConnectionDrawingPolicy() {} FConnectionDrawingPolicy(int32 InBackLayerID, int32 InFrontLayerID, float InZoomFactor, const FSlateRect& InClippingRect, FSlateWindowElementList& InDrawElements); // Update the drawing policy with the set of hovered pins (which can be empty) void SetHoveredPins(const TSet< FEdGraphPinReference >& InHoveredPins, const TArray< TSharedPtr >& OverridePins, double HoverTime); void SetMousePosition(const UE::Slate::FDeprecateVector2DParameter& InMousePos); // Update the drawing policy with the marked pin (which may not be valid) void SetMarkedPin(TWeakPtr InMarkedPin); // Set the selected nodes from the graph panel. void SetSelectedNodes(const TArray& InSelectedNodes) { SelectedGraphNodes = InSelectedNodes; } // Set the list of currently relinked connections. void SetRelinkConnections(const TArray& Connections) { RelinkConnections = Connections; } static float MakeSplineReparamTable(const UE::Slate::FDeprecateVector2DParameter& P0, const UE::Slate::FDeprecateVector2DParameter& P0Tangent, const UE::Slate::FDeprecateVector2DParameter& P1, const UE::Slate::FDeprecateVector2DParameter& P1Tangent, FInterpCurve& OutReparamTable); UE_DEPRECATED(5.6, "Use the version of the function accepting FVector2f; this Slate API no longer interfaces directly with double-precision scalars and vectors.") virtual void DrawSplineWithArrow(const FVector2D& StartPoint, const FVector2D& EndPoint, const FConnectionParams& Params) UE_SLATE_DEPRECATED_VECTOR_VIRTUAL_FUNCTION; virtual void DrawSplineWithArrow(const FVector2f& StartPoint, const FVector2f& EndPoint, const FConnectionParams& Params); virtual void DrawSplineWithArrow(const FGeometry& StartGeom, const FGeometry& EndGeom, const FConnectionParams& Params); UE_DEPRECATED(5.6, "Use the version of the function accepting FVector2f; this Slate API no longer interfaces directly with double-precision scalars and vectors.") virtual FVector2D ComputeSplineTangent(const FVector2D& Start, const FVector2D& End) const UE_SLATE_DEPRECATED_VECTOR_VIRTUAL_FUNCTION; virtual FVector2f ComputeSplineTangent(const FVector2f& Start, const FVector2f& End) const; UE_DEPRECATED(5.6, "Use the version of the function accepting FVector2f; this Slate API no longer interfaces directly with double-precision scalars and vectors.") virtual void DrawConnection(int32 LayerId, const FVector2D& Start, const FVector2D& End, const FConnectionParams& Params) UE_SLATE_DEPRECATED_VECTOR_VIRTUAL_FUNCTION; virtual void DrawConnection(int32 LayerId, const FVector2f& Start, const FVector2f& End, const FConnectionParams& Params); UE_DEPRECATED(5.6, "Use the version of the function accepting FVector2f; this Slate API no longer interfaces directly with double-precision scalars and vectors.") virtual void DrawPreviewConnector(const FGeometry& PinGeometry, const FVector2D& StartPoint, const FVector2D& EndPoint, UEdGraphPin* Pin) UE_SLATE_DEPRECATED_VECTOR_VIRTUAL_FUNCTION; virtual void DrawPreviewConnector(const FGeometry& PinGeometry, const FVector2f& StartPoint, const FVector2f& EndPoint, UEdGraphPin* Pin); // Give specific editor modes a chance to highlight this connection or darken non-interesting connections virtual void DetermineWiringStyle(UEdGraphPin* OutputPin, UEdGraphPin* InputPin, /*inout*/ FConnectionParams& Params); virtual void Draw(TMap, FArrangedWidget>& InPinGeometries, FArrangedChildren& ArrangedNodes); virtual void DetermineLinkGeometry( FArrangedChildren& ArrangedNodes, TSharedRef& OutputPinWidget, UEdGraphPin* OutputPin, UEdGraphPin* InputPin, /*out*/ FArrangedWidget*& StartWidgetGeometry, /*out*/ FArrangedWidget*& EndWidgetGeometry ); // Choose whether we want to cache the pins draw state to avoid resetting it for every tick virtual bool UseDrawStateCaching() const { return false; } virtual void SetIncompatiblePinDrawState(const TSharedPtr& StartPin, const TSet< TSharedRef >& VisiblePins); virtual void ResetIncompatiblePinDrawState(const TSet< TSharedRef >& VisiblePins); virtual void ApplyHoverDeemphasis(UEdGraphPin* OutputPin, UEdGraphPin* InputPin, /*inout*/ float& Thickness, /*inout*/ FLinearColor& WireColor); virtual bool IsConnectionCulled( const FArrangedWidget& StartLink, const FArrangedWidget& EndLink ) const; virtual TSharedPtr GetConnectionToolTip(const SGraphPanel& GraphPanel, const FGraphSplineOverlapResult& OverlapData) const; protected: // Helper function used by Draw(). Called before DrawPinGeometries to populate PinToPinWidgetMap virtual void BuildPinToPinWidgetMap(TMap, FArrangedWidget>& InPinGeometries); // Helper function used by Draw(). Iterates over the pin geometries, drawing connections between them virtual void DrawPinGeometries(TMap, FArrangedWidget>& InPinGeometries, FArrangedChildren& ArrangedNodes); private: // Note - these helpers are temporary, to be replaced entirely by the public API's 2f/float functions once the 2D/double deprecated functions can be removed void DrawSplineWithArrow_DeprecationHelper(const UE::Slate::FDeprecateVector2DParameter& StartPoint, const UE::Slate::FDeprecateVector2DParameter& EndPoint, const FConnectionParams& Params); UE::Slate::FDeprecateVector2DResult ComputeSplineTangent_DeprecationHelper(const UE::Slate::FDeprecateVector2DParameter& Start, const UE::Slate::FDeprecateVector2DParameter& End) const; void DrawConnection_DeprecationHelper(int32 LayerId, const UE::Slate::FDeprecateVector2DParameter& Start, const UE::Slate::FDeprecateVector2DParameter& End, const FConnectionParams& Params); void DrawPreviewConnector_DeprecationHelper(const FGeometry& PinGeometry, const UE::Slate::FDeprecateVector2DParameter& StartPoint, const UE::Slate::FDeprecateVector2DParameter& EndPoint, UEdGraphPin* Pin); };