diff --git a/Source/StevesUEHelpers/Private/StevesUI/MenuBase.cpp b/Source/StevesUEHelpers/Private/StevesUI/MenuBase.cpp index e1439ee..74fc3d9 100644 --- a/Source/StevesUEHelpers/Private/StevesUI/MenuBase.cpp +++ b/Source/StevesUEHelpers/Private/StevesUI/MenuBase.cpp @@ -27,6 +27,7 @@ void UMenuBase::AddedToStack(UMenuStack* Parent) ParentStack = MakeWeakObjectPtr(Parent); Open(false); + OnAddedToStack(Parent); } @@ -45,11 +46,22 @@ void UMenuBase::InputModeChanged(EInputMode OldMode, EInputMode NewMode) } } +bool UMenuBase::IsTopOfStack() const +{ + if (ParentStack.IsValid()) + { + return ParentStack->GetTopMenu() == this; + } + + return true; +} + void UMenuBase::RemovedFromStack(UMenuStack* Parent) { // This works whether embedded or not RemoveFromParent(); PreviousFocusWidget.Reset(); + OnRemovedFromStack(Parent); } void UMenuBase::SupercededInStack(UMenuBase* ByMenu) @@ -66,12 +78,13 @@ void UMenuBase::SupercededInStack(UMenuBase* ByMenu) if (bHideWhenSuperceded) SetVisibility(ESlateVisibility::Collapsed); } + OnSupercededInStack(ByMenu); } void UMenuBase::RegainedFocusInStack() { Open(true); - + OnRegainedFocusInStack(); } void UMenuBase::EmbedInParent() @@ -156,3 +169,19 @@ bool UMenuBase::ValidateClose_Implementation(bool bWasCancel) // Default always pass return true; } + +void UMenuBase::OnSupercededInStack_Implementation(UMenuBase* ByMenu) +{ +} + +void UMenuBase::OnRegainedFocusInStack_Implementation() +{ +} + +void UMenuBase::OnAddedToStack_Implementation(UMenuStack* Parent) +{ +} + +void UMenuBase::OnRemovedFromStack_Implementation(UMenuStack* Parent) +{ +} diff --git a/Source/StevesUEHelpers/Private/StevesUI/MenuStack.cpp b/Source/StevesUEHelpers/Private/StevesUI/MenuStack.cpp index 28298b6..93f45c0 100644 --- a/Source/StevesUEHelpers/Private/StevesUI/MenuStack.cpp +++ b/Source/StevesUEHelpers/Private/StevesUI/MenuStack.cpp @@ -269,6 +269,15 @@ void UMenuStack::RemoveFromParent() } +UMenuBase* UMenuStack::GetTopMenu() const +{ + if (Menus.Num() > 0) + { + return Menus.Top(); + } + return nullptr; +} + UMenuStack::UMenuStack() { // Default to enabling automatic focus for menus (can still be overridden in serialized properties) diff --git a/Source/StevesUEHelpers/Public/StevesUI/MenuBase.h b/Source/StevesUEHelpers/Public/StevesUI/MenuBase.h index 3ee2d19..417c10f 100644 --- a/Source/StevesUEHelpers/Public/StevesUI/MenuBase.h +++ b/Source/StevesUEHelpers/Public/StevesUI/MenuBase.h @@ -62,6 +62,19 @@ protected: UFUNCTION(BlueprintNativeEvent) bool ValidateClose(bool bWasCancel); + + /// Called when this menu is superceded by another menu being pushed on to this stack + UFUNCTION(BlueprintNativeEvent) + void OnSupercededInStack(UMenuBase* ByMenu); + /// Called when this menu is superceded by another menu being pushed on to this stack + UFUNCTION(BlueprintNativeEvent) + void OnRegainedFocusInStack(); + + UFUNCTION(BlueprintNativeEvent) + void OnAddedToStack(UMenuStack* Parent); + UFUNCTION(BlueprintNativeEvent) + void OnRemovedFromStack(UMenuStack* Parent); + public: /** @@ -96,4 +109,9 @@ public: void SupercededInStack(UMenuBase* ByMenu); void RegainedFocusInStack(); void InputModeChanged(EInputMode OldMode, EInputMode NewMode); + + /// Return whether this menu is currently at the top of the menu stack + /// Note: if this menu is not owned by a stack, will always return true + UFUNCTION(BlueprintCallable) + bool IsTopOfStack() const; }; diff --git a/Source/StevesUEHelpers/Public/StevesUI/MenuStack.h b/Source/StevesUEHelpers/Public/StevesUI/MenuStack.h index b9921bc..4baa2eb 100644 --- a/Source/StevesUEHelpers/Public/StevesUI/MenuStack.h +++ b/Source/StevesUEHelpers/Public/StevesUI/MenuStack.h @@ -139,6 +139,9 @@ public: virtual void PopMenuIfTop(UMenuBase* UiMenuBase, bool bWasCancel); virtual void RemoveFromParent() override; + /// Return the menu which is currently top of the stack + UFUNCTION(BlueprintCallable) + UMenuBase* GetTopMenu() const; UMenuStack();