From f48f9a30ef5f598e3fa9ac42e07a89b78c5dbc74 Mon Sep 17 00:00:00 2001 From: ocornut Date: Fri, 13 May 2016 11:13:54 +0200 Subject: [PATCH] ButtonBehavior(), fixed subtle old bug when a repeating button would also return true on release + comments (#656) --- imgui.cpp | 18 ++++++++++++------ imgui.h | 2 +- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index bee8bb79..a9e64892 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -5341,7 +5341,12 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool SetHoveredID(id); if (!(flags & ImGuiButtonFlags_NoKeyModifiers) || (!g.IO.KeyCtrl && !g.IO.KeyShift && !g.IO.KeyAlt)) { - if ((flags & ImGuiButtonFlags_PressedOnClickRelease) && g.IO.MouseClicked[0]) // Most common type + // | CLICKING | HOLDING with ImGuiButtonFlags_Repeat + // PressedOnClickRelease | * | .. (NOT on release) <-- MOST COMMON! (*) only if both click/release were over bounds + // PressedOnClick | | .. + // PressedOnRelease | | .. (NOT on release) + // PressedOnDoubleClick | | .. + if ((flags & ImGuiButtonFlags_PressedOnClickRelease) && g.IO.MouseClicked[0]) { SetActiveID(id, window); // Hold on ID FocusWindow(window); @@ -5354,13 +5359,13 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool } if ((flags & ImGuiButtonFlags_PressedOnRelease) && g.IO.MouseReleased[0]) { - pressed = true; + if (!((flags & ImGuiButtonFlags_Repeat) && g.IO.MouseDownDurationPrev[0] >= g.IO.KeyRepeatDelay)) // Repeat mode trumps + pressed = true; SetActiveID(0); } - // 'Repeat' mode acts when held regardless of _PressedOn flags - // FIXME: Need to clarify the repeat behavior with those differents flags. Currently the typical PressedOnClickRelease+Repeat will add an extra click on final release (hardly noticeable with repeat rate, but technically an issue) - // Relies on repeat behavior of IsMouseClicked() but we may as well do it ourselves if we end up exposing finer RepeatDelay/RepeatRate settings. + // 'Repeat' mode acts when held regardless of _PressedOn flags (see table above). + // Relies on repeat logic of IsMouseClicked() but we may as well do it ourselves if we end up exposing finer RepeatDelay/RepeatRate settings. if ((flags & ImGuiButtonFlags_Repeat) && g.ActiveId == id && g.IO.MouseDownDuration[0] > 0.0f && ImGui::IsMouseClicked(0, true)) pressed = true; } @@ -5376,7 +5381,8 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool else { if (hovered && (flags & ImGuiButtonFlags_PressedOnClickRelease)) - pressed = true; + if (!((flags & ImGuiButtonFlags_Repeat) && g.IO.MouseDownDurationPrev[0] >= g.IO.KeyRepeatDelay)) // Repeat mode trumps + pressed = true; SetActiveID(0); } } diff --git a/imgui.h b/imgui.h index fecfe3bf..38e36762 100644 --- a/imgui.h +++ b/imgui.h @@ -732,7 +732,7 @@ struct ImGuiIO float MouseDoubleClickMaxDist; // = 6.0f // Distance threshold to stay in to validate a double-click, in pixels. float MouseDragThreshold; // = 6.0f // Distance threshold before considering we are dragging int KeyMap[ImGuiKey_COUNT]; // // Map of indices into the KeysDown[512] entries array - float KeyRepeatDelay; // = 0.250f // When holding a key/button, time before it starts repeating, in seconds. (for actions where 'repeat' is active) + float KeyRepeatDelay; // = 0.250f // When holding a key/button, time before it starts repeating, in seconds (for buttons in Repeat mode, etc.). float KeyRepeatRate; // = 0.020f // When holding a key/button, rate at which it repeats, in seconds. void* UserData; // = NULL // Store your own data for retrieval by callbacks.