Docking: Fixed tab order restoring (follow up to 67be485e, broken in 455dc6e2)

This commit is contained in:
omar 2018-09-26 17:07:58 +02:00
parent 45731cca19
commit 4053d9d638
3 changed files with 24 additions and 18 deletions

View File

@ -10229,7 +10229,7 @@ static void ImGui::DockNodeAddWindow(ImGuiDockNode* node, ImGuiWindow* window, b
node->TabBar = IM_NEW(ImGuiTabBar)(); node->TabBar = IM_NEW(ImGuiTabBar)();
node->TabBar->SelectedTabId = node->TabBar->NextSelectedTabId = node->SelectedTabID; node->TabBar->SelectedTabId = node->TabBar->NextSelectedTabId = node->SelectedTabID;
} }
TabBarAddTab(node->TabBar, window); TabBarAddTab(node->TabBar, window, ImGuiTabItemFlags_Unsorted);
} }
DockNodeUpdateVisibleFlag(node); DockNodeUpdateVisibleFlag(node);
@ -10729,15 +10729,22 @@ static void ImGui::DockNodeUpdateTabBar(ImGuiDockNode* node, ImGuiWindow* host_w
tab_bar->SelectedTabId = focused_id; tab_bar->SelectedTabId = focused_id;
} }
// Submit tabs order // Submit new tabs
// If multiple tabs are appearing on the same frame, we add them ahead sorted based on their persistent DockOrder value const int tabs_count_old = tab_bar->Tabs.Size;
int tabs_count_old = tab_bar->Tabs.Size;
for (int window_n = 0; window_n < node->Windows.Size; window_n++) for (int window_n = 0; window_n < node->Windows.Size; window_n++)
if (TabBarFindTabByID(tab_bar, node->Windows[window_n]->ID) == NULL) if (TabBarFindTabByID(tab_bar, node->Windows[window_n]->ID) == NULL)
TabBarAddTab(tab_bar, node->Windows[window_n]); TabBarAddTab(tab_bar, node->Windows[window_n], ImGuiTabItemFlags_Unsorted);
//printf("[%05d] Sorting %d new appearing tabs\n", g.FrameCount, tab_bar->Tabs.Size - tabs_count_old);
if (tab_bar->Tabs.Size > tabs_count_old + 1) // If multiple tabs are appearing on the same frame, sort them based on their persistent DockOrder value
ImQsort(tab_bar->Tabs.Data + tabs_count_old, tab_bar->Tabs.Size - tabs_count_old, sizeof(ImGuiTabItem), TabItemComparerByDockOrder); int tabs_unsorted_start = tab_bar->Tabs.Size;
for (int tab_n = tab_bar->Tabs.Size - 1; tab_n >= 0 && (tab_bar->Tabs[tab_n].Flags & ImGuiTabItemFlags_Unsorted); tab_n--)
{
tab_bar->Tabs[tab_n].Flags &= ~ImGuiTabItemFlags_Unsorted;
tabs_unsorted_start = tab_n;
}
//printf("[%05d] Sorting %d new appearing tabs\n", g.FrameCount, tab_bar->Tabs.Size - tabs_unsorted_start);
if (tab_bar->Tabs.Size > tabs_unsorted_start + 1)
ImQsort(tab_bar->Tabs.Data + tabs_unsorted_start, tab_bar->Tabs.Size - tabs_unsorted_start, sizeof(ImGuiTabItem), TabItemComparerByDockOrder);
// Selected newly added tabs, or persistent tab ID if the tab bar was just recreated // Selected newly added tabs, or persistent tab ID if the tab bar was just recreated
if (tab_bar_is_recreated && TabBarFindTabByID(tab_bar, node->SelectedTabID) != NULL) if (tab_bar_is_recreated && TabBarFindTabByID(tab_bar, node->SelectedTabID) != NULL)

View File

@ -1304,8 +1304,9 @@ enum ImGuiTabBarFlagsPrivate_
enum ImGuiTabItemFlagsPrivate_ enum ImGuiTabItemFlagsPrivate_
{ {
ImGuiTabItemFlags_DockedWindow = 1 << 20, ImGuiTabItemFlags_DockedWindow = 1 << 20, // [Docking]
ImGuiTabItemFlags_Preview = 1 << 21 ImGuiTabItemFlags_Unsorted = 1 << 22, // [Docking] Trailing tabs with the _Unsorted flag will be sorted based on the DockOrder of their Window.
ImGuiTabItemFlags_Preview = 1 << 21 // [Docking] Display tab shape for docking preview (height is adjusted slightly to compensate for the yet missing tab bar)
}; };
// Storage for one active tab item (sizeof() 32~40 bytes) // Storage for one active tab item (sizeof() 32~40 bytes)
@ -1504,7 +1505,7 @@ namespace ImGui
// Tab Bars // Tab Bars
IMGUI_API bool BeginTabBarEx(ImGuiTabBar* tab_bar, const ImRect& bb, ImGuiTabBarFlags flags, ImGuiDockNode* dock_node); IMGUI_API bool BeginTabBarEx(ImGuiTabBar* tab_bar, const ImRect& bb, ImGuiTabBarFlags flags, ImGuiDockNode* dock_node);
IMGUI_API ImGuiTabItem* TabBarFindTabByID(ImGuiTabBar* tab_bar, ImGuiID tab_id); IMGUI_API ImGuiTabItem* TabBarFindTabByID(ImGuiTabBar* tab_bar, ImGuiID tab_id);
IMGUI_API void TabBarAddTab(ImGuiTabBar* tab_bar, ImGuiWindow* window); IMGUI_API void TabBarAddTab(ImGuiTabBar* tab_bar, ImGuiWindow* window, ImGuiTabItemFlags tab_flags = ImGuiTabItemFlags_None);
IMGUI_API void TabBarRemoveTab(ImGuiTabBar* tab_bar, ImGuiID tab_id); IMGUI_API void TabBarRemoveTab(ImGuiTabBar* tab_bar, ImGuiID tab_id);
IMGUI_API void TabBarCloseTab(ImGuiTabBar* tab_bar, ImGuiTabItem* tab); IMGUI_API void TabBarCloseTab(ImGuiTabBar* tab_bar, ImGuiTabItem* tab);
IMGUI_API void TabBarQueueChangeTabOrder(ImGuiTabBar* tab_bar, const ImGuiTabItem* tab, int dir); IMGUI_API void TabBarQueueChangeTabOrder(ImGuiTabBar* tab_bar, const ImGuiTabItem* tab, int dir);

View File

@ -6106,22 +6106,20 @@ ImGuiTabItem* ImGui::TabBarFindTabByID(ImGuiTabBar* tab_bar, ImGuiID tab_id)
// The purpose of this call is to register tab in advance so we can control their order at the time they appear. // The purpose of this call is to register tab in advance so we can control their order at the time they appear.
// Otherwise calling this is unnecessary as tabs are appending as needed by the BeginTabItem() function. // Otherwise calling this is unnecessary as tabs are appending as needed by the BeginTabItem() function.
void ImGui::TabBarAddTab(ImGuiTabBar* tab_bar, ImGuiWindow* window) void ImGui::TabBarAddTab(ImGuiTabBar* tab_bar, ImGuiWindow* window, ImGuiTabItemFlags tab_flags)
{ {
ImGuiContext& g = *GImGui; ImGuiContext& g = *GImGui;
IM_ASSERT(TabBarFindTabByID(tab_bar, window->ID) == NULL); IM_ASSERT(TabBarFindTabByID(tab_bar, window->ID) == NULL);
IM_ASSERT(g.CurrentTabBar.empty()); // Can't work while the tab bar is active as our tab doesn't have an X offset yet IM_ASSERT(g.CurrentTabBar.empty()); // Can't work while the tab bar is active as our tab doesn't have an X offset yet
ImGuiTabItem new_tab; ImGuiTabItem new_tab;
new_tab.ID = window->ID; new_tab.ID = window->ID;
new_tab.LastFrameVisible = tab_bar->CurrFrameVisible; // Required so BeginTabBar doesn't ditch the tab new_tab.Flags = tab_flags;
new_tab.LastFrameVisible = tab_bar->CurrFrameVisible; // Required so BeginTabBar() doesn't ditch the tab
if (new_tab.LastFrameVisible == -1) if (new_tab.LastFrameVisible == -1)
new_tab.LastFrameVisible = g.FrameCount - 1; new_tab.LastFrameVisible = g.FrameCount - 1;
new_tab.Window = window; // Required so tab bar layout can compute the tab width before tab submission new_tab.Window = window; // Required so tab bar layout can compute the tab width before tab submission
if (tab_bar->Tabs.empty()) tab_bar->Tabs.push_back(new_tab);
tab_bar->Tabs.push_back(new_tab);
else
tab_bar->Tabs.insert(tab_bar->Tabs.Data + tab_bar->Tabs.Size, new_tab);
} }
// The *TabId fields be already set by the docking system _before_ the actual TabItem was created, so we clear them regardless. // The *TabId fields be already set by the docking system _before_ the actual TabItem was created, so we clear them regardless.