diff --git a/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_CommandBindings.cpp b/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_CommandBindings.cpp index c7ab994..f3775a0 100644 --- a/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_CommandBindings.cpp +++ b/Plugins/Cog/Source/CogEngine/Private/CogEngineWindow_CommandBindings.cpp @@ -59,7 +59,7 @@ void FCogEngineWindow_CommandBindings::RenderContent() "[F5] Cog.ToggleSelectionMode\n" )) { - GetOwner()->RegisterDefaultCommands(); + GetOwner()->RegisterDefaultCommandBindings(); } for (FKeyBind& KeyBind : PlayerInput->DebugExecBindings) diff --git a/Plugins/Cog/Source/CogImgui/Private/CogImGuiInputProcessor.cpp b/Plugins/Cog/Source/CogImgui/Private/CogImGuiInputProcessor.cpp new file mode 100644 index 0000000..fd10ab5 --- /dev/null +++ b/Plugins/Cog/Source/CogImgui/Private/CogImGuiInputProcessor.cpp @@ -0,0 +1,487 @@ +#include "CogImguiInputProcessor.h" + +#include "CogImguiHelper.h" +#include "CogImguiInputHelper.h" +#include "CogImguiWidget.h" +#include "GameFramework/InputSettings.h" +#include "GameFramework/PlayerInput.h" +#include "imgui.h" +#include "Slate/SGameLayerManager.h" + +#if WITH_EDITOR +#include "Kismet2/DebuggerCommands.h" +#endif //WITH_EDITOR + +constexpr bool ForwardEvent = false; +constexpr bool TerminateEvent = true; + +//-------------------------------------------------------------------------------------------------------------------------- +FImGuiInputProcessor::FImGuiInputProcessor(UPlayerInput* InPlayerInput, SCogImguiWidget* InMainWidget) +{ + PlayerInput = InPlayerInput; + MainWidget = InMainWidget; +} + +//-------------------------------------------------------------------------------------------------------------------------- +static FVector2D TransformScreenPointToImGui(const FGeometry& MyGeometry, const FVector2D& Point) +{ + const FSlateRenderTransform ImGuiToScreen = MyGeometry.GetAccumulatedRenderTransform(); + return ImGuiToScreen.Inverse().TransformPoint(Point); +} + +//-------------------------------------------------------------------------------------------------------------------------- +void FImGuiInputProcessor::Tick(const float DeltaTime, FSlateApplication& SlateApp, TSharedRef SlateCursor) +{ + ImGuiIO& IO = ImGui::GetIO(); + + const bool bHasGamepad = (IO.BackendFlags & ImGuiBackendFlags_HasGamepad); + if (bHasGamepad != SlateApp.IsGamepadAttached()) + { + IO.BackendFlags ^= ImGuiBackendFlags_HasGamepad; + UE_LOG(LogCogImGui, VeryVerbose, TEXT("FImGuiInputProcessor::Tick | HasGamePad Changed")); + } + + if (IO.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + { + const FVector2D MousePosition = SlateApp.GetCursorPos(); + IO.AddMousePosEvent(MousePosition.X, MousePosition.Y); + } + else + { + const FVector2D MousePosition = TransformScreenPointToImGui(MainWidget->GetTickSpaceGeometry(), SlateApp.GetCursorPos()); + IO.AddMousePosEvent(MousePosition.X, MousePosition.Y); + } + + if ((IO.ConfigFlags & ImGuiConfigFlags_NoMouse) == 0) + { + SlateCursor->SetType(FCogImguiInputHelper::ToSlateMouseCursor(ImGui::GetMouseCursor())); + } + + if (IO.WantSetMousePos) + { + SlateApp.SetCursorPos(FCogImguiHelper::ToVector2D(IO.MousePos)); + //UE_LOG(LogCogImGui, VeryVerbose, TEXT("FImGuiInputProcessor::Tick | SetCursorPos")); + } +} + +//-------------------------------------------------------------------------------------------------------------------------- +bool FImGuiInputProcessor::HandleKeyDownEvent(FSlateApplication& SlateApp, const FKeyEvent& Event) +{ + return HandleKeyEvent(SlateApp, Event, true); +} + +//-------------------------------------------------------------------------------------------------------------------------- +bool FImGuiInputProcessor::HandleKeyUpEvent(FSlateApplication& SlateApp, const FKeyEvent& Event) +{ + return HandleKeyEvent(SlateApp, Event, false); +} + +//-------------------------------------------------------------------------------------------------------------------------- +bool FImGuiInputProcessor::HandleKeyEvent(FSlateApplication& SlateApp, const FKeyEvent& Event, bool IsKeyDown) +{ + //------------------------------------------------------------------------------------------------ + // We want the user to be able to open the console command when imgui has the input. + //------------------------------------------------------------------------------------------------ + if (IsConsoleEvent(Event)) + { + const bool Result = ForwardEvent; + UE_LOG(LogCogImGui, VeryVerbose, TEXT("FImGuiInputProcessor::HandleKeyEvent | Key:%s | IsKeyDown:%d | TerminateEvent:%d | ConsoleEvent"), *Event.GetKey().ToString(), IsKeyDown, Result); + return Result; + } + + //------------------------------------------------------------------------------------------------ + // We want the user to be able to stop its session by pressing Esc, even when imgui has the input + //------------------------------------------------------------------------------------------------ + if (IsStopPlaySessionEvent(Event)) + { + const bool Result = ForwardEvent; + UE_LOG(LogCogImGui, VeryVerbose, TEXT("FImGuiInputProcessor::HandleKeyEvent | Key:%s | IsKeyDown:%d | TerminateEvent:%d | StopPlaySessionEvent"), *Event.GetKey().ToString(), IsKeyDown, Result); + return Result; + } + + //------------------------------------------------------------------------------------------------ + // We want the user to be able to use command bingings, even when imgui has the input. + // We actually use a console command to toggle the input from the game to imgui, and other + // windows command such as LoadLayout. + //------------------------------------------------------------------------------------------------ + if (IsKeyBoundToCommand(Event)) + { + const bool Result = ForwardEvent; + UE_LOG(LogCogImGui, VeryVerbose, TEXT("FImGuiInputProcessor::HandleKeyEvent | Key:%s | IsKeyDown:%d | TerminateEvent:%d | KeyBoundToCommand"), *Event.GetKey().ToString(), IsKeyDown, Result); + return Result; + } + + ImGuiIO& IO = ImGui::GetIO(); + + IO.AddKeyEvent(ToImKey(Event.GetKey()), IsKeyDown); + + const FModifierKeysState& ModifierKeys = Event.GetModifierKeys(); + IO.AddKeyEvent(ImGuiMod_Ctrl, ModifierKeys.IsControlDown()); + IO.AddKeyEvent(ImGuiMod_Shift, ModifierKeys.IsShiftDown()); + IO.AddKeyEvent(ImGuiMod_Alt, ModifierKeys.IsAltDown()); + IO.AddKeyEvent(ImGuiMod_Super, ModifierKeys.IsCommandDown()); + + //------------------------------------------------------------------------------------------------ + // If we receive a key modifier, we want to let others systems know about it. + // Otherwise, the console command bindings that are bound to something like CTRL+Key + // won't work, even if we let the KeyEvent pass with 'IsKeyBoundToCommand' below. + // It seems the command binings system needs to know about the modifier key press event itself, + // and not the Key+Modifier event. + //------------------------------------------------------------------------------------------------ + const bool IsModifierKey = Event.GetKey().IsModifierKey(); + if (IsModifierKey) + { + const bool Result = ForwardEvent; + UE_LOG(LogCogImGui, VeryVerbose, TEXT("FImGuiInputProcessor::HandleKeyEvent | Key:%s | IsKeyDown:%d | TerminateEvent:%d | IsModifierKey"), *Event.GetKey().ToString(), IsKeyDown, Result); + return Result; + } + + if (Event.GetKey().IsGamepadKey()) + { + if (IO.WantCaptureKeyboard && (IO.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad)) + { + const bool Result = TerminateEvent; + UE_LOG(LogCogImGui, VeryVerbose, TEXT("FImGuiInputProcessor::HandleKeyEvent | Key:%s | IsKeyDown:%d | TerminateEvent:%d | NavEnableGamepad"), *Event.GetKey().ToString(), IsKeyDown, Result); + return Result; + } + } + + const bool Result = IO.WantCaptureKeyboard ? TerminateEvent : ForwardEvent; + UE_LOG(LogCogImGui, VeryVerbose, TEXT("FImGuiInputProcessor::HandleKeyEvent | Key:%s | IsKeyDown:%d | WantCaptureKeyboard:%d | TerminateEvent:%d"), *Event.GetKey().ToString(), IsKeyDown, IO.WantCaptureKeyboard, Result); + return Result; +} + +//-------------------------------------------------------------------------------------------------------------------------- +bool FImGuiInputProcessor::HandleAnalogInputEvent(FSlateApplication& SlateApp, const FAnalogInputEvent& Event) +{ + const float Value = Event.GetAnalogValue(); + + ImGuiIO& IO = ImGui::GetIO(); + IO.AddKeyAnalogEvent(ToImKey(Event.GetKey()), FMath::Abs(Value) > 0.0f, Value); + + if (Event.GetKey().IsGamepadKey()) + { + if (IO.WantCaptureKeyboard && (IO.ConfigFlags & ImGuiConfigFlags_NavEnableGamepad)) + { + return TerminateEvent; + } + + return ForwardEvent; + } + else + { + if (IO.WantCaptureKeyboard) + { + return TerminateEvent; + } + + return ForwardEvent; + } +} + +//-------------------------------------------------------------------------------------------------------------------------- +bool FImGuiInputProcessor::HandleMouseMoveEvent(FSlateApplication& SlateApp, const FPointerEvent& Event) +{ + ImGuiIO& IO = ImGui::GetIO(); + + if (IO.ConfigFlags & ImGuiConfigFlags_ViewportsEnable) + { + const FVector2D MousePosition = Event.GetScreenSpacePosition();; + IO.AddMousePosEvent(MousePosition.X, MousePosition.Y); + } + else + { + const FVector2D MousePosition = TransformScreenPointToImGui(MainWidget->GetTickSpaceGeometry(), Event.GetScreenSpacePosition()); + IO.AddMousePosEvent(MousePosition.X, MousePosition.Y); + } + + if (MainWidget->GetEnableInput() && MainWidget->GetShareMouse() == false) + { + return TerminateEvent; + } + + const bool Result = IO.WantCaptureMouse ? TerminateEvent : ForwardEvent; + return Result; +} + +//-------------------------------------------------------------------------------------------------------------------------- +bool FImGuiInputProcessor::HandleMouseButtonDownEvent(FSlateApplication& SlateApp, const FPointerEvent& Event) +{ + return HandleMouseButtonEvent(SlateApp, Event, true); +} + +//-------------------------------------------------------------------------------------------------------------------------- +bool FImGuiInputProcessor::HandleMouseButtonUpEvent(FSlateApplication& SlateApp, const FPointerEvent& Event) +{ + return HandleMouseButtonEvent(SlateApp, Event, false); +} + +//-------------------------------------------------------------------------------------------------------------------------- +bool FImGuiInputProcessor::HandleMouseButtonDoubleClickEvent(FSlateApplication& SlateApp, const FPointerEvent& Event) +{ + return HandleMouseButtonEvent(SlateApp, Event, true); +} + +//-------------------------------------------------------------------------------------------------------------------------- +bool FImGuiInputProcessor::HandleMouseButtonEvent(FSlateApplication& SlateApp, const FPointerEvent& Event, bool IsButtonDown) +{ + ImGuiIO& IO = ImGui::GetIO(); + + const uint32 Button = ToImGuiMouseButton(Event.GetEffectingButton()); + IO.AddMouseButtonEvent(Button, IsButtonDown); + + if (MainWidget->GetEnableInput() && MainWidget->GetShareMouse() == false) + { + const bool Result = TerminateEvent; + UE_LOG(LogCogImGui, VeryVerbose, TEXT("FImGuiInputProcessor::HandleMouseButtonEvent | Button:%d | IsButtonDown:%d | WantCaptureMouse:%d | TerminateEvent:%d | ShareMouse == false"), Button, IsButtonDown, IO.WantCaptureMouse, Result); + return Result; + } + + const bool Result = IO.WantCaptureMouse ? TerminateEvent : ForwardEvent; + UE_LOG(LogCogImGui, VeryVerbose, TEXT("FImGuiInputProcessor::HandleMouseButtonEvent | Button:%d | IsButtonDown:%d | WantCaptureMouse:%d | TerminateEvent:%d"), Button, IsButtonDown, IO.WantCaptureMouse, Result); + return Result; +} + +//-------------------------------------------------------------------------------------------------------------------------- +bool FImGuiInputProcessor::HandleMouseWheelOrGestureEvent(FSlateApplication& SlateApp, const FPointerEvent& Event, const FPointerEvent* GestureEvent) +{ + ImGuiIO& IO = ImGui::GetIO(); + + IO.AddMouseWheelEvent(0.0f, Event.GetWheelDelta()); + + return IO.WantCaptureMouse; +} + +//-------------------------------------------------------------------------------------------------------------------------- +bool FImGuiInputProcessor::IsKeyEventMatchingKeyBind(const FKeyEvent& KeyEvent, const FKeyBind& KeyBind) +{ + if (KeyBind.bDisabled) + { + return false; + } + + if (KeyBind.Key != KeyEvent.GetKey()) + { + return false; + } + + const bool bControlPressed = KeyEvent.IsControlDown(); + const bool bShiftPressed = KeyEvent.IsShiftDown(); + const bool bAltPressed = KeyEvent.IsAltDown(); + const bool bCmdPressed = KeyEvent.IsCommandDown(); + + if ((!KeyBind.Control || bControlPressed) + && (!KeyBind.Shift || bShiftPressed) + && (!KeyBind.Alt || bAltPressed) + && (!KeyBind.Cmd || bCmdPressed) + && (!KeyBind.bIgnoreCtrl || !bControlPressed) + && (!KeyBind.bIgnoreShift || !bShiftPressed) + && (!KeyBind.bIgnoreAlt || !bAltPressed) + && (!KeyBind.bIgnoreCmd || !bCmdPressed)) + { + return true; + } + + return false; +} + +//-------------------------------------------------------------------------------------------------------------------------- +bool FImGuiInputProcessor::IsKeyBoundToCommand(const FKeyEvent& KeyEvent) +{ + if (PlayerInput == nullptr) + { + return false; + } + + for (const FKeyBind& KeyBind : PlayerInput->DebugExecBindings) + { + if (IsKeyEventMatchingKeyBind(KeyEvent, KeyBind)) + { + return true; + } + } + + return false; +} + +//-------------------------------------------------------------------------------------------------------------------------- +bool FImGuiInputProcessor::IsConsoleEvent(const FKeyEvent& KeyEvent) +{ + const bool bModifierDown = KeyEvent.IsControlDown() || KeyEvent.IsShiftDown() || KeyEvent.IsAltDown() || KeyEvent.IsCommandDown(); + const bool Result = !bModifierDown && GetDefault()->ConsoleKeys.Contains(KeyEvent.GetKey()); + return Result; +} + +//-------------------------------------------------------------------------------------------------------------------------- +bool FImGuiInputProcessor::IsStopPlaySessionEvent(const FKeyEvent& KeyEvent) +{ +#if WITH_EDITOR + static TSharedPtr StopPlaySessionCommandInfo = FInputBindingManager::Get().FindCommandInContext("PlayWorld", "StopPlaySession"); + + if (StopPlaySessionCommandInfo.IsValid()) + { + const FInputChord InputChord(KeyEvent.GetKey(), KeyEvent.IsShiftDown(), KeyEvent.IsControlDown(), KeyEvent.IsAltDown(), KeyEvent.IsCommandDown()); + const bool bHasActiveChord = StopPlaySessionCommandInfo->HasActiveChord(InputChord); + return bHasActiveChord && FPlayWorldCommands::GlobalPlayWorldActions->CanExecuteAction(StopPlaySessionCommandInfo.ToSharedRef()); + } +#endif // WITH_EDITOR + + return false; +} + +//-------------------------------------------------------------------------------------------------------------------------- +uint32 FImGuiInputProcessor::ToImGuiMouseButton(const FKey& MouseButton) +{ + if (MouseButton == EKeys::LeftMouseButton) { return 0; } + if (MouseButton == EKeys::RightMouseButton) { return 1; } + if (MouseButton == EKeys::MiddleMouseButton) { return 2; } + if (MouseButton == EKeys::ThumbMouseButton) { return 3; } + if (MouseButton == EKeys::ThumbMouseButton2) { return 4; } + + return -1; +} + +//-------------------------------------------------------------------------------------------------------------------------- +ImGuiKey FImGuiInputProcessor::ToImKey(const FKey& Key) +{ + static const TMap LookupMap = { + { EKeys::Tab, ImGuiKey_Tab }, + + { EKeys::Left, ImGuiKey_LeftArrow }, + { EKeys::Right, ImGuiKey_RightArrow }, + { EKeys::Up, ImGuiKey_UpArrow }, + { EKeys::Down, ImGuiKey_DownArrow }, + + { EKeys::PageUp, ImGuiKey_PageUp }, + { EKeys::PageDown, ImGuiKey_PageDown }, + { EKeys::Home, ImGuiKey_Home }, + { EKeys::End, ImGuiKey_End }, + { EKeys::Insert, ImGuiKey_Insert }, + { EKeys::Delete, ImGuiKey_Delete }, + + { EKeys::BackSpace, ImGuiKey_Backspace }, + { EKeys::SpaceBar, ImGuiKey_Space }, + { EKeys::Enter, ImGuiKey_Enter }, + { EKeys::Escape, ImGuiKey_Escape }, + + { EKeys::LeftControl, ImGuiKey_LeftCtrl }, + { EKeys::LeftShift, ImGuiKey_LeftShift }, + { EKeys::LeftAlt, ImGuiKey_LeftAlt }, + { EKeys::LeftCommand, ImGuiKey_LeftSuper }, + { EKeys::RightControl, ImGuiKey_RightCtrl }, + { EKeys::RightShift, ImGuiKey_RightShift }, + { EKeys::RightAlt, ImGuiKey_RightAlt }, + { EKeys::RightCommand, ImGuiKey_RightSuper }, + + { EKeys::Zero, ImGuiKey_0 }, + { EKeys::One, ImGuiKey_1 }, + { EKeys::Two, ImGuiKey_2 }, + { EKeys::Three, ImGuiKey_3 }, + { EKeys::Four, ImGuiKey_4 }, + { EKeys::Five, ImGuiKey_5 }, + { EKeys::Six, ImGuiKey_6 }, + { EKeys::Seven, ImGuiKey_7 }, + { EKeys::Eight, ImGuiKey_8 }, + { EKeys::Nine, ImGuiKey_9 }, + + { EKeys::A, ImGuiKey_A }, + { EKeys::B, ImGuiKey_B }, + { EKeys::C, ImGuiKey_C }, + { EKeys::D, ImGuiKey_D }, + { EKeys::E, ImGuiKey_E }, + { EKeys::F, ImGuiKey_F }, + { EKeys::G, ImGuiKey_G }, + { EKeys::H, ImGuiKey_H }, + { EKeys::I, ImGuiKey_I }, + { EKeys::J, ImGuiKey_J }, + { EKeys::K, ImGuiKey_K }, + { EKeys::L, ImGuiKey_L }, + { EKeys::M, ImGuiKey_M }, + { EKeys::N, ImGuiKey_N }, + { EKeys::O, ImGuiKey_O }, + { EKeys::P, ImGuiKey_P }, + { EKeys::Q, ImGuiKey_Q }, + { EKeys::R, ImGuiKey_R }, + { EKeys::S, ImGuiKey_S }, + { EKeys::T, ImGuiKey_T }, + { EKeys::U, ImGuiKey_U }, + { EKeys::V, ImGuiKey_V }, + { EKeys::W, ImGuiKey_W }, + { EKeys::X, ImGuiKey_X }, + { EKeys::Y, ImGuiKey_Y }, + { EKeys::Z, ImGuiKey_Z }, + + { EKeys::F1, ImGuiKey_F1 }, + { EKeys::F2, ImGuiKey_F2 }, + { EKeys::F3, ImGuiKey_F3 }, + { EKeys::F4, ImGuiKey_F4 }, + { EKeys::F5, ImGuiKey_F5 }, + { EKeys::F6, ImGuiKey_F6 }, + { EKeys::F7, ImGuiKey_F7 }, + { EKeys::F8, ImGuiKey_F8 }, + { EKeys::F9, ImGuiKey_F9 }, + { EKeys::F10, ImGuiKey_F10 }, + { EKeys::F11, ImGuiKey_F11 }, + { EKeys::F12, ImGuiKey_F12 }, + + { EKeys::Apostrophe, ImGuiKey_Apostrophe }, + { EKeys::Comma, ImGuiKey_Comma }, + { EKeys::Period, ImGuiKey_Period }, + { EKeys::Slash, ImGuiKey_Slash }, + { EKeys::Semicolon, ImGuiKey_Semicolon }, + { EKeys::LeftBracket, ImGuiKey_LeftBracket }, + { EKeys::Backslash, ImGuiKey_Backslash }, + { EKeys::RightBracket, ImGuiKey_RightBracket }, + + { EKeys::CapsLock, ImGuiKey_CapsLock }, + { EKeys::ScrollLock, ImGuiKey_ScrollLock }, + { EKeys::NumLock, ImGuiKey_NumLock }, + { EKeys::Pause, ImGuiKey_Pause }, + + { EKeys::NumPadZero, ImGuiKey_Keypad0 }, + { EKeys::NumPadOne, ImGuiKey_Keypad1 }, + { EKeys::NumPadTwo, ImGuiKey_Keypad2 }, + { EKeys::NumPadThree, ImGuiKey_Keypad3 }, + { EKeys::NumPadFour, ImGuiKey_Keypad4 }, + { EKeys::NumPadFive, ImGuiKey_Keypad5 }, + { EKeys::NumPadSix, ImGuiKey_Keypad6 }, + { EKeys::NumPadSeven, ImGuiKey_Keypad7 }, + { EKeys::NumPadEight, ImGuiKey_Keypad8 }, + { EKeys::NumPadNine, ImGuiKey_Keypad9 }, + + { EKeys::Decimal, ImGuiKey_KeypadDecimal }, + { EKeys::Divide, ImGuiKey_KeypadDivide }, + { EKeys::Multiply, ImGuiKey_KeypadMultiply }, + { EKeys::Subtract, ImGuiKey_KeypadSubtract }, + { EKeys::Add, ImGuiKey_KeypadAdd }, + { EKeys::Equals, ImGuiKey_KeypadEqual }, + + { EKeys::Gamepad_Special_Right, ImGuiKey_GamepadStart }, + { EKeys::Gamepad_Special_Left, ImGuiKey_GamepadBack }, + { EKeys::Gamepad_FaceButton_Left, ImGuiKey_GamepadFaceLeft }, + { EKeys::Gamepad_FaceButton_Right, ImGuiKey_GamepadFaceRight }, + { EKeys::Gamepad_FaceButton_Top, ImGuiKey_GamepadFaceUp }, + { EKeys::Gamepad_FaceButton_Bottom, ImGuiKey_GamepadFaceDown }, + { EKeys::Gamepad_DPad_Left, ImGuiKey_GamepadDpadLeft }, + { EKeys::Gamepad_DPad_Right, ImGuiKey_GamepadDpadRight }, + { EKeys::Gamepad_DPad_Up, ImGuiKey_GamepadDpadUp }, + { EKeys::Gamepad_DPad_Down, ImGuiKey_GamepadDpadDown }, + { EKeys::Gamepad_LeftShoulder, ImGuiKey_GamepadL1 }, + { EKeys::Gamepad_RightShoulder, ImGuiKey_GamepadR1 }, + { EKeys::Gamepad_LeftTrigger, ImGuiKey_GamepadL2 }, + { EKeys::Gamepad_RightTrigger, ImGuiKey_GamepadR2 }, + { EKeys::Gamepad_LeftThumbstick, ImGuiKey_GamepadL3 }, + { EKeys::Gamepad_RightThumbstick, ImGuiKey_GamepadR3 }, + { EKeys::Gamepad_LeftStick_Left, ImGuiKey_GamepadLStickLeft }, + { EKeys::Gamepad_LeftStick_Right, ImGuiKey_GamepadLStickRight }, + { EKeys::Gamepad_LeftStick_Up, ImGuiKey_GamepadLStickUp }, + { EKeys::Gamepad_LeftStick_Down, ImGuiKey_GamepadLStickDown }, + { EKeys::Gamepad_RightStick_Left, ImGuiKey_GamepadRStickLeft }, + { EKeys::Gamepad_RightStick_Right, ImGuiKey_GamepadRStickRight }, + { EKeys::Gamepad_RightStick_Up, ImGuiKey_GamepadRStickUp }, + { EKeys::Gamepad_RightStick_Down, ImGuiKey_GamepadRStickDown } + }; + + const ImGuiKey* Result = LookupMap.Find(Key); + return (Result != nullptr) ? *Result : ImGuiKey_None; +} diff --git a/Plugins/Cog/Source/CogImgui/Private/CogImguiHelper.cpp b/Plugins/Cog/Source/CogImgui/Private/CogImguiHelper.cpp index 2d7a29c..4cb08cf 100644 --- a/Plugins/Cog/Source/CogImgui/Private/CogImguiHelper.cpp +++ b/Plugins/Cog/Source/CogImgui/Private/CogImguiHelper.cpp @@ -3,6 +3,8 @@ #include "InputCoreTypes.h" #include "imgui_internal.h" +DEFINE_LOG_CATEGORY(LogCogImGui); + //---------------------------------------------------------------------------------------------------------------------- FString FCogImguiHelper::GetIniSaveDirectory() { @@ -124,3 +126,16 @@ FSlateRenderTransform FCogImguiHelper::RoundTranslation(const FSlateRenderTransf { return FSlateRenderTransform(Transform.GetMatrix(), RoundVector(Transform.GetTranslation())); } + +//-------------------------------------------------------------------------------------------------------------------------- +void FCogImguiHelper::SetFlags(int32& Value, int32 Flags, bool EnableFlags) +{ + if (EnableFlags) + { + Value |= Flags; + } + else + { + Value &= ~Flags; + } +} \ No newline at end of file diff --git a/Plugins/Cog/Source/CogImgui/Private/CogImguiWidget.cpp b/Plugins/Cog/Source/CogImgui/Private/CogImguiWidget.cpp index 11b5cdd..d596e13 100644 --- a/Plugins/Cog/Source/CogImgui/Private/CogImguiWidget.cpp +++ b/Plugins/Cog/Source/CogImgui/Private/CogImguiWidget.cpp @@ -2,6 +2,7 @@ #include "CogImguiInputHelper.h" #include "CogImguiInputHelper.h" +#include "CogImGuiInputProcessor.h" #include "CogImguiModule.h" #include "CogImguiModule.h" #include "CogImguiTextureManager.h" @@ -30,7 +31,7 @@ void SCogImguiWidget::Construct(const FArguments& InArgs) FontAtlas = InArgs._FontAtlas; Render = InArgs._Render; - RefreshVisibility(); + SetVisibility(EVisibility::SelfHitTestInvisible); ImGuiContext = ImGui::CreateContext(FontAtlas); ImPlotContext = ImPlot::CreateContext(); @@ -43,12 +44,27 @@ void SCogImguiWidget::Construct(const FArguments& InArgs) IO.IniFilename = IniFilename; IO.DisplaySize = ImVec2(100, 100); IO.ConfigFlags |= ImGuiConfigFlags_DockingEnable; + IO.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; + IO.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; + IO.ConfigFlags |= ImGuiConfigFlags_NavNoCaptureKeyboard; + + //-------------------------------------------------------------------- + // 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); } END_SLATE_FUNCTION_BUILD_OPTIMIZATION //-------------------------------------------------------------------------------------------------------------------------- SCogImguiWidget::~SCogImguiWidget() { + if (InputProcessor.IsValid()) + { + FSlateApplication::Get().UnregisterInputPreProcessor(InputProcessor); + } + DestroyImGuiContext(); } @@ -76,6 +92,20 @@ void SCogImguiWidget::Tick(const FGeometry& AllottedGeometry, const double InCur TickKeyModifiers(); TickFocus(); TickImGui(InDeltaTime); + + //ImGuiIO& IO = ImGui::GetIO(); + //if (GetEnableInput()) + //{ + // IO.ConfigFlags &= ~ImGuiConfigFlags_NoMouse; + // IO.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; + // IO.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; + //} + //else + //{ + // IO.ConfigFlags |= ImGuiConfigFlags_NoMouse; + // IO.ConfigFlags &= ~ImGuiConfigFlags_NavEnableKeyboard; + // IO.ConfigFlags &= ~ImGuiConfigFlags_NavEnableGamepad; + //} } //-------------------------------------------------------------------------------------------------------------------------- @@ -116,7 +146,10 @@ void SCogImguiWidget::TickImGui(float InDeltaTime) Render(InDeltaTime); ImGui::Render(); - SetCursor(FCogImguiInputHelper::ToSlateMouseCursor(ImGui::GetMouseCursor())); + if ((IO.ConfigFlags & ImGuiConfigFlags_NoMouse) == 0) + { + SetCursor(FCogImguiInputHelper::ToSlateMouseCursor(ImGui::GetMouseCursor())); + } ImDrawData* DrawData = ImGui::GetDrawData(); if (DrawData && DrawData->CmdListsCount > 0) @@ -297,11 +330,6 @@ void SCogImguiWidget::SetAsCurrentContext() //-------------------------------------------------------------------------------------------------------------------------- void SCogImguiWidget::SetEnableInput(bool Value) { - if (bEnableInput == Value) - { - return; - } - bEnableInput = Value; if (bEnableInput) @@ -313,19 +341,14 @@ void SCogImguiWidget::SetEnableInput(bool Value) ReturnFocus(); } - RefreshVisibility(); -} - -//-------------------------------------------------------------------------------------------------------------------------- -void SCogImguiWidget::RefreshVisibility() -{ + ImGuiIO& IO = ImGui::GetIO(); if (bEnableInput) { - SetVisibility(EVisibility::Visible); + IO.ConfigFlags &= ~ImGuiConfigFlags_NoMouse; } else { - SetVisibility(EVisibility::SelfHitTestInvisible); + IO.ConfigFlags |= ImGuiConfigFlags_NoMouse; } } @@ -366,156 +389,6 @@ void SCogImguiWidget::OnDpiChanged() NewStyle.ScaleAllSizes(DpiScale); } - -//-------------------------------------------------------------------------------------------------------------------------- -FReply SCogImguiWidget::OnKeyChar(const FGeometry& MyGeometry, const FCharacterEvent& CharacterEvent) -{ - if (bEnableInput == false) - { - ImGui::GetIO().AddInputCharacter(FCogImguiInputHelper::CastInputChar(CharacterEvent.GetCharacter())); - } - - if (bShareKeyboard) - { - return FReply::Unhandled(); - } - - return FReply::Handled(); -} - -//-------------------------------------------------------------------------------------------------------------------------- -FReply SCogImguiWidget::OnKeyDown(const FGeometry& MyGeometry, const FKeyEvent& KeyEvent) -{ - return HandleKeyEvent(MyGeometry, KeyEvent); -} - -//-------------------------------------------------------------------------------------------------------------------------- -FReply SCogImguiWidget::OnKeyUp(const FGeometry& MyGeometry, const FKeyEvent& KeyEvent) -{ - return HandleKeyEvent(MyGeometry, KeyEvent); -} - -//-------------------------------------------------------------------------------------------------------------------------- -FReply SCogImguiWidget::HandleKeyEvent(const FGeometry& MyGeometry, const FKeyEvent& KeyEvent) -{ - if (bEnableInput == false) - { - return FReply::Unhandled(); - } - - if (KeyEvent.GetKey().IsGamepadKey()) - { - if (bShareGamepad) - { - // TODO: handle imgui gamepad - return FReply::Unhandled(); - } - } - else - { - if (FCogImguiInputHelper::IsKeyEventHandled(GameViewport->GetWorld(), KeyEvent) == false) - { - return FReply::Unhandled(); - } - - ImGuiIO& IO = ImGui::GetIO(); - IO.AddKeyEvent(FCogImguiInputHelper::KeyEventToImGuiKey(KeyEvent), false); - IO.AddKeyEvent(ImGuiMod_Ctrl, KeyEvent.IsControlDown()); - IO.AddKeyEvent(ImGuiMod_Shift, KeyEvent.IsShiftDown()); - IO.AddKeyEvent(ImGuiMod_Alt, KeyEvent.IsAltDown()); - IO.AddKeyEvent(ImGuiMod_Super, KeyEvent.IsCommandDown()); - - if (bShareKeyboard) - { - return FReply::Unhandled(); - } - } - - return FReply::Handled(); -} - - -//-------------------------------------------------------------------------------------------------------------------------- -FReply SCogImguiWidget::OnAnalogValueChanged(const FGeometry& MyGeometry, const FAnalogInputEvent& AnalogInputEvent) -{ - if (AnalogInputEvent.GetKey().IsGamepadKey()) - { - if (bShareGamepad) - { - // TODO: handle imgui gamepad - return FReply::Unhandled(); - } - } - else - { - if (bShareKeyboard) - { - return FReply::Unhandled(); - } - } - - return FReply::Handled(); -} - -//-------------------------------------------------------------------------------------------------------------------------- -FReply SCogImguiWidget::OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) -{ - if (bEnableInput == false) - { - return FReply::Unhandled(); - } - - const uint32 MouseButton = FCogImguiInputHelper::MouseButtonToImGuiMouseButton(MouseEvent.GetEffectingButton()); - ImGui::GetIO().AddMouseSourceEvent(ImGuiMouseSource_Mouse); - ImGui::GetIO().AddMouseButtonEvent(MouseButton, true); - - return FReply::Handled(); -} - -//-------------------------------------------------------------------------------------------------------------------------- -FReply SCogImguiWidget::OnMouseButtonUp(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) -{ - if (bEnableInput == false) - { - return FReply::Unhandled(); - } - - const uint32 MouseButton = FCogImguiInputHelper::MouseButtonToImGuiMouseButton(MouseEvent.GetEffectingButton()); - ImGui::GetIO().AddMouseSourceEvent(ImGuiMouseSource_Mouse); - ImGui::GetIO().AddMouseButtonEvent(MouseButton, false); - - return FReply::Handled(); -} - -//-------------------------------------------------------------------------------------------------------------------------- -FReply SCogImguiWidget::OnMouseWheel(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) -{ - if (bEnableInput == false) - { - return FReply::Unhandled(); - } - - ImGui::GetIO().AddMouseSourceEvent(ImGuiMouseSource_Mouse); - ImGui::GetIO().AddMouseWheelEvent(0, MouseEvent.GetWheelDelta()); - - return FReply::Handled(); -} - -//-------------------------------------------------------------------------------------------------------------------------- -FReply SCogImguiWidget::OnMouseMove(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) -{ - if (bEnableInput == false) - { - return FReply::Unhandled(); - } - - ImGui::GetIO().AddMouseSourceEvent(ImGuiMouseSource_Mouse); - const FVector2D Pos = TransformScreenPointToImGui(MyGeometry, MouseEvent.GetScreenSpacePosition()); - ImGui::GetIO().AddMousePosEvent(Pos.X, Pos.Y); - - return FReply::Handled(); -} - //-------------------------------------------------------------------------------------------------------------------------- FReply SCogImguiWidget::OnFocusReceived(const FGeometry& MyGeometry, const FFocusEvent& FocusEvent) { @@ -532,37 +405,11 @@ FReply SCogImguiWidget::OnFocusReceived(const FGeometry& MyGeometry, const FFocu } //-------------------------------------------------------------------------------------------------------------------------- -void SCogImguiWidget::OnFocusLost(const FFocusEvent& FocusEvent) +FReply SCogImguiWidget::OnKeyChar(const FGeometry& MyGeometry, const FCharacterEvent& CharacterEvent) { - return Super::OnFocusLost(FocusEvent); -} + ImGuiIO& IO = ImGui::GetIO(); + IO.AddInputCharacter(FCogImguiInputHelper::CastInputChar(CharacterEvent.GetCharacter())); -//-------------------------------------------------------------------------------------------------------------------------- -void SCogImguiWidget::OnMouseEnter(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) -{ - Super::OnMouseEnter(MyGeometry, MouseEvent); + const FReply Result = IO.WantCaptureKeyboard ? FReply::Handled() : FReply::Unhandled(); + return Result; } - -//-------------------------------------------------------------------------------------------------------------------------- -void SCogImguiWidget::OnMouseLeave(const FPointerEvent& MouseEvent) -{ - Super::OnMouseLeave(MouseEvent); -} - -//-------------------------------------------------------------------------------------------------------------------------- -FReply SCogImguiWidget::OnTouchStarted(const FGeometry& MyGeometry, const FPointerEvent& TouchEvent) -{ - return Super::OnTouchStarted(MyGeometry, TouchEvent); -} - -//-------------------------------------------------------------------------------------------------------------------------- -FReply SCogImguiWidget::OnTouchMoved(const FGeometry& MyGeometry, const FPointerEvent& TouchEvent) -{ - return Super::OnTouchMoved(MyGeometry, TouchEvent); -} - -//-------------------------------------------------------------------------------------------------------------------------- -FReply SCogImguiWidget::OnTouchEnded(const FGeometry& MyGeometry, const FPointerEvent& TouchEvent) -{ - return Super::OnTouchEnded(MyGeometry, TouchEvent); -} \ No newline at end of file diff --git a/Plugins/Cog/Source/CogImgui/Public/CogImGuiInputProcessor.h b/Plugins/Cog/Source/CogImgui/Public/CogImGuiInputProcessor.h new file mode 100644 index 0000000..b6d960a --- /dev/null +++ b/Plugins/Cog/Source/CogImgui/Public/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/Public/CogImguiHelper.h b/Plugins/Cog/Source/CogImgui/Public/CogImguiHelper.h index 290813d..858f6e9 100644 --- a/Plugins/Cog/Source/CogImgui/Public/CogImguiHelper.h +++ b/Plugins/Cog/Source/CogImgui/Public/CogImguiHelper.h @@ -4,6 +4,8 @@ #include "imgui.h" #include "Layout/SlateRect.h" +COGIMGUI_API DECLARE_LOG_CATEGORY_EXTERN(LogCogImGui, Warning, All); + struct ImGuiWindow; using CogTextureIndex = int32; @@ -48,4 +50,5 @@ public: static FSlateRenderTransform RoundTranslation(const FSlateRenderTransform& Transform); + static void SetFlags(int32& Value, int32 Flags, bool EnableFlags); }; diff --git a/Plugins/Cog/Source/CogImgui/Public/CogImguiWidget.h b/Plugins/Cog/Source/CogImgui/Public/CogImguiWidget.h index 4630162..8551400 100644 --- a/Plugins/Cog/Source/CogImgui/Public/CogImguiWidget.h +++ b/Plugins/Cog/Source/CogImgui/Public/CogImguiWidget.h @@ -7,6 +7,7 @@ #include "Widgets/DeclarativeSyntaxSupport.h" #include "Widgets/SCompoundWidget.h" +class IInputProcessor; class UGameViewportClient; class ULocalPlayer; struct ImFontAtlas; @@ -37,40 +38,14 @@ public: //---------------------------------------------------------------------------------------------------- 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; } virtual FReply OnKeyChar(const FGeometry& MyGeometry, const FCharacterEvent& CharacterEvent) override; - virtual FReply OnKeyDown(const FGeometry& MyGeometry, const FKeyEvent& KeyEvent) override; - - virtual FReply OnKeyUp(const FGeometry& MyGeometry, const FKeyEvent& KeyEvent) override; - - virtual FReply OnAnalogValueChanged(const FGeometry& MyGeometry, const FAnalogInputEvent& AnalogInputEvent) override; - - virtual FReply OnMouseButtonDown(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override; - - virtual FReply OnMouseButtonUp(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override; - - virtual FReply OnMouseWheel(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override; - - virtual FReply OnMouseMove(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override; - virtual FReply OnFocusReceived(const FGeometry& MyGeometry, const FFocusEvent& FocusEvent) override; - - virtual void OnFocusLost(const FFocusEvent& FocusEvent) override; - - virtual void OnMouseEnter(const FGeometry& MyGeometry, const FPointerEvent& MouseEvent) override; - - virtual void OnMouseLeave(const FPointerEvent& MouseEvent) override; - - virtual FReply OnTouchStarted(const FGeometry& MyGeometry, const FPointerEvent& TouchEvent) override; - - virtual FReply OnTouchMoved(const FGeometry& MyGeometry, const FPointerEvent& TouchEvent) override; - - virtual FReply OnTouchEnded(const FGeometry& MyGeometry, const FPointerEvent& TouchEvent) 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 FVector2D ComputeDesiredSize(float Scale) const override; ULocalPlayer* GetLocalPlayer() const; @@ -79,14 +54,6 @@ public: void SetEnableInput(bool Value); - bool GetShareGamepad() const { return bShareGamepad; } - - void SetShareGamepad(bool Value) { bShareGamepad = Value; } - - bool GetShareKeyboard() const { return bShareKeyboard; } - - void SetShareKeyboard(bool Value) { bShareKeyboard= Value; } - bool GetShareMouse() const { return bShareMouse; } void SetShareMouse(bool Value) { bShareMouse = Value; } @@ -119,12 +86,8 @@ protected: virtual void OnDpiChanged(); - virtual void RefreshVisibility(); - virtual bool IsConsoleOpened() const; - virtual FReply HandleKeyEvent(const FGeometry& MyGeometry, const FKeyEvent& KeyEvent); - TWeakObjectPtr GameViewport; ImFontAtlas* FontAtlas = nullptr; @@ -133,10 +96,6 @@ protected: bool bEnableInput = false; - bool bShareGamepad = true; - - bool bShareKeyboard = false; - bool bShareMouse = false; FSlateRenderTransform ImGuiRenderTransform; @@ -156,4 +115,6 @@ protected: float DpiScale = 1.f; char IniFilename[512]; + + TSharedPtr InputProcessor = nullptr; }; diff --git a/Plugins/Cog/Source/CogWindow/Private/CogWindowManager.cpp b/Plugins/Cog/Source/CogWindow/Private/CogWindowManager.cpp index 599ec77..731828f 100644 --- a/Plugins/Cog/Source/CogWindow/Private/CogWindowManager.cpp +++ b/Plugins/Cog/Source/CogWindow/Private/CogWindowManager.cpp @@ -31,7 +31,7 @@ void UCogWindowManager::PostInitProperties() if (bRegisterDefaultCommands) { - if (RegisterDefaultCommands()) + if (RegisterDefaultCommandBindings()) { bRegisterDefaultCommands = false; } @@ -42,10 +42,6 @@ void UCogWindowManager::PostInitProperties() void UCogWindowManager::InitializeInternal() { ImGuiWidget = FCogImguiModule::Get().CreateImGuiWidget(GEngine->GameViewport, [this](float DeltaTime) { Render(DeltaTime); }); - ImGuiWidget->SetEnableInput(bEnableInput); - ImGuiWidget->SetShareGamepad(bShareGamepad); - ImGuiWidget->SetShareKeyboard(bShareKeyboard); - ImGuiWidget->SetShareMouse(bShareMouse); ImGuiSettingsHandler IniHandler; IniHandler.TypeName = "Cog"; @@ -97,12 +93,13 @@ void UCogWindowManager::InitializeInternal() void UCogWindowManager::Shutdown() { //------------------------------------------------------------ - // To save the input mode for the next session + // Call PreSaveConfig before destroying imgui context + // if PreSaveConfig needs to read ImGui IO for example //------------------------------------------------------------ - bEnableInput = ImGuiWidget->GetEnableInput(); - bShareGamepad = ImGuiWidget->GetEnableInput(); - bShareKeyboard = ImGuiWidget->GetEnableInput(); - bShareMouse = ImGuiWidget->GetEnableInput(); + for (FCogWindow* Window : Windows) + { + Window->PreSaveConfig(); + } //------------------------------------------------------------ // Destroy ImGui before destroying the windows to make sure @@ -114,7 +111,6 @@ void UCogWindowManager::Shutdown() for (FCogWindow* Window : Windows) { - Window->PreSaveConfig(); Window->Shutdown(); delete Window; } @@ -678,7 +674,7 @@ void UCogWindowManager::ResetAllWindowsConfig() } //-------------------------------------------------------------------------------------------------------------------------- -bool UCogWindowManager::RegisterDefaultCommands() +bool UCogWindowManager::RegisterDefaultCommandBindings() { if (GetWorld() == nullptr) { @@ -790,5 +786,6 @@ const UObject* UCogWindowManager::GetAsset(const TSubclassOf AssetClass //-------------------------------------------------------------------------------------------------------------------------- void UCogWindowManager::ToggleInputMode() { + UE_LOG(LogCogImGui, Verbose, TEXT("UCogWindowManager::ToggleInputMode")); ImGuiWidget->SetEnableInput(!ImGuiWidget->GetEnableInput()); } \ No newline at end of file diff --git a/Plugins/Cog/Source/CogWindow/Private/CogWindow_Inputs.cpp b/Plugins/Cog/Source/CogWindow/Private/CogWindow_Inputs.cpp index d728257..ab8178e 100644 --- a/Plugins/Cog/Source/CogWindow/Private/CogWindow_Inputs.cpp +++ b/Plugins/Cog/Source/CogWindow/Private/CogWindow_Inputs.cpp @@ -13,6 +13,32 @@ void FCogWindow_Inputs::Initialize() Super::Initialize(); bHasMenu = false; + + Config = GetConfig(); + + SCogImguiWidget* ImGuiWidget = GetOwner()->GetImGuiWidget().Get(); + ImGuiWidget->SetEnableInput(Config->bEnableInput); + + ImGuiIO& IO = ImGui::GetIO(); + FCogImguiHelper::SetFlags(IO.ConfigFlags, ImGuiConfigFlags_NavEnableKeyboard, Config->bNavEnableKeyboard); + FCogImguiHelper::SetFlags(IO.ConfigFlags, ImGuiConfigFlags_NavEnableGamepad, Config->bNavEnableGamepad); + FCogImguiHelper::SetFlags(IO.ConfigFlags, ImGuiConfigFlags_NavNoCaptureKeyboard, Config->bNavNoCaptureInput); +} + +//-------------------------------------------------------------------------------------------------------------------------- +void FCogWindow_Inputs::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; + + if (SCogImguiWidget* ImGuiWidget = GetOwner()->GetImGuiWidget().Get()) + { + Config->bShareMouse = ImGuiWidget->GetShareMouse(); + } } //-------------------------------------------------------------------------------------------------------------------------- @@ -48,26 +74,15 @@ void FCogWindow_Inputs::RenderContent() } ImGui::Separator(); - - bool bShareGamepad = ImGuiWidget->GetShareGamepad(); - if (ImGui::Checkbox("Share Gamepad", &bShareGamepad)) - { - ImGuiWidget->SetShareGamepad(bShareGamepad); - } - - bool bShareKeyboard = ImGuiWidget->GetShareKeyboard(); - if (ImGui::Checkbox("Share Keyboard", &bShareKeyboard)) - { - ImGuiWidget->SetShareKeyboard(bShareKeyboard); - } - + bool bShareMouse = ImGuiWidget->GetShareMouse(); if (ImGui::Checkbox("Share Mouse", &bShareMouse)) { - //ImGuiWidget->SetShareMouse(bShareMouse); - } - if (ImGui::IsItemHovered()) - { - ImGui::SetTooltip("Mouse sharing is currently not supported"); + ImGuiWidget->SetShareMouse(bShareMouse); } + + ImGuiIO& IO = ImGui::GetIO(); + 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); } diff --git a/Plugins/Cog/Source/CogWindow/Public/CogWindowConfig.h b/Plugins/Cog/Source/CogWindow/Public/CogWindowConfig.h index 15034c8..f5ebf54 100644 --- a/Plugins/Cog/Source/CogWindow/Public/CogWindowConfig.h +++ b/Plugins/Cog/Source/CogWindow/Public/CogWindowConfig.h @@ -13,6 +13,11 @@ public: UPROPERTY(Config) bool bHideMenu = false; + UCogWindowConfig() + { + Reset(); + } + virtual void Reset() { bHideMenu = true; diff --git a/Plugins/Cog/Source/CogWindow/Public/CogWindowManager.h b/Plugins/Cog/Source/CogWindow/Public/CogWindowManager.h index fc3d8fd..bb5a960 100644 --- a/Plugins/Cog/Source/CogWindow/Public/CogWindowManager.h +++ b/Plugins/Cog/Source/CogWindow/Public/CogWindowManager.h @@ -73,7 +73,7 @@ public: virtual void ResetAllWindowsConfig(); - virtual bool RegisterDefaultCommands(); + virtual bool RegisterDefaultCommandBindings(); UCogWindowConfig* GetConfig(const TSubclassOf ConfigClass); @@ -144,18 +144,6 @@ protected: UPROPERTY() mutable TArray Assets; - UPROPERTY(Config) - bool bEnableInput = false; - - UPROPERTY(Config) - bool bShareGamepad = true; - - UPROPERTY(Config) - bool bShareKeyboard = false; - - UPROPERTY(Config) - bool bShareMouse = false; - UPROPERTY(Config) bool bCompactMode = false; diff --git a/Plugins/Cog/Source/CogWindow/Public/CogWindow_Inputs.h b/Plugins/Cog/Source/CogWindow/Public/CogWindow_Inputs.h index 3f94124..20b5008 100644 --- a/Plugins/Cog/Source/CogWindow/Public/CogWindow_Inputs.h +++ b/Plugins/Cog/Source/CogWindow/Public/CogWindow_Inputs.h @@ -2,6 +2,10 @@ #include "CoreMinimal.h" #include "CogWindow.h" +#include "CogWindowConfig.h" +#include "CogWindow_Inputs.generated.h" + +class UCogEngineConfig_Inputs; class COGWINDOW_API FCogWindow_Inputs : public FCogWindow { @@ -11,7 +15,46 @@ public: virtual void Initialize() override; + virtual void PreSaveConfig() override; + protected: virtual void RenderContent() override; + + TObjectPtr Config = nullptr; }; + +//-------------------------------------------------------------------------------------------------------------------------- +UCLASS(Config = Cog) +class UCogEngineConfig_Inputs : public UCogWindowConfig +{ + GENERATED_BODY() + +public: + + UPROPERTY(Config) + bool bEnableInput = false; + + UPROPERTY(Config) + bool bShareMouse = true; + + UPROPERTY(Config) + bool bNavEnableKeyboard = true; + + UPROPERTY(Config) + bool bNavEnableGamepad = true; + + UPROPERTY(Config) + bool bNavNoCaptureInput = true; + + virtual void Reset() override + { + Super::Reset(); + + bEnableInput = false; + bShareMouse = true; + bNavEnableKeyboard = true; + bNavEnableGamepad = true; + bNavNoCaptureInput = false; + } +}; \ No newline at end of file diff --git a/Source/CogSample/CogSampleLogCategories.cpp b/Source/CogSample/CogSampleLogCategories.cpp index 6dc265a..a04d321 100644 --- a/Source/CogSample/CogSampleLogCategories.cpp +++ b/Source/CogSample/CogSampleLogCategories.cpp @@ -1,6 +1,7 @@ #include "CogSampleLogCategories.h" #include "AbilitySystemLog.h" +#include "CogImguiHelper.h" #include "CogSampleDefines.h" #if ENABLE_COG @@ -39,6 +40,7 @@ namespace CogSampleLog FCogDebugLog::AddLogCategory(LogCogBaseAimRotation, "Base Aim Rotation", "Debug Draw of a Character BaseAimRotation"); FCogDebugLog::AddLogCategory(LogCogCollision, "Collision", "Debug Draw a Character Collision"); FCogDebugLog::AddLogCategory(LogCogControlRotation, "Control Rotation", "Debug Draw of the Character Control Rotation"); + FCogDebugLog::AddLogCategory(LogCogImGui, "ImGui", "Log related to imgui integration"); FCogDebugLog::AddLogCategory(LogCogInput, "Input", "Log about the input actions"); FCogDebugLog::AddLogCategory(LogCogPosition, "Position", "Debug draw of a character position"); FCogDebugLog::AddLogCategory(LogCogPossession, "Possession", "Log about the possession of a PlayerController over a Character"); diff --git a/TODO.txt b/TODO.txt index 362e913..a464aaa 100644 --- a/TODO.txt +++ b/TODO.txt @@ -7,6 +7,7 @@ - CogWindow: Overlay window should have achnoring options (top bottom left right center mid) - 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 - CogEngine: More stats in the stats window - CogEngine: Overlay mode of stats.