|
@@ -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
|
|
|
{
|