From c571ae4029a4652792430d3967440fee325fb456 Mon Sep 17 00:00:00 2001 From: Rory O'Connell <19547+RoryO@users.noreply.github.com> Date: Tue, 4 Aug 2020 16:02:48 -0700 Subject: [PATCH 1/5] Collect keyboard inputs over one frame, release them next frame --- examples/imgui_impl_win32.cpp | 8 +++++--- imgui.cpp | 16 +++++++++++++--- imgui.h | 23 +++++++++++++---------- 3 files changed, 31 insertions(+), 16 deletions(-) diff --git a/examples/imgui_impl_win32.cpp b/examples/imgui_impl_win32.cpp index f6dd5b8285e4..605f0ba67416 100644 --- a/examples/imgui_impl_win32.cpp +++ b/examples/imgui_impl_win32.cpp @@ -315,13 +315,15 @@ IMGUI_IMPL_API LRESULT ImGui_ImplWin32_WndProcHandler(HWND hwnd, UINT msg, WPARA return 0; case WM_KEYDOWN: case WM_SYSKEYDOWN: - if (wParam < 256) - io.KeysDown[wParam] = 1; + // Win32 sets bit 30 if the key is repeating. We handle that internally so we + // only want the first down. + if ((wParam < 256) && !(lParam & (1 << 30))) + io.KeysDown[wParam]++; return 0; case WM_KEYUP: case WM_SYSKEYUP: if (wParam < 256) - io.KeysDown[wParam] = 0; + io.KeysUp[wParam]++; return 0; case WM_CHAR: // You can also use ToAscii()+GetKeyboardState() to retrieve characters. diff --git a/imgui.cpp b/imgui.cpp index 28c975e2cfaa..e0ed373d4ec2 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3609,7 +3609,7 @@ void ImGui::UpdateHoveredWindowAndCaptureFlags() { if (g.IO.MouseClicked[i]) g.IO.MouseDownOwned[i] = (g.HoveredWindow != NULL) || (g.OpenPopupStack.Size > 0); - mouse_any_down |= g.IO.MouseDown[i]; + mouse_any_down |= g.IO.MouseDown[i] ? true : false; if (g.IO.MouseDown[i]) if (mouse_earliest_button_down == -1 || g.IO.MouseClickedTime[i] < g.IO.MouseClickedTime[mouse_earliest_button_down]) mouse_earliest_button_down = i; @@ -3758,8 +3758,18 @@ void ImGui::NewFrame() // Synchronize io.KeyMods with individual modifiers io.KeyXXX bools g.IO.KeyMods = GetMergedKeyModFlags(); memcpy(g.IO.KeysDownDurationPrev, g.IO.KeysDownDuration, sizeof(g.IO.KeysDownDuration)); - for (int i = 0; i < IM_ARRAYSIZE(g.IO.KeysDown); i++) - g.IO.KeysDownDuration[i] = g.IO.KeysDown[i] ? (g.IO.KeysDownDuration[i] < 0.0f ? 0.0f : g.IO.KeysDownDuration[i] + g.IO.DeltaTime) : -1.0f; + for (int i = 0; i < IM_ARRAYSIZE(g.IO.KeysDown); i++) { + g.IO.KeysDown[i] -= g.IO.KeysUpPrev[i]; + if(g.IO.KeysDown[i]) + if(g.IO.KeysDownDuration[i] < 0.0f) + g.IO.KeysDownDuration[i] = 0.0f; + else + g.IO.KeysDownDuration[i] += g.IO.DeltaTime; + else + g.IO.KeysDownDuration[i] = -1.0f; + } + memcpy(g.IO.KeysUpPrev, g.IO.KeysUp, sizeof(g.IO.KeysUp)); + memset(g.IO.KeysUp, 0, sizeof(g.IO.KeysUp)); // Update gamepad/keyboard navigation NavUpdate(); diff --git a/imgui.h b/imgui.h index 80dcf7714925..033c92baf000 100644 --- a/imgui.h +++ b/imgui.h @@ -1525,16 +1525,19 @@ struct ImGuiIO // Input - Fill before calling NewFrame() //------------------------------------------------------------------ - ImVec2 MousePos; // Mouse position, in pixels. Set to ImVec2(-FLT_MAX, -FLT_MAX) if mouse is unavailable (on another screen, etc.) - bool MouseDown[5]; // Mouse buttons: 0=left, 1=right, 2=middle + extras (ImGuiMouseButton_COUNT == 5). Dear ImGui mostly uses left and right buttons. Others buttons allows us to track if the mouse is being used by your application + available to user as a convenience via IsMouse** API. - float MouseWheel; // Mouse wheel Vertical: 1 unit scrolls about 5 lines text. - float MouseWheelH; // Mouse wheel Horizontal. Most users don't have a mouse with an horizontal wheel, may not be filled by all back-ends. - bool KeyCtrl; // Keyboard modifier pressed: Control - bool KeyShift; // Keyboard modifier pressed: Shift - bool KeyAlt; // Keyboard modifier pressed: Alt - bool KeySuper; // Keyboard modifier pressed: Cmd/Super/Windows - bool KeysDown[512]; // Keyboard keys that are pressed (ideally left in the "native" order your engine has access to keyboard keys, so you can use your own defines/enums for keys). - float NavInputs[ImGuiNavInput_COUNT]; // Gamepad inputs. Cleared back to zero by EndFrame(). Keyboard keys will be auto-mapped and be written here by NewFrame(). + ImVec2 MousePos; // Mouse position, in pixels. Set to ImVec2(-FLT_MAX, -FLT_MAX) if mouse is unavailable (on another screen, etc.) + unsigned short MouseDown[5]; // Mouse buttons: 0 = left, 1=right, 2=middle + extras (ImGuiMouseButton_COUNT == 5). Dear ImGui mostly uses left and right buttons. Others buttons allows us to track if the mouse is being used by your application + available to user as a convenience via IsMouse** API. + unsigned short MouseUp[5]; // Mouse buttons: 0 = left, 1=right, 2=middle + extras (ImGuiMouseButton_COUNT == 5). Dear ImGui mostly uses left and right buttons. Others buttons allows us to track if the mouse is being used by your application + available to user as a convenience via IsMouse** API. + float MouseWheel; // Mouse wheel Vertical: 1 unit scrolls about 5 lines text. + float MouseWheelH; // Mouse wheel Horizontal. Most users don't have a mouse with an horizontal wheel, may not be filled by all back-ends. + bool KeyCtrl; // Keyboard modifier pressed: Control + bool KeyShift; // Keyboard modifier pressed: Shift + bool KeyAlt; // Keyboard modifier pressed: Alt + bool KeySuper; // Keyboard modifier pressed: Cmd/Super/Windows + unsigned short KeysDown[512]; // Number of keyboard key inputs that are pressed since last frame (ideally left in the "native" order your engine has access to keyboard keys, so you can use your own defines/enums for keys). + unsigned short KeysUp[512]; // Number of keyboard up inputs since last frame + int KeysUpPrev[512]; // Number of keyboard up inputs since last frame + float NavInputs[ImGuiNavInput_COUNT]; // Gamepad inputs. Cleared back to zero by EndFrame(). Keyboard keys will be auto-mapped and be written here by NewFrame(). // Functions IMGUI_API void AddInputCharacter(unsigned int c); // Queue new character input From 2c799718b7b22728e494084f176172e9c1d643d4 Mon Sep 17 00:00:00 2001 From: Rory O'Connell <19547+RoryO@users.noreply.github.com> Date: Tue, 4 Aug 2020 21:13:46 -0700 Subject: [PATCH 2/5] Less wasteful data type --- imgui.h | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/imgui.h b/imgui.h index 033c92baf000..240af549baca 100644 --- a/imgui.h +++ b/imgui.h @@ -1525,19 +1525,19 @@ struct ImGuiIO // Input - Fill before calling NewFrame() //------------------------------------------------------------------ - ImVec2 MousePos; // Mouse position, in pixels. Set to ImVec2(-FLT_MAX, -FLT_MAX) if mouse is unavailable (on another screen, etc.) - unsigned short MouseDown[5]; // Mouse buttons: 0 = left, 1=right, 2=middle + extras (ImGuiMouseButton_COUNT == 5). Dear ImGui mostly uses left and right buttons. Others buttons allows us to track if the mouse is being used by your application + available to user as a convenience via IsMouse** API. - unsigned short MouseUp[5]; // Mouse buttons: 0 = left, 1=right, 2=middle + extras (ImGuiMouseButton_COUNT == 5). Dear ImGui mostly uses left and right buttons. Others buttons allows us to track if the mouse is being used by your application + available to user as a convenience via IsMouse** API. - float MouseWheel; // Mouse wheel Vertical: 1 unit scrolls about 5 lines text. - float MouseWheelH; // Mouse wheel Horizontal. Most users don't have a mouse with an horizontal wheel, may not be filled by all back-ends. - bool KeyCtrl; // Keyboard modifier pressed: Control - bool KeyShift; // Keyboard modifier pressed: Shift - bool KeyAlt; // Keyboard modifier pressed: Alt - bool KeySuper; // Keyboard modifier pressed: Cmd/Super/Windows - unsigned short KeysDown[512]; // Number of keyboard key inputs that are pressed since last frame (ideally left in the "native" order your engine has access to keyboard keys, so you can use your own defines/enums for keys). - unsigned short KeysUp[512]; // Number of keyboard up inputs since last frame - int KeysUpPrev[512]; // Number of keyboard up inputs since last frame - float NavInputs[ImGuiNavInput_COUNT]; // Gamepad inputs. Cleared back to zero by EndFrame(). Keyboard keys will be auto-mapped and be written here by NewFrame(). + ImVec2 MousePos; // Mouse position, in pixels. Set to ImVec2(-FLT_MAX, -FLT_MAX) if mouse is unavailable (on another screen, etc.) + unsigned char MouseDown[5]; // Mouse buttons: 0 = left, 1=right, 2=middle + extras (ImGuiMouseButton_COUNT == 5). Dear ImGui mostly uses left and right buttons. Others buttons allows us to track if the mouse is being used by your application + available to user as a convenience via IsMouse** API. + unsigned char MouseUp[5]; // Mouse buttons: 0 = left, 1=right, 2=middle + extras (ImGuiMouseButton_COUNT == 5). Dear ImGui mostly uses left and right buttons. Others buttons allows us to track if the mouse is being used by your application + available to user as a convenience via IsMouse** API. + float MouseWheel; // Mouse wheel Vertical: 1 unit scrolls about 5 lines text. + float MouseWheelH; // Mouse wheel Horizontal. Most users don't have a mouse with an horizontal wheel, may not be filled by all back-ends. + bool KeyCtrl; // Keyboard modifier pressed: Control + bool KeyShift; // Keyboard modifier pressed: Shift + bool KeyAlt; // Keyboard modifier pressed: Alt + bool KeySuper; // Keyboard modifier pressed: Cmd/Super/Windows + unsigned char KeysDown[512]; // Number of keyboard key inputs that are pressed since last frame (ideally left in the "native" order your engine has access to keyboard keys, so you can use your own defines/enums for keys). + unsigned char KeysUp[512]; // Number of keyboard up inputs since last frame + int KeysUpPrev[512]; // Number of keyboard up inputs since last frame + float NavInputs[ImGuiNavInput_COUNT]; // Gamepad inputs. Cleared back to zero by EndFrame(). Keyboard keys will be auto-mapped and be written here by NewFrame(). // Functions IMGUI_API void AddInputCharacter(unsigned int c); // Queue new character input From a31a16effaddac2665884c758ba2ac863e323876 Mon Sep 17 00:00:00 2001 From: Rory O'Connell <19547+RoryO@users.noreply.github.com> Date: Tue, 4 Aug 2020 21:14:35 -0700 Subject: [PATCH 3/5] Fixing data type --- imgui.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.h b/imgui.h index 240af549baca..1992fac4735e 100644 --- a/imgui.h +++ b/imgui.h @@ -1536,7 +1536,7 @@ struct ImGuiIO bool KeySuper; // Keyboard modifier pressed: Cmd/Super/Windows unsigned char KeysDown[512]; // Number of keyboard key inputs that are pressed since last frame (ideally left in the "native" order your engine has access to keyboard keys, so you can use your own defines/enums for keys). unsigned char KeysUp[512]; // Number of keyboard up inputs since last frame - int KeysUpPrev[512]; // Number of keyboard up inputs since last frame + unsigned char KeysUpPrev[512]; // Number of keyboard up inputs since last frame float NavInputs[ImGuiNavInput_COUNT]; // Gamepad inputs. Cleared back to zero by EndFrame(). Keyboard keys will be auto-mapped and be written here by NewFrame(). // Functions From a90c428629a8d6ea5778aac333350f6f244c871c Mon Sep 17 00:00:00 2001 From: Rory O'Connell <19547+RoryO@users.noreply.github.com> Date: Tue, 4 Aug 2020 21:16:16 -0700 Subject: [PATCH 4/5] Better description --- imgui.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imgui.h b/imgui.h index 1992fac4735e..44b2575380fa 100644 --- a/imgui.h +++ b/imgui.h @@ -1536,7 +1536,7 @@ struct ImGuiIO bool KeySuper; // Keyboard modifier pressed: Cmd/Super/Windows unsigned char KeysDown[512]; // Number of keyboard key inputs that are pressed since last frame (ideally left in the "native" order your engine has access to keyboard keys, so you can use your own defines/enums for keys). unsigned char KeysUp[512]; // Number of keyboard up inputs since last frame - unsigned char KeysUpPrev[512]; // Number of keyboard up inputs since last frame + unsigned char KeysUpPrev[512]; // Number of keyboard up inputs since last frame - 1 float NavInputs[ImGuiNavInput_COUNT]; // Gamepad inputs. Cleared back to zero by EndFrame(). Keyboard keys will be auto-mapped and be written here by NewFrame(). // Functions From 6194b77d02ae46515b8bb1b873b0992d924ab376 Mon Sep 17 00:00:00 2001 From: Rory OConnell <19547+RoryO@users.noreply.github.com> Date: Wed, 5 Aug 2020 13:34:28 -0700 Subject: [PATCH 5/5] do not coalesce mouse inputs --- imgui.cpp | 2 +- imgui.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index e0ed373d4ec2..85951c498319 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3609,7 +3609,7 @@ void ImGui::UpdateHoveredWindowAndCaptureFlags() { if (g.IO.MouseClicked[i]) g.IO.MouseDownOwned[i] = (g.HoveredWindow != NULL) || (g.OpenPopupStack.Size > 0); - mouse_any_down |= g.IO.MouseDown[i] ? true : false; + mouse_any_down |= g.IO.MouseDown[i]; if (g.IO.MouseDown[i]) if (mouse_earliest_button_down == -1 || g.IO.MouseClickedTime[i] < g.IO.MouseClickedTime[mouse_earliest_button_down]) mouse_earliest_button_down = i; diff --git a/imgui.h b/imgui.h index 44b2575380fa..3d723180cac1 100644 --- a/imgui.h +++ b/imgui.h @@ -1526,8 +1526,8 @@ struct ImGuiIO //------------------------------------------------------------------ ImVec2 MousePos; // Mouse position, in pixels. Set to ImVec2(-FLT_MAX, -FLT_MAX) if mouse is unavailable (on another screen, etc.) - unsigned char MouseDown[5]; // Mouse buttons: 0 = left, 1=right, 2=middle + extras (ImGuiMouseButton_COUNT == 5). Dear ImGui mostly uses left and right buttons. Others buttons allows us to track if the mouse is being used by your application + available to user as a convenience via IsMouse** API. - unsigned char MouseUp[5]; // Mouse buttons: 0 = left, 1=right, 2=middle + extras (ImGuiMouseButton_COUNT == 5). Dear ImGui mostly uses left and right buttons. Others buttons allows us to track if the mouse is being used by your application + available to user as a convenience via IsMouse** API. + bool MouseDown[5]; // Mouse buttons: 0 = left, 1=right, 2=middle + extras (ImGuiMouseButton_COUNT == 5). Dear ImGui mostly uses left and right buttons. Others buttons allows us to track if the mouse is being used by your application + available to user as a convenience via IsMouse** API. + bool MouseUp[5]; // Mouse buttons: 0 = left, 1=right, 2=middle + extras (ImGuiMouseButton_COUNT == 5). Dear ImGui mostly uses left and right buttons. Others buttons allows us to track if the mouse is being used by your application + available to user as a convenience via IsMouse** API. float MouseWheel; // Mouse wheel Vertical: 1 unit scrolls about 5 lines text. float MouseWheelH; // Mouse wheel Horizontal. Most users don't have a mouse with an horizontal wheel, may not be filled by all back-ends. bool KeyCtrl; // Keyboard modifier pressed: Control