From 52915aa1056f50a939fa3d69c6688e33b9557c52 Mon Sep 17 00:00:00 2001 From: Steve Streeting Date: Mon, 26 Oct 2020 14:57:33 +0000 Subject: [PATCH] MenuStack can now change the input mode, game pause and mouse visibility on enter & exit if required --- .../Private/StevesUI/MenuStack.cpp | 60 +++++++++++++++++++ .../Public/StevesHelperCommon.h | 25 ++++++++ .../Public/StevesUI/MenuBase.h | 26 -------- .../Public/StevesUI/MenuStack.h | 32 +++++++++- 4 files changed, 115 insertions(+), 28 deletions(-) diff --git a/Source/StevesUEHelpers/Private/StevesUI/MenuStack.cpp b/Source/StevesUEHelpers/Private/StevesUI/MenuStack.cpp index 149cb90..ff0740c 100644 --- a/Source/StevesUEHelpers/Private/StevesUI/MenuStack.cpp +++ b/Source/StevesUEHelpers/Private/StevesUI/MenuStack.cpp @@ -5,6 +5,7 @@ #include "StevesUEHelpers.h" #include "StevesUI/MenuBase.h" #include "Framework/Application/SlateApplication.h" +#include "Kismet/GameplayStatics.h" void UMenuStack::NativeConstruct() @@ -25,6 +26,10 @@ void UMenuStack::NativeConstruct() GS->OnInputModeChanged.AddDynamic(this, &UMenuStack::InputModeChanged); LastInputMode = GS->GetLastInputModeUsed(); } + + ApplyInputModeChange(InputModeSettingOnOpen); + ApplyMousePointerVisibility(MousePointerVisibilityOnOpen); + ApplyGamePauseChange(GamePauseSettingOnOpen); } void UMenuStack::NativeDestruct() @@ -36,6 +41,56 @@ void UMenuStack::NativeDestruct() if (GS) GS->OnInputModeChanged.RemoveDynamic(this, &UMenuStack::InputModeChanged); +} + +void UMenuStack::ApplyInputModeChange(EInputModeChange Change) const +{ + auto PC = GetOwningPlayer(); + switch (Change) + { + case EInputModeChange::DoNotChange: + break; + case EInputModeChange::UIOnly: + PC->SetInputMode(FInputModeUIOnly()); + break; + case EInputModeChange::GameAndUI: + PC->SetInputMode(FInputModeGameAndUI()); + break; + case EInputModeChange::GameOnly: + PC->SetInputMode(FInputModeGameOnly()); + break; + } +} + +void UMenuStack::ApplyMousePointerVisibility(EMousePointerVisibilityChange Change) const +{ + auto PC = GetOwningPlayer(); + switch (Change) + { + case EMousePointerVisibilityChange::DoNotChange: + break; + case EMousePointerVisibilityChange::Visible: + PC->bShowMouseCursor = true; + break; + case EMousePointerVisibilityChange::Hidden: + PC->bShowMouseCursor = false; + break; + } +} + +void UMenuStack::ApplyGamePauseChange(EGamePauseChange Change) const +{ + switch (Change) + { + case EGamePauseChange::DoNotChange: + break; + case EGamePauseChange::Paused: + UGameplayStatics::SetGamePaused(GetWorld(), true); + break; + case EGamePauseChange::Unpaused: + UGameplayStatics::SetGamePaused(GetWorld(), false); + break; + } } @@ -131,6 +186,11 @@ void UMenuStack::LastMenuClosed(bool bWasCancel) { RemoveFromParent(); OnClosed.Broadcast(this, bWasCancel); + + ApplyInputModeChange(InputModeSettingOnClose); + ApplyMousePointerVisibility(MousePointerVisibilityOnClose); + ApplyGamePauseChange(GamePauseSettingOnClose); + } void UMenuStack::CloseAll(bool bWasCancel) diff --git a/Source/StevesUEHelpers/Public/StevesHelperCommon.h b/Source/StevesUEHelpers/Public/StevesHelperCommon.h index e3f8f02..d3df577 100644 --- a/Source/StevesUEHelpers/Public/StevesHelperCommon.h +++ b/Source/StevesUEHelpers/Public/StevesHelperCommon.h @@ -10,3 +10,28 @@ enum class EInputMode : uint8 Unknown }; +UENUM(BlueprintType) +enum class EInputModeChange : uint8 +{ + DoNotChange UMETA(DisplayName="No Change"), + UIOnly UMETA(DisplayName="UI Only"), + GameAndUI UMETA(DisplayName="Game And UI"), + GameOnly UMETA(DisplayName="Game Only") +}; + +UENUM(BlueprintType) +enum class EMousePointerVisibilityChange : uint8 +{ + DoNotChange UMETA(DisplayName="No Change"), + Visible UMETA(DisplayName="Pointer Visible"), + Hidden UMETA(DisplayName="Pointer Hidden") +}; + +UENUM(BlueprintType) +enum class EGamePauseChange : uint8 +{ + DoNotChange UMETA(DisplayName="No Change"), + Paused UMETA(DisplayName="Pause Game"), + Unpaused UMETA(DisplayName="Unpause Game") +}; + diff --git a/Source/StevesUEHelpers/Public/StevesUI/MenuBase.h b/Source/StevesUEHelpers/Public/StevesUI/MenuBase.h index 135648d..e0f32ce 100644 --- a/Source/StevesUEHelpers/Public/StevesUI/MenuBase.h +++ b/Source/StevesUEHelpers/Public/StevesUI/MenuBase.h @@ -8,34 +8,8 @@ #include "MenuBase.generated.h" - DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnMenuClosed, UMenuBase*, Menu, bool, bWasCancelled); -UENUM(BlueprintType) -enum class EInputModeChange : uint8 -{ - DoNotChange UMETA(DisplayName="No Change"), - UIOnly UMETA(DisplayName="UI Only"), - GameAndUI UMETA(DisplayName="Game And UI"), - GameOnly UMETA(DisplayName="Game Only") -}; - -UENUM(BlueprintType) -enum class EMousePointerVisibilityChange : uint8 -{ - DoNotChange UMETA(DisplayName="No Change"), - Visible UMETA(DisplayName="Pointer Visible"), - Hidden UMETA(DisplayName="Pointer Hidden") -}; - -UENUM(BlueprintType) -enum class EGamePauseChange : uint8 -{ - DoNotChange UMETA(DisplayName="No Change"), - Paused UMETA(DisplayName="Pause Game"), - Unpaused UMETA(DisplayName="Unpause Game") -}; - /// This class is a type of focusable panel designed for menus or other dialogs. /// It can be added to a UMenuStack to put it in context of a larger navigable group, /// and if so represents one level in the chain of an assumed modal stack. Use UMenuStack::PushMenuByClass/Object diff --git a/Source/StevesUEHelpers/Public/StevesUI/MenuStack.h b/Source/StevesUEHelpers/Public/StevesUI/MenuStack.h index 05cd6bc..90729c2 100644 --- a/Source/StevesUEHelpers/Public/StevesUI/MenuStack.h +++ b/Source/StevesUEHelpers/Public/StevesUI/MenuStack.h @@ -5,7 +5,6 @@ #include "FocusableUserWidget.h" #include "Framework/Application/IInputProcessor.h" #include "StevesHelperCommon.h" -#include "UObject/ObjectMacros.h" #include "MenuStack.generated.h" @@ -49,10 +48,15 @@ protected: TSharedPtr InputPreprocessor; - void LastMenuClosed(bool bWasCancel); + virtual void LastMenuClosed(bool bWasCancel); virtual void NativeConstruct() override; virtual void NativeDestruct() override; + + virtual void ApplyInputModeChange(EInputModeChange Change) const; + virtual void ApplyMousePointerVisibility(EMousePointerVisibilityChange Change) const; + virtual void ApplyGamePauseChange(EGamePauseChange Change) const; + UFUNCTION() bool HandleKeyDownEvent(const FKeyEvent& InKeyEvent); UFUNCTION() @@ -70,6 +74,30 @@ public: UPROPERTY(BlueprintAssignable) FOnMenuStackClosed OnClosed; + /// How this stack should change the input mode when it opens (default no change) + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Behavior") + EInputModeChange InputModeSettingOnOpen = EInputModeChange::DoNotChange; + + /// How this stack should set the mouse pointer visibility when it opens (default no change) + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Behavior") + EMousePointerVisibilityChange MousePointerVisibilityOnOpen = EMousePointerVisibilityChange::DoNotChange; + + /// How this stack should set the game pause state when it opens (default no change) + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Behavior") + EGamePauseChange GamePauseSettingOnOpen = EGamePauseChange::DoNotChange; + + /// How this stack should change the input mode when it closes (default no change) + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Behavior") + EInputModeChange InputModeSettingOnClose = EInputModeChange::DoNotChange; + + /// How this stack should set the mouse pointer visibility when it closes (default no change) + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Behavior") + EMousePointerVisibilityChange MousePointerVisibilityOnClose = EMousePointerVisibilityChange::DoNotChange; + + /// How this stack should set the game pause state when it closes (default no change) + UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Behavior") + EGamePauseChange GamePauseSettingOnClose = EGamePauseChange::DoNotChange; + /// Push a new menu level by class. This will instantiate the new menu, display it, and inform the previous menu that it's /// been superceded. Use the returned instance if you want to cache it UFUNCTION(BlueprintCallable)