mirror of
https://github.com/Drezil/imgui.git
synced 2024-11-15 01:17:00 +00: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
|
// Tabs
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
struct ImGuiTabBarSortItem
|
struct ImGuiShrinkWidthItem
|
||||||
{
|
{
|
||||||
int Index;
|
int Index;
|
||||||
float Width;
|
float Width;
|
||||||
@ -976,7 +976,7 @@ struct ImGuiContext
|
|||||||
ImPool<ImGuiTabBar> TabBars;
|
ImPool<ImGuiTabBar> TabBars;
|
||||||
ImGuiTabBar* CurrentTabBar;
|
ImGuiTabBar* CurrentTabBar;
|
||||||
ImVector<ImGuiTabBarRef> CurrentTabBarStack;
|
ImVector<ImGuiTabBarRef> CurrentTabBarStack;
|
||||||
ImVector<ImGuiTabBarSortItem> TabSortByWidthBuffer;
|
ImVector<ImGuiShrinkWidthItem> ShrinkWidthBuffer;
|
||||||
|
|
||||||
// Widget state
|
// Widget state
|
||||||
ImVec2 LastValidMousePos;
|
ImVec2 LastValidMousePos;
|
||||||
@ -1495,6 +1495,7 @@ namespace ImGui
|
|||||||
IMGUI_API void PopItemFlag();
|
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 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 ImVec2 GetWorkRectMax();
|
||||||
|
IMGUI_API void ShrinkWidths(ImGuiShrinkWidthItem* items, int count, float width_excess);
|
||||||
|
|
||||||
// Logging/Capture
|
// 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.
|
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]
|
// - SeparatorEx() [Internal]
|
||||||
// - Separator()
|
// - Separator()
|
||||||
// - SplitterBehavior() [Internal]
|
// - SplitterBehavior() [Internal]
|
||||||
|
// - ShrinkWidths() [Internal]
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
|
|
||||||
void ImGui::Spacing()
|
void ImGui::Spacing()
|
||||||
@ -1330,6 +1331,33 @@ bool ImGui::SplitterBehavior(const ImRect& bb, ImGuiID id, ImGuiAxis axis, float
|
|||||||
return held;
|
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
|
// [SECTION] Widgets: ComboBox
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
@ -6221,15 +6249,6 @@ static int IMGUI_CDECL TabItemComparerByVisibleOffset(const void* lhs, const voi
|
|||||||
return (int)(a->Offset - b->Offset);
|
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)
|
static ImGuiTabBar* GetTabBarFromTabBarRef(const ImGuiTabBarRef& ref)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
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!
|
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;
|
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
|
// Compute ideal widths
|
||||||
|
g.ShrinkWidthBuffer.resize(tab_bar->Tabs.Size);
|
||||||
float width_total_contents = 0.0f;
|
float width_total_contents = 0.0f;
|
||||||
ImGuiTabItem* most_recently_selected_tab = NULL;
|
ImGuiTabItem* most_recently_selected_tab = NULL;
|
||||||
bool found_selected_tab_id = false;
|
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;
|
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
|
// 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;
|
g.ShrinkWidthBuffer[tab_n].Index = tab_n;
|
||||||
width_sort_buffer[tab_n].Width = tab->WidthContents;
|
g.ShrinkWidthBuffer[tab_n].Width = tab->WidthContents;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute width
|
// Compute width
|
||||||
@ -6439,21 +6456,9 @@ static void ImGui::TabBarLayout(ImGuiTabBar* tab_bar)
|
|||||||
if (width_excess > 0.0f && (tab_bar->Flags & ImGuiTabBarFlags_FittingPolicyResizeDown))
|
if (width_excess > 0.0f && (tab_bar->Flags & ImGuiTabBarFlags_FittingPolicyResizeDown))
|
||||||
{
|
{
|
||||||
// If we don't have enough room, resize down the largest tabs first
|
// If we don't have enough room, resize down the largest tabs first
|
||||||
if (tab_bar->Tabs.Size > 1)
|
ShrinkWidths(g.ShrinkWidthBuffer.Data, g.ShrinkWidthBuffer.Size, width_excess);
|
||||||
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;
|
|
||||||
}
|
|
||||||
for (int tab_n = 0; tab_n < tab_bar->Tabs.Size; tab_n++)
|
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
|
else
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user