// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "CoreMinimal.h" #include "Widgets/DeclarativeSyntaxSupport.h" #include "Widgets/SCompoundWidget.h" class SDockTab; class SOverlay; class STabDrawerButton; class SVerticalBox; class STabDrawer; struct FTabId; enum class ESidebarLocation : uint8; /** * A Sidebar is a widget that contains STabDrawers which can be opened and closed from the drawer to allow temporary access to the tab * A drawer is automatically dismissed when it or any of its children loses focus * * Tabs can be pinned in the sidebar: this prevents them from being automatically dismissed when they lose focus, * and it also causes them to be summoned back when all other drawers are dismissed */ class STabSidebar : public SCompoundWidget { SLATE_BEGIN_ARGS(STabSidebar) {} SLATE_ARGUMENT(ESidebarLocation, Location) SLATE_END_ARGS() public: ~STabSidebar(); void Construct(const FArguments& InArgs, TSharedRef InDrawersOverlay); /** * Sets an offset for the sidebar from the top of the window */ void SetOffset(float Offset); /** * Adds a tab to the sidebar */ void AddTab(TSharedRef Tab); /** * Removes a tab from the sidebar. Does not restore it to the parent stack * * Note it is not sufficient to call this to clean up the tab completely. Call RequestCloseTab on the dock tab to do that. * @return true if the tab was found and removal was successful */ bool RemoveTab(TSharedRef TabToRemove); /** * Restores a tab to the parent tab stack and removes it from this sidebar * * @return true if the tab was found and removal was successful */ bool RestoreTab(TSharedRef TabToRestore); /** * @return true if this sidebar contains the provided tab */ bool ContainsTab(TSharedPtr Tab) const; /** * Get all layout identifiers for tabs in this sidebar */ TArray GetAllTabIds() const; /** * Get all tabs in this sidebar */ TArray> GetAllTabs() const; /** * Attempt to open a drawer in the sidebar for a specified tab * * @return true if the passed in tab is contained in this sidebar and was opened */ bool TryOpenSidebarDrawer(TSharedRef ForTab); private: void OnTabDrawerButtonPressed(TSharedRef ForTab); void OnTabDrawerPinButtonToggled(TSharedRef ForTab, bool bIsPinned); void OnTabDrawerFocusLost(TSharedRef Drawer); void OnTabDrawerClosed(TSharedRef Drawer); void OnTargetDrawerSizeChanged(TSharedRef Drawer, float NewSize); TSharedRef OnGetTabDrawerContextMenuWidget(TSharedRef ForTab); void OnRestoreTab(TSharedRef TabToRestore); void OnCloseTab(TSharedRef TabToClose); /** * Removes a single drawer for a specified tab from this sidebar * Removal is done instantly not waiting for any close animation */ void RemoveDrawer(TSharedRef ForTab); /** * Removes all drawers instantly (including drawers for pinned tabs) */ void RemoveAllDrawers(); EActiveTimerReturnType OnOpenPendingDrawerTimer(double CurrentTime, float DeltaTime); void OpenDrawerNextFrame(TSharedRef ForTab, bool bAnimateOpen); void OpenDrawerInternal(TSharedRef ForTab, bool bAnimateOpen); void CloseDrawerInternal(TSharedRef ForTab); /** * Reopens the pinned tab only if there are no other open drawers; * this should be used to bring pinned tabs back after other tabs lose focus/are closed */ void SummonPinnedTabIfNothingOpened(); /** * Updates the appearance of open drawers */ void UpdateDrawerAppearance(); /** * Returns the first tab in this sidebar that is marked pinned */ TSharedPtr FindFirstPinnedTab() const; /** * Returns the tab for the last-opened drawer that is still open, * excluding any drawers that are in the process of closing */ TSharedPtr GetForegroundTab() const; /** * Returns the drawer for the given tab if it's open */ TSharedPtr FindOpenedDrawer(TSharedRef ForTab) const; private: TSharedPtr TabBox; TArray, TSharedRef>> Tabs; TSharedPtr OpenPendingDrawerTimerHandle; ESidebarLocation Location; TSharedPtr DrawersOverlay; /** Generally speaking one drawer is only ever open at once but we animate any previous drawer closing so there could be more than one while an animation is playing */ TArray> OpenedDrawers; /** Any pending drawer tab to open */ TWeakPtr PendingTabToOpen; /** Whether to animate the pending tab open */ bool bAnimatePendingTabOpen = false; };