// Copyright Epic Games, Inc. All Rights Reserved. #include "LyraTabListWidgetBase.h" #include "Blueprint/UserWidget.h" #include "CommonAnimatedSwitcher.h" #include "CommonButtonBase.h" #include "CommonUserWidget.h" #include "Components/SlateWrapperTypes.h" #include "Components/Widget.h" #include "Containers/UnrealString.h" #include "Misc/AssertionMacros.h" #include "Templates/Casts.h" #include "Templates/SharedPointer.h" #include "UObject/Class.h" void ULyraTabListWidgetBase::NativeOnInitialized() { Super::NativeOnInitialized(); } void ULyraTabListWidgetBase::NativeConstruct() { Super::NativeConstruct(); SetupTabs(); } void ULyraTabListWidgetBase::NativeDestruct() { for (FLyraTabDescriptor& TabInfo : PreregisteredTabInfoArray) { if (TabInfo.CreatedTabContentWidget) { TabInfo.CreatedTabContentWidget->RemoveFromParent(); TabInfo.CreatedTabContentWidget = nullptr; } } Super::NativeDestruct(); } bool ULyraTabListWidgetBase::GetPreregisteredTabInfo(const FName TabNameId, FLyraTabDescriptor& OutTabInfo) { const FLyraTabDescriptor* const FoundTabInfo = PreregisteredTabInfoArray.FindByPredicate([&](FLyraTabDescriptor& TabInfo) -> bool { return TabInfo.TabId == TabNameId; }); if (!FoundTabInfo) { return false; } OutTabInfo = *FoundTabInfo; return true; } void ULyraTabListWidgetBase::SetTabHiddenState(FName TabNameId, bool bHidden) { for (FLyraTabDescriptor& TabInfo : PreregisteredTabInfoArray) { if (TabInfo.TabId == TabNameId) { TabInfo.bHidden = bHidden; break; } } } bool ULyraTabListWidgetBase::RegisterDynamicTab(const FLyraTabDescriptor& TabDescriptor) { // If it's hidden we just ignore it. if (TabDescriptor.bHidden) { return true; } PendingTabLabelInfoMap.Add(TabDescriptor.TabId, TabDescriptor); return RegisterTab(TabDescriptor.TabId, TabDescriptor.TabButtonType, TabDescriptor.CreatedTabContentWidget); } void ULyraTabListWidgetBase::HandlePreLinkedSwitcherChanged() { for (const FLyraTabDescriptor& TabInfo : PreregisteredTabInfoArray) { // Remove tab content widget from linked switcher, as it is being disassociated. if (TabInfo.CreatedTabContentWidget) { TabInfo.CreatedTabContentWidget->RemoveFromParent(); } } Super::HandlePreLinkedSwitcherChanged(); } void ULyraTabListWidgetBase::HandlePostLinkedSwitcherChanged() { if (!IsDesignTime() && GetCachedWidget().IsValid()) { // Don't bother making tabs if we're in the designer or haven't been constructed yet SetupTabs(); } Super::HandlePostLinkedSwitcherChanged(); } void ULyraTabListWidgetBase::HandleTabCreation_Implementation(FName TabId, UCommonButtonBase* TabButton) { FLyraTabDescriptor* TabInfoPtr = nullptr; FLyraTabDescriptor TabInfo; if (GetPreregisteredTabInfo(TabId, TabInfo)) { TabInfoPtr = &TabInfo; } else { TabInfoPtr = PendingTabLabelInfoMap.Find(TabId); } if (TabButton->GetClass()->ImplementsInterface(ULyraTabButtonInterface::StaticClass())) { if (ensureMsgf(TabInfoPtr, TEXT("A tab button was created with id %s but no label info was specified. RegisterDynamicTab should be used over RegisterTab to provide label info."), *TabId.ToString())) { ILyraTabButtonInterface::Execute_SetTabLabelInfo(TabButton, *TabInfoPtr); } } PendingTabLabelInfoMap.Remove(TabId); } bool ULyraTabListWidgetBase::IsFirstTabActive() const { if (PreregisteredTabInfoArray.Num() > 0) { return GetActiveTab() == PreregisteredTabInfoArray[0].TabId; } return false; } bool ULyraTabListWidgetBase::IsLastTabActive() const { if (PreregisteredTabInfoArray.Num() > 0) { return GetActiveTab() == PreregisteredTabInfoArray.Last().TabId; } return false; } bool ULyraTabListWidgetBase::IsTabVisible(FName TabId) { if (const UCommonButtonBase* Button = GetTabButtonBaseByID(TabId)) { const ESlateVisibility TabVisibility = Button->GetVisibility(); return (TabVisibility == ESlateVisibility::Visible || TabVisibility == ESlateVisibility::HitTestInvisible || TabVisibility == ESlateVisibility::SelfHitTestInvisible); } return false; } int32 ULyraTabListWidgetBase::GetVisibleTabCount() { int32 Result = 0; const int32 TabCount = GetTabCount(); for ( int32 Index = 0; Index < TabCount; Index++ ) { if (IsTabVisible(GetTabIdAtIndex( Index ))) { Result++; } } return Result; } void ULyraTabListWidgetBase::SetupTabs() { for (FLyraTabDescriptor& TabInfo : PreregisteredTabInfoArray) { if (TabInfo.bHidden) { continue; } // If the tab content hasn't been created already, create it. if (!TabInfo.CreatedTabContentWidget && TabInfo.TabContentType) { TabInfo.CreatedTabContentWidget = CreateWidget(GetOwningPlayer(), TabInfo.TabContentType); OnTabContentCreatedNative.Broadcast(TabInfo.TabId, Cast(TabInfo.CreatedTabContentWidget)); OnTabContentCreated.Broadcast(TabInfo.TabId, Cast(TabInfo.CreatedTabContentWidget)); } if (UCommonAnimatedSwitcher* CurrentLinkedSwitcher = GetLinkedSwitcher()) { // Add the tab content to the newly linked switcher. if (!CurrentLinkedSwitcher->HasChild(TabInfo.CreatedTabContentWidget)) { CurrentLinkedSwitcher->AddChild(TabInfo.CreatedTabContentWidget); } } // If the tab is not already registered, register it. if (GetTabButtonBaseByID(TabInfo.TabId) == nullptr) { RegisterTab(TabInfo.TabId, TabInfo.TabButtonType, TabInfo.CreatedTabContentWidget); } } }