From c4b91017599e222d538c917930d70f7fe0a04de1 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 21 Jun 2022 17:11:51 +0200 Subject: [PATCH] TabBar: Tweak shrinking policy so that while resizing tabs that don't need shrinking keep their initial width more precisely. Has been the case before but adding support for SetNextItemWidth() #5262 made this more noticeable. --- docs/CHANGELOG.txt | 2 ++ imgui_internal.h | 1 + imgui_widgets.cpp | 15 +++++++++------ 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index e005264d..339e5c0b 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -106,6 +106,8 @@ Other Changes: - Inputs: Fixed IsMouseClicked() repeat mode rate being half of keyboard repeat rate. - ColorEdit: Fixed text baseline alignment after a SameLine() after a ColorEdit() with visible label. - TabBar: TabItem() now reacts to SetNextItemWidth() and SetNextItemOpen(true). (#5262) +- TabBar: Tweak shrinking policy so that while resizing tabs that don't need shrinking keep their + initial width more precisely (without the occasional +1 worth of width). - Menus: Adjusted BeginMenu() closing logic so hovering void or non-MenuItem() in parent window always lead to menu closure. Fixes using items that are not MenuItem() or BeginItem() at the root level of a popup with a child menu opened. diff --git a/imgui_internal.h b/imgui_internal.h index a7a3b9f1..602066a8 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1150,6 +1150,7 @@ struct ImGuiShrinkWidthItem { int Index; float Width; + float InitialWidth; }; struct ImGuiPtrOrIndex diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index c70e7d37..ac1d47d7 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -1540,7 +1540,7 @@ void ImGui::ShrinkWidths(ImGuiShrinkWidthItem* items, int count, float width_exc width_excess -= width_to_remove_per_item * count_same_width; } - // Round width and redistribute remainder left-to-right (could make it an option of the function?) + // Round width and redistribute remainder // Ensure that e.g. the right-most tab of a shrunk tab-bar always reaches exactly at the same distance from the right-most edge of the tab bar separator. width_excess = 0.0f; for (int n = 0; n < count; n++) @@ -1549,10 +1549,13 @@ void ImGui::ShrinkWidths(ImGuiShrinkWidthItem* items, int count, float width_exc width_excess += items[n].Width - width_rounded; items[n].Width = width_rounded; } - if (width_excess > 0.0f) + while (width_excess > 0.0f) for (int n = 0; n < count; n++) - if (items[n].Index < (int)(width_excess + 0.01f)) + if (items[n].Width + 1.0f <= items[n].InitialWidth) + { items[n].Width += 1.0f; + width_excess -= 1.0f; + } } //------------------------------------------------------------------------- @@ -7557,9 +7560,9 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar) // Store data so we can build an array sorted by width if we need to shrink tabs down IM_MSVC_WARNING_SUPPRESS(6385); - int shrink_buffer_index = shrink_buffer_indexes[section_n]++; - g.ShrinkWidthBuffer[shrink_buffer_index].Index = tab_n; - g.ShrinkWidthBuffer[shrink_buffer_index].Width = tab->ContentWidth; + ImGuiShrinkWidthItem* shrink_width_item = &g.ShrinkWidthBuffer[shrink_buffer_indexes[section_n]++]; + shrink_width_item->Index = tab_n; + shrink_width_item->Width = shrink_width_item->InitialWidth = tab->ContentWidth; IM_ASSERT(tab->ContentWidth > 0.0f); tab->Width = tab->ContentWidth;