Skip to content

Commit 3ab50c3

Browse files
committed
TreeNode, Style: added style.TreeLinesRounding support. (#2920)
1 parent 9943137 commit 3ab50c3

File tree

5 files changed

+39
-14
lines changed

5 files changed

+39
-14
lines changed

docs/CHANGELOG.txt

+2-1
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,10 @@ Other changes:
6060
- ImGuiTreeNodeFlags_DrawLinesNone: No lines drawn (default value in style.TreeLinesFlags).
6161
- ImGuiTreeNodeFlags_DrawLinesFull: Horizontal lines to child nodes. Vertical line drawn down to TreePop() position: cover full contents.
6262
- ImGuiTreeNodeFlags_DrawLinesToNodes: Horizontal lines to child nodes. Vertical line drawn down to bottom-most child node.
63-
- Added style.TreeLinesFlags which stores the default setting,
63+
- Added style.TreeLinesFlags which stores the default setting,
6464
which may be overriden in individual TreeNode() calls.
6565
- Added style.TreeLinesSize (default to 1.0f).
66+
- Added style.TreeLinesRadius (default to 0.0f).
6667
- Added ImGuiCol_TreeLines (in default style this is the same as ImGuiCol_Border).
6768
- Caveats:
6869
- Tree nodes may be used in many creative ways (manually positioning openable

imgui.cpp

+3
Original file line numberDiff line numberDiff line change
@@ -1362,6 +1362,7 @@ ImGuiStyle::ImGuiStyle()
13621362
TableAngledHeadersTextAlign = ImVec2(0.5f,0.0f);// Alignment of angled headers within the cell
13631363
TreeLinesFlags = ImGuiTreeNodeFlags_DrawLinesNone;
13641364
TreeLinesSize = 1.0f; // Thickness of outlines when using ImGuiTreeNodeFlags_DrawLines.
1365+
TreeLinesRounding = 0.0f; // Radius of lines connecting child nodes to the vertical line.
13651366
ColorButtonPosition = ImGuiDir_Right; // Side of the color button in the ColorEdit4 widget (left/right). Defaults to ImGuiDir_Right.
13661367
ButtonTextAlign = ImVec2(0.5f,0.5f);// Alignment of button text when button is larger than text.
13671368
SelectableTextAlign = ImVec2(0.0f,0.0f);// Alignment of selectable text. Defaults to (0.0f, 0.0f) (top-left aligned). It's generally important to keep this left-aligned if you want to lay multiple items on a same line.
@@ -1416,6 +1417,7 @@ void ImGuiStyle::ScaleAllSizes(float scale_factor)
14161417
TabCloseButtonMinWidthSelected = (TabCloseButtonMinWidthSelected > 0.0f && TabCloseButtonMinWidthSelected != FLT_MAX) ? ImTrunc(TabCloseButtonMinWidthSelected * scale_factor) : TabCloseButtonMinWidthSelected;
14171418
TabCloseButtonMinWidthUnselected = (TabCloseButtonMinWidthUnselected > 0.0f && TabCloseButtonMinWidthUnselected != FLT_MAX) ? ImTrunc(TabCloseButtonMinWidthUnselected * scale_factor) : TabCloseButtonMinWidthUnselected;
14181419
TabBarOverlineSize = ImTrunc(TabBarOverlineSize * scale_factor);
1420+
TreeLinesRounding = ImTrunc(TreeLinesRounding * scale_factor);
14191421
SeparatorTextPadding = ImTrunc(SeparatorTextPadding * scale_factor);
14201422
DisplayWindowPadding = ImTrunc(DisplayWindowPadding * scale_factor);
14211423
DisplaySafeAreaPadding = ImTrunc(DisplaySafeAreaPadding * scale_factor);
@@ -3418,6 +3420,7 @@ static const ImGuiStyleVarInfo GStyleVarsInfo[] =
34183420
{ 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, TableAngledHeadersAngle)}, // ImGuiStyleVar_TableAngledHeadersAngle
34193421
{ 2, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, TableAngledHeadersTextAlign)},// ImGuiStyleVar_TableAngledHeadersTextAlign
34203422
{ 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, TreeLinesSize)}, // ImGuiStyleVar_TreeLinesSize
3423+
{ 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, TreeLinesRounding)}, // ImGuiStyleVar_TreeLinesRounding
34213424
{ 2, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, ButtonTextAlign) }, // ImGuiStyleVar_ButtonTextAlign
34223425
{ 2, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, SelectableTextAlign) }, // ImGuiStyleVar_SelectableTextAlign
34233426
{ 1, ImGuiDataType_Float, (ImU32)offsetof(ImGuiStyle, SeparatorTextBorderSize)}, // ImGuiStyleVar_SeparatorTextBorderSize

