From 0106dcbd0253df387d929b60c4edafee1254d173 Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 28 Sep 2017 15:43:26 +0200 Subject: [PATCH] Fixed IsItemHovered() - part of the processing has to be done in ItemAdd() because the widget may alter clipping rectangle temporarily. --- imgui.cpp | 12 ++++++++---- imgui_demo.cpp | 5 +++-- imgui_internal.h | 4 +++- 3 files changed, 14 insertions(+), 7 deletions(-) diff --git a/imgui.cpp b/imgui.cpp index 59b4c275..4a1f49fc 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -1952,12 +1952,16 @@ bool ImGui::ItemAdd(const ImRect& bb, const ImGuiID* id) { ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; + const bool is_clipped = IsClippedEx(bb, id, false); window->DC.LastItemId = id ? *id : 0; window->DC.LastItemRect = bb; - if (IsClippedEx(bb, id, false)) + window->DC.LastItemRectHoveredRect = false; + if (is_clipped) return false; //if (g.IO.KeyAlt) window->DrawList->AddRect(bb.Min, bb.Max, IM_COL32(255,255,0,120)); // [DEBUG] + // We need to calculate this now to take account of the current clipping rectangle (as items like Selectable may change them) + window->DC.LastItemRectHoveredRect = IsMouseHoveringRect(bb.Min, bb.Max); return true; } @@ -1968,12 +1972,12 @@ bool ImGui::IsItemHovered() ImGuiContext& g = *GImGui; ImGuiWindow* window = g.CurrentWindow; + if (!window->DC.LastItemRectHoveredRect) + return false; if (g.HoveredWindow != window) return false; if (g.ActiveId != 0 && g.ActiveId != window->DC.LastItemId && !g.ActiveIdAllowOverlap && g.ActiveId != window->MoveId) return false; - if (!IsMouseHoveringRect(window->DC.LastItemRect.Min, window->DC.LastItemRect.Max)) - return false; if (!IsWindowContentHoverable(window)) return false; return true; @@ -1982,7 +1986,7 @@ bool ImGui::IsItemHovered() bool ImGui::IsItemRectHovered() { ImGuiWindow* window = GetCurrentWindowRead(); - return IsMouseHoveringRect(window->DC.LastItemRect.Min, window->DC.LastItemRect.Max); + return window->DC.LastItemRectHoveredRect; } // Internal facing ItemHoverable() used when submitting widgets. Differs slightly from IsItemHovered(). diff --git a/imgui_demo.cpp b/imgui_demo.cpp index d846faa1..bc75508a 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -1505,7 +1505,7 @@ void ImGui::ShowTestWindow(bool* p_open) ImGui::Text("ID"); ImGui::NextColumn(); ImGui::Text("Name"); ImGui::NextColumn(); ImGui::Text("Path"); ImGui::NextColumn(); - ImGui::Text("Flags"); ImGui::NextColumn(); + ImGui::Text("Hovered"); ImGui::NextColumn(); ImGui::Separator(); const char* names[3] = { "One", "Two", "Three" }; const char* paths[3] = { "/path/one", "/path/two", "/path/three" }; @@ -1516,10 +1516,11 @@ void ImGui::ShowTestWindow(bool* p_open) sprintf(label, "%04d", i); if (ImGui::Selectable(label, selected == i, ImGuiSelectableFlags_SpanAllColumns)) selected = i; + bool hovered = ImGui::IsItemHovered(); ImGui::NextColumn(); ImGui::Text(names[i]); ImGui::NextColumn(); ImGui::Text(paths[i]); ImGui::NextColumn(); - ImGui::Text("...."); ImGui::NextColumn(); + ImGui::Text("%d", hovered); ImGui::NextColumn(); } ImGui::Columns(1); ImGui::Separator(); diff --git a/imgui_internal.h b/imgui_internal.h index 67ccf4eb..29d8ca7c 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -600,6 +600,7 @@ struct IMGUI_API ImGuiDrawContext int TreeDepth; ImGuiID LastItemId; ImRect LastItemRect; + bool LastItemRectHoveredRect; bool MenuBarAppending; float MenuBarOffsetX; ImVector ChildWindows; @@ -639,7 +640,8 @@ struct IMGUI_API ImGuiDrawContext LogLinePosY = -1.0f; TreeDepth = 0; LastItemId = 0; - LastItemRect = ImRect(0.0f,0.0f,0.0f,0.0f); + LastItemRect = ImRect(); + LastItemRectHoveredRect = false; MenuBarAppending = false; MenuBarOffsetX = 0.0f; StateStorage = NULL;