mirror of
https://github.com/sinbad/StevesUEHelpers.git
synced 2025-02-23 17:45:23 +00:00
Enabling UMenuBase to set its own input mode, mouse pointer and game paused & to be used outside of UMenuStack
This commit is contained in:
parent
f6cd57c5ee
commit
0f2c000939
@ -5,6 +5,7 @@
|
|||||||
#include "StevesUEHelpers.h"
|
#include "StevesUEHelpers.h"
|
||||||
#include "StevesUI/MenuStack.h"
|
#include "StevesUI/MenuStack.h"
|
||||||
#include "Components/ContentWidget.h"
|
#include "Components/ContentWidget.h"
|
||||||
|
#include "Kismet/GameplayStatics.h"
|
||||||
|
|
||||||
void UMenuBase::Close(bool bWasCancel)
|
void UMenuBase::Close(bool bWasCancel)
|
||||||
{
|
{
|
||||||
@ -13,26 +14,19 @@ void UMenuBase::Close(bool bWasCancel)
|
|||||||
if (ParentStack.IsValid())
|
if (ParentStack.IsValid())
|
||||||
{
|
{
|
||||||
ParentStack->PopMenuIfTop(this, bWasCancel);
|
ParentStack->PopMenuIfTop(this, bWasCancel);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
// standalone mode
|
||||||
|
RemoveFromParent();
|
||||||
|
PreviousFocusWidget.Reset();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void UMenuBase::AddedToStack(UMenuStack* Parent)
|
void UMenuBase::AddedToStack(UMenuStack* Parent)
|
||||||
{
|
{
|
||||||
ParentStack = MakeWeakObjectPtr(Parent);
|
ParentStack = MakeWeakObjectPtr(Parent);
|
||||||
if (bEmbedInParentContainer)
|
|
||||||
EmbedInParent();
|
|
||||||
else
|
|
||||||
AddToViewport();
|
|
||||||
SetVisibility(ESlateVisibility::Visible);
|
|
||||||
|
|
||||||
auto GS = GetStevesGameSubsystem(GetWorld());
|
Open(false);
|
||||||
if (bRequestFocus &&
|
|
||||||
GS && (GS->GetLastInputModeUsed() != EInputMode::Gamepad || GS->GetLastInputModeUsed() != EInputMode::Keyboard))
|
|
||||||
{
|
|
||||||
SetFocusProperly();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -73,16 +67,7 @@ void UMenuBase::SupercededInStack()
|
|||||||
|
|
||||||
void UMenuBase::RegainedFocusInStack()
|
void UMenuBase::RegainedFocusInStack()
|
||||||
{
|
{
|
||||||
if (bEmbedInParentContainer)
|
Open(true);
|
||||||
EmbedInParent();
|
|
||||||
else
|
|
||||||
AddToViewport();
|
|
||||||
SetVisibility(ESlateVisibility::Visible);
|
|
||||||
|
|
||||||
if (bRequestFocus)
|
|
||||||
{
|
|
||||||
SetFocusProperly();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,3 +82,61 @@ void UMenuBase::EmbedInParent()
|
|||||||
UE_LOG(LogStevesUI, Error, TEXT("Cannot embed %s in parent, missing container"), *this->GetName())
|
UE_LOG(LogStevesUI, Error, TEXT("Cannot embed %s in parent, missing container"), *this->GetName())
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UMenuBase::Open(bool bIsRegain)
|
||||||
|
{
|
||||||
|
if (ParentStack.IsValid() && bEmbedInParentContainer)
|
||||||
|
EmbedInParent();
|
||||||
|
else
|
||||||
|
AddToViewport();
|
||||||
|
SetVisibility(ESlateVisibility::Visible);
|
||||||
|
|
||||||
|
auto PC = GetOwningPlayer();
|
||||||
|
switch (InputModeSetting)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (MousePointerVisibility)
|
||||||
|
{
|
||||||
|
case EMousePointerVisibilityChange::DoNotChange:
|
||||||
|
break;
|
||||||
|
case EMousePointerVisibilityChange::Visible:
|
||||||
|
PC->bShowMouseCursor = true;
|
||||||
|
break;
|
||||||
|
case EMousePointerVisibilityChange::Hidden:
|
||||||
|
PC->bShowMouseCursor = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (GamePauseSetting)
|
||||||
|
{
|
||||||
|
case EGamePauseChange::DoNotChange:
|
||||||
|
break;
|
||||||
|
case EGamePauseChange::Paused:
|
||||||
|
UGameplayStatics::SetGamePaused(GetWorld(), true);
|
||||||
|
break;
|
||||||
|
case EGamePauseChange::Unpaused:
|
||||||
|
UGameplayStatics::SetGamePaused(GetWorld(), false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto GS = GetStevesGameSubsystem(GetWorld());
|
||||||
|
if (bRequestFocus &&
|
||||||
|
GS && (GS->GetLastInputModeUsed() != EInputMode::Gamepad || GS->GetLastInputModeUsed() != EInputMode::Keyboard))
|
||||||
|
{
|
||||||
|
SetFocusProperly();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
@ -10,10 +10,38 @@
|
|||||||
|
|
||||||
|
|
||||||
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnMenuClosed, UMenuBase*, Menu, bool, bWasCancelled);
|
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(FOnMenuClosed, UMenuBase*, Menu, bool, bWasCancelled);
|
||||||
/// This class is one element of the UUiMenuStack and represents one level in the chain of
|
|
||||||
/// an assumed modal stack. It is responsible for implementing how it gets added
|
UENUM(BlueprintType)
|
||||||
/// to the viewport or parent container, and removed again, and what it does when receiving
|
enum class EInputModeChange : uint8
|
||||||
/// focus.
|
{
|
||||||
|
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
|
||||||
|
/// to add an entry of this type to the stack
|
||||||
|
/// If you use this class standalone instead without a stack, then you must call Open() on this instance to
|
||||||
|
/// make it add itself to the viewport.
|
||||||
UCLASS(Abstract, BlueprintType)
|
UCLASS(Abstract, BlueprintType)
|
||||||
class STEVESUEHELPERS_API UMenuBase : public UFocusablePanel
|
class STEVESUEHELPERS_API UMenuBase : public UFocusablePanel
|
||||||
{
|
{
|
||||||
@ -29,23 +57,48 @@ protected:
|
|||||||
/// Whether this menu should request focus when it is displayed
|
/// Whether this menu should request focus when it is displayed
|
||||||
/// The widget which is focussed will either be the InitialFocusWidget on newly displayed, or
|
/// The widget which is focussed will either be the InitialFocusWidget on newly displayed, or
|
||||||
/// the previously selected widget if regaining focus
|
/// the previously selected widget if regaining focus
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Focus")
|
||||||
bool bRequestFocus = true;
|
bool bRequestFocus = true;
|
||||||
|
|
||||||
/// Set this property to true if you want this menu to embed itself in the parent UUiMenuStack's MenuContainer
|
/// Set this property to true if you want this menu to embed itself in the parent UMenuStack's MenuContainer
|
||||||
/// If false, this Menu will be added to the viewport independently and can float over other menus in the stack
|
/// If false, this Menu will be added to the viewport independently and can float over other menus in the stack
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Layout")
|
||||||
bool bEmbedInParentContainer = true;
|
bool bEmbedInParentContainer = true;
|
||||||
|
|
||||||
/// Whether to hide this menu when it's superceded by another in the stack. This property is only relevant
|
/// Whether to hide this menu when it's superceded by another in the stack. This property is only relevant
|
||||||
/// when bEmbedInParentContainer = false, since only one menu can be embedded at once.
|
/// when bEmbedInParentContainer = false, since only one menu can be embedded at once.
|
||||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Behavior")
|
||||||
bool bHideWhenSuperceded = true;
|
bool bHideWhenSuperceded = true;
|
||||||
|
|
||||||
void EmbedInParent();
|
/// How this menu should set the input mode when it becomes the top of the stack
|
||||||
|
/// This can be useful if your menus have variable input settings between levels in the stack
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Behavior")
|
||||||
|
EInputModeChange InputModeSetting = EInputModeChange::DoNotChange;
|
||||||
|
|
||||||
|
/// How this menu should set the mouse pointer visibility when it becomes the top of the stack
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Behavior")
|
||||||
|
EMousePointerVisibilityChange MousePointerVisibility = EMousePointerVisibilityChange::DoNotChange;
|
||||||
|
|
||||||
|
/// How this menu should set the game pause state when it becomes top of the stack
|
||||||
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Behavior")
|
||||||
|
EGamePauseChange GamePauseSetting = EGamePauseChange::DoNotChange;
|
||||||
|
|
||||||
|
virtual void EmbedInParent();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// Close this menu level
|
|
||||||
|
/**
|
||||||
|
* @brief Open this menu. You should only call this if you're NOT using this in a UMenuStack, because the stack will
|
||||||
|
* call it for you when you add this menu to it
|
||||||
|
|
||||||
|
* @param bIsRegainedFocus Set this to true if the reason this menu is opening is that it regained focus in a stack
|
||||||
|
*/
|
||||||
|
UFUNCTION(BlueprintCallable)
|
||||||
|
void Open(bool bIsRegainedFocus = false);
|
||||||
|
/**
|
||||||
|
* @brief Close this menu.
|
||||||
|
* @param bWasCancel Set this to true if the reason for closure was a cancellation action
|
||||||
|
*/
|
||||||
UFUNCTION(BlueprintCallable)
|
UFUNCTION(BlueprintCallable)
|
||||||
void Close(bool bWasCancel);
|
void Close(bool bWasCancel);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user