imgui.h

+3-1
Original file line numberDiff line numberDiff line change
@@ -1730,6 +1730,7 @@ enum ImGuiStyleVar_
17301730
ImGuiStyleVar_TableAngledHeadersAngle, // float TableAngledHeadersAngle
17311731
ImGuiStyleVar_TableAngledHeadersTextAlign,// ImVec2 TableAngledHeadersTextAlign
17321732
ImGuiStyleVar_TreeLinesSize, // float TreeLinesSize
1733+
ImGuiStyleVar_TreeLinesRounding, // float TreeLinesRounding
17331734
ImGuiStyleVar_ButtonTextAlign, // ImVec2 ButtonTextAlign
17341735
ImGuiStyleVar_SelectableTextAlign, // ImVec2 SelectableTextAlign
17351736
ImGuiStyleVar_SeparatorTextBorderSize, // float SeparatorTextBorderSize
@@ -2190,7 +2191,8 @@ struct ImGuiStyle
21902191
float TableAngledHeadersAngle; // Angle of angled headers (supported values range from -50.0f degrees to +50.0f degrees).
21912192
ImVec2 TableAngledHeadersTextAlign;// Alignment of angled headers within the cell
21922193
ImGuiTreeNodeFlags TreeLinesFlags; // Default way to draw lines connecting TreeNode hierarchy. ImGuiTreeNodeFlags_DrawLinesNone or ImGuiTreeNodeFlags_DrawLinesFull or ImGuiTreeNodeFlags_DrawLinesToNodes.
2193-
float TreeLinesSize; // Thickness of outlines when using ImGuiTreeNodeFlags_DrawLines.
2194+
float TreeLinesSize; // Thickness of outlines when using ImGuiTreeNodeFlags_DrawLines.
2195+
float TreeLinesRounding; // Radius of lines connecting child nodes to the vertical line.
21942196
ImGuiDir ColorButtonPosition; // Side of the color button in the ColorEdit4 widget (left/right). Defaults to ImGuiDir_Right.
21952197
ImVec2 ButtonTextAlign; // Alignment of button text when button is larger than text. Defaults to (0.5f, 0.5f) (centered).
21962198
ImVec2 SelectableTextAlign; // Alignment of selectable text. Defaults to (0.0f, 0.0f) (top-left aligned). It's generally important to keep this left-aligned if you want to lay multiple items on a same line.

imgui_demo.cpp

+15-9
Original file line numberDiff line numberDiff line change
@@ -8270,15 +8270,11 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
82708270
ImGui::SliderAngle("TableAngledHeadersAngle", &style.TableAngledHeadersAngle, -50.0f, +50.0f);
82718271
ImGui::SliderFloat2("TableAngledHeadersTextAlign", (float*)&style.TableAngledHeadersTextAlign, 0.0f, 1.0f, "%.2f");
82728272

