mirror of
https://github.com/sinbad/StevesUEHelpers.git
synced 2025-02-23 17:45:23 +00:00
Merge branch 'master' of github.com:sinbad/StevesUEHelpers
This commit is contained in:
commit
0fd38e1869
@ -21,6 +21,8 @@ which makes a bunch of things better:
|
||||
* Events raised whenever a player uses a different input method (in game, and in UI)
|
||||
(Actually reliable and not dependent on vagaries of input mappings / differences between UI and game input)
|
||||
|
||||
:heart: **[Support my work on Patreon!](https://www.patreon.com/stevestreeting)**
|
||||
|
||||
## Installing this plugin
|
||||
|
||||
### Cloning
|
||||
|
@ -149,7 +149,11 @@ void UInputImage::UpdateImageFromTable(const FKey& InKey, const TSoftObjectPtr<U
|
||||
// Rows are named the same as the key name
|
||||
const auto SpriteRow = Table->FindRow<FKeySprite>(InKey.GetFName(), "Find Key Image");
|
||||
if (SpriteRow)
|
||||
SetBrushFromAtlasInterface(SpriteRow->Sprite);
|
||||
{
|
||||
// Match size is needed incase size has changed
|
||||
// Need to make it update region in case inside a scale box or something else that needs to adjust
|
||||
SetBrushFromAtlasInterface(SpriteRow->Sprite, true);
|
||||
}
|
||||
}
|
||||
|
||||
UUiTheme* UInputImage::GetTheme()
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "StevesUEHelpers.h"
|
||||
#include "StevesUI/MenuStack.h"
|
||||
#include "Components/ContentWidget.h"
|
||||
#include "Kismet/GameplayStatics.h"
|
||||
|
||||
void UMenuBase::Close(bool bWasCancel)
|
||||
{
|
||||
@ -13,26 +14,19 @@ void UMenuBase::Close(bool bWasCancel)
|
||||
if (ParentStack.IsValid())
|
||||
{
|
||||
ParentStack->PopMenuIfTop(this, bWasCancel);
|
||||
} else
|
||||
{
|
||||
// standalone mode
|
||||
RemoveFromParent();
|
||||
PreviousFocusWidget.Reset();
|
||||
}
|
||||
}
|
||||
|
||||
void UMenuBase::AddedToStack(UMenuStack* Parent)
|
||||
{
|
||||
ParentStack = MakeWeakObjectPtr(Parent);
|
||||
if (bEmbedInParentContainer)
|
||||
EmbedInParent();
|
||||
else
|
||||
AddToViewport();
|
||||
SetVisibility(ESlateVisibility::Visible);
|
||||
|
||||
auto GS = GetStevesGameSubsystem(GetWorld());
|
||||
if (bRequestFocus &&
|
||||
GS && (GS->GetLastInputModeUsed() != EInputMode::Gamepad || GS->GetLastInputModeUsed() != EInputMode::Keyboard))
|
||||
{
|
||||
SetFocusProperly();
|
||||
}
|
||||
|
||||
|
||||
Open(false);
|
||||
}
|
||||
|
||||
|
||||
@ -73,16 +67,7 @@ void UMenuBase::SupercededInStack()
|
||||
|
||||
void UMenuBase::RegainedFocusInStack()
|
||||
{
|
||||
if (bEmbedInParentContainer)
|
||||
EmbedInParent();
|
||||
else
|
||||
AddToViewport();
|
||||
SetVisibility(ESlateVisibility::Visible);
|
||||
|
||||
if (bRequestFocus)
|
||||
{
|
||||
SetFocusProperly();
|
||||
}
|
||||
Open(true);
|
||||
|
||||
}
|
||||
|
||||
@ -94,6 +79,64 @@ void UMenuBase::EmbedInParent()
|
||||
ParentStack->MenuContainer->SetContent(this);
|
||||
}
|
||||
else
|
||||
UE_LOG(LogCustomUI, 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();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
@ -123,7 +123,7 @@ void UMenuStack::PopMenuIfTop(UMenuBase* UiMenuBase, bool bWasCancel)
|
||||
}
|
||||
else
|
||||
{
|
||||
UE_LOG(LogCustomUI, Error, TEXT("Tried to pop menu %s but it wasn't the top level"), *UiMenuBase->GetName());
|
||||
UE_LOG(LogStevesUI, Error, TEXT("Tried to pop menu %s but it wasn't the top level"), *UiMenuBase->GetName());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,29 +19,29 @@ void UOptionWidgetBase::NativeConstruct()
|
||||
ClearOptions();
|
||||
}
|
||||
else
|
||||
UE_LOG(LogCustomUI, Error, TEXT("StevesGameSubsystem is missing!"));
|
||||
UE_LOG(LogStevesUI, Error, TEXT("StevesGameSubsystem is missing!"));
|
||||
|
||||
// Check we can bind everything we need, bind click
|
||||
if (!MouseVersion)
|
||||
UE_LOG(LogCustomUI, Error, TEXT("%s should have a MouseVersion instance."), *this->GetClass()->GetName());
|
||||
UE_LOG(LogStevesUI, Error, TEXT("%s should have a MouseVersion instance."), *this->GetClass()->GetName());
|
||||
if (!GamepadVersion)
|
||||
UE_LOG(LogCustomUI, Error, TEXT("%s should have a GamepadVersion instance."), *this->GetClass()->GetName());
|
||||
UE_LOG(LogStevesUI, Error, TEXT("%s should have a GamepadVersion instance."), *this->GetClass()->GetName());
|
||||
if (MouseUpButton)
|
||||
MouseUpButton->OnClicked.AddDynamic(this, &UOptionWidgetBase::MouseUpClicked);
|
||||
else
|
||||
UE_LOG(LogCustomUI, Error, TEXT("%s should have a MouseUpButton instance."), *this->GetClass()->GetName());
|
||||
UE_LOG(LogStevesUI, Error, TEXT("%s should have a MouseUpButton instance."), *this->GetClass()->GetName());
|
||||
if (MouseDownButton)
|
||||
MouseDownButton->OnClicked.AddDynamic(this, &UOptionWidgetBase::MouseDownClicked);
|
||||
else
|
||||
UE_LOG(LogCustomUI, Error, TEXT("%s should have a MouseDownButton instance."), *this->GetClass()->GetName());
|
||||
UE_LOG(LogStevesUI, Error, TEXT("%s should have a MouseDownButton instance."), *this->GetClass()->GetName());
|
||||
if (!MouseUpImage)
|
||||
UE_LOG(LogCustomUI, Error, TEXT("%s should have a MouseUpImage instance."), *this->GetClass()->GetName());
|
||||
UE_LOG(LogStevesUI, Error, TEXT("%s should have a MouseUpImage instance."), *this->GetClass()->GetName());
|
||||
if (!MouseDownImage)
|
||||
UE_LOG(LogCustomUI, Error, TEXT("%s should have a MouseDownImage instance."), *this->GetClass()->GetName());
|
||||
UE_LOG(LogStevesUI, Error, TEXT("%s should have a MouseDownImage instance."), *this->GetClass()->GetName());
|
||||
if (!GamepadUpImage)
|
||||
UE_LOG(LogCustomUI, Error, TEXT("%s should have a GamepadUpImage instance."), *this->GetClass()->GetName());
|
||||
UE_LOG(LogStevesUI, Error, TEXT("%s should have a GamepadUpImage instance."), *this->GetClass()->GetName());
|
||||
if (!GamepadDownImage)
|
||||
UE_LOG(LogCustomUI, Error, TEXT("%s should have a GamepadDownImage instance."), *this->GetClass()->GetName());
|
||||
UE_LOG(LogStevesUI, Error, TEXT("%s should have a GamepadDownImage instance."), *this->GetClass()->GetName());
|
||||
|
||||
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
#include "Components/PanelWidget.h"
|
||||
#include "Components/Widget.h"
|
||||
|
||||
DEFINE_LOG_CATEGORY(LogCustomUI);
|
||||
DEFINE_LOG_CATEGORY(LogStevesUI);
|
||||
|
||||
UWidget* FindWidgetFromSlate(SWidget* SW, UWidget* Parent)
|
||||
{
|
||||
|
@ -5,7 +5,7 @@
|
||||
class UWidget;
|
||||
class SWidget;
|
||||
|
||||
DECLARE_LOG_CATEGORY_EXTERN(LogCustomUI, Warning, Warning)
|
||||
DECLARE_LOG_CATEGORY_EXTERN(LogStevesUI, Warning, Warning)
|
||||
|
||||
|
||||
/**
|
||||
|
@ -14,7 +14,7 @@ class STEVESUEHELPERS_API UFocusableUserWidget : public UUserWidget
|
||||
public:
|
||||
/// UWidget::SetFocus is not virtual FFS. This does the same as SetFocus by default but can be overridden,
|
||||
/// e.g. to delegate focus to specific children
|
||||
UFUNCTION(BlueprintNativeEvent)
|
||||
UFUNCTION(BlueprintNativeEvent, BlueprintCallable)
|
||||
void SetFocusProperly();
|
||||
|
||||
};
|
||||
|
@ -10,10 +10,38 @@
|
||||
|
||||
|
||||
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
|
||||
/// to the viewport or parent container, and removed again, and what it does when receiving
|
||||
/// focus.
|
||||
|
||||
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
|
||||
/// 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)
|
||||
class STEVESUEHELPERS_API UMenuBase : public UFocusablePanel
|
||||
{
|
||||
@ -29,23 +57,48 @@ protected:
|
||||
/// 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 previously selected widget if regaining focus
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Focus")
|
||||
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
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Layout")
|
||||
bool bEmbedInParentContainer = true;
|
||||
|
||||
/// 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.
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite)
|
||||
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="Behavior")
|
||||
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:
|
||||
/// 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)
|
||||
void Close(bool bWasCancel);
|
||||
|
||||
|
@ -9,7 +9,7 @@
|
||||
"CreatedByURL" : "https://www.stevestreeting.com",
|
||||
"DocsURL" : "",
|
||||
"MarketplaceURL" : "",
|
||||
"SupportURL" : "",
|
||||
"SupportURL" : "https://github.com/sinbad/StevesUEHelpers",
|
||||
"EnabledByDefault" : true,
|
||||
"CanContainContent" : false,
|
||||
"IsBetaVersion" : true,
|
||||
|
Loading…
x
Reference in New Issue
Block a user