Browse Source

TreeNode: extracted TreeNodeDrawLineToChildNode() for usage by custom widgets (#2920)

ocornut 4 months ago
parent
commit
789de09dda
5 changed files with 29 additions and 16 deletions
  1. 6 2
      docs/CHANGELOG.txt
  2. 2 2
      imgui.cpp
  3. 1 1
      imgui.h
  4. 1 0
      imgui_internal.h
  5. 19 11
      imgui_widgets.cpp

+ 6 - 2
docs/CHANGELOG.txt

@@ -57,14 +57,18 @@ Other changes:
   one in docking (they accidentally diverged). (#8554)
 - TreeNode: added flags to draw tree hierarchy outlines linking parent
   and tree nodes: (#2920)
-  - ImGuiTreeNodeFlags_DrawLinesNone: No lines drawn.
+  - ImGuiTreeNodeFlags_DrawLinesNone: No lines drawn (default value in style.TreeLinesFlags).
   - ImGuiTreeNodeFlags_DrawLinesFull: Horizontal lines to child nodes. Vertical line drawn down to TreePop() position: cover full contents.
   - ImGuiTreeNodeFlags_DrawLinesToNodes: Horizontal lines to child nodes. Vertical line drawn down to bottom-most child node.
   - Added style.TreeLinesFlags which stores the default setting, 
     which may be overriden in individual TreeNode() calls.
   - Added style.TreeLinesSize (default to 1.0f).
   - Added ImGuiCol_TreeLines (in default style this is the same as ImGuiCol_Border).
-  - The feature adds a little cost as extra data needs to be stored.
+  - Caveats:
+    - Tree nodes may be used in many creative ways (manually positioning openable
+      nodes in unusual ways, using indent to create tree-looking structures, etc.)
+      and the feature may not accurately represent them in every cases.
+    - The feature adds a little cost as extra data needs to be stored.
 - Nav: fixed assertion when holding gamepad FaceLeft/West button to open
   CTRL+Tab windowing + pressing a keyboard key. (#8525)
 - Error Handling: added better error report and recovery for extraneous

+ 2 - 2
imgui.cpp

@@ -16578,9 +16578,9 @@ void ImGui::DebugNodeWindowsListByBeginStackParent(ImGuiWindow** windows, int wi
         ImFormatString(buf, IM_ARRAYSIZE(buf), "[%04d] Window", window->BeginOrderWithinContext);
         //BulletText("[%04d] Window '%s'", window->BeginOrderWithinContext, window->Name);
         DebugNodeWindow(window, buf);
-        Indent();
+        TreePush(buf);
         DebugNodeWindowsListByBeginStackParent(windows + i + 1, windows_size - i - 1, window);
-        Unindent();
+        TreePop();
     }
 }
 

+ 1 - 1
imgui.h

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

+ 1 - 0
imgui_internal.h

@@ -3467,6 +3467,7 @@ namespace ImGui
 
     // Widgets: Tree Nodes
     IMGUI_API bool          TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* label, const char* label_end = NULL);
+    IMGUI_API void          TreeNodeDrawLineToChildNode(const ImVec2& target_pos);
     IMGUI_API void          TreePushOverrideID(ImGuiID id);
     IMGUI_API bool          TreeNodeGetOpen(ImGuiID storage_id);
     IMGUI_API void          TreeNodeSetOpen(ImGuiID storage_id, bool open);

+ 19 - 11
imgui_widgets.cpp

@@ -6822,17 +6822,8 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
                 LogSetNextTextDecoration(">", NULL);
         }
 
-        if (draw_tree_lines && (window->DC.TreeHasStackDataDepthMask & (1 << (window->DC.TreeDepth - 1))))
-        {
-            // Draw horizontal line from our parent node
-            ImGuiTreeNodeStackData* parent_data = &g.TreeNodeStack.Data[g.TreeNodeStack.Size - 1];
-            float x1 = parent_data->DrawLinesX1 + ImTrunc(g.FontSize * 0.5f + g.Style.FramePadding.x); // GetTreeNodeToLabelSpacing() * 0.5f
-            float x2 = text_pos.x - text_offset_x;
-            float y = text_pos.y + ImTrunc(g.FontSize * 0.5f);
-            parent_data->DrawLinesY2 = ImMax(parent_data->DrawLinesY2, y);
-            if (x1 < x2)
-                window->DrawList->AddLine(ImVec2(x1, y), ImVec2(x2, y), GetColorU32(ImGuiCol_TreeLines), g.Style.TreeLinesSize);
-        }
+        if (draw_tree_lines)
+            TreeNodeDrawLineToChildNode(ImVec2(text_pos.x - text_offset_x, text_pos.y + g.FontSize * 0.5f));
 
         if (span_all_columns && !span_all_columns_label)
             TablePopBackgroundChannel();
@@ -6856,6 +6847,23 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l
     return is_open;
 }
 
+// Draw horizontal line from our parent node
+// This is only called for visible child nodes so we are not too fussy anymore about performances
+void ImGui::TreeNodeDrawLineToChildNode(const ImVec2& target_pos)
+{
+    ImGuiContext& g = *GImGui;
+    ImGuiWindow* window = g.CurrentWindow;
+    if ((window->DC.TreeHasStackDataDepthMask & (1 << (window->DC.TreeDepth - 1))) == 0)
+        return;
+
+    ImGuiTreeNodeStackData* parent_data = &g.TreeNodeStack.Data[g.TreeNodeStack.Size - 1];
+    float x1 = parent_data->DrawLinesX1 + ImTrunc(g.FontSize * 0.5f + g.Style.FramePadding.x); // GetTreeNodeToLabelSpacing() * 0.5f
+    float y = ImTrunc(target_pos.y);
+    parent_data->DrawLinesY2 = ImMax(parent_data->DrawLinesY2, y);
+    if (x1 < target_pos.x)
+        window->DrawList->AddLine(ImVec2(x1, y), ImVec2(target_pos.x, y), GetColorU32(ImGuiCol_TreeLines), g.Style.TreeLinesSize);
+}
+
 void ImGui::TreePush(const char* str_id)
 {
     ImGuiWindow* window = GetCurrentWindow();