8273-
ImGui::SeparatorText("Windows");
8274-
ImGui::SliderFloat2("WindowTitleAlign", (float*)&style.WindowTitleAlign, 0.0f, 1.0f, "%.2f");
8275-
ImGui::SliderFloat("WindowBorderHoverPadding", &style.WindowBorderHoverPadding, 1.0f, 20.0f, "%.0f");
8276-
int window_menu_button_position = style.WindowMenuButtonPosition + 1;
8277-
if (ImGui::Combo("WindowMenuButtonPosition", (int*)&window_menu_button_position, "None\0Left\0Right\0"))
8278-
style.WindowMenuButtonPosition = (ImGuiDir)(window_menu_button_position - 1);
8279-
8280-
ImGui::SeparatorText("Widgets");
8281-
if (ImGui::BeginCombo("TreeLinesFlags", GetTreeLinesFlagsName(style.TreeLinesFlags)))
8273+
ImGui::SeparatorText("Trees");
8274+
bool combo_open = ImGui::BeginCombo("TreeLinesFlags", GetTreeLinesFlagsName(style.TreeLinesFlags));
8275+
ImGui::SameLine();
8276+
HelpMarker("[Experimental] Tree lines may not work in all situations (e.g. using a clipper) and may incurs slight traversal overhead.\n\nImGuiTreeNodeFlags_DrawLinesFull is faster than ImGuiTreeNodeFlags_DrawLinesToNode.");
8277+
if (combo_open)
82828278
{
82838279
const ImGuiTreeNodeFlags options[] = { ImGuiTreeNodeFlags_DrawLinesNone, ImGuiTreeNodeFlags_DrawLinesFull, ImGuiTreeNodeFlags_DrawLinesToNodes };
82848280
for (ImGuiTreeNodeFlags option : options)
@@ -8287,6 +8283,16 @@ void ImGui::ShowStyleEditor(ImGuiStyle* ref)
82878283
ImGui::EndCombo();
82888284
}
82898285
ImGui::SliderFloat("TreeLinesSize", &style.TreeLinesSize, 0.0f, 2.0f, "%.0f");
8286+
ImGui::SliderFloat("TreeLinesRounding", &style.TreeLinesRounding, 0.0f, 12.0f, "%.0f");
8287+
8288+
ImGui::SeparatorText("Windows");
8289+
ImGui::SliderFloat2("WindowTitleAlign", (float*)&style.WindowTitleAlign, 0.0f, 1.0f, "%.2f");
8290+
ImGui::SliderFloat("WindowBorderHoverPadding", &style.WindowBorderHoverPadding, 1.0f, 20.0f, "%.0f");
8291+
int window_menu_button_position = style.WindowMenuButtonPosition + 1;
8292+
if (ImGui::Combo("WindowMenuButtonPosition", (int*)&window_menu_button_position, "None\0Left\0Right\0"))
8293+
style.WindowMenuButtonPosition = (ImGuiDir)(window_menu_button_position - 1);
8294+
8295+
ImGui::SeparatorText("Widgets");
82908296
ImGui::Combo("ColorButtonPosition", (int*)&style.ColorButtonPosition, "Left\0Right\0");
82918297
ImGui::SliderFloat2("ButtonTextAlign", (float*)&style.ButtonTextAlign, 0.0f, 1.0f, "%.2f");
82928298
ImGui::SameLine(); HelpMarker("Alignment applies when a button is larger than its text content.");

imgui_widgets.cpp

+16-3
Original file line numberDiff line numberDiff line change
@@ -6867,9 +6867,22 @@ void ImGui::TreeNodeDrawLineToChildNode(const ImVec2& target_pos)
68676867
float x1 = ImTrunc(parent_data->DrawLinesX1);
68686868
float x2 = ImTrunc(target_pos.x - g.Style.ItemInnerSpacing.x);
68696869
float y = ImTrunc(target_pos.y);
6870-
parent_data->DrawLinesToNodesY2 = ImMax(parent_data->DrawLinesToNodesY2, y);
6871-
if (x1 < x2)
6870+
float rounding = (g.Style.TreeLinesRounding > 0.0f) ? ImMin(x2 - x1, g.Style.TreeLinesRounding) : 0.0f;
6871+
parent_data->DrawLinesToNodesY2 = ImMax(parent_data->DrawLinesToNodesY2, y - rounding);
6872+
if (x1 >= x2)
6873+
return;
6874+
if (rounding > 0.0f)
6875+
{
6876+
x1 += 0.5f + rounding;
6877+
window->DrawList->PathArcToFast(ImVec2(x1, y - rounding), rounding, 6, 3);
6878+
if (x1 < x2)
6879+
window->DrawList->PathLineTo(ImVec2(x2, y));
6880+
window->DrawList->PathStroke(GetColorU32(ImGuiCol_TreeLines), ImDrawFlags_None, g.Style.TreeLinesSize);
6881+
}
6882+
else
6883+
{
68726884
window->DrawList->AddLine(ImVec2(x1, y), ImVec2(x2, y), GetColorU32(ImGuiCol_TreeLines), g.Style.TreeLinesSize);
6885+
}
68736886
}
68746887

68756888
// Draw vertical line of the hierarchy
@@ -6885,7 +6898,7 @@ void ImGui::TreeNodeDrawLineToTreePop(const ImGuiTreeNodeStackData* data)
68856898
if (g.CurrentTable)
68866899
y2_full = ImMax(g.CurrentTable->RowPosY2, y2_full);
68876900
y2_full = ImTrunc(y2_full - g.Style.ItemSpacing.y - g.FontSize * 0.5f);
6888-
if (y2 + g.Style.ItemSpacing.y < y2_full) // FIXME: threshold to use ToNodes Y2 instead of Full Y2 when close by ItemSpacing.y
6901+
if (y2 + (g.Style.ItemSpacing.y + g.Style.TreeLinesRounding) < y2_full) // FIXME: threshold to use ToNodes Y2 instead of Full Y2 when close by ItemSpacing.y
68896902
y2 = y2_full;
68906903
}
68916904
y2 = ImMin(y2, window->ClipRect.Max.y);

0 commit comments

Comments
 (0)