From cb7ba60d3f7d691c698c4a7499ed64757664d7b8 Mon Sep 17 00:00:00 2001 From: omar Date: Tue, 28 May 2019 21:22:18 +0200 Subject: [PATCH] CollapsingHeader: When a close button is enabled, better clip the label to avoid overlap. (#600) --- docs/CHANGELOG.txt | 1 + imgui_internal.h | 6 ++++++ imgui_widgets.cpp | 14 +++++++++----- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 059950ebe..acd43c0e9 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -51,6 +51,7 @@ Other Changes: - Fixed crash when appending with BeginMainMenuBar() more than once and no other window are showing. (#2567) - ColorEdit: Fixed the color picker popup only displaying inputs as HSV instead of showing multiple options. (#2587, broken in 1.69 by #2384). +- CollapsingHeader: Better clipping when a close button is enabled and it overlaps the label. (#600) - Scrollbar: Very minor bounding box adjustment to cope with various border size. - Style: Added style.WindowMenuButtonPosition (left/right, defaults to ImGuiDir_Left) to move the collapsing/docking button to the other side of the title bar. diff --git a/imgui_internal.h b/imgui_internal.h index cbefc9ea8..ef25cda17 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -361,6 +361,12 @@ enum ImGuiSelectableFlagsPrivate_ ImGuiSelectableFlags_AllowItemOverlap = 1 << 24 }; +// Extend ImGuiTreeNodeFlags_ +enum ImGuiTreeNodeFlagsPrivate_ +{ + ImGuiTreeNodeFlags_ClipLabelForTrailingButton = 1 << 20 +}; + enum ImGuiSeparatorFlags_ { ImGuiSeparatorFlags_None = 0, diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index a691185a3..e806eec01 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -5131,8 +5131,8 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l if (display_frame) { // Framed header expand a little outside the default padding - frame_bb.Min.x -= (float)(int)(window->WindowPadding.x*0.5f) - 1; - frame_bb.Max.x += (float)(int)(window->WindowPadding.x*0.5f) - 1; + frame_bb.Min.x -= (float)(int)(window->WindowPadding.x * 0.5f) - 1; + frame_bb.Max.x += (float)(int)(window->WindowPadding.x * 0.5f) - 1; } const float text_offset_x = (g.FontSize + (display_frame ? padding.x*3 : padding.x*2)); // Collapser arrow width + Spacing @@ -5229,6 +5229,8 @@ bool ImGui::TreeNodeBehavior(ImGuiID id, ImGuiTreeNodeFlags flags, const char* l RenderFrame(frame_bb.Min, frame_bb.Max, col, true, style.FrameRounding); RenderNavHighlight(frame_bb, id, nav_highlight_flags); RenderArrow(frame_bb.Min + ImVec2(padding.x, text_base_offset_y), is_open ? ImGuiDir_Down : ImGuiDir_Right, 1.0f); + if (flags & ImGuiTreeNodeFlags_ClipLabelForTrailingButton) + frame_bb.Max.x -= g.FontSize + style.FramePadding.x; if (g.LogEnabled) { // NB: '##' is normally used to hide text (as a library-wide feature), so we need to specify the text range to make sure the ## aren't stripped out here. @@ -5355,7 +5357,8 @@ bool ImGui::CollapsingHeader(const char* label, bool* p_open, ImGuiTreeNodeFlags return false; ImGuiID id = window->GetID(label); - bool is_open = TreeNodeBehavior(id, flags | ImGuiTreeNodeFlags_CollapsingHeader | (p_open ? ImGuiTreeNodeFlags_AllowItemOverlap : 0), label); + flags |= ImGuiTreeNodeFlags_CollapsingHeader | (p_open ? ImGuiTreeNodeFlags_AllowItemOverlap | ImGuiTreeNodeFlags_ClipLabelForTrailingButton : 0); + bool is_open = TreeNodeBehavior(id, flags, label); if (p_open) { // Create a small overlapping close button @@ -5364,8 +5367,9 @@ bool ImGui::CollapsingHeader(const char* label, bool* p_open, ImGuiTreeNodeFlags ImGuiContext& g = *GImGui; ImGuiItemHoveredDataBackup last_item_backup; float button_size = g.FontSize; - ImVec2 button_pos = ImVec2(ImMin(window->DC.LastItemRect.Max.x, window->ClipRect.Max.x) - g.Style.FramePadding.x * 2.0f - button_size, window->DC.LastItemRect.Min.y); - if (CloseButton(window->GetID((void*)((intptr_t)id + 1)), button_pos)) + float button_x = ImMax(window->DC.LastItemRect.Min.x, window->DC.LastItemRect.Max.x - g.Style.FramePadding.x * 2.0f - button_size); + float button_y = window->DC.LastItemRect.Min.y; + if (CloseButton(window->GetID((void*)((intptr_t)id + 1)), ImVec2(button_x, button_y))) *p_open = false; last_item_backup.Restore(); }