From dff7f5704ae59b2086c96ea8aab022261d517d71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 6 Nov 2024 21:27:13 +0100 Subject: [PATCH] Implement mousewheel vertical scroll and hover in ImGui integration --- Common/Input/InputState.h | 5 +++++ Common/UI/View.cpp | 1 + Windows/MainWindow.cpp | 23 +++++++++++---------- Windows/RawInput.cpp | 1 + ext/imgui/imgui_impl_platform.cpp | 33 ++++++++++++++++++++++--------- 5 files changed, 42 insertions(+), 21 deletions(-) diff --git a/Common/Input/InputState.h b/Common/Input/InputState.h index 4a0a5a331e2d..2edb14210e9c 100644 --- a/Common/Input/InputState.h +++ b/Common/Input/InputState.h @@ -180,6 +180,11 @@ struct KeyInput { int unicodeChar; // for KEY_CHAR }; int flags; + + // Used by mousewheel events. The delta is packed in the upper 16 bits of flags. + int Delta() const { + return flags >> 16; + } }; struct AxisInput { diff --git a/Common/UI/View.cpp b/Common/UI/View.cpp index 1f7da023ffff..05a48d3f0567 100644 --- a/Common/UI/View.cpp +++ b/Common/UI/View.cpp @@ -1413,6 +1413,7 @@ bool TriggerButton::Touch(const TouchInput &input) { down_ |= 1 << input.id; } } + if (input.flags & TOUCH_MOVE) { if (contains) down_ |= 1 << input.id; diff --git a/Windows/MainWindow.cpp b/Windows/MainWindow.cpp index bacff3426c50..ab00f6c49580 100644 --- a/Windows/MainWindow.cpp +++ b/Windows/MainWindow.cpp @@ -680,19 +680,18 @@ namespace MainWindow float y = (float)cursorY * g_display.dpi_scale_y; WindowsRawInput::SetMousePos(x, y); - if (wParam & (MK_LBUTTON | MK_RBUTTON)) { - TouchInput touch{}; - touch.flags = TOUCH_MOVE | TOUCH_MOUSE; - if (wParam & MK_LBUTTON) { - touch.buttons |= 1; - } - if (wParam & MK_RBUTTON) { - touch.buttons |= 2; - } - touch.x = x; - touch.y = y; - NativeTouch(touch); + // Mouse moves now happen also when no button is pressed. + TouchInput touch{}; + touch.flags = TOUCH_MOVE | TOUCH_MOUSE; + if (wParam & MK_LBUTTON) { + touch.buttons |= 1; + } + if (wParam & MK_RBUTTON) { + touch.buttons |= 2; } + touch.x = x; + touch.y = y; + NativeTouch(touch); } break; diff --git a/Windows/RawInput.cpp b/Windows/RawInput.cpp index 0227675d48c2..d5d4726b837b 100644 --- a/Windows/RawInput.cpp +++ b/Windows/RawInput.cpp @@ -156,6 +156,7 @@ namespace WindowsRawInput { { VK_OEM_5, NKCODE_BACKSLASH }, { VK_OEM_6, NKCODE_RIGHT_BRACKET }, { VK_OEM_7, NKCODE_APOSTROPHE }, + { VK_OEM_8, NKCODE_GRAVE }, // Key left of 1 (above Q) on a lot of layouts. { VK_RETURN, NKCODE_ENTER }, { VK_APPS, NKCODE_MENU }, // Context menu key, let's call this "menu". { VK_PAUSE, NKCODE_BREAK }, diff --git a/ext/imgui/imgui_impl_platform.cpp b/ext/imgui/imgui_impl_platform.cpp index 0bd33d25d90e..62344d2c7652 100644 --- a/ext/imgui/imgui_impl_platform.cpp +++ b/ext/imgui/imgui_impl_platform.cpp @@ -11,9 +11,24 @@ void ImGui_ImplPlatform_KeyEvent(const KeyInput &key) { ImGuiIO& io = ImGui::GetIO(); if (key.flags & KEY_DOWN) { - ImGuiKey keyCode = KeyCodeToImGui(key.keyCode); - if (keyCode != ImGuiKey_None) { - io.AddKeyEvent(keyCode, true); + // Specially handle scroll events and any other special keys. + switch (key.keyCode) { + case NKCODE_EXT_MOUSEWHEEL_UP: + io.AddMouseWheelEvent(0, key.Delta() * 0.010f); + break; + case NKCODE_EXT_MOUSEWHEEL_DOWN: + io.AddMouseWheelEvent(0, -key.Delta() * 0.010f); + break; + default: + { + ImGuiKey keyCode = KeyCodeToImGui(key.keyCode); + if (keyCode == ImGuiKey_None) { + WARN_LOG(Log::System, "Unmapped ImGui keycode conversion from %d", key.keyCode); + } else { + io.AddKeyEvent(keyCode, true); + } + break; + } } } if (key.flags & KEY_UP) { @@ -103,7 +118,7 @@ ImGuiKey KeyCodeToImGui(InputKeyCode keyCode) { case NKCODE_MOVE_END: return ImGuiKey_End; case NKCODE_INSERT: return ImGuiKey_Insert; - // Numeric keys + // Numeric keys case NKCODE_0: return ImGuiKey_0; case NKCODE_1: return ImGuiKey_1; case NKCODE_2: return ImGuiKey_2; @@ -115,7 +130,7 @@ ImGuiKey KeyCodeToImGui(InputKeyCode keyCode) { case NKCODE_8: return ImGuiKey_8; case NKCODE_9: return ImGuiKey_9; - // Letter keys + // Letter keys case NKCODE_A: return ImGuiKey_A; case NKCODE_B: return ImGuiKey_B; case NKCODE_C: return ImGuiKey_C; @@ -143,7 +158,7 @@ ImGuiKey KeyCodeToImGui(InputKeyCode keyCode) { case NKCODE_Y: return ImGuiKey_Y; case NKCODE_Z: return ImGuiKey_Z; - // Symbols + // Symbols case NKCODE_COMMA: return ImGuiKey_Comma; case NKCODE_PERIOD: return ImGuiKey_Period; case NKCODE_MINUS: return ImGuiKey_Minus; @@ -156,7 +171,7 @@ ImGuiKey KeyCodeToImGui(InputKeyCode keyCode) { case NKCODE_SLASH: return ImGuiKey_Slash; case NKCODE_GRAVE: return ImGuiKey_GraveAccent; - // Function keys + // Function keys case NKCODE_F1: return ImGuiKey_F1; case NKCODE_F2: return ImGuiKey_F2; case NKCODE_F3: return ImGuiKey_F3; @@ -170,7 +185,7 @@ ImGuiKey KeyCodeToImGui(InputKeyCode keyCode) { case NKCODE_F11: return ImGuiKey_F11; case NKCODE_F12: return ImGuiKey_F12; - // Keypad + // Keypad case NKCODE_NUMPAD_0: return ImGuiKey_Keypad0; case NKCODE_NUMPAD_1: return ImGuiKey_Keypad1; case NKCODE_NUMPAD_2: return ImGuiKey_Keypad2; @@ -188,7 +203,7 @@ ImGuiKey KeyCodeToImGui(InputKeyCode keyCode) { case NKCODE_NUMPAD_ENTER: return ImGuiKey_KeypadEnter; case NKCODE_NUMPAD_EQUALS: return ImGuiKey_KeypadEqual; - // Lock keys + // Lock keys case NKCODE_NUM_LOCK: return ImGuiKey_NumLock; case NKCODE_SCROLL_LOCK: return ImGuiKey_ScrollLock;