TabBar: using <> scrolling buttons while the selected Tab is at either end of the section mid-section but not fully visible always makes it fully visible.

This commit is contained in:
ocornut 2026-09-14 19:25:33 +02:00
parent c8b9f0d6be
commit b00dd14a34
3 changed files with 26 additions and 4 deletions

View file

@ -62,7 +62,10 @@ Other Changes:
features or other features requiring stack storage. (#9509) [@lasrod]
- TabBar:
- Improved scroll target when clicking a Tab that is larger than the scrolling
region width.
section width.
- Using <> scrolling buttons while the selected Tab is at either end of the
section mid-section but not fully visible always makes it fully visible
(before eventually selecting a Tab in the leading/trailing section)
- Fonts:
- Reworked `AddFontDefault()` to use `io.DisplayFrameBufferScale` as part of the heuristic
to select `AddFontDefaultVector()` by default, effectively using ProggyForever instead of

View file

@ -3744,8 +3744,10 @@ static void DemoWindowWidgetsTabs()
// but they tend to make more sense together)
static bool show_leading_button = true;
static bool show_trailing_button = true;
static bool show_leading_trailing_tabs = false;
ImGui::Checkbox("Show Leading TabItemButton()", &show_leading_button);
ImGui::Checkbox("Show Trailing TabItemButton()", &show_trailing_button);
ImGui::Checkbox("Show Leading+Trailing TabItem()", &show_leading_trailing_tabs);
// Expose some other flags which are useful to showcase how they interact with Leading/Trailing tabs
static ImGuiTabBarFlags tab_bar_flags = ImGuiTabBarFlags_AutoSelectNewTabs | ImGuiTabBarFlags_Reorderable | ImGuiTabBarFlags_FittingPolicyMixed;
@ -3763,6 +3765,15 @@ static void DemoWindowWidgetsTabs()
ImGui::EndPopup();
}
// Demo Leading/Trailing Tabs
if (show_leading_trailing_tabs)
{
if (ImGui::BeginTabItem("Leading", NULL, ImGuiTabItemFlags_Leading))
ImGui::EndTabItem();
if (ImGui::BeginTabItem("Trailing", NULL, ImGuiTabItemFlags_Trailing))
ImGui::EndTabItem();
}
// Demo Trailing Tabs: click the "+" button to add a new tab.
// (In your app you may want to use a font icon instead of the "+")
// We submit it before the regular tabs, but thanks to the ImGuiTabItemFlags_Trailing flag it will always appear at the end.

View file

@ -10220,16 +10220,17 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar)
}
// Horizontal scrolling buttons
// Important: note that TabBarScrollButtons() will alter BarRect.Max.x.
// - Important: note that TabBarScrollButtons() will alter BarRect.Max.x.
// - Selection skips buttons and might cross through sections if there are Tabs in Leading/Trailing sections.
const bool can_scroll = (tab_bar->Flags & ImGuiTabBarFlags_FittingPolicyScroll) || (tab_bar->Flags & ImGuiTabBarFlags_FittingPolicyMixed);
const float width_all_tabs_to_use_for_scroll = (tab_bar->Flags & ImGuiTabBarFlags_FittingPolicyScroll) ? tab_bar->WidthAllTabs : width_all_tabs_after_min_width_shrink;
tab_bar->ScrollButtonEnabled = ((width_all_tabs_to_use_for_scroll > tab_bar->BarRect.GetWidth() && tab_bar->Tabs.Size > 1) && !(tab_bar->Flags & ImGuiTabBarFlags_NoTabListScrollingButtons) && can_scroll);
if (tab_bar->ScrollButtonEnabled)
if (ImGuiTabItem* scroll_and_select_tab = TabBarScrollingButtons(tab_bar))
{
scroll_to_tab_id = scroll_and_select_tab->ID;
if ((scroll_and_select_tab->Flags & ImGuiTabItemFlags_Button) == 0)
tab_bar->SelectedTabId = scroll_to_tab_id;
tab_bar->SelectedTabId = scroll_and_select_tab->ID;
scroll_to_tab_id = scroll_and_select_tab->ID;
}
if (scroll_to_tab_id == 0 && scroll_to_selected_tab)
scroll_to_tab_id = tab_bar->SelectedTabId;
@ -10457,6 +10458,13 @@ static void ImGui::TabBarScrollToTab(ImGuiTabBar* tab_bar, ImGuiID tab_id, ImGui
ImGuiTabItem* tab = TabBarFindTabByID(tab_bar, tab_id);
if (tab == NULL)
return;
// Clamp attempt to scroll to leading/trailing sections items.
// This could be done at the TabBarScrollingButtons() call site as well, but here works.
if (tab->Flags & ImGuiTabItemFlags_Leading)
tab = &tab_bar->Tabs[sections[0].TabCount];
else if (tab->Flags & ImGuiTabItemFlags_Trailing)
tab = &tab_bar->Tabs[sections[0].TabCount + sections[1].TabCount];
if (tab->Flags & ImGuiTabItemFlags_SectionMask_)
return;