diff --git a/imgui.cpp b/imgui.cpp index ed69170f..80da3418 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -3154,6 +3154,25 @@ bool ImGui::IsKeyDown(int user_key_index) return GImGui->IO.KeysDown[user_key_index]; } +int ImGui::CalcTypematicPressedRepeatAmount(float t, float t_prev, float repeat_delay, float repeat_rate) +{ + if (t == 0.0f) + return 1; + if (t <= repeat_delay || repeat_rate <= 0.0f) + return 0; + const int count = (int)((t - repeat_delay) / repeat_rate) - (int)((t_prev - repeat_delay) / repeat_rate); + return (count > 0) ? count : 0; +} + +int ImGui::GetKeyPressedAmount(int key_index, float repeat_delay, float repeat_rate) +{ + ImGuiContext& g = *GImGui; + if (key_index < 0) return false; + IM_ASSERT(key_index >= 0 && key_index < IM_ARRAYSIZE(g.IO.KeysDown)); + const float t = g.IO.KeysDownDuration[key_index]; + return CalcTypematicPressedRepeatAmount(t, t - g.IO.DeltaTime, repeat_delay, repeat_rate); +} + bool ImGui::IsKeyPressed(int user_key_index, bool repeat) { ImGuiContext& g = *GImGui; @@ -3162,13 +3181,8 @@ bool ImGui::IsKeyPressed(int user_key_index, bool repeat) const float t = g.IO.KeysDownDuration[user_key_index]; if (t == 0.0f) return true; - if (repeat && t > g.IO.KeyRepeatDelay) - { - float delay = g.IO.KeyRepeatDelay, rate = g.IO.KeyRepeatRate; - if ((fmodf(t - delay, rate) > rate*0.5f) != (fmodf(t - delay - g.IO.DeltaTime, rate) > rate*0.5f)) - return true; - } + return GetKeyPressedAmount(user_key_index, g.IO.KeyRepeatDelay, g.IO.KeyRepeatRate) > 0; return false; } diff --git a/imgui.h b/imgui.h index 14fd4d9d..f40c7db9 100644 --- a/imgui.h +++ b/imgui.h @@ -452,6 +452,7 @@ namespace ImGui IMGUI_API bool IsKeyDown(int user_key_index); // is key being held. == io.KeysDown[user_key_index]. note that imgui doesn't know the semantic of each entry of io.KeyDown[]. Use your own indices/enums according to how your backend/engine stored them into KeyDown[]! IMGUI_API bool IsKeyPressed(int user_key_index, bool repeat = true); // was key pressed (went from !Down to Down). if repeat=true, uses io.KeyRepeatDelay / KeyRepeatRate IMGUI_API bool IsKeyReleased(int user_key_index); // was key released (went from Down to !Down).. + IMGUI_API int GetKeyPressedAmount(int key_index, float repeat_delay, float rate); // uses provided repeat rate/delay. return a count, most often 0 or 1 but might be >1 if RepeatRate is small enough that DeltaTime > RepeatRate IMGUI_API bool IsMouseDown(int button); // is mouse button held IMGUI_API bool IsMouseClicked(int button, bool repeat = false); // did mouse button clicked (went from !Down to Down) IMGUI_API bool IsMouseDoubleClicked(int button); // did mouse button double-clicked. a double-click returns false in IsMouseClicked(). uses io.MouseDoubleClickTime. diff --git a/imgui_internal.h b/imgui_internal.h index 10598ac6..80b2f4de 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -764,6 +764,8 @@ namespace ImGui IMGUI_API void OpenPopupEx(ImGuiID id, bool reopen_existing); IMGUI_API bool IsPopupOpen(ImGuiID id); + IMGUI_API int CalcTypematicPressedRepeatAmount(float t, float t_prev, float repeat_delay, float repeat_rate); + // New Columns API IMGUI_API void BeginColumns(const char* id, int count, ImGuiColumnsFlags flags = 0); // setup number of columns. use an identifier to distinguish multiple column sets. close with EndColumns(). IMGUI_API void EndColumns(); // close columns