diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 044c099ae..590fa118c 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -54,6 +54,10 @@ Other Changes: - Menus: - Fixed MenuItem() label position and BeginMenu() arrow/icon/popup positions, when used inside a line with a baseline offset. +- TreeNode: + - Fixed highlight position when used inside a line with a large text baseline offset. + (never quite worked in this situation; but then most of the time the text + baseline offset ends up being zero or FramePadding.y for a given line). - Tables: - Fixed an issue where a very thin scrolling table would advance parent layout slightly differently depending on its visibility (caused by a mismatch diff --git a/imgui.h b/imgui.h index ac64c2ded..facb99975 100644 --- a/imgui.h +++ b/imgui.h @@ -30,7 +30,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.6 WIP" -#define IMGUI_VERSION_NUM 19251 +#define IMGUI_VERSION_NUM 19252 #define IMGUI_HAS_TABLE // Added BeginTable() - from IMGUI_VERSION_NUM >= 18000 #define IMGUI_HAS_TEXTURES // Added ImGuiBackendFlags_RendererHasTextures - from IMGUI_VERSION_NUM >= 19198 diff --git a/imgui_demo.cpp b/imgui_demo.cpp index f3bf332d6..1d914b371 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -4086,6 +4086,7 @@ static void DemoWindowWidgetsTreeNodes() ImGui::CheckboxFlags("ImGuiTreeNodeFlags_SpanAllColumns", &base_flags, ImGuiTreeNodeFlags_SpanAllColumns); ImGui::SameLine(); HelpMarker("For use in Tables only."); ImGui::CheckboxFlags("ImGuiTreeNodeFlags_AllowOverlap", &base_flags, ImGuiTreeNodeFlags_AllowOverlap); ImGui::CheckboxFlags("ImGuiTreeNodeFlags_Framed", &base_flags, ImGuiTreeNodeFlags_Framed); ImGui::SameLine(); HelpMarker("Draw frame with background (e.g. for CollapsingHeader)"); + ImGui::CheckboxFlags("ImGuiTreeNodeFlags_FramePadding", &base_flags, ImGuiTreeNodeFlags_FramePadding); ImGui::CheckboxFlags("ImGuiTreeNodeFlags_NavLeftJumpsToParent", &base_flags, ImGuiTreeNodeFlags_NavLeftJumpsToParent); HelpMarker("Default option for DrawLinesXXX is stored in style.TreeLinesFlags"); @@ -4750,7 +4751,7 @@ static void DemoWindowLayout() // Tree // (here the node appears after a button and has odd intent, so we use ImGuiTreeNodeFlags_DrawLinesNone to disable hierarchy outline) const float spacing = ImGui::GetStyle().ItemInnerSpacing.x; - ImGui::Button("Button##1"); + ImGui::Button("Button##1"); // Will make line higher ImGui::SameLine(0.0f, spacing); if (ImGui::TreeNodeEx("Node##1", ImGuiTreeNodeFlags_DrawLinesNone)) { @@ -4760,14 +4761,22 @@ static void DemoWindowLayout() ImGui::TreePop(); } + const float padding = (float)(int)(ImGui::GetFontSize() * 1.20f); // Large padding + ImGui::PushStyleVarY(ImGuiStyleVar_FramePadding, padding); + ImGui::Button("Button##2"); + ImGui::PopStyleVar(); + ImGui::SameLine(0.0f, spacing); + if (ImGui::TreeNodeEx("Node##2", ImGuiTreeNodeFlags_DrawLinesNone)) + ImGui::TreePop(); + // Vertically align text node a bit lower so it'll be vertically centered with upcoming widget. // Otherwise you can use SmallButton() (smaller fit). ImGui::AlignTextToFramePadding(); // Common mistake to avoid: if we want to SameLine after TreeNode we need to do it before we add - // other contents below the node. - bool node_open = ImGui::TreeNode("Node##2"); - ImGui::SameLine(0.0f, spacing); ImGui::Button("Button##2"); + // other contents "inside" the node. + bool node_open = ImGui::TreeNode("Node##3"); + ImGui::SameLine(0.0f, spacing); ImGui::Button("Button##3"); if (node_open) { // Placeholder tree data @@ -4777,13 +4786,13 @@ static void DemoWindowLayout() } // Bullet - ImGui::Button("Button##3"); + ImGui::Button("Button##4"); ImGui::SameLine(0.0f, spacing); ImGui::BulletText("Bullet text"); ImGui::AlignTextToFramePadding(); ImGui::BulletText("Node"); - ImGui::SameLine(0.0f, spacing); ImGui::Button("Button##4"); + ImGui::SameLine(0.0f, spacing); ImGui::Button("Button##5"); ImGui::Unindent(); } diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index ebb7491ff..2e05af1c6 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -6776,7 +6776,6 @@ static void TreeNodeStoreStackData(ImGuiTreeNodeFlags flags, float x1) window->DC.TreeRecordsClippedNodesY2Mask |= (1 << window->DC.TreeDepth); } -// When using public API, currently 'id == storage_id' is always true, but we separate the values to facilitate advanced user code doing storage queries outside of UI loop. bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* label, const char* label_end) { ImGuiWindow* window = GetCurrentWindow(); @@ -6785,26 +6784,28 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l ImGuiContext& g = *GImGui; const ImGuiStyle& style = g.Style; + + // When not framed, we vertically increase height up to typical framed widget height const bool display_frame = (flags & ImGuiTreeNodeFlags_Framed) != 0; - const ImVec2 padding = (display_frame || (flags & ImGuiTreeNodeFlags_FramePadding)) ? style.FramePadding : ImVec2(style.FramePadding.x, ImMin(window->DC.CurrLineTextBaseOffset, style.FramePadding.y)); + const bool use_frame_padding = (display_frame || (flags & ImGuiTreeNodeFlags_FramePadding)); + const ImVec2 padding = use_frame_padding ? style.FramePadding : ImVec2(style.FramePadding.x, ImMin(window->DC.CurrLineTextBaseOffset, style.FramePadding.y)); if (!label_end) label_end = FindRenderedTextEnd(label); const ImVec2 label_size = CalcTextSize(label, label_end, false); const float text_offset_x = g.FontSize + (display_frame ? padding.x * 3 : padding.x * 2); // Collapsing arrow width + Spacing - const float text_offset_y = ImMax(padding.y, window->DC.CurrLineTextBaseOffset); // Latch before ItemSize changes it + const float text_offset_y = use_frame_padding ? ImMax(style.FramePadding.y, window->DC.CurrLineTextBaseOffset) : window->DC.CurrLineTextBaseOffset; // Latch before ItemSize changes it const float text_width = g.FontSize + label_size.x + padding.x * 2; // Include collapsing arrow - // We vertically grow up to current line height up the typical widget height. - const float frame_height = ImMax(ImMin(window->DC.CurrLineSize.y, g.FontSize + style.FramePadding.y * 2), label_size.y + padding.y * 2); + const float frame_height = label_size.y + padding.y * 2; const bool span_all_columns = (flags & ImGuiTreeNodeFlags_SpanAllColumns) != 0 && (g.CurrentTable != NULL); const bool span_all_columns_label = (flags & ImGuiTreeNodeFlags_LabelSpanAllColumns) != 0 && (g.CurrentTable != NULL); ImRect frame_bb; frame_bb.Min.x = span_all_columns ? window->ParentWorkRect.Min.x : (flags & ImGuiTreeNodeFlags_SpanFullWidth) ? window->WorkRect.Min.x : window->DC.CursorPos.x; - frame_bb.Min.y = window->DC.CursorPos.y; + frame_bb.Min.y = window->DC.CursorPos.y + (text_offset_y - padding.y); frame_bb.Max.x = span_all_columns ? window->ParentWorkRect.Max.x : (flags & ImGuiTreeNodeFlags_SpanLabelWidth) ? window->DC.CursorPos.x + text_width + padding.x : window->WorkRect.Max.x; - frame_bb.Max.y = window->DC.CursorPos.y + frame_height; + frame_bb.Max.y = window->DC.CursorPos.y + (text_offset_y - padding.y) + frame_height; if (display_frame) { const float outer_extend = IM_TRUNC(window->WindowPadding.x * 0.5f); // Framed header expand a little outside of current limits