Browse Source

Made BeginItemTooltip() and IsItemHovered() with delay flag infer an implicit ID using Pos only. (#7945, #1485, #143)

Perhaps a better approach would be to: store last non-zero ID + count successive zero ID and combine then.
ocornut 11 months ago
parent
commit
f99febfd6f
4 changed files with 16 additions and 3 deletions
  1. 2 0
      docs/CHANGELOG.txt
  2. 11 1
      imgui.cpp
  3. 1 1
      imgui.h
  4. 2 1
      imgui_internal.h

+ 2 - 0
docs/CHANGELOG.txt

@@ -76,6 +76,8 @@ Other changes:
 - Windows: adjust default ClipRect to better match rendering of thick borders (which are in
 - Windows: adjust default ClipRect to better match rendering of thick borders (which are in
   theory not supported). Compensate for the fact that borders are centered around the windows
   theory not supported). Compensate for the fact that borders are centered around the windows
   edge rather than inner. (#7887, #7888 + #3312, #7540, #3756, #6170, #6365)
   edge rather than inner. (#7887, #7888 + #3312, #7540, #3756, #6170, #6365)
+- Made BeginItemTooltip() and IsItemHovered() with delay flag infer an implicit ID (for
+  ID-less items such as Text element) in a way that works when item resizes. (#7945, #1485)
 - MultiSelect+TreeNode+Drag and Drop: fixed an issue where carrying a drag and drop
 - MultiSelect+TreeNode+Drag and Drop: fixed an issue where carrying a drag and drop
   payload over an already open tree node would incorrectly select it. (#7850)
   payload over an already open tree node would incorrectly select it. (#7850)
 - MultiSelect+TreeNode: default open behavior is OpenOnDoubleClick + OpenOnArrow
 - MultiSelect+TreeNode: default open behavior is OpenOnDoubleClick + OpenOnArrow

+ 11 - 1
imgui.cpp

@@ -4261,7 +4261,7 @@ bool ImGui::IsItemHovered(ImGuiHoveredFlags flags)
     const float delay = CalcDelayFromHoveredFlags(flags);
     const float delay = CalcDelayFromHoveredFlags(flags);
     if (delay > 0.0f || (flags & ImGuiHoveredFlags_Stationary))
     if (delay > 0.0f || (flags & ImGuiHoveredFlags_Stationary))
     {
     {
-        ImGuiID hover_delay_id = (g.LastItemData.ID != 0) ? g.LastItemData.ID : window->GetIDFromRectangle(g.LastItemData.Rect);
+        ImGuiID hover_delay_id = (g.LastItemData.ID != 0) ? g.LastItemData.ID : window->GetIDFromPos(g.LastItemData.Rect.Min);
         if ((flags & ImGuiHoveredFlags_NoSharedDelay) && (g.HoverItemDelayIdPreviousFrame != hover_delay_id))
         if ((flags & ImGuiHoveredFlags_NoSharedDelay) && (g.HoverItemDelayIdPreviousFrame != hover_delay_id))
             g.HoverItemDelayTimer = 0.0f;
             g.HoverItemDelayTimer = 0.0f;
         g.HoverItemDelayId = hover_delay_id;
         g.HoverItemDelayId = hover_delay_id;
@@ -8367,6 +8367,16 @@ ImGuiID ImGuiWindow::GetID(int n)
 }
 }
 
 
 // This is only used in rare/specific situations to manufacture an ID out of nowhere.
 // This is only used in rare/specific situations to manufacture an ID out of nowhere.
+// FIXME: Consider instead storing last non-zero ID + count of successive zero-ID, and combine those?
+ImGuiID ImGuiWindow::GetIDFromPos(const ImVec2& p_abs)
+{
+    ImGuiID seed = IDStack.back();
+    ImVec2 p_rel = ImGui::WindowPosAbsToRel(this, p_abs);
+    ImGuiID id = ImHashData(&p_rel, sizeof(p_rel), seed);
+    return id;
+}
+
+// "
 ImGuiID ImGuiWindow::GetIDFromRectangle(const ImRect& r_abs)
 ImGuiID ImGuiWindow::GetIDFromRectangle(const ImRect& r_abs)
 {
 {
     ImGuiID seed = IDStack.back();
     ImGuiID seed = IDStack.back();

+ 1 - 1
imgui.h

@@ -29,7 +29,7 @@
 // Library Version
 // Library Version
 // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
 // (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM >= 12345')
 #define IMGUI_VERSION       "1.91.1 WIP"
 #define IMGUI_VERSION       "1.91.1 WIP"
-#define IMGUI_VERSION_NUM   19104
+#define IMGUI_VERSION_NUM   19105
 #define IMGUI_HAS_TABLE
 #define IMGUI_HAS_TABLE
 
 
 /*
 /*

+ 2 - 1
imgui_internal.h

@@ -2715,6 +2715,7 @@ public:
     ImGuiID     GetID(const char* str, const char* str_end = NULL);
     ImGuiID     GetID(const char* str, const char* str_end = NULL);
     ImGuiID     GetID(const void* ptr);
     ImGuiID     GetID(const void* ptr);
     ImGuiID     GetID(int n);
     ImGuiID     GetID(int n);
+    ImGuiID     GetIDFromPos(const ImVec2& p_abs);
     ImGuiID     GetIDFromRectangle(const ImRect& r_abs);
     ImGuiID     GetIDFromRectangle(const ImRect& r_abs);
 
 
     // We don't use g.FontSize because the window may be != g.CurrentWindow.
     // We don't use g.FontSize because the window may be != g.CurrentWindow.
@@ -3124,8 +3125,8 @@ namespace ImGui
     inline void             SetWindowParentWindowForFocusRoute(ImGuiWindow* window, ImGuiWindow* parent_window) { window->ParentWindowForFocusRoute = parent_window; }
     inline void             SetWindowParentWindowForFocusRoute(ImGuiWindow* window, ImGuiWindow* parent_window) { window->ParentWindowForFocusRoute = parent_window; }
     inline ImRect           WindowRectAbsToRel(ImGuiWindow* window, const ImRect& r) { ImVec2 off = window->DC.CursorStartPos; return ImRect(r.Min.x - off.x, r.Min.y - off.y, r.Max.x - off.x, r.Max.y - off.y); }
     inline ImRect           WindowRectAbsToRel(ImGuiWindow* window, const ImRect& r) { ImVec2 off = window->DC.CursorStartPos; return ImRect(r.Min.x - off.x, r.Min.y - off.y, r.Max.x - off.x, r.Max.y - off.y); }
     inline ImRect           WindowRectRelToAbs(ImGuiWindow* window, const ImRect& r) { ImVec2 off = window->DC.CursorStartPos; return ImRect(r.Min.x + off.x, r.Min.y + off.y, r.Max.x + off.x, r.Max.y + off.y); }
     inline ImRect           WindowRectRelToAbs(ImGuiWindow* window, const ImRect& r) { ImVec2 off = window->DC.CursorStartPos; return ImRect(r.Min.x + off.x, r.Min.y + off.y, r.Max.x + off.x, r.Max.y + off.y); }
-    inline ImVec2           WindowPosRelToAbs(ImGuiWindow* window, const ImVec2& p)  { ImVec2 off = window->DC.CursorStartPos; return ImVec2(p.x + off.x, p.y + off.y); }
     inline ImVec2           WindowPosAbsToRel(ImGuiWindow* window, const ImVec2& p)  { ImVec2 off = window->DC.CursorStartPos; return ImVec2(p.x - off.x, p.y - off.y); }
     inline ImVec2           WindowPosAbsToRel(ImGuiWindow* window, const ImVec2& p)  { ImVec2 off = window->DC.CursorStartPos; return ImVec2(p.x - off.x, p.y - off.y); }
+    inline ImVec2           WindowPosRelToAbs(ImGuiWindow* window, const ImVec2& p)  { ImVec2 off = window->DC.CursorStartPos; return ImVec2(p.x + off.x, p.y + off.y); }
 
 
     // Windows: Display Order and Focus Order
     // Windows: Display Order and Focus Order
     IMGUI_API void          FocusWindow(ImGuiWindow* window, ImGuiFocusRequestFlags flags = 0);
     IMGUI_API void          FocusWindow(ImGuiWindow* window, ImGuiFocusRequestFlags flags = 0);