From 75f38faa81bcbdbc9d69a7fcef66e307f9db12e8 Mon Sep 17 00:00:00 2001 From: EmiStorrs Date: Tue, 3 Dec 2024 17:47:04 -0500 Subject: [PATCH 1/2] Unfocus on Unhover for Button and Checkbox --- .../Private/StevesUI/FocusableButton.cpp | 25 ++++++++++++++++++- .../Private/StevesUI/FocusableCheckBox.cpp | 25 ++++++++++++++++++- .../Public/StevesUI/FocusableButton.h | 5 ++++ .../Public/StevesUI/FocusableCheckBox.h | 6 +++++ 4 files changed, 59 insertions(+), 2 deletions(-) diff --git a/Source/StevesUEHelpers/Private/StevesUI/FocusableButton.cpp b/Source/StevesUEHelpers/Private/StevesUI/FocusableButton.cpp index a5378cd..8bd3945 100644 --- a/Source/StevesUEHelpers/Private/StevesUI/FocusableButton.cpp +++ b/Source/StevesUEHelpers/Private/StevesUI/FocusableButton.cpp @@ -109,5 +109,28 @@ void UFocusableButton::SlateHandleHovered() void UFocusableButton::SlateHandleUnhovered() { - OnUnhovered.Broadcast(); + if (bLoseFocusOnUnhover) + { + Unfocus(); + } + OnUnhovered.Broadcast(); +} + +void UFocusableButton::Unfocus() const +{ + APlayerController* OwningPlayer = GetOwningPlayer(); + if (OwningPlayer == nullptr || !OwningPlayer->IsLocalController() || OwningPlayer->Player == + nullptr) + { + return; + } + if (ULocalPlayer* LocalPlayer = OwningPlayer->GetLocalPlayer()) + { + TOptional UserIndex = FSlateApplication::Get().GetUserIndexForController( + LocalPlayer->GetControllerId()); + if (UserIndex.IsSet()) + { + FSlateApplication::Get().ClearUserFocus(UserIndex.GetValue()); + } + } } diff --git a/Source/StevesUEHelpers/Private/StevesUI/FocusableCheckBox.cpp b/Source/StevesUEHelpers/Private/StevesUI/FocusableCheckBox.cpp index c3e5f05..1b98fff 100644 --- a/Source/StevesUEHelpers/Private/StevesUI/FocusableCheckBox.cpp +++ b/Source/StevesUEHelpers/Private/StevesUI/FocusableCheckBox.cpp @@ -95,5 +95,28 @@ void UFocusableCheckBox::SlateHandleHovered() void UFocusableCheckBox::SlateHandleUnhovered() { - OnUnhovered.Broadcast(); + if (bLoseFocusOnUnhover) + { + Unfocus(); + } + OnUnhovered.Broadcast(); +} + +void UFocusableCheckBox::Unfocus() const +{ + APlayerController* OwningPlayer = GetOwningPlayer(); + if (OwningPlayer == nullptr || !OwningPlayer->IsLocalController() || OwningPlayer->Player == + nullptr) + { + return; + } + if (ULocalPlayer* LocalPlayer = OwningPlayer->GetLocalPlayer()) + { + TOptional UserIndex = FSlateApplication::Get().GetUserIndexForController( + LocalPlayer->GetControllerId()); + if (UserIndex.IsSet()) + { + FSlateApplication::Get().ClearUserFocus(UserIndex.GetValue()); + } + } } diff --git a/Source/StevesUEHelpers/Public/StevesUI/FocusableButton.h b/Source/StevesUEHelpers/Public/StevesUI/FocusableButton.h index a6f610f..7d0c847 100644 --- a/Source/StevesUEHelpers/Public/StevesUI/FocusableButton.h +++ b/Source/StevesUEHelpers/Public/StevesUI/FocusableButton.h @@ -38,6 +38,9 @@ public: UPROPERTY(BlueprintReadWrite, EditAnywhere) bool bTakeFocusOnHover = true; + UPROPERTY(BlueprintReadWrite, EditAnywhere) + bool bLoseFocusOnUnhover = true; + // Simulate a button press UFUNCTION(BlueprintCallable) void SimulatePress(); @@ -56,6 +59,8 @@ protected: void SlateHandleHovered(); void SlateHandleUnhovered(); + void Unfocus() const; + virtual TSharedRef RebuildWidget() override; diff --git a/Source/StevesUEHelpers/Public/StevesUI/FocusableCheckBox.h b/Source/StevesUEHelpers/Public/StevesUI/FocusableCheckBox.h index db595c1..f647eb6 100644 --- a/Source/StevesUEHelpers/Public/StevesUI/FocusableCheckBox.h +++ b/Source/StevesUEHelpers/Public/StevesUI/FocusableCheckBox.h @@ -43,6 +43,10 @@ public: UPROPERTY(BlueprintReadWrite, EditAnywhere) bool bTakeFocusOnHover = true; + + UPROPERTY(BlueprintReadWrite, EditAnywhere) + bool bLoseFocusOnUnhover = true; + protected: FCheckBoxStyle FocussedStyle; @@ -54,6 +58,8 @@ protected: void SlateHandleHovered(); void SlateHandleUnhovered(); + void Unfocus() const; + virtual TSharedRef RebuildWidget() override; public: From 6af2ba276647c53509a8c1c8a6321de6149aa3fc Mon Sep 17 00:00:00 2001 From: EmiStorrs Date: Wed, 4 Dec 2024 12:46:27 -0500 Subject: [PATCH 2/2] Prevent Unfocus if the widget is not focused by the current user --- .../StevesUEHelpers/Private/StevesUI/FocusableButton.cpp | 9 ++++++++- .../Private/StevesUI/FocusableCheckBox.cpp | 9 ++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/Source/StevesUEHelpers/Private/StevesUI/FocusableButton.cpp b/Source/StevesUEHelpers/Private/StevesUI/FocusableButton.cpp index 8bd3945..f327d9d 100644 --- a/Source/StevesUEHelpers/Private/StevesUI/FocusableButton.cpp +++ b/Source/StevesUEHelpers/Private/StevesUI/FocusableButton.cpp @@ -130,7 +130,14 @@ void UFocusableButton::Unfocus() const LocalPlayer->GetControllerId()); if (UserIndex.IsSet()) { - FSlateApplication::Get().ClearUserFocus(UserIndex.GetValue()); + TSharedPtr SafeWidget = GetCachedWidget(); + if (SafeWidget.IsValid()) + { + if (SafeWidget->HasUserFocus(UserIndex.GetValue())) + { + FSlateApplication::Get().ClearUserFocus(UserIndex.GetValue()); + } + } } } } diff --git a/Source/StevesUEHelpers/Private/StevesUI/FocusableCheckBox.cpp b/Source/StevesUEHelpers/Private/StevesUI/FocusableCheckBox.cpp index 1b98fff..da1f6d2 100644 --- a/Source/StevesUEHelpers/Private/StevesUI/FocusableCheckBox.cpp +++ b/Source/StevesUEHelpers/Private/StevesUI/FocusableCheckBox.cpp @@ -116,7 +116,14 @@ void UFocusableCheckBox::Unfocus() const LocalPlayer->GetControllerId()); if (UserIndex.IsSet()) { - FSlateApplication::Get().ClearUserFocus(UserIndex.GetValue()); + TSharedPtr SafeWidget = GetCachedWidget(); + if (SafeWidget.IsValid()) + { + if (SafeWidget->HasUserFocus(UserIndex.GetValue())) + { + FSlateApplication::Get().ClearUserFocus(UserIndex.GetValue()); + } + } } } }