Browse Source

Fixed IsItemHovered() - part of the processing has to be done in ItemAdd() because the widget may alter clipping rectangle temporarily.

omar 8 years ago
parent
commit
0106dcbd02
3 changed files with 14 additions and 7 deletions
  1. 8 4
      imgui.cpp
  2. 3 2
      imgui_demo.cpp
  3. 3 1
      imgui_internal.h

+ 8 - 4
imgui.cpp

@@ -1952,12 +1952,16 @@ bool ImGui::ItemAdd(const ImRect& bb, const ImGuiID* id)
 {
 {
     ImGuiContext& g = *GImGui;
     ImGuiContext& g = *GImGui;
     ImGuiWindow* window = g.CurrentWindow;
     ImGuiWindow* window = g.CurrentWindow;
+    const bool is_clipped = IsClippedEx(bb, id, false);
     window->DC.LastItemId = id ? *id : 0;
     window->DC.LastItemId = id ? *id : 0;
     window->DC.LastItemRect = bb;
     window->DC.LastItemRect = bb;
-    if (IsClippedEx(bb, id, false))
+    window->DC.LastItemRectHoveredRect = false;
+    if (is_clipped)
         return false;
         return false;
     //if (g.IO.KeyAlt) window->DrawList->AddRect(bb.Min, bb.Max, IM_COL32(255,255,0,120)); // [DEBUG]
     //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;
     return true;
 }
 }
 
 
@@ -1968,12 +1972,12 @@ bool ImGui::IsItemHovered()
     ImGuiContext& g = *GImGui;
     ImGuiContext& g = *GImGui;
 
 
     ImGuiWindow* window = g.CurrentWindow;
     ImGuiWindow* window = g.CurrentWindow;
+    if (!window->DC.LastItemRectHoveredRect)
+        return false;
     if (g.HoveredWindow != window)
     if (g.HoveredWindow != window)
         return false;
         return false;
     if (g.ActiveId != 0 && g.ActiveId != window->DC.LastItemId && !g.ActiveIdAllowOverlap && g.ActiveId != window->MoveId)
     if (g.ActiveId != 0 && g.ActiveId != window->DC.LastItemId && !g.ActiveIdAllowOverlap && g.ActiveId != window->MoveId)
         return false;
         return false;
-    if (!IsMouseHoveringRect(window->DC.LastItemRect.Min, window->DC.LastItemRect.Max))
-        return false;
     if (!IsWindowContentHoverable(window))
     if (!IsWindowContentHoverable(window))
         return false;
         return false;
     return true;
     return true;
@@ -1982,7 +1986,7 @@ bool ImGui::IsItemHovered()
 bool ImGui::IsItemRectHovered()
 bool ImGui::IsItemRectHovered()
 {
 {
     ImGuiWindow* window = GetCurrentWindowRead();
     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().
 // Internal facing ItemHoverable() used when submitting widgets. Differs slightly from IsItemHovered().

+ 3 - 2
imgui_demo.cpp

@@ -1505,7 +1505,7 @@ void ImGui::ShowTestWindow(bool* p_open)
             ImGui::Text("ID"); ImGui::NextColumn();
             ImGui::Text("ID"); ImGui::NextColumn();
             ImGui::Text("Name"); ImGui::NextColumn();
             ImGui::Text("Name"); ImGui::NextColumn();
             ImGui::Text("Path"); ImGui::NextColumn();
             ImGui::Text("Path"); ImGui::NextColumn();
-            ImGui::Text("Flags"); ImGui::NextColumn();
+            ImGui::Text("Hovered"); ImGui::NextColumn();
             ImGui::Separator();
             ImGui::Separator();
             const char* names[3] = { "One", "Two", "Three" };
             const char* names[3] = { "One", "Two", "Three" };
             const char* paths[3] = { "/path/one", "/path/two", "/path/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);
                 sprintf(label, "%04d", i);
                 if (ImGui::Selectable(label, selected == i, ImGuiSelectableFlags_SpanAllColumns))
                 if (ImGui::Selectable(label, selected == i, ImGuiSelectableFlags_SpanAllColumns))
                     selected = i;
                     selected = i;
+                bool hovered = ImGui::IsItemHovered();
                 ImGui::NextColumn();
                 ImGui::NextColumn();
                 ImGui::Text(names[i]); ImGui::NextColumn();
                 ImGui::Text(names[i]); ImGui::NextColumn();
                 ImGui::Text(paths[i]); ImGui::NextColumn();
                 ImGui::Text(paths[i]); ImGui::NextColumn();
-                ImGui::Text("...."); ImGui::NextColumn();
+                ImGui::Text("%d", hovered); ImGui::NextColumn();
             }
             }
             ImGui::Columns(1);
             ImGui::Columns(1);
             ImGui::Separator();
             ImGui::Separator();

+ 3 - 1
imgui_internal.h

@@ -600,6 +600,7 @@ struct IMGUI_API ImGuiDrawContext
     int                     TreeDepth;
     int                     TreeDepth;
     ImGuiID                 LastItemId;
     ImGuiID                 LastItemId;
     ImRect                  LastItemRect;
     ImRect                  LastItemRect;
+    bool                    LastItemRectHoveredRect;
     bool                    MenuBarAppending;
     bool                    MenuBarAppending;
     float                   MenuBarOffsetX;
     float                   MenuBarOffsetX;
     ImVector<ImGuiWindow*>  ChildWindows;
     ImVector<ImGuiWindow*>  ChildWindows;
@@ -639,7 +640,8 @@ struct IMGUI_API ImGuiDrawContext
         LogLinePosY = -1.0f;
         LogLinePosY = -1.0f;
         TreeDepth = 0;
         TreeDepth = 0;
         LastItemId = 0;
         LastItemId = 0;
-        LastItemRect = ImRect(0.0f,0.0f,0.0f,0.0f);
+        LastItemRect = ImRect();
+        LastItemRectHoveredRect = false;
         MenuBarAppending = false;
         MenuBarAppending = false;
         MenuBarOffsetX = 0.0f;
         MenuBarOffsetX = 0.0f;
         StateStorage = NULL;
         StateStorage = NULL;