// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "CoreMinimal.h" #include "SlateFwd.h" #include "Stats/Stats.h" #include "Misc/Attribute.h" #include "Animation/CurveSequence.h" #include "Layout/Visibility.h" #include "Widgets/SWidget.h" #include "Editor/UnrealEdTypes.h" #include "Application/ThrottleManager.h" #include "EditorViewportLayout.h" #include "TickableEditorObject.h" #include "SEditorViewport.h" class FAssetEditorViewportLayout; class SAssetEditorViewportsOverlay; class SWindow; class SAssetEditorViewport; class FEditorViewportTabContent; class FViewportTabContent; /** Arguments for constructing a viewport */ struct FAssetEditorViewportConstructionArgs { FAssetEditorViewportConstructionArgs() : ViewportType(LVT_Perspective) , bRealtime(false) {} /** The viewport's parent layout */ TSharedPtr ParentLayout; /** The viewport's desired type */ ELevelViewportType ViewportType; /** Whether the viewport should default to realtime */ bool bRealtime; /** A config key for loading/saving settings for the viewport */ FName ConfigKey; /** Widget enabled attribute */ TAttribute IsEnabled; }; using AssetEditorViewportFactoryFunction = TFunction(const FAssetEditorViewportConstructionArgs&)>; namespace EditorViewportConfigurationNames { static const FName TwoPanesHoriz("TwoPanesHoriz"); static const FName TwoPanesVert("TwoPanesVert"); static const FName ThreePanesLeft("ThreePanesLeft"); static const FName ThreePanesRight("ThreePanesRight"); static const FName ThreePanesTop("ThreePanesTop"); static const FName ThreePanesBottom("ThreePanesBottom"); static const FName FourPanesLeft("FourPanesLeft"); static const FName FourPanesRight("FourPanesRight"); static const FName FourPanesTop("FourPanesTop"); static const FName FourPanesBottom("FourPanesBottom"); static const FName FourPanes2x2("FourPanes2x2"); static const FName OnePane("OnePane"); } /** * Overlay wrapper class so that we can cache the size of the widget * It will also store the ViewportLayout data because that data can't be stored * per app; it must be stored per viewport overlay in case the app that made it closes. */ class SAssetEditorViewportsOverlay : public SCompoundWidget { public: SLATE_BEGIN_ARGS(SAssetEditorViewportsOverlay) {} SLATE_DEFAULT_SLOT(FArguments, Content) SLATE_ARGUMENT(TSharedPtr, ViewportTab) SLATE_END_ARGS() UNREALED_API void Construct(const FArguments& InArgs); /** Default constructor */ SAssetEditorViewportsOverlay() : CachedSize(FVector2D::ZeroVector) {} /** Overridden from SWidget */ UNREALED_API virtual void Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime) override; /** Wraps SOverlay::AddSlot() */ UNREALED_API SOverlay::FScopedWidgetSlotArguments AddSlot(); /** Wraps SOverlay::RemoveSlot() */ UNREALED_API void RemoveSlot(); /** * Returns the cached size of this viewport overlay * * @return The size that was cached */ UNREALED_API const FVector2D& GetCachedSize() const; /** Gets the Viewport Tab that created this overlay */ UNREALED_API TSharedPtr GetViewportTab() const; private: /** Reference to the owning viewport tab */ TSharedPtr ViewportTab; /** The overlay widget we're containing */ TSharedPtr< SOverlay > OverlayWidget; /** Cache our size, so that we can use this when animating a viewport maximize/restore */ FVector2D CachedSize; }; class FAssetEditorViewportPaneLayout { public: virtual ~FAssetEditorViewportPaneLayout() = default; /** * Sets up the layout based on the specific layout configuration implementation. * * @param SpecificLayoutString The layout string loaded from a file. * @return The base widget representing the layout. This is commonly a splitter. */ virtual TSharedRef MakeViewportLayout(TSharedPtr InParentLayout, const FString& LayoutString) = 0; /** * Returns the typename of this layout * Generally one of EditorViewportConfigurationNames */ virtual const FName& GetLayoutTypeName() const = 0; UNREALED_API void LoadConfig(const FString& LayoutString, TFunction LoadAdditionalLayoutInfoCallback = nullptr); UNREALED_API void SaveConfig(const FString& LayoutString, TFunction SaveAdditionalLayoutInfoCallback = nullptr) const; virtual void ReplaceWidget(TSharedRef OriginalWidget, TSharedRef ReplacementWidget) = 0; protected: UNREALED_API FString GetTypeSpecificLayoutString(const FString& LayoutString) const; virtual void SaveLayoutString(const FString& LayoutString) const {} virtual void LoadLayoutString(const FString& LayoutString) {} FName PerspectiveViewportConfigKey; }; /** * Base class for viewport layout configurations * Handles maximizing and restoring well as visibility of specific viewports. */ class FAssetEditorViewportLayout : public TSharedFromThis, public FEditorViewportLayout, public FTickableEditorObject { public: /** * Constructor */ UNREALED_API FAssetEditorViewportLayout(); /** * Destructor */ UNREALED_API virtual ~FAssetEditorViewportLayout(); /** Create an instance of a custom viewport from the specified viewport type name */ UNREALED_API virtual TSharedRef FactoryViewport(FName InTypeName, const FAssetEditorViewportConstructionArgs& ConstructionArgs); /** FTickableEditorObject interface */ virtual void Tick(float DeltaTime) override {} virtual bool IsTickable() const override { return false; } virtual TStatId GetStatId() const override { return TStatId(); } UNREALED_API virtual void FactoryPaneConfigurationFromTypeName(const FName& InLayoutConfigTypeName) override; UNREALED_API virtual const FName GetActivePaneConfigurationTypeName() const override; /** * Builds a viewport layout and returns the widget containing the layout * * @param InParentDockTab The parent dock tab widget of this viewport configuration * @param InParentTab The parent tab object * @param LayoutString The layout string loaded from file to custom build the layout with */ UNREALED_API virtual TSharedRef BuildViewportLayout(TSharedPtr InParentDockTab, TSharedPtr InParentTab, const FString& LayoutString ); /** Returns the parent tab content object */ TWeakPtr< FEditorViewportTabContent > GetParentTabContent() const { return ParentTabContent; } /** * Sets up the layout based on the specific layout configuration implementation. * * @param LayoutString The layout string loaded from a file. * @return The base widget representing the layout. This is commonly a splitter. */ UE_DEPRECATED(5.0, "This functionality has moved to the layout configurations. Use BuildViewportLayout.") UNREALED_API virtual TSharedRef MakeViewportLayout(const FString& LayoutString) final; UNREALED_API virtual void LoadConfig(const FString& LayoutString); UNREALED_API virtual void SaveConfig(const FString& LayoutString) const; protected: /** * Delegate called to get the visibility of the non-maximized viewports * The non-maximized viewports are not visible if there is a maximized viewport on top of them * * @param EVisibility::Visible when visible, EVisibility::Collapsed otherwise */ UNREALED_API virtual EVisibility OnGetNonMaximizedVisibility() const; /** The overlay widget that handles what viewports should be on top (non-maximized or maximized) */ TWeakPtr< SAssetEditorViewportsOverlay > ViewportsOverlayPtr; /** The parent tab content object where this layout resides */ TWeakPtr< FEditorViewportTabContent > ParentTabContent; /** The parent tab where this layout resides */ TWeakPtr< SDockTab > ParentTab; TSharedPtr LayoutConfiguration; };