From ecddecf3e51239971186b1a41da8bdae2fe4464a Mon Sep 17 00:00:00 2001 From: Arnaud Jamin Date: Fri, 24 Nov 2023 09:46:03 -0500 Subject: [PATCH] Use InputProcessor to support shared mouse --- .../Private/CogEngineWindow_Selection.cpp | 6 - .../Source/CogImgui/CogImGuiInputProcessor.h | 55 ++++++ .../CogImgui/Private/CogImguiInputHelper.cpp | 161 ------------------ .../CogImgui/Private/CogImguiWidget.cpp | 16 +- .../CogImgui/Public/CogImguiInputHelper.h | 6 - .../Source/CogImgui/Public/CogImguiWidget.h | 2 +- .../CogWindow/Private/CogWindowManager.cpp | 9 +- .../CogWindow/Public/CogWindow_Inputs.h | 2 +- Source/CogSample/CogSample.Build.cs | 2 +- .../CogSample/CogSamplePlayerController.cpp | 2 + TODO.txt | 6 +- 11 files changed, 80 insertions(+), 187 deletions(-) create mode 100644 Plugins/Cog/Source/CogImgui/CogImGuiInputProcessor.h diff --git a/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Selection.cpp b/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Selection.cpp index f298434..f58e7f0 100644 --- a/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Selection.cpp +++ b/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_Selection.cpp @@ -386,11 +386,6 @@ void FCogEngineWindow_Selection::TickSelectionMode() return; } - if (ImGui::IsItemHovered(ImGuiHoveredFlags_AnyWindow)) - { - return; - } - APlayerController* PlayerController = GetLocalPlayerController(); if (PlayerController == nullptr) { @@ -398,7 +393,6 @@ void FCogEngineWindow_Selection::TickSelectionMode() return; } - ImDrawList* DrawList = ImGui::GetBackgroundDrawList(); DrawList->AddRect(ImVec2(0, 0), ImGui::GetIO().DisplaySize, IM_COL32(255, 0, 0, 128), 0.0f, 0, 20.0f); FCogWindowWidgets::AddTextWithShadow(DrawList, ImVec2(20, 20), IM_COL32(255, 255, 255, 255), "Picking Mode. \n[LMB] Pick \n[RMB] Cancel"); diff --git a/Plugins/Cog/Source/CogImgui/CogImGuiInputProcessor.h b/Plugins/Cog/Source/CogImgui/CogImGuiInputProcessor.h new file mode 100644 index 0000000..b6d960a --- /dev/null +++ b/Plugins/Cog/Source/CogImgui/CogImGuiInputProcessor.h @@ -0,0 +1,55 @@ +#pragma once + +#include "Framework/Application/IInputProcessor.h" + +class SCogImguiWidget; +class UPlayerInput; +enum ImGuiKey : int; +struct FKeyBind; + +class FImGuiInputProcessor : public IInputProcessor +{ +public: + + FImGuiInputProcessor(UPlayerInput* InPlayerInput, SCogImguiWidget* InWidget); + + virtual void Tick(const float DeltaTime, FSlateApplication& SlateApp, TSharedRef SlateCursor) override; + + virtual bool HandleKeyDownEvent(FSlateApplication& SlateApp, const FKeyEvent& Event) override; + + virtual bool HandleKeyUpEvent(FSlateApplication& SlateApp, const FKeyEvent& Event) override; + + virtual bool HandleAnalogInputEvent(FSlateApplication& SlateApp, const FAnalogInputEvent& Event) override; + + virtual bool HandleMouseMoveEvent(FSlateApplication& SlateApp, const FPointerEvent& Event) override; + + virtual bool HandleMouseButtonDownEvent(FSlateApplication& SlateApp, const FPointerEvent& Event) override; + + virtual bool HandleMouseButtonUpEvent(FSlateApplication& SlateApp, const FPointerEvent& Event) override; + + virtual bool HandleMouseButtonDoubleClickEvent(FSlateApplication& SlateApp, const FPointerEvent& Event) override; + + virtual bool HandleMouseWheelOrGestureEvent(FSlateApplication& SlateApp, const FPointerEvent& Event, const FPointerEvent* GestureEvent) override; + +protected: + + bool HandleKeyEvent(FSlateApplication& SlateApp, const FKeyEvent& Event, bool IsKeyDown); + + bool HandleMouseButtonEvent(FSlateApplication& SlateApp, const FPointerEvent& Event, bool IsButtonDown); + + bool IsKeyBoundToCommand(const FKeyEvent& KeyEvent); + + static ImGuiKey ToImKey(const FKey& Key); + + static bool IsKeyEventMatchingKeyBind(const FKeyEvent& KeyEvent, const FKeyBind& KeyBind); + + static bool IsConsoleEvent(const FKeyEvent& KeyEvent); + + static bool IsStopPlaySessionEvent(const FKeyEvent& KeyEvent); + + static uint32 ToImGuiMouseButton(const FKey& MouseButton); + + TObjectPtr PlayerInput = nullptr; + + TObjectPtr MainWidget = nullptr; +}; diff --git a/Plugins/Cog/Source/CogImgui/Private/CogImguiInputHelper.cpp b/Plugins/Cog/Source/CogImgui/Private/CogImguiInputHelper.cpp index e765604..0947109 100644 --- a/Plugins/Cog/Source/CogImgui/Private/CogImguiInputHelper.cpp +++ b/Plugins/Cog/Source/CogImgui/Private/CogImguiInputHelper.cpp @@ -13,9 +13,6 @@ #include "Kismet2/DebuggerCommands.h" #endif //WITH_EDITOR -//-------------------------------------------------------------------------------------------------------------------------- -TMap FCogImguiInputHelper::KeyMap; - //-------------------------------------------------------------------------------------------------------------------------- APlayerController* FCogImguiInputHelper::GetFirstLocalPlayerController(const UWorld& World) { @@ -244,22 +241,6 @@ bool FCogImguiInputHelper::IsStopPlaySessionEvent(const FKeyEvent& KeyEvent) return false; } -//-------------------------------------------------------------------------------------------------------------------------- -ImGuiKey FCogImguiInputHelper::KeyEventToImGuiKey(const FKeyEvent& KeyEvent) -{ - if (KeyMap.IsEmpty()) - { - InitializeKeyMap(); - } - - if (const ImGuiKey* Key = KeyMap.Find(KeyEvent.GetKey())) - { - return *Key; - } - - return ImGuiKey_None; -} - //-------------------------------------------------------------------------------------------------------------------------- uint32 FCogImguiInputHelper::MouseButtonToImGuiMouseButton(const FKey& MouseButton) { @@ -291,148 +272,6 @@ EMouseCursor::Type FCogImguiInputHelper::ToSlateMouseCursor(ImGuiMouseCursor Mou } } -//-------------------------------------------------------------------------------------------------------------------------- -void FCogImguiInputHelper::InitializeKeyMap() -{ - KeyMap.Add(EKeys::LeftMouseButton, ImGuiKey_MouseLeft); - KeyMap.Add(EKeys::RightMouseButton, ImGuiKey_MouseRight); - KeyMap.Add(EKeys::MiddleMouseButton, ImGuiKey_MouseMiddle); - KeyMap.Add(EKeys::ThumbMouseButton, ImGuiKey_MouseX1); - KeyMap.Add(EKeys::ThumbMouseButton2, ImGuiKey_MouseX2); - - KeyMap.Add(EKeys::BackSpace, ImGuiKey_Backspace); - KeyMap.Add(EKeys::Tab, ImGuiKey_Tab); - KeyMap.Add(EKeys::Enter, ImGuiKey_Enter); - KeyMap.Add(EKeys::Pause, ImGuiKey_Pause); - - KeyMap.Add(EKeys::CapsLock, ImGuiKey_CapsLock); - KeyMap.Add(EKeys::Escape, ImGuiKey_Escape); - KeyMap.Add(EKeys::SpaceBar, ImGuiKey_Space); - KeyMap.Add(EKeys::PageUp, ImGuiKey_PageUp); - KeyMap.Add(EKeys::PageDown, ImGuiKey_PageDown); - KeyMap.Add(EKeys::End, ImGuiKey_End); - KeyMap.Add(EKeys::Home, ImGuiKey_Home); - - KeyMap.Add(EKeys::Left, ImGuiKey_LeftArrow); - KeyMap.Add(EKeys::Up, ImGuiKey_UpArrow); - KeyMap.Add(EKeys::Right, ImGuiKey_RightArrow); - KeyMap.Add(EKeys::Down, ImGuiKey_DownArrow); - - KeyMap.Add(EKeys::Insert, ImGuiKey_Insert); - KeyMap.Add(EKeys::Delete, ImGuiKey_Delete); - - KeyMap.Add(EKeys::Zero, ImGuiKey_0); - KeyMap.Add(EKeys::One, ImGuiKey_1); - KeyMap.Add(EKeys::Two, ImGuiKey_2); - KeyMap.Add(EKeys::Three, ImGuiKey_3); - KeyMap.Add(EKeys::Four, ImGuiKey_4); - KeyMap.Add(EKeys::Five, ImGuiKey_5); - KeyMap.Add(EKeys::Six, ImGuiKey_6); - KeyMap.Add(EKeys::Seven, ImGuiKey_7); - KeyMap.Add(EKeys::Eight, ImGuiKey_8); - KeyMap.Add(EKeys::Nine, ImGuiKey_9); - - KeyMap.Add(EKeys::A, ImGuiKey_A); - KeyMap.Add(EKeys::B, ImGuiKey_B); - KeyMap.Add(EKeys::C, ImGuiKey_C); - KeyMap.Add(EKeys::D, ImGuiKey_D); - KeyMap.Add(EKeys::E, ImGuiKey_E); - KeyMap.Add(EKeys::F, ImGuiKey_F); - KeyMap.Add(EKeys::G, ImGuiKey_G); - KeyMap.Add(EKeys::H, ImGuiKey_H); - KeyMap.Add(EKeys::I, ImGuiKey_I); - KeyMap.Add(EKeys::J, ImGuiKey_J); - KeyMap.Add(EKeys::K, ImGuiKey_K); - KeyMap.Add(EKeys::L, ImGuiKey_L); - KeyMap.Add(EKeys::M, ImGuiKey_M); - KeyMap.Add(EKeys::N, ImGuiKey_N); - KeyMap.Add(EKeys::O, ImGuiKey_O); - KeyMap.Add(EKeys::P, ImGuiKey_P); - KeyMap.Add(EKeys::Q, ImGuiKey_Q); - KeyMap.Add(EKeys::R, ImGuiKey_R); - KeyMap.Add(EKeys::S, ImGuiKey_S); - KeyMap.Add(EKeys::T, ImGuiKey_T); - KeyMap.Add(EKeys::U, ImGuiKey_U); - KeyMap.Add(EKeys::V, ImGuiKey_V); - KeyMap.Add(EKeys::W, ImGuiKey_W); - KeyMap.Add(EKeys::X, ImGuiKey_X); - KeyMap.Add(EKeys::Y, ImGuiKey_Y); - KeyMap.Add(EKeys::Z, ImGuiKey_Z); - - KeyMap.Add(EKeys::NumPadZero, ImGuiKey_Keypad0); - KeyMap.Add(EKeys::NumPadOne, ImGuiKey_Keypad1); - KeyMap.Add(EKeys::NumPadTwo, ImGuiKey_Keypad2); - KeyMap.Add(EKeys::NumPadThree, ImGuiKey_Keypad3); - KeyMap.Add(EKeys::NumPadFour, ImGuiKey_Keypad4); - KeyMap.Add(EKeys::NumPadFive, ImGuiKey_Keypad5); - KeyMap.Add(EKeys::NumPadSix, ImGuiKey_Keypad6); - KeyMap.Add(EKeys::NumPadSeven, ImGuiKey_Keypad7); - KeyMap.Add(EKeys::NumPadEight, ImGuiKey_Keypad8); - KeyMap.Add(EKeys::NumPadNine, ImGuiKey_Keypad9); - - KeyMap.Add(EKeys::Multiply, ImGuiKey_KeypadMultiply); - KeyMap.Add(EKeys::Add, ImGuiKey_KeypadAdd); - KeyMap.Add(EKeys::Subtract, ImGuiKey_KeypadSubtract); - KeyMap.Add(EKeys::Decimal, ImGuiKey_KeypadDecimal); - KeyMap.Add(EKeys::Divide, ImGuiKey_KeypadDivide); - - KeyMap.Add(EKeys::F1, ImGuiKey_F1); - KeyMap.Add(EKeys::F2, ImGuiKey_F2); - KeyMap.Add(EKeys::F3, ImGuiKey_F3); - KeyMap.Add(EKeys::F4, ImGuiKey_F4); - KeyMap.Add(EKeys::F5, ImGuiKey_F5); - KeyMap.Add(EKeys::F6, ImGuiKey_F6); - KeyMap.Add(EKeys::F7, ImGuiKey_F7); - KeyMap.Add(EKeys::F8, ImGuiKey_F8); - KeyMap.Add(EKeys::F9, ImGuiKey_F9); - KeyMap.Add(EKeys::F10, ImGuiKey_F10); - KeyMap.Add(EKeys::F11, ImGuiKey_F11); - KeyMap.Add(EKeys::F12, ImGuiKey_F12); - - KeyMap.Add(EKeys::NumLock, ImGuiKey_NumLock); - - KeyMap.Add(EKeys::ScrollLock, ImGuiKey_ScrollLock); - - KeyMap.Add(EKeys::LeftShift, ImGuiKey_LeftShift); - KeyMap.Add(EKeys::RightShift, ImGuiKey_RightShift); - KeyMap.Add(EKeys::LeftControl, ImGuiKey_LeftCtrl); - KeyMap.Add(EKeys::RightControl, ImGuiKey_RightCtrl); - KeyMap.Add(EKeys::LeftAlt, ImGuiKey_LeftAlt); - KeyMap.Add(EKeys::RightAlt, ImGuiKey_RightAlt); - KeyMap.Add(EKeys::LeftCommand, ImGuiKey_LeftSuper); - KeyMap.Add(EKeys::RightCommand, ImGuiKey_RightSuper); - - KeyMap.Add(EKeys::Semicolon, ImGuiKey_Semicolon); - KeyMap.Add(EKeys::Equals, ImGuiKey_Equal); - KeyMap.Add(EKeys::Comma, ImGuiKey_Comma); - KeyMap.Add(EKeys::Hyphen, ImGuiKey_Minus); - KeyMap.Add(EKeys::Period, ImGuiKey_Period); - KeyMap.Add(EKeys::Slash, ImGuiKey_Slash); - - KeyMap.Add(EKeys::LeftBracket, ImGuiKey_LeftBracket); - KeyMap.Add(EKeys::Backslash, ImGuiKey_Backslash); - KeyMap.Add(EKeys::RightBracket, ImGuiKey_RightBracket); - KeyMap.Add(EKeys::Apostrophe, ImGuiKey_Apostrophe); - - //KeyMap.Add(EKeys::MouseX, ImGuiKey_None; - //KeyMap.Add(EKeys::MouseY, ImGuiKey_None; - //KeyMap.Add(EKeys::Mouse2D, ImGuiKey_None; - //KeyMap.Add(EKeys::MouseScrollUp, ImGuiKey_None; - //KeyMap.Add(EKeys::MouseScrollDown, ImGuiKey_None; - //KeyMap.Add(EKeys::MouseWheelAxis, ImGuiKey_None; - //KeyMap.Add(EKeys::Underscore, ImGuiKey_None; - //KeyMap.Add(EKeys::Tilde, ImGuiKey_None; - //KeyMap.Add(EKeys::Ampersand, ImGuiKey_None; - //KeyMap.Add(EKeys::Asterix, ImGuiKey_None; - //KeyMap.Add(EKeys::Caret, ImGuiKey_None; - //KeyMap.Add(EKeys::Colon, ImGuiKey_None; - //KeyMap.Add(EKeys::Dollar, ImGuiKey_None; - //KeyMap.Add(EKeys::Exclamation, ImGuiKey_None; - //KeyMap.Add(EKeys::LeftParantheses, ImGuiKey_None; - //KeyMap.Add(EKeys::RightParantheses, ImGuiKey_None; - //KeyMap.Add(EKeys::Quote, ImGuiKey_None; -} - //-------------------------------------------------------------------------------------------------------------------------- FString FCogImguiInputHelper::CommandToString(const UWorld& World, const FString& Command) { diff --git a/Plugins/Cog/Source/CogImgui/Private/CogImguiWidget.cpp b/Plugins/Cog/Source/CogImgui/Private/CogImguiWidget.cpp index d596e13..75c1c5a 100644 --- a/Plugins/Cog/Source/CogImgui/Private/CogImguiWidget.cpp +++ b/Plugins/Cog/Source/CogImgui/Private/CogImguiWidget.cpp @@ -51,18 +51,24 @@ void SCogImguiWidget::Construct(const FArguments& InArgs) //-------------------------------------------------------------------- // Register input processor to forward input events to imgui //-------------------------------------------------------------------- - UPlayerInput* PlayerInput = FCogImguiInputHelper::GetPlayerInput(*GameViewport->GetWorld()); - InputProcessor = MakeShared(PlayerInput, this); - FSlateApplication::Get().RegisterInputPreProcessor(InputProcessor.ToSharedRef(), 0); + if (FSlateApplication::IsInitialized()) + { + UPlayerInput* PlayerInput = FCogImguiInputHelper::GetPlayerInput(*GameViewport->GetWorld()); + InputProcessor = MakeShared(PlayerInput, this); + FSlateApplication::Get().RegisterInputPreProcessor(InputProcessor.ToSharedRef(), 0); + } } END_SLATE_FUNCTION_BUILD_OPTIMIZATION //-------------------------------------------------------------------------------------------------------------------------- SCogImguiWidget::~SCogImguiWidget() { - if (InputProcessor.IsValid()) + if (FSlateApplication::IsInitialized()) { - FSlateApplication::Get().UnregisterInputPreProcessor(InputProcessor); + if (InputProcessor.IsValid()) + { + FSlateApplication::Get().UnregisterInputPreProcessor(InputProcessor); + } } DestroyImGuiContext(); diff --git a/Plugins/Cog/Source/CogImgui/Public/CogImguiInputHelper.h b/Plugins/Cog/Source/CogImgui/Public/CogImguiInputHelper.h index 332838a..8d92a79 100644 --- a/Plugins/Cog/Source/CogImgui/Public/CogImguiInputHelper.h +++ b/Plugins/Cog/Source/CogImgui/Public/CogImguiInputHelper.h @@ -38,8 +38,6 @@ public: static bool IsStopPlaySessionEvent(const FKeyEvent& KeyEvent); - static ImGuiKey KeyEventToImGuiKey(const FKeyEvent& KeyEvent); - static uint32 MouseButtonToImGuiMouseButton(const FKey& MouseButton); static EMouseCursor::Type ToSlateMouseCursor(ImGuiMouseCursor MouseCursor); @@ -55,8 +53,4 @@ public: { return static_cast(Char); } - - static void InitializeKeyMap(); - - static TMap KeyMap; }; diff --git a/Plugins/Cog/Source/CogImgui/Public/CogImguiWidget.h b/Plugins/Cog/Source/CogImgui/Public/CogImguiWidget.h index 8551400..fdd5668 100644 --- a/Plugins/Cog/Source/CogImgui/Public/CogImguiWidget.h +++ b/Plugins/Cog/Source/CogImgui/Public/CogImguiWidget.h @@ -96,7 +96,7 @@ protected: bool bEnableInput = false; - bool bShareMouse = false; + bool bShareMouse = true; FSlateRenderTransform ImGuiRenderTransform; diff --git a/Plugins/Cog/Source/CogWindow/Private/CogWindowManager.cpp b/Plugins/Cog/Source/CogWindow/Private/CogWindowManager.cpp index 731828f..f102cbc 100644 --- a/Plugins/Cog/Source/CogWindow/Private/CogWindowManager.cpp +++ b/Plugins/Cog/Source/CogWindow/Private/CogWindowManager.cpp @@ -683,11 +683,10 @@ bool UCogWindowManager::RegisterDefaultCommandBindings() UPlayerInput* PlayerInput = FCogImguiInputHelper::GetPlayerInput(*GetWorld()); - AddCommand(PlayerInput, "Cog.ToggleInput", EKeys::Tab); - AddCommand(PlayerInput, "Cog.LoadLayout 1", EKeys::F1); - AddCommand(PlayerInput, "Cog.LoadLayout 2", EKeys::F2); - AddCommand(PlayerInput, "Cog.LoadLayout 3", EKeys::F3); - AddCommand(PlayerInput, "Cog.LoadLayout 4", EKeys::F4); + AddCommand(PlayerInput, "Cog.ToggleInput", EKeys::F1); + AddCommand(PlayerInput, "Cog.LoadLayout 1", EKeys::F2); + AddCommand(PlayerInput, "Cog.LoadLayout 2", EKeys::F3); + AddCommand(PlayerInput, "Cog.LoadLayout 3", EKeys::F4); AddCommand(PlayerInput, "Cog.ToggleSelectionMode", EKeys::F5); SortCommands(PlayerInput); diff --git a/Plugins/Cog/Source/CogWindow/Public/CogWindow_Inputs.h b/Plugins/Cog/Source/CogWindow/Public/CogWindow_Inputs.h index 20b5008..89b15ca 100644 --- a/Plugins/Cog/Source/CogWindow/Public/CogWindow_Inputs.h +++ b/Plugins/Cog/Source/CogWindow/Public/CogWindow_Inputs.h @@ -55,6 +55,6 @@ public: bShareMouse = true; bNavEnableKeyboard = true; bNavEnableGamepad = true; - bNavNoCaptureInput = false; + bNavNoCaptureInput = true; } }; \ No newline at end of file diff --git a/Source/CogSample/CogSample.Build.cs b/Source/CogSample/CogSample.Build.cs index ec5da5c..ae8847d 100644 --- a/Source/CogSample/CogSample.Build.cs +++ b/Source/CogSample/CogSample.Build.cs @@ -14,9 +14,9 @@ public class CogSample : ModuleRules "CoreUObject", "Engine", "EnhancedInput", - "GameplayTasks", "GameplayAbilities", "GameplayTags", + "GameplayTasks", "InputCore", "NetCore", "Niagara", diff --git a/Source/CogSample/CogSamplePlayerController.cpp b/Source/CogSample/CogSamplePlayerController.cpp index c5e3eb1..6c4dccb 100644 --- a/Source/CogSample/CogSamplePlayerController.cpp +++ b/Source/CogSample/CogSamplePlayerController.cpp @@ -15,6 +15,8 @@ #include "CogDebugPlot.h" #include "CogDebugReplicator.h" #include "CogEngineReplicator.h" +#include "Framework/Application/NavigationConfig.h" +#include "Framework/Application/SlateApplication.h" #endif //ENABLE_COG //-------------------------------------------------------------------------------------------------------------------------- diff --git a/TODO.txt b/TODO.txt index a464aaa..7eef99c 100644 --- a/TODO.txt +++ b/TODO.txt @@ -1,6 +1,6 @@ - CogImGui: Add a way to create and override CogImguiwidget - CogImGui: Try to find a global solution to prevent crash when breaking in a blueprint from an imgui action (reset the stack) -- CogImgui: support multi viewports +- CogImgui: Support multi viewports - CogWindow: Add reset window position menu item or reset layout (window can get far away) - CogWindow: Try to remove CogWindow dependency to cogimgui. Should only depends on imgui (currently use setdpiscale of cogimgui) @@ -8,6 +8,7 @@ - CogWindow: Hide menu is not saved anymore - CogWindow: DPI change on mousewheel should be a command with a key bind as the rest. - CogWindow: Add more window help and tooltip on input window and more +- CogWindow: Support loading/saving custom style - CogEngine: More stats in the stats window - CogEngine: Overlay mode of stats. @@ -28,3 +29,6 @@ - CogDebug: Check KismetExecutionMessage for warnings. As an exemple it is used by GEngine::GetWorldFromContextObject. - CogDebug: Rework Thickness and Duration params. + +- CogInput: Add help about usnig CTRL+Drag on the stick to lock them +