From 20d1490bd3350297eaa404daa238a11aab27ebca Mon Sep 17 00:00:00 2001 From: Sebastian Date: Sun, 28 Oct 2018 21:15:02 +0000 Subject: [PATCH] Replaced 'ImGui.DrawMouseCursor' console variable with a settings property. --- Source/ImGui/Private/ImGuiSettings.cpp | 4 +++ Source/ImGui/Private/ImGuiSettings.h | 12 ++++++++ Source/ImGui/Private/SImGuiWidget.cpp | 38 +++++++++++++++++--------- Source/ImGui/Private/SImGuiWidget.h | 9 ++++-- 4 files changed, 48 insertions(+), 15 deletions(-) diff --git a/Source/ImGui/Private/ImGuiSettings.cpp b/Source/ImGui/Private/ImGuiSettings.cpp index 534dd73..a216200 100644 --- a/Source/ImGui/Private/ImGuiSettings.cpp +++ b/Source/ImGui/Private/ImGuiSettings.cpp @@ -64,6 +64,10 @@ void UImGuiSettings::OnPropertyChanged(class UObject* ObjectBeingModified, struc { DebugExecBindings::UpdatePlayerInputs(SwitchInputModeKey, Commands::SwitchInputMode); } + else if (UpdatedPropertyName == GET_MEMBER_NAME_CHECKED(UImGuiSettings, bUseSoftwareCursor)) + { + OnSoftwareCursorChanged.Broadcast(); + } } } diff --git a/Source/ImGui/Private/ImGuiSettings.h b/Source/ImGui/Private/ImGuiSettings.h index 6310173..fe6ad0e 100644 --- a/Source/ImGui/Private/ImGuiSettings.h +++ b/Source/ImGui/Private/ImGuiSettings.h @@ -59,9 +59,15 @@ public: // Get mapping for 'ImGui.SwitchInputMode' command. const FImGuiKeyInfo& GetSwitchInputModeKey() const { return SwitchInputModeKey; } + // Check whether ImGui should draw its own software cursor. + bool UseSoftwareCursor() const { return bUseSoftwareCursor; } + // Delegate raised when ImGuiInputHandlerClass property has changed. FSimpleMulticastDelegate OnImGuiInputHandlerClassChanged; + // Delegate raised when SoftwareCursorEnabled property has changed. + FSimpleMulticastDelegate OnSoftwareCursorChanged; + virtual void PostInitProperties() override; protected: @@ -79,6 +85,12 @@ protected: UPROPERTY(EditAnywhere, config, Category = "Keyboard Shortcuts") FImGuiKeyInfo SwitchInputModeKey; + // If true, then in input mode ImGui will draw its own cursor in place of the hardware one. + // When disabled (default) there is a noticeable difference between cursor position seen by ImGui and position on + // the screen. Enabling this option removes that effect but with lower frame-rates UI becomes quickly unusable. + UPROPERTY(EditAnywhere, config, Category = "Input") + bool bUseSoftwareCursor = false; + private: #if WITH_EDITOR diff --git a/Source/ImGui/Private/SImGuiWidget.cpp b/Source/ImGui/Private/SImGuiWidget.cpp index 631473c..27caa9d 100644 --- a/Source/ImGui/Private/SImGuiWidget.cpp +++ b/Source/ImGui/Private/SImGuiWidget.cpp @@ -62,12 +62,6 @@ namespace CVars TEXT("3: keyboard and gamepad navigation (gamepad input is consumed)"), ECVF_Default); - TAutoConsoleVariable DrawMouseCursor(TEXT("ImGui.DrawMouseCursor"), 0, - TEXT("Whether or not mouse cursor in input mode should be drawn by ImGui.\n") - TEXT("0: disabled, hardware cursor will be used (default)\n") - TEXT("1: enabled, ImGui will take care for drawing mouse cursor"), - ECVF_Default); - TAutoConsoleVariable DebugWidget(TEXT("ImGui.Debug.Widget"), 0, TEXT("Show debug for SImGuiWidget.\n") TEXT("0: disabled (default)\n") @@ -110,16 +104,23 @@ void SImGuiWidget::Construct(const FArguments& InArgs) ContextProxy->OnDraw().AddRaw(this, &SImGuiWidget::OnDebugDraw); ContextProxy->SetInputState(&InputState); + // Cache locally software cursor mode. + UpdateSoftwareCursorMode(); + // Create ImGui Input Handler. CreateInputHandler(); - RegisterInputHandlerChangedDelegate(); + + // Register for settings change. + RegisterImGuiSettingsDelegates(); } END_SLATE_FUNCTION_BUILD_OPTIMIZATION SImGuiWidget::~SImGuiWidget() { + // Stop listening for settings change. + UnregisterImGuiSettingsDelegates(); + // Release ImGui Input Handler. - UnregisterInputHandlerChangedDelegate(); ReleaseInputHandler(); // Remove binding between this widget and its context proxy. @@ -378,7 +379,7 @@ FCursorReply SImGuiWidget::OnCursorQuery(const FGeometry& MyGeometry, const FPoi { MouseCursor = MouseCursorOverride; } - else if (CVars::DrawMouseCursor.GetValueOnGameThread() <= 0) + else if (!bUseSoftwareCursor) { if (FImGuiContextProxy* ContextProxy = ModuleManager->GetContextManager().GetContextProxy(ContextIndex)) { @@ -412,7 +413,13 @@ void SImGuiWidget::RecreateInputHandler() CreateInputHandler(); } -void SImGuiWidget::RegisterInputHandlerChangedDelegate() +void SImGuiWidget::UpdateSoftwareCursorMode() +{ + UImGuiSettings* Settings = GetMutableDefault(); + bUseSoftwareCursor = Settings && Settings->UseSoftwareCursor(); +} + +void SImGuiWidget::RegisterImGuiSettingsDelegates() { if (UImGuiSettings* Settings = GetMutableDefault()) { @@ -420,14 +427,19 @@ void SImGuiWidget::RegisterInputHandlerChangedDelegate() { Settings->OnImGuiInputHandlerClassChanged.AddRaw(this, &SImGuiWidget::RecreateInputHandler); } + if (!Settings->OnSoftwareCursorChanged.IsBoundToObject(this)) + { + Settings->OnSoftwareCursorChanged.AddRaw(this, &SImGuiWidget::UpdateSoftwareCursorMode); + } } } -void SImGuiWidget::UnregisterInputHandlerChangedDelegate() +void SImGuiWidget::UnregisterImGuiSettingsDelegates() { if (UImGuiSettings* Settings = GetMutableDefault()) { Settings->OnImGuiInputHandlerClassChanged.RemoveAll(this); + Settings->OnSoftwareCursorChanged.RemoveAll(this); } } @@ -476,7 +488,7 @@ void SImGuiWidget::SetMouseCursorOverride(EMouseCursor::Type InMouseCursorOverri { MouseCursorOverride = InMouseCursorOverride; FSlateApplication::Get().QueryCursor(); - InputState.SetMousePointer(MouseCursorOverride == EMouseCursor::None && IsDirectlyHovered() && CVars::DrawMouseCursor.GetValueOnGameThread() > 0); + InputState.SetMousePointer(bUseSoftwareCursor && MouseCursorOverride == EMouseCursor::None && IsDirectlyHovered()); } } @@ -581,7 +593,7 @@ void SImGuiWidget::UpdateInputMode(bool bHasKeyboardFocus, bool bHasMousePointer } } - InputState.SetMousePointer(MouseCursorOverride == EMouseCursor::None && bHasMousePointer && CVars::DrawMouseCursor.GetValueOnGameThread() > 0); + InputState.SetMousePointer(bUseSoftwareCursor && MouseCursorOverride == EMouseCursor::None && bHasMousePointer); } void SImGuiWidget::UpdateMouseStatus() diff --git a/Source/ImGui/Private/SImGuiWidget.h b/Source/ImGui/Private/SImGuiWidget.h index 957fe69..0d86451 100644 --- a/Source/ImGui/Private/SImGuiWidget.h +++ b/Source/ImGui/Private/SImGuiWidget.h @@ -91,8 +91,10 @@ private: void ReleaseInputHandler(); void RecreateInputHandler(); - void RegisterInputHandlerChangedDelegate(); - void UnregisterInputHandlerChangedDelegate(); + void UpdateSoftwareCursorMode(); + + void RegisterImGuiSettingsDelegates(); + void UnregisterImGuiSettingsDelegates(); // If needed, add to event reply a mouse lock or unlock request. FORCEINLINE FReply WithMouseLockRequests(FReply&& Reply); @@ -167,6 +169,9 @@ private: bool bReceivedMouseEvent = false; bool bMouseLock = false; + // Whether or not ImGui should draw its own cursor. + bool bUseSoftwareCursor = false; + // Canvas map mode allows to zoom in/out and navigate between different parts of ImGui canvas. bool bCanvasMapMode = false;