diff --git a/Source/StevesUEHelpers/Private/StevesUI/MenuSystem.cpp b/Source/StevesUEHelpers/Private/StevesUI/MenuSystem.cpp new file mode 100644 index 0000000..5122cd8 --- /dev/null +++ b/Source/StevesUEHelpers/Private/StevesUI/MenuSystem.cpp @@ -0,0 +1,75 @@ +#include "StevesUI/MenuSystem.h" +#include "StevesUI/MenuStack.h" + +DEFINE_LOG_CATEGORY(LogMenuSystem) + +TWeakObjectPtr FMenuSystem::GetHighestFocusPriority() +{ + int Highest = -999; + TWeakObjectPtr Ret; + + for (auto && S : ActiveMenuStacks) + { + if (S.IsValid() && S->IsRequestingFocus() && S->FocusPriority > Highest) + { + Highest = S->FocusPriority; + Ret = S; + } + } + + return Ret; +} + +void FMenuSystem::MenuStackOpened(UMenuStack* Stack) +{ + UE_LOG(LogMenuSystem, Display, TEXT("MenuStack %s opened"), *Stack->GetName()); + // check to make sure we never dupe, shouldn't normally be a problem + // but let's just be safe, there will never be that many + bool bPresent = false; + for (auto && S : ActiveMenuStacks) + { + if (S.Get() == Stack) + { + bPresent = true; + break; + } + } + if (!bPresent) + ActiveMenuStacks.Add(Stack); + + if (Stack->IsRequestingFocus()) + { + auto Highest = GetHighestFocusPriority(); + if (!Highest.IsValid() || Highest->FocusPriority <= Stack->FocusPriority) + { + // give new stack the focus if it's equal or higher priority than anything else + UE_LOG(LogMenuSystem, Display, TEXT("Giving focus to MenuStack %s"), *Stack->GetName()); + Stack->TakeFocusIfDesired(); + } + } +} + +void FMenuSystem::MenuStackClosed(UMenuStack* Stack) +{ + UE_LOG(LogMenuSystem, Display, TEXT("MenuStack %s closed"), *Stack->GetName()); + + for (int i = 0; i < ActiveMenuStacks.Num(); ++i) + { + if (ActiveMenuStacks[i].Get() == Stack) + { + ActiveMenuStacks.RemoveAt(i); + break; + } + } + + // if the menu closing had focus, give it to the highest remaining stack + if (Stack->HasFocusedDescendants()) + { + auto Highest = GetHighestFocusPriority(); + if (Highest.IsValid()) + { + UE_LOG(LogMenuSystem, Display, TEXT("Giving focus to MenuStack %s"), *Highest->GetName()); + Highest->TakeFocusIfDesired(); + } + } +} diff --git a/Source/StevesUEHelpers/Public/StevesUI/MenuSystem.h b/Source/StevesUEHelpers/Public/StevesUI/MenuSystem.h new file mode 100644 index 0000000..5715839 --- /dev/null +++ b/Source/StevesUEHelpers/Public/StevesUI/MenuSystem.h @@ -0,0 +1,17 @@ +#pragma once + +#include "CoreMinimal.h" + +DECLARE_LOG_CATEGORY_EXTERN(LogMenuSystem, Log, All) + +class FMenuSystem +{ +protected: + TArray> ActiveMenuStacks; + + TWeakObjectPtr GetHighestFocusPriority(); +public: + void MenuStackOpened(UMenuStack* Stack); + void MenuStackClosed(UMenuStack* Stack); + +};