// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "Components/PrimitiveComponent.h" #include "Elements/Framework/TypedElementHandle.h" #include "GenericPlatform/ICursor.h" #include "Internationalization/Text.h" #include "Math/Color.h" #include "Misc/Optional.h" class AActor; class FCanvas; class FEditorViewportClient; class FLevelEditorViewportClient; class FUICommandInfo; class HHitProxy; class ITypedElementWorldInterface; class UTypedElementSelectionSet; struct FConvexVolume; struct FTypedElementHandle; struct FViewportClick; DECLARE_DELEGATE_RetVal(UWorld*, FOnGetWorld); DECLARE_DELEGATE_RetVal_OneParam(bool, FOnIsObjectSelectableInViewport, UObject* /*InObject*/); /** * Manages level actor viewport selectability and hovered visual states. * Contains static methods to enable outside modules to implement their own management. */ class UNREALED_API FEditorViewportSelectability { public: /** Default text to display in the viewport when selection is limited as a helpful reminder to the user. */ static const FText DefaultLimitedSelectionText; /** Updates a single primitive component's hovered state and visuals. */ static void UpdatePrimitiveVisuals(const bool bInSelectedLimited, UPrimitiveComponent* const InPrimitive, const TOptional& InColor = TOptional()); /** Updates a list of hovered primitive component's hovered state and visuals */ static bool UpdateHoveredPrimitive(const bool bInSelectedLimited , UPrimitiveComponent* const InPrimitiveComponent , TMap, TOptional>& InOutHoveredPrimitiveComponents , const TFunctionRef& InSelectablePredicate); /** Updates an actors hovered state and visuals. */ static bool UpdateHoveredActorPrimitives(const bool bInSelectedLimited , AActor* const InActor , TMap, TOptional>& InOutHoveredPrimitiveComponents , const TFunctionRef& InSelectablePredicate); static FText GetLimitedSelectionText(const TSharedPtr& InToggleAction, const FText& InDefaultText = DefaultLimitedSelectionText); static void DrawEnabledTextNotice(FCanvas* const InCanvas, const FText& InText); FEditorViewportSelectability() = delete; FEditorViewportSelectability(const FOnGetWorld& InOnGetWorld, const FOnIsObjectSelectableInViewport& InOnIsObjectSelectableInViewport); /** Enables or disables the selectability tool */ void EnableLimitedSelection(const bool bInEnabled); bool IsSelectionLimited() const { return bSelectionLimited; } /** @return True if the specified object is selectable in the viewport and not made unselectable by the Sequencer selection limiting. */ bool IsObjectSelectableInViewport(UObject* const InObject) const; /** Updates hover visual states based on current selection limiting settings */ void UpdateSelectionLimitedVisuals(const bool bInClearHovered); void DeselectNonSelectableActors(); bool GetCursorForHovered(EMouseCursor::Type& OutCursor) const; void UpdateHoverFromHitProxy(HHitProxy* const InHitProxy); bool HandleClick(FEditorViewportClient* const InViewportClient, HHitProxy* const InHitProxy, const FViewportClick& InClick); void StartTracking(FEditorViewportClient* const InViewportClient, FViewport* const InViewport); void EndTracking(FEditorViewportClient* const InViewportClient, FViewport* const InViewport); /** Selects or deselects all actors in a level world that are inside a defined box. */ bool BoxSelectWorldActors(FBox& InBox, FEditorViewportClient* const InEditorViewportClient, const bool bInSelect); /** Selects or deselects all actors in a level world that are inside a defined convex volume. */ bool FrustumSelectWorldActors(const FConvexVolume& InFrustum, FEditorViewportClient* const InEditorViewportClient, const bool bInSelect); protected: static bool IsActorSelectableClass(const AActor& InActor); static bool IsActorInLevelHiddenLayer(const AActor& InActor, FLevelEditorViewportClient* const InLevelEditorViewportClient); static TTypedElement GetTypedWorldElementFromActor(const AActor& InActor); /** * Selects or deselects actors in a world. If no actors are specified, uses all the actors in the level. * * @param InPredicate Function to use to check if the actor should be selected/deselected * @param InActors Optional list of actors to selected/deselected * @param bInSelect If true, selects the actors. If false, deselects the actors * @param bInClearSelection If true, clears the current selection before selecting the new actors * @return True if atleast one new actor was selected/deselected */ static bool SelectActorsByPredicate(UWorld* const InWorld , const bool bInSelect , const bool bInClearSelection , const TFunctionRef InPredicate , const TArray& InActors = {}); /** Updates an actors hovered state and visuals. */ void UpdateHoveredActorPrimitives(AActor* const InActor); static UTypedElementSelectionSet* GetLevelEditorSelectionSet(); bool IsTypedElementSelectable(const FTypedElementHandle& InElementHandle) const; void GetSelectionElements(AActor* const InActor, const TFunctionRef&)> InPredicate); bool bSelectionLimited = false; /** Hovered primitives and their last overlay color before we apply the hover overlay */ TMap, TOptional> HoveredPrimitiveComponents; /** Mouse cursor to display for the viewport when selection is limited. */ TOptional MouseCursor; FOnGetWorld OnGetWorld; /** Delegate used to check if an object is selectable in the viewport */ FOnIsObjectSelectableInViewport OnIsObjectSelectableInViewportDelegate; FVector DragStartPosition; FVector DragEndPosition; FIntRect DragSelectionRect; };