TabBar: TabItem() now reacts to SetNextItemWidth() and SetNextItemOpen(true). (#5262)

This commit is contained in:
ocornut 2022-06-21 16:20:01 +02:00
parent d3fd2630b7
commit 4b97296148
3 changed files with 29 additions and 15 deletions

View File

@ -105,6 +105,7 @@ Other Changes:
merging drawcall of the last column didn't always work (regression since 1.87). (#4843, #4844) [@rokups]
- Inputs: Fixed IsMouseClicked() repeat mode rate being half of keyboard repeat rate.
- ColorEdit: Fixed text baseline alignment after a SameLine() after a ColorEdit() with visible label.
- TabBar: TabItem() now reacts to SetNextItemWidth() and SetNextItemOpen(true). (#5262)
- Menus: Adjusted BeginMenu() closing logic so hovering void or non-MenuItem() in parent window
always lead to menu closure. Fixes using items that are not MenuItem() or BeginItem() at the root
level of a popup with a child menu opened.

View File

@ -2184,6 +2184,7 @@ struct ImGuiTabItem
float Offset; // Position relative to beginning of tab
float Width; // Width currently displayed
float ContentWidth; // Width of label, stored during BeginTabItem() call
float RequestedWidth; // Width optionally requested by caller, -1.0f is unused
ImS32 NameOffset; // When Window==NULL, offset to name within parent ImGuiTabBar::TabsNames
ImS16 BeginOrder; // BeginTabItem() order, used to re-order tabs after toggling ImGuiTabBarFlags_Reorderable
ImS16 IndexDuringLayout; // Index only used during TabBarLayout()

View File

@ -7548,7 +7548,7 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar)
// and we cannot wait for the next BeginTabItem() call. We cannot compute this width within TabBarAddTab() because font size depends on the active window.
const char* tab_name = tab_bar->GetTabName(tab);
const bool has_close_button = (tab->Flags & ImGuiTabItemFlags_NoCloseButton) ? false : true;
tab->ContentWidth = TabItemCalcSize(tab_name, has_close_button).x;
tab->ContentWidth = (tab->RequestedWidth > 0.0f) ? tab->RequestedWidth : TabItemCalcSize(tab_name, has_close_button).x;
int section_n = TabItemGetSectionIdx(tab);
ImGuiTabBarSection* section = &sections[section_n];
@ -8029,10 +8029,13 @@ bool ImGui::TabItemButton(const char* label, ImGuiTabItemFlags flags)
bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open, ImGuiTabItemFlags flags)
{
// Layout whole tab bar if not already done
if (tab_bar->WantLayout)
TabBarLayout(tab_bar);
ImGuiContext& g = *GImGui;
if (tab_bar->WantLayout)
{
ImGuiNextItemData backup_next_item_data = g.NextItemData;
TabBarLayout(tab_bar);
g.NextItemData = backup_next_item_data;
}
ImGuiWindow* window = g.CurrentWindow;
if (window->SkipItems)
return false;
@ -8058,9 +8061,6 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
else if (p_open == NULL)
flags |= ImGuiTabItemFlags_NoCloseButton;
// Calculate tab contents size
ImVec2 size = TabItemCalcSize(label, p_open != NULL);
// Acquire tab data
ImGuiTabItem* tab = TabBarFindTabByID(tab_bar, id);
bool tab_is_new = false;
@ -8069,11 +8069,17 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
tab_bar->Tabs.push_back(ImGuiTabItem());
tab = &tab_bar->Tabs.back();
tab->ID = id;
tab->Width = size.x;
tab_bar->TabsAddedNew = true;
tab_is_new = true;
tab_bar->TabsAddedNew = tab_is_new = true;
}
tab_bar->LastTabItemIdx = (ImS16)tab_bar->Tabs.index_from_ptr(tab);
// Calculate tab contents size
ImVec2 size = TabItemCalcSize(label, p_open != NULL);
tab->RequestedWidth = -1.0f;
if (g.NextItemData.Flags & ImGuiNextItemDataFlags_HasWidth)
size.x = tab->RequestedWidth = g.NextItemData.Width;
if (tab_is_new)
tab->Width = size.x;
tab->ContentWidth = size.x;
tab->BeginOrder = tab_bar->TabsActiveCount++;
@ -8089,13 +8095,19 @@ bool ImGui::TabItemEx(ImGuiTabBar* tab_bar, const char* label, bool* p_open,
tab_bar->TabsNames.append(label, label + strlen(label) + 1);
// Update selected tab
if (tab_appearing && (tab_bar->Flags & ImGuiTabBarFlags_AutoSelectNewTabs) && tab_bar->NextSelectedTabId == 0)
if (!tab_bar_appearing || tab_bar->SelectedTabId == 0)
if (!is_tab_button)
if (!is_tab_button)
{
if (tab_appearing && (tab_bar->Flags & ImGuiTabBarFlags_AutoSelectNewTabs) && tab_bar->NextSelectedTabId == 0)
if (!tab_bar_appearing || tab_bar->SelectedTabId == 0)
tab_bar->NextSelectedTabId = id; // New tabs gets activated
if ((flags & ImGuiTabItemFlags_SetSelected) && (tab_bar->SelectedTabId != id)) // SetSelected can only be passed on explicit tab bar
if (!is_tab_button)
if ((flags & ImGuiTabItemFlags_SetSelected) && (tab_bar->SelectedTabId != id)) // _SetSelected can only be passed on explicit tab bar
tab_bar->NextSelectedTabId = id;
if (g.NextItemData.Flags & ImGuiNextItemDataFlags_HasOpen)
{
IM_ASSERT(g.NextItemData.OpenVal == true && g.NextItemData.OpenCond == ImGuiCond_Always); // SetNextItemOpen(true, ImGuiCond_Always) is supported but other combinations are not.
tab_bar->NextSelectedTabId = id;
}
}
// Lock visibility
// (Note: tab_contents_visible != tab_selected... because CTRL+TAB operations may preview some tabs without selecting them!)