Internals: Docking, Tab Bar: Add DockNodeBeginAmendTabBar() and work toward making hybrid dock node with windows tab bars somehow work (not done).

This commit is contained in:
ocornut
2020-10-14 19:11:00 +02:00
parent bae2240eda
commit b26f1530b7
3 changed files with 56 additions and 22 deletions

View File

@ -6824,7 +6824,7 @@ struct ImGuiTabBarSection
namespace ImGui
{
static void TabBarLayout(ImGuiTabBar* tab_bar);
static ImU32 TabBarCalcTabID(ImGuiTabBar* tab_bar, const char* label);
static ImU32 TabBarCalcTabID(ImGuiTabBar* tab_bar, const char* label, ImGuiWindow* docked_window);
static float TabBarCalcMaxTabWidth();
static float TabBarScrollClamp(ImGuiTabBar* tab_bar, float scrolling);
static void TabBarScrollToTab(ImGuiTabBar* tab_bar, ImGuiTabItem* tab, ImGuiTabBarSection* sections);
@ -6918,7 +6918,7 @@ bool ImGui::BeginTabBarEx(ImGuiTabBar* tab_bar, const ImRect& tab_bar_bb, ImG
// Ensure correct ordering when toggling ImGuiTabBarFlags_Reorderable flag, or when a new tab was added while being not reorderable
if ((flags & ImGuiTabBarFlags_Reorderable) != (tab_bar->Flags & ImGuiTabBarFlags_Reorderable) || (tab_bar->TabsAddedNew && !(flags & ImGuiTabBarFlags_Reorderable)))
if (tab_bar->Tabs.Size > 1 && (flags & ImGuiTabBarFlags_DockNode) == 0)
if (tab_bar->Tabs.Size > 1 && (flags & ImGuiTabBarFlags_DockNode) == 0) // FIXME: TabBar with DockNode can now be hybrid
ImQsort(tab_bar->Tabs.Data, tab_bar->Tabs.Size, sizeof(ImGuiTabItem), TabItemComparerByBeginOrder);
tab_bar->TabsAddedNew = false;
@ -7177,6 +7177,7 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar)
{
ImGuiTabItem* tab = &tab_bar->Tabs[section_tab_index + tab_n];
tab->Offset = tab_offset;
tab->NameOffset = -1;
tab_offset += tab->Width + (tab_n < section->TabCount - 1 ? g.Style.ItemInnerSpacing.x : 0.0f);
}
tab_bar->WidthAllTabs += ImMax(section->Width + section->Spacing, 0.0f);
@ -7184,6 +7185,9 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar)
section_tab_index += section->TabCount;
}
// Clear name buffers
tab_bar->TabsNames.Buf.resize(0);
// If we have lost the selected tab, select the next most recently active one
if (found_selected_tab_id == false)
tab_bar->SelectedTabId = 0;
@ -7220,21 +7224,18 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar)
tab_bar->ScrollingRectMinX = tab_bar->BarRect.Min.x + sections[0].Width + sections[0].Spacing;
tab_bar->ScrollingRectMaxX = tab_bar->BarRect.Max.x - sections[2].Width - sections[1].Spacing;
// Clear name buffers
if ((tab_bar->Flags & ImGuiTabBarFlags_DockNode) == 0)
tab_bar->TabsNames.Buf.resize(0);
// Actual layout in host window (we don't do it in BeginTabBar() so as not to waste an extra frame)
ImGuiWindow* window = g.CurrentWindow;
window->DC.CursorPos = tab_bar->BarRect.Min;
ItemSize(ImVec2(tab_bar->WidthAllTabsIdeal, tab_bar->BarRect.GetHeight()), tab_bar->FramePadding.y);
}
// Dockables uses Name/ID in the global namespace. Non-dockable items use the ID stack.
static ImU32 ImGui::TabBarCalcTabID(ImGuiTabBar* tab_bar, const char* label)
// Dockable uses Name/ID in the global namespace. Non-dockable items use the ID stack.
static ImU32 ImGui::TabBarCalcTabID(ImGuiTabBar* tab_bar, const char* label, ImGuiWindow* docked_window)
{
if (tab_bar->Flags & ImGuiTabBarFlags_DockNode)
if (docked_window != NULL)
{
IM_ASSERT(tab_bar->Flags & ImGuiTabBarFlags_DockNode);
ImGuiID id = ImHashStr(label);
KeepAliveID(id);
return id;
@ -7581,7 +7582,7 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
return false;
const ImGuiStyle& style = g.Style;
const ImGuiID id = TabBarCalcTabID(tab_bar, label);
const ImGuiID id = TabBarCalcTabID(tab_bar, label, docked_window);
// If the user called us with *p_open == false, we early out and don't render.
// We make a call to ItemAdd() so that attempts to use a contextual popup menu with an implicit ID won't use an older ID.
@ -7631,9 +7632,10 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
tab->Window = docked_window;
// Append name with zero-terminator
if (tab_bar->Flags & ImGuiTabBarFlags_DockNode)
// (regular tabs are permitted in a DockNode tab bar, but window tabs not permitted in a non-DockNode tab bar)
if (tab->Window != NULL)
{
IM_ASSERT(tab->Window != NULL);
IM_ASSERT(tab_bar->Flags & ImGuiTabBarFlags_DockNode);
tab->NameOffset = -1;
}
else
@ -7851,7 +7853,7 @@ void ImGui::SetTabItemClosed(const char* label)
if (is_within_manual_tab_bar)
{
ImGuiTabBar* tab_bar = g.CurrentTabBar;
ImGuiID tab_id = TabBarCalcTabID(tab_bar, label);
ImGuiID tab_id = TabBarCalcTabID(tab_bar, label, NULL);
if (ImGuiTabItem* tab = TabBarFindTabByID(tab_bar, tab_id))
tab->WantClose = true; // Will be processed by next call to TabBarLayout()
}
@ -7860,7 +7862,7 @@ void ImGui::SetTabItemClosed(const char* label)
if (window->DockIsActive)
if (ImGuiDockNode* node = window->DockNode)
{
ImGuiID tab_id = TabBarCalcTabID(node->TabBar, label);
ImGuiID tab_id = TabBarCalcTabID(node->TabBar, label, window);
TabBarRemoveTab(node->TabBar, tab_id);
window->DockTabWantClose = true;
}