From 8c9b3c9013167606b7398188a81ac5d106b56b96 Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 19 Oct 2020 11:51:38 +0200 Subject: [PATCH] Tab Bar: Fixed using more than 128 tabs in a tab bar. Using ImS16 consistently + some better packing to avoid struct growing size. --- docs/CHANGELOG.txt | 1 + imgui_internal.h | 10 +++++----- imgui_widgets.cpp | 11 +++++------ 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/docs/CHANGELOG.txt b/docs/CHANGELOG.txt index c4a8a8bd..3ede8331 100644 --- a/docs/CHANGELOG.txt +++ b/docs/CHANGELOG.txt @@ -55,6 +55,7 @@ Breaking Changes: Other Changes: - Tab Bar: Made it possible to append to an existing tab bar by calling BeginTabBar()/EndTabBar() again. +- Tab Bar: Fixed using more than 128 tabs in a tab bar (scrolling policy recommended). - Drag and Drop: Fix drag and drop to tie same-size drop targets by choosen the later one. Fixes dragging into a full-window-sized dockspace inside a zero-padded window. (#3519, #2717) [@Black-Cat] - Backends: OpenGL: use glGetString(GL_VERSION) query instead of glGetIntegerv(GL_MAJOR_VERSION, ...) diff --git a/imgui_internal.h b/imgui_internal.h index 3cdc7792..5e408b62 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1736,8 +1736,8 @@ struct ImGuiTabItem float Width; // Width currently displayed float ContentWidth; // Width of label, stored during BeginTabItem() call ImS16 NameOffset; // When Window==NULL, offset to name within parent ImGuiTabBar::TabsNames - ImS8 BeginOrder; // BeginTabItem() order, used to re-order tabs after toggling ImGuiTabBarFlags_Reorderable - ImS8 IndexDuringLayout; // Index only used during TabBarLayout() + ImS16 BeginOrder; // BeginTabItem() order, used to re-order tabs after toggling ImGuiTabBarFlags_Reorderable + ImS16 IndexDuringLayout; // Index only used during TabBarLayout() bool WantClose; // Marked as closed by SetTabItemClosed() ImGuiTabItem() { ID = 0; Flags = ImGuiTabItemFlags_None; LastFrameVisible = LastFrameSelected = -1; NameOffset = -1; Offset = Width = ContentWidth = 0.0f; BeginOrder = -1; IndexDuringLayout = -1; WantClose = false; } @@ -1767,14 +1767,14 @@ struct ImGuiTabBar float ScrollingRectMaxX; ImGuiID ReorderRequestTabId; ImS8 ReorderRequestDir; - ImS8 TabsActiveCount; // Number of tabs submitted this frame. - ImS8 LastTabItemIdx; // Index of last BeginTabItem() tab for use by EndTabItem() ImS8 BeginCount; bool WantLayout; bool VisibleTabWasSubmitted; bool TabsAddedNew; // Set to true when a new tab item or button has been added to the tab bar during last frame + ImS16 TabsActiveCount; // Number of tabs submitted this frame. + ImS16 LastTabItemIdx; // Index of last BeginTabItem() tab for use by EndTabItem() + float ItemSpacingY; ImVec2 FramePadding; // style.FramePadding locked at the time of BeginTabBar() - ImVec2 TabsContentsMin; ImVec2 BackupCursorPos; ImGuiTextBuffer TabsNames; // For non-docking tab bar we re-append names in a contiguous buffer. diff --git a/imgui_widgets.cpp b/imgui_widgets.cpp index b9346e3d..022012fc 100644 --- a/imgui_widgets.cpp +++ b/imgui_widgets.cpp @@ -6882,7 +6882,7 @@ bool ImGui::BeginTabBarEx(ImGuiTabBar* tab_bar, const ImRect& tab_bar_bb, ImG tab_bar->BackupCursorPos = window->DC.CursorPos; if (tab_bar->CurrFrameVisible == g.FrameCount) { - window->DC.CursorPos = tab_bar->TabsContentsMin; + window->DC.CursorPos = ImVec2(tab_bar->BarRect.Min.x, tab_bar->BarRect.Max.y + tab_bar->ItemSpacingY); tab_bar->BeginCount++; return true; } @@ -6904,14 +6904,13 @@ bool ImGui::BeginTabBarEx(ImGuiTabBar* tab_bar, const ImRect& tab_bar_bb, ImG tab_bar->CurrFrameVisible = g.FrameCount; tab_bar->PrevTabsContentsHeight = tab_bar->CurrTabsContentsHeight; tab_bar->CurrTabsContentsHeight = 0.0f; + tab_bar->ItemSpacingY = g.Style.ItemSpacing.y; tab_bar->FramePadding = g.Style.FramePadding; tab_bar->TabsActiveCount = 0; tab_bar->BeginCount = 1; // Set cursor pos in a way which only be used in the off-chance the user erroneously submits item before BeginTabItem(): items will overlap - tab_bar->TabsContentsMin.x = tab_bar->BarRect.Min.x; - tab_bar->TabsContentsMin.y = tab_bar->BarRect.Max.y + g.Style.ItemSpacing.y; - window->DC.CursorPos = tab_bar->TabsContentsMin; + window->DC.CursorPos = ImVec2(tab_bar->BarRect.Min.x, tab_bar->BarRect.Max.y + tab_bar->ItemSpacingY); // Draw separator const ImU32 col = GetColorU32((flags & ImGuiTabBarFlags_IsFocused) ? ImGuiCol_TabActive : ImGuiCol_TabUnfocusedActive); @@ -6990,7 +6989,7 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar) tab_bar->Tabs[tab_dst_n] = tab_bar->Tabs[tab_src_n]; tab = &tab_bar->Tabs[tab_dst_n]; - tab->IndexDuringLayout = (ImS8)tab_dst_n; + tab->IndexDuringLayout = (ImS16)tab_dst_n; // We will need sorting if tabs have changed section (e.g. moved from one of Leading/Central/Trailing to another) int curr_tab_section_n = (tab->Flags & ImGuiTabItemFlags_Leading) ? 0 : (tab->Flags & ImGuiTabItemFlags_Trailing) ? 2 : 1; @@ -7549,7 +7548,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open, tab_bar->TabsAddedNew = true; tab_is_new = true; } - tab_bar->LastTabItemIdx = (ImS8)tab_bar->Tabs.index_from_ptr(tab); + tab_bar->LastTabItemIdx = (ImS16)tab_bar->Tabs.index_from_ptr(tab); tab->ContentWidth = size.x; tab->BeginOrder = tab_bar->TabsActiveCount++;