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

This commit is contained in:
ocornut 2025-04-09 12:04:09 +02:00
parent 39f34e1e58
commit 789de09dda
5 changed files with 29 additions and 16 deletions

View file

@ -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

View file

@ -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();
}
}

View file

@ -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
/*

View file

@ -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);

View file

@ -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();