CogImGui: Rework input mangement.

This commit is contained in:
Arnaud Jamin
2023-11-29 01:27:41 -05:00
parent cf07a05424
commit d1a4c8027f
7 changed files with 77 additions and 279 deletions
Binary file not shown.
@@ -132,6 +132,8 @@ void FCogImguiContext::Shutdown()
}
}
GameViewport->RemoveViewportWidgetContent(MainWidget.ToSharedRef());
if (PlotContext)
{
ImPlot::DestroyContext(PlotContext);
@@ -223,7 +225,6 @@ void FCogImguiContext::BeginFrame(float InDeltaTime)
if (ModifierKeys.IsAltDown() != IO.KeyAlt) { IO.AddKeyEvent(ImGuiMod_Alt, ModifierKeys.IsAltDown()); }
if (ModifierKeys.IsCommandDown() != IO.KeySuper) { IO.AddKeyEvent(ImGuiMod_Super, ModifierKeys.IsCommandDown()); }
//-------------------------------------------------------------------------------------------------------
//
//-------------------------------------------------------------------------------------------------------
@@ -236,8 +237,6 @@ void FCogImguiContext::BeginFrame(float InDeltaTime)
IO.ConfigFlags |= ImGuiConfigFlags_NoMouse;
}
TickFocus();
//-------------------------------------------------------------------------------------------------------
//
//-------------------------------------------------------------------------------------------------------
@@ -579,68 +578,39 @@ void FCogImguiContext::SetEnableInput(bool Value)
{
bEnableInput = Value;
FSlateThrottleManager::Get().DisableThrottle(bEnableInput);
if (bEnableInput == false)
if (bEnableInput)
{
TryGiveMouseCaptureBackToGame();
FSlateThrottleManager::Get().DisableThrottle(true);
IsThrottleDisabled = true;
FSlateApplication& SlateApp = FSlateApplication::Get();
if (ULocalPlayer* LocalPlayer = GetLocalPlayer())
{
LocalPlayer->GetSlateOperations()
.ReleaseMouseLock()
.ReleaseMouseCapture();
}
}
else
{
if (IsThrottleDisabled)
{
FSlateThrottleManager::Get().DisableThrottle(false);
}
if (ULocalPlayer* LocalPlayer = GetLocalPlayer())
{
LocalPlayer->GetSlateOperations().CaptureMouse(GameViewport->GetGameViewportWidget().ToSharedRef());
}
}
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogImguiContext::SetShareMouse(bool Value)
{
bShareMouse = Value;
if (bEnableInput == false)
{
TryGiveMouseCaptureBackToGame();
}
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogImguiContext::TryReleaseGameMouseCapture()
{
if (bShareMouse)
{
return;
}
if (TSharedPtr<FSlateUser> User = FSlateApplication::Get().GetCursorUser())
{
if (User->HasCursorCapture())
{
PreviousMouseCaptor = User->GetCursorCaptor();
}
}
if (ULocalPlayer* LocalPlayer = GetLocalPlayer())
{
LocalPlayer->GetSlateOperations()
.ReleaseMouseLock()
.ReleaseMouseCapture();
}
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogImguiContext::TryGiveMouseCaptureBackToGame()
{
if (PreviousMouseCaptor.IsValid() == false)
{
return;
}
TSharedRef<SWidget> PreviousMouseCaptorRef = PreviousMouseCaptor.Pin().ToSharedRef();
if (ULocalPlayer* LocalPlayer = GetLocalPlayer())
{
LocalPlayer->GetSlateOperations().CaptureMouse(PreviousMouseCaptorRef);
}
PreviousMouseCaptor.Reset();
bShareMouse = Value;
}
//--------------------------------------------------------------------------------------------------------------------------
@@ -743,80 +713,3 @@ ULocalPlayer* FCogImguiContext::GetLocalPlayer() const
ULocalPlayer* LocalPlayer = World->GetFirstLocalPlayerFromController();
return LocalPlayer;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogImguiContext::TickFocus()
{
const bool bShouldEnableInput = bEnableInput;
if (bEnableInput != bShouldEnableInput)
{
bEnableInput = bShouldEnableInput;
if (bEnableInput)
{
TakeFocus();
}
else
{
ReturnFocus();
}
}
else if (bEnableInput)
{
const auto& ViewportWidget = GameViewport->GetGameViewportWidget();
if (!MainWidget->HasKeyboardFocus() && !IsConsoleOpened() && (ViewportWidget->HasKeyboardFocus() || ViewportWidget->HasFocusedDescendants()))
{
TakeFocus();
}
}
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogImguiContext::TakeFocus()
{
FSlateApplication& SlateApplication = FSlateApplication::Get();
PreviousMouseCaptor = SlateApplication.GetUserFocusedWidget(SlateApplication.GetUserIndexForKeyboard());
if (ULocalPlayer* LocalPlayer = GetLocalPlayer())
{
TSharedRef<SWidget> FocusWidget = MainWidget->AsShared();
LocalPlayer->GetSlateOperations().CaptureMouse(FocusWidget);
LocalPlayer->GetSlateOperations().SetUserFocus(FocusWidget);
}
else
{
SlateApplication.SetKeyboardFocus(MainWidget->AsShared());
}
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogImguiContext::ReturnFocus()
{
//if (MainWidget->HasKeyboardFocus())
//{
// auto FocusWidgetPtr = PreviousMouseCaptor.IsValid()
// ? PreviousMouseCaptor.Pin()
// : GameViewport->GetGameViewportWidget();
// if (ULocalPlayer* LocalPlayer = GetLocalPlayer())
// {
// auto FocusWidgetRef = FocusWidgetPtr.ToSharedRef();
// if (FocusWidgetPtr == GameViewport->GetGameViewportWidget())
// {
// LocalPlayer->GetSlateOperations().CaptureMouse(FocusWidgetRef);
// }
// LocalPlayer->GetSlateOperations().SetUserFocus(FocusWidgetRef);
// }
// else
// {
// FSlateApplication& SlateApplication = FSlateApplication::Get();
// SlateApplication.ResetToDefaultPointerInputSettings();
// SlateApplication.SetUserFocus(SlateApplication.GetUserIndexForKeyboard(), FocusWidgetPtr);
// }
//}
//PreviousMouseCaptor.Reset();
}
@@ -3,7 +3,6 @@
#include "CogImguiInputHelper.h"
#include "CogImguiModule.h"
#include "CogImguiWidget.h"
#include "CogImGuiContext.h"
#include "imgui.h"
#include "SlateOptMacros.h"
@@ -14,8 +13,7 @@ void SCogImguiWidget::Construct(const FArguments& InArgs)
{
Context = InArgs._Context;
//SetVisibility(EVisibility::SelfHitTestInvisible);
SetVisibility(EVisibility::Visible);
RefreshVisibility();
}
END_SLATE_FUNCTION_BUILD_OPTIMIZATION
@@ -30,6 +28,13 @@ void SCogImguiWidget::SetDrawData(const ImDrawData* InDrawData)
DrawData = FCogImguiDrawData(InDrawData);
}
//--------------------------------------------------------------------------------------------------------------------------
void SCogImguiWidget::Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime)
{
Super::Tick(AllottedGeometry, InCurrentTime, InDeltaTime);
RefreshVisibility();
}
//--------------------------------------------------------------------------------------------------------------------------
int32 SCogImguiWidget::OnPaint(
const FPaintArgs& Args,
@@ -104,21 +109,6 @@ FVector2D SCogImguiWidget::ComputeDesiredSize(float Scale) const
return FVector2D::ZeroVector;
}
////--------------------------------------------------------------------------------------------------------------------------
//FReply SCogImguiWidget::OnFocusReceived(const FGeometry& MyGeometry, const FFocusEvent& FocusEvent)
//{
// if (bEnableInput == false)
// {
// return FReply::Unhandled();
// }
//
// Super::OnFocusReceived(MyGeometry, FocusEvent);
//
// FSlateApplication::Get().ResetToDefaultPointerInputSettings();
//
// return FReply::Handled();
//}
//--------------------------------------------------------------------------------------------------------------------------
FReply SCogImguiWidget::OnKeyChar(const FGeometry& MyGeometry, const FCharacterEvent& CharacterEvent)
{
@@ -189,13 +179,7 @@ FReply SCogImguiWidget::OnAnalogValueChanged(const FGeometry& MyGeometry, const
return FReply::Unhandled();
}
else
{
//if (bShareKeyboard)
//{
// return FReply::Unhandled();
//}
}
return FReply::Handled();
}
@@ -272,83 +256,15 @@ FReply SCogImguiWidget::OnFocusReceived(const FGeometry& MyGeometry, const FFocu
return Super::OnFocusReceived(MyGeometry, FocusEvent);
}
//--------------------------------------------------------------------------------------------------------------------------
//void SCogImguiWidget::TickFocus()
//{
// FCogImguiModule& Module = FCogImguiModule::Get();
//
// const bool bShouldEnableInput = Module.GetEnableInput();
// if (bEnableInput != bShouldEnableInput)
// {
// bEnableInput = bShouldEnableInput;
//
// if (bEnableInput)
// {
// TakeFocus();
// }
// else
// {
// ReturnFocus();
// }
// }
// else if (bEnableInput)
// {
// const auto& ViewportWidget = GameViewport->GetGameViewportWidget();
// if (!HasKeyboardFocus() && !IsConsoleOpened() && (ViewportWidget->HasKeyboardFocus() || ViewportWidget->HasFocusedDescendants()))
// {
// TakeFocus();
// }
// }
//}
//
//
////--------------------------------------------------------------------------------------------------------------------------
//void SCogImguiWidget::TakeFocus()
//{
// FSlateApplication& SlateApplication = FSlateApplication::Get();
//
// PreviousUserFocusedWidget = SlateApplication.GetUserFocusedWidget(SlateApplication.GetUserIndexForKeyboard());
//
// if (ULocalPlayer* LocalPlayer = GetLocalPlayer())
// {
// TSharedRef<SWidget> FocusWidget = SharedThis(this);
// LocalPlayer->GetSlateOperations().CaptureMouse(FocusWidget);
// LocalPlayer->GetSlateOperations().SetUserFocus(FocusWidget);
// }
// else
// {
// SlateApplication.SetKeyboardFocus(SharedThis(this));
// }
//}
//
////--------------------------------------------------------------------------------------------------------------------------
//void SCogImguiWidget::ReturnFocus()
//{
// if (HasKeyboardFocus())
// {
// auto FocusWidgetPtr = PreviousUserFocusedWidget.IsValid()
// ? PreviousUserFocusedWidget.Pin()
// : GameViewport->GetGameViewportWidget();
//
// if (ULocalPlayer* LocalPlayer = GetLocalPlayer())
// {
// auto FocusWidgetRef = FocusWidgetPtr.ToSharedRef();
//
// if (FocusWidgetPtr == GameViewport->GetGameViewportWidget())
// {
// LocalPlayer->GetSlateOperations().CaptureMouse(FocusWidgetRef);
// }
//
// LocalPlayer->GetSlateOperations().SetUserFocus(FocusWidgetRef);
// }
// else
// {
// FSlateApplication& SlateApplication = FSlateApplication::Get();
// SlateApplication.ResetToDefaultPointerInputSettings();
// SlateApplication.SetUserFocus(SlateApplication.GetUserIndexForKeyboard(), FocusWidgetPtr);
// }
// }
//
// PreviousUserFocusedWidget.Reset();
//}
void SCogImguiWidget::RefreshVisibility()
{
if (Context->GetEnableInput())
{
SetVisibility(EVisibility::Visible);
}
else
{
SetVisibility(EVisibility::SelfHitTestInvisible);
}
}
@@ -2,9 +2,9 @@
#include "CoreMinimal.h"
#include "Engine/Texture2D.h"
#include "imgui.h"
#include "Templates/SharedPointer.h"
#include "UObject/StrongObjectPtr.h"
#include "imgui.h"
class FCogImguiContext;
class IInputProcessor;
@@ -57,18 +57,8 @@ private:
void DrawDebug();
void TryGiveMouseCaptureBackToGame();
void TryReleaseGameMouseCapture();
void BuildFont();
void ReturnFocus();
void TickFocus();
void TakeFocus();
ULocalPlayer* GetLocalPlayer() const;
static void ImGui_CreateWindow(ImGuiViewport* Viewport);
@@ -122,4 +112,6 @@ private:
float DpiScale = 1.f;
bool bRefreshDPIScale = false;
bool IsThrottleDisabled = false;
};
@@ -26,6 +26,8 @@ public:
~SCogImguiWidget();
virtual void Tick(const FGeometry& AllottedGeometry, const double InCurrentTime, const float InDeltaTime) override;
virtual int32 OnPaint(const FPaintArgs& Args, const FGeometry& AllottedGeometry, const FSlateRect& MyClippingRect, FSlateWindowElementList& OutDrawElements, int32 LayerId, const FWidgetStyle& WidgetStyle, bool bParentEnabled) const override;
virtual bool SupportsKeyboardFocus() const override { return true; }
@@ -53,11 +55,7 @@ protected:
FReply HandleKeyEvent(const FGeometry& MyGeometry, const FKeyEvent& KeyEvent);
void TickFocus();
void TakeFocus();
void ReturnFocus();
void RefreshVisibility();
TObjectPtr<FCogImguiContext> Context = nullptr;
@@ -85,7 +85,7 @@ void UCogWindowManager::InitializeInternal()
TEXT("Save the layout. Cog.SaveLayout <Index>"),
FConsoleCommandWithArgsDelegate::CreateLambda([this](const TArray<FString>& Args) { if (Args.Num() > 0) { SaveLayout(FCString::Atoi(*Args[0])); }}),
ECVF_Cheat));
IsInitialized = true;
}
@@ -25,12 +25,12 @@ void FCogWindow_Settings::Initialize()
FCogImguiContext& Context = GetOwner()->GetContext();
Context.SetEnableInput(Config->bEnableInput);
Context.SetShareMouse(Config->bShareMouse);
//Context.SetShareMouse(Config->bShareMouse);
FCogImguiHelper::SetFlags(IO.ConfigFlags, ImGuiConfigFlags_NavEnableKeyboard, Config->bNavEnableKeyboard);
FCogImguiHelper::SetFlags(IO.ConfigFlags, ImGuiConfigFlags_NavEnableGamepad, Config->bNavEnableGamepad);
FCogImguiHelper::SetFlags(IO.ConfigFlags, ImGuiConfigFlags_NavNoCaptureKeyboard, Config->bNavNoCaptureInput);
FCogImguiHelper::SetFlags(IO.ConfigFlags, ImGuiConfigFlags_NoMouseCursorChange, Config->bNoMouseCursorChange);
//FCogImguiHelper::SetFlags(IO.ConfigFlags, ImGuiConfigFlags_NavEnableKeyboard, Config->bNavEnableKeyboard);
//FCogImguiHelper::SetFlags(IO.ConfigFlags, ImGuiConfigFlags_NavEnableGamepad, Config->bNavEnableGamepad);
//FCogImguiHelper::SetFlags(IO.ConfigFlags, ImGuiConfigFlags_NavNoCaptureKeyboard, Config->bNavNoCaptureInput);
//FCogImguiHelper::SetFlags(IO.ConfigFlags, ImGuiConfigFlags_NoMouseCursorChange, Config->bNoMouseCursorChange);
}
//--------------------------------------------------------------------------------------------------------------------------
@@ -38,15 +38,15 @@ void FCogWindow_Settings::PreSaveConfig()
{
Super::PreSaveConfig();
ImGuiIO& IO = ImGui::GetIO();
Config->bNavEnableKeyboard = IO.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard;
Config->bNavEnableGamepad = IO.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad;
Config->bNavNoCaptureInput = IO.ConfigFlags & ImGuiConfigFlags_NavNoCaptureKeyboard;
Config->bNoMouseCursorChange = IO.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange;
//ImGuiIO& IO = ImGui::GetIO();
//Config->bNavEnableKeyboard = IO.ConfigFlags & ImGuiConfigFlags_NavEnableKeyboard;
//Config->bNavEnableGamepad = IO.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad;
//Config->bNavNoCaptureInput = IO.ConfigFlags & ImGuiConfigFlags_NavNoCaptureKeyboard;
//Config->bNoMouseCursorChange = IO.ConfigFlags & ImGuiConfigFlags_NoMouseCursorChange;
const FCogImguiContext& Context = GetOwner()->GetContext();
Config->bEnableInput = Context.GetEnableInput();
Config->bShareMouse = Context.GetShareMouse();
//Config->bShareMouse = Context.GetShareMouse();
}
//--------------------------------------------------------------------------------------------------------------------------
@@ -86,8 +86,6 @@ void FCogWindow_Settings::RenderContent()
ImGui::PopStyleColor();
}
ImGui::Separator();
FCogWindowWidgets::SetNextItemToShortWidth();
ImGui::SliderFloat("DPI Scale", &Config->DPIScale, 0.5f, 2.0f, "%.1f");
if (ImGui::IsItemDeactivatedAfterEdit())
@@ -103,31 +101,32 @@ void FCogWindow_Settings::RenderContent()
ImGui::EndTooltip();
}
ImGui::Separator();
if (ImGui::Checkbox("Enable Viewports", &Config->bEnableViewports))
{
FCogImguiHelper::SetFlags(IO.ConfigFlags, ImGuiConfigFlags_ViewportsEnable, Config->bEnableViewports);
}
if (ImGui::IsItemHovered())
{
ImGui::SetTooltip("Cog imgui viewport integration in Unreal is still experimental");
}
ImGui::Checkbox("Compact Mode", &Config->bCompactMode);
ImGui::Checkbox("Show Windows In Main Menu", &Config->bShowWindowsInMainMenu);
ImGui::Checkbox("Show Window Help", &Config->bShowHelp);
ImGui::Separator();
//bool bShareMouse = Context.GetShareMouse();
//if (ImGui::Checkbox("Share Mouse", &bShareMouse))
//{
// Context.SetShareMouse(bShareMouse);
//}
bool bShareMouse = Context.GetShareMouse();
if (ImGui::Checkbox("Share Mouse", &bShareMouse))
{
Context.SetShareMouse(bShareMouse);
}
ImGui::CheckboxFlags("Keyboard Navigation", &IO.ConfigFlags, ImGuiConfigFlags_NavEnableKeyboard);
ImGui::CheckboxFlags("Gamepad Navigation", &IO.ConfigFlags, ImGuiConfigFlags_NavEnableGamepad);
ImGui::CheckboxFlags("Navigation No Capture", &IO.ConfigFlags, ImGuiConfigFlags_NavNoCaptureKeyboard);
ImGui::CheckboxFlags("No Mouse Cursor Change", &IO.ConfigFlags, ImGuiConfigFlags_NoMouseCursorChange);
//ImGui::CheckboxFlags("Keyboard Navigation", &IO.ConfigFlags, ImGuiConfigFlags_NavEnableKeyboard);
//ImGui::CheckboxFlags("Gamepad Navigation", &IO.ConfigFlags, ImGuiConfigFlags_NavEnableGamepad);
//ImGui::CheckboxFlags("Navigation No Capture", &IO.ConfigFlags, ImGuiConfigFlags_NavNoCaptureKeyboard);
//ImGui::CheckboxFlags("No Mouse Cursor Change", &IO.ConfigFlags, ImGuiConfigFlags_NoMouseCursorChange);
ImGui::Separator();