mirror of
https://github.com/ocornut/imgui.git
synced 2024-11-23 21:09:01 +08:00
Internals: Extracted some of the tab bar shrinking code into a ShrinkWidths() function so columns/table can use it.
This commit is contained in:
parent
3fda90d6a7
commit
ec3ec24157
@ -811,7 +811,7 @@ struct ImGuiNextItemData
|
||||
// Tabs
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
struct ImGuiTabBarSortItem
|
||||
struct ImGuiShrinkWidthItem
|
||||
{
|
||||
int Index;
|
||||
float Width;
|
||||
@ -976,7 +976,7 @@ struct ImGuiContext
|
||||
ImPool<ImGuiTabBar> TabBars;
|
||||
ImGuiTabBar* CurrentTabBar;
|
||||
ImVector<ImGuiTabBarRef> CurrentTabBarStack;
|
||||
ImVector<ImGuiTabBarSortItem> TabSortByWidthBuffer;
|
||||
ImVector<ImGuiShrinkWidthItem> ShrinkWidthBuffer;
|
||||
|
||||
// Widget state
|
||||
ImVec2 LastValidMousePos;
|
||||
@ -1495,6 +1495,7 @@ namespace ImGui
|
||||
IMGUI_API void PopItemFlag();
|
||||
IMGUI_API bool IsItemToggledSelection(); // was the last item selection toggled? (after Selectable(), TreeNode() etc. We only returns toggle _event_ in order to handle clipping correctly)
|
||||
IMGUI_API ImVec2 GetWorkRectMax();
|
||||
IMGUI_API void ShrinkWidths(ImGuiShrinkWidthItem* items, int count, float width_excess);
|
||||
|
||||
// Logging/Capture
|
||||
IMGUI_API void LogBegin(ImGuiLogType type, int auto_open_depth); // -> BeginCapture() when we design v2 api, for now stay under the radar by using the old name.
|
||||
|
@ -1149,6 +1149,7 @@ void ImGui::Bullet()
|
||||
// - SeparatorEx() [Internal]
|
||||
// - Separator()
|
||||
// - SplitterBehavior() [Internal]
|
||||
// - ShrinkWidths() [Internal]
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
void ImGui::Spacing()
|
||||
@ -1330,6 +1331,33 @@ bool ImGui::SplitterBehavior(const ImRect& bb, ImGuiID id, ImGuiAxis axis, float
|
||||
return held;
|
||||
}
|
||||
|
||||
static int IMGUI_CDECL ShrinkWidthItemComparer(const void* lhs, const void* rhs)
|
||||
{
|
||||
const ImGuiShrinkWidthItem* a = (const ImGuiShrinkWidthItem*)lhs;
|
||||
const ImGuiShrinkWidthItem* b = (const ImGuiShrinkWidthItem*)rhs;
|
||||
if (int d = (int)(b->Width - a->Width))
|
||||
return d;
|
||||
return (b->Index - a->Index);
|
||||
}
|
||||
|
||||
// Shrink excess width from a set of item, by removing width from the larger items first.
|
||||
void ImGui::ShrinkWidths(ImGuiShrinkWidthItem* items, int count, float width_excess)
|
||||
{
|
||||
if (count > 1)
|
||||
ImQsort(items, (size_t)count, sizeof(ImGuiShrinkWidthItem), ShrinkWidthItemComparer);
|
||||
int count_same_width = 1;
|
||||
while (width_excess > 0.0f && count_same_width < count)
|
||||
{
|
||||
while (count_same_width < count && items[0].Width == items[count_same_width].Width)
|
||||
count_same_width++;
|
||||
float width_to_remove_per_item_max = (count_same_width < count) ? (items[0].Width - items[count_same_width].Width) : (items[0].Width - 1.0f);
|
||||
float width_to_remove_per_item = ImMin(width_excess / count_same_width, width_to_remove_per_item_max);
|
||||
for (int item_n = 0; item_n < count_same_width; item_n++)
|
||||
items[item_n].Width -= width_to_remove_per_item;
|
||||
width_excess -= width_to_remove_per_item * count_same_width;
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// [SECTION] Widgets: ComboBox
|
||||
//-------------------------------------------------------------------------
|
||||
@ -6221,15 +6249,6 @@ static int IMGUI_CDECL TabItemComparerByVisibleOffset(const void* lhs, const voi
|
||||
return (int)(a->Offset - b->Offset);
|
||||
}
|
||||
|
||||
static int IMGUI_CDECL TabBarSortItemComparer(const void* lhs, const void* rhs)
|
||||
{
|
||||
const ImGuiTabBarSortItem* a = (const ImGuiTabBarSortItem*)lhs;
|
||||
const ImGuiTabBarSortItem* b = (const ImGuiTabBarSortItem*)rhs;
|
||||
if (int d = (int)(b->Width - a->Width))
|
||||
return d;
|
||||
return (b->Index - a->Index);
|
||||
}
|
||||
|
||||
static ImGuiTabBar* GetTabBarFromTabBarRef(const ImGuiTabBarRef& ref)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
@ -6403,10 +6422,8 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar)
|
||||
if (ImGuiTabItem* tab_to_select = TabBarTabListPopupButton(tab_bar)) // NB: Will alter BarRect.Max.x!
|
||||
scroll_track_selected_tab_id = tab_bar->SelectedTabId = tab_to_select->ID;
|
||||
|
||||
ImVector<ImGuiTabBarSortItem>& width_sort_buffer = g.TabSortByWidthBuffer;
|
||||
width_sort_buffer.resize(tab_bar->Tabs.Size);
|
||||
|
||||
// Compute ideal widths
|
||||
g.ShrinkWidthBuffer.resize(tab_bar->Tabs.Size);
|
||||
float width_total_contents = 0.0f;
|
||||
ImGuiTabItem* most_recently_selected_tab = NULL;
|
||||
bool found_selected_tab_id = false;
|
||||
@ -6429,8 +6446,8 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar)
|
||||
width_total_contents += (tab_n > 0 ? g.Style.ItemInnerSpacing.x : 0.0f) + tab->WidthContents;
|
||||
|
||||
// Store data so we can build an array sorted by width if we need to shrink tabs down
|
||||
width_sort_buffer[tab_n].Index = tab_n;
|
||||
width_sort_buffer[tab_n].Width = tab->WidthContents;
|
||||
g.ShrinkWidthBuffer[tab_n].Index = tab_n;
|
||||
g.ShrinkWidthBuffer[tab_n].Width = tab->WidthContents;
|
||||
}
|
||||
|
||||
// Compute width
|
||||
@ -6439,21 +6456,9 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar)
|
||||
if (width_excess > 0.0f && (tab_bar->Flags & ImGuiTabBarFlags_FittingPolicyResizeDown))
|
||||
{
|
||||
// If we don't have enough room, resize down the largest tabs first
|
||||
if (tab_bar->Tabs.Size > 1)
|
||||
ImQsort(width_sort_buffer.Data, (size_t)width_sort_buffer.Size, sizeof(ImGuiTabBarSortItem), TabBarSortItemComparer);
|
||||
int tab_count_same_width = 1;
|
||||
while (width_excess > 0.0f && tab_count_same_width < tab_bar->Tabs.Size)
|
||||
{
|
||||
while (tab_count_same_width < tab_bar->Tabs.Size && width_sort_buffer[0].Width == width_sort_buffer[tab_count_same_width].Width)
|
||||
tab_count_same_width++;
|
||||
float width_to_remove_per_tab_max = (tab_count_same_width < tab_bar->Tabs.Size) ? (width_sort_buffer[0].Width - width_sort_buffer[tab_count_same_width].Width) : (width_sort_buffer[0].Width - 1.0f);
|
||||
float width_to_remove_per_tab = ImMin(width_excess / tab_count_same_width, width_to_remove_per_tab_max);
|
||||
for (int tab_n = 0; tab_n < tab_count_same_width; tab_n++)
|
||||
width_sort_buffer[tab_n].Width -= width_to_remove_per_tab;
|
||||
width_excess -= width_to_remove_per_tab * tab_count_same_width;
|
||||
}
|
||||
ShrinkWidths(g.ShrinkWidthBuffer.Data, g.ShrinkWidthBuffer.Size, width_excess);
|
||||
for (int tab_n = 0; tab_n < tab_bar->Tabs.Size; tab_n++)
|
||||
tab_bar->Tabs[width_sort_buffer[tab_n].Index].Width = (float)(int)width_sort_buffer[tab_n].Width;
|
||||
tab_bar->Tabs[g.ShrinkWidthBuffer[tab_n].Index].Width = (float)(int)g.ShrinkWidthBuffer[tab_n].Width;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user