From 320c94bfaa475fae8e2c3ec2c52cbd48fcbd567a Mon Sep 17 00:00:00 2001 From: ocornut Date: Thu, 31 Jul 2025 23:39:44 +0900 Subject: [PATCH] Tabs: when scrolling is enabled, track selected tabs when resizing down parent container. (#3421, #8800) --- docs/CHANGELOG.txt | 3 +++ imgui_internal.h | 1 + imgui_widgets.cpp | 6 ++++++ 3 files changed, 10 insertions(+) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index 808007d6f..89e8b34eb 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -60,6 +60,9 @@ Other Changes: - Tabs: added style.TabMinWidthShrink, ImGuiStyleVar_TabMinWidthShrink to control the width to shrink to in ImGuiTabBarFlags_FittingPolicyMixed mode. (#3421, #8800). +- Tabs: when scrolling is enabled, track selected tabs when resizing down + parent container. This does not prevent to horizontally scroll it out of + view during normal operations. (#3421, #8800) - Tabs: added style.TabMinWidthBase, ImGuiStyleVar_TabMinWidthBase to control the base minimum width of a tab (default to 1.0f). This is the size before any potential shrinking is applied. diff --git a/imgui_internal.h b/imgui_internal.h index 553c314d3..87472b1fb 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -2758,6 +2758,7 @@ struct IMGUI_API ImGuiTabBar int CurrFrameVisible; int PrevFrameVisible; ImRect BarRect; + float BarRectPrevWidth; // Backup of previous width. When width change we enforce keep horizontal scroll on focused tab. float CurrTabsContentsHeight; float PrevTabsContentsHeight; // Record the height of contents submitted below the tab bar float WidthAllTabs; // Actual width of all tabs (locked during layout) diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index f96a61a0b..3210140c9 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -9555,6 +9555,10 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar) ImGuiContext& g = *GImGui; tab_bar->WantLayout = false; + // Track selected tab when resizing our parent down + const bool scroll_to_selected_tab = (tab_bar->BarRectPrevWidth > tab_bar->BarRect.GetWidth()); + tab_bar->BarRectPrevWidth = tab_bar->BarRect.GetWidth(); + // Garbage collect by compacting list // Detect if we need to sort out tab list (e.g. in rare case where a tab changed section) int tab_dst_n = 0; @@ -9693,6 +9697,8 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar) if ((scroll_and_select_tab->Flags & ImGuiTabItemFlags_Button) == 0) tab_bar->SelectedTabId = scroll_to_tab_id; } + if (scroll_to_tab_id == 0 && scroll_to_selected_tab) + scroll_to_tab_id = tab_bar->SelectedTabId; // Shrink widths if full tabs don't fit in their allocated space float section_0_w = sections[0].Width + sections[0].Spacing;