Skip to content

Commit 9564357

Browse files
committed
Tables: (breaking) renamed ImGuiTableColumnFlags_WidthAutoResize to _WidthAuto., default to WidthFixed policy when host window has auto-resize.
Fix edge case with TableSetColumnWidth on small windows (amend 972ca81)
1 parent d497f11 commit 9564357

File tree

3 files changed

+38
-32
lines changed

3 files changed

+38
-32
lines changed

imgui.h

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1035,22 +1035,25 @@ enum ImGuiTabItemFlags_
10351035
};
10361036

10371037
// Flags for ImGui::BeginTable()
1038-
// - Important! Sizing policies have particularly complex and subtle side effects, more so than you would expect.
1038+
// - Important! Sizing policies have complex and subtle side effects, more so than you would expect.
10391039
// Read comments/demos carefully + experiment with live demos to get acquainted with them.
1040-
// - The default sizing policy for columns depends on whether the ScrollX flag is set on the table:
1041-
// When ScrollX is off:
1040+
// - The DEFAULT policy depends on whether the _ScrollX flag is set on the table, and whether _AlwaysAutoResize flag is set on window.
1041+
// - ImGuiTableFlags_ColumnsWidthStretch is the default if ScrollX if off.
1042+
// - ImGuiTableFlags_ColumnsWidthFixed is the default if ScrollX is on, or if host window has ImGuiWindowFlags_AlwaysAutoResize.
1043+
// - When ScrollX is off:
10421044
// - Table defaults to ImGuiTableFlags_ColumnsWidthStretch -> all Columns defaults to ImGuiTableColumnFlags_WidthStretch.
1043-
// - Columns sizing policy allowed: Stretch (default) or Fixed/Auto.
1044-
// - Fixed Columns will generally obtain their requested width (unless the Table cannot fit them all).
1045+
// - Columns sizing policy allowed: Stretch (default), Fixed/Auto.
1046+
// - Fixed Columns will generally obtain their requested width (unless the table cannot fit them all).
10451047
// - Stretch Columns will share the remaining width.
1046-
// When ScrollX is on:
1047-
// - Table defaults to ImGuiTableFlags_ColumnsWidthFixed -> all Columns defaults to ImGuiTableColumnFlags_WidthFixed.
1048-
// - Columns sizing policy allowed: Fixed/Auto mostly!
1048+
// - Mixed Fixed/Stretch columns is possible but has various side-effects on resizing behaviors.
1049+
// The typical use of mixing sizing policies is: any number of LEADING Fixed columns, followed by one or two TRAILING Stretch columns.
1050+
// (this is because the visible order of columns have subtle but necessary effects on how they react to manual resizing).
1051+
// - When ScrollX is on:
1052+
// - Table defaults to ImGuiTableFlags_ColumnsWidthFixed -> all Columns defaults to ImGuiTableColumnFlags_WidthFixed or ImGuiTableColumnFlags_WidthAuto
1053+
// - Columns sizing policy allowed: Fixed/Auto mostly.
10491054
// - Fixed Columns can be enlarged as needed. Table will show an horizontal scrollbar if needed.
10501055
// - Using Stretch columns OFTEN DOES NOT MAKE SENSE if ScrollX is on, UNLESS you have specified a value for 'inner_width' in BeginTable().
1051-
// - Mixing up columns with different sizing policy is possible BUT can be tricky and has some side-effects and restrictions.
1052-
// (their visible order and the scrolling state have subtle but necessary effects on how they can be manually resized).
1053-
// The typical use of mixing sizing policies is to have ScrollX disabled, first Fixed columns and then one or two TRAILING Stretch columns.
1056+
// If you specify a value for 'inner_width' then effectively the scrolling space is known and Stretch or mixed Fixed/Stretch columns become meaningful again.
10541057
enum ImGuiTableFlags_
10551058
{
10561059
// Features
@@ -1076,7 +1079,7 @@ enum ImGuiTableFlags_
10761079
ImGuiTableFlags_NoBordersInBodyUntilResize = 1 << 12, // Disable vertical borders in columns Body until hovered for resize (borders will always appears in Headers).
10771080
// Sizing
10781081
ImGuiTableFlags_ColumnsWidthStretch = 1 << 13, // Default if ScrollX is off. Columns will default to use _WidthStretch. Read description above for more details.
1079-
ImGuiTableFlags_ColumnsWidthFixed = 1 << 14, // Default if ScrollX is on. Columns will default to use _WidthFixed or _WidthAutoResize policy (if Resizable is off). Read description above for more details.
1082+
ImGuiTableFlags_ColumnsWidthFixed = 1 << 14, // Default if ScrollX is on. Columns will default to use _WidthFixed or _WidthAuto policy (if Resizable is off). Read description above for more details.
10801083
ImGuiTableFlags_SameWidths = 1 << 15, // Make all columns the same widths which is useful with Fixed columns policy (but granted by default with Stretch policy + no resize). Implicitly enable ImGuiTableFlags_NoKeepColumnsVisible and disable ImGuiTableFlags_Resizable.
10811084
ImGuiTableFlags_NoHostExtendY = 1 << 16, // Disable extending table past the limit set by outer_size.y. Only meaningful when neither ScrollX nor ScrollY are set (data below the limit will be clipped and not visible)
10821085
ImGuiTableFlags_NoKeepColumnsVisible = 1 << 17, // Disable keeping column always minimally visible when ScrollX is off and table gets too small. Not recommended if columns are resizable.
@@ -1104,7 +1107,7 @@ enum ImGuiTableColumnFlags_
11041107
ImGuiTableColumnFlags_DefaultSort = 1 << 1, // Default as a sorting column.
11051108
ImGuiTableColumnFlags_WidthStretch = 1 << 2, // Column will stretch. Preferable with horizontal scrolling disabled (default if table sizing policy is _ColumnsWidthStretch).
11061109
ImGuiTableColumnFlags_WidthFixed = 1 << 3, // Column will not stretch. Preferable with horizontal scrolling enabled (default if table sizing policy is _ColumnsWidthFixed and table is resizable).
1107-
ImGuiTableColumnFlags_WidthAutoResize = 1 << 4, // Column will not stretch and keep resizing based on submitted contents (default if table sizing policy is _ColumnsWidthFixed and table is not resizable).
1110+
ImGuiTableColumnFlags_WidthAuto = 1 << 4, // Column will not stretch and keep resizing based on submitted contents (default if table sizing policy is _ColumnsWidthFixed and table is not resizable). Generally compatible with using right-most fitting widgets (e.g. SetNextItemWidth(-FLT_MIN))
11081111
ImGuiTableColumnFlags_NoResize = 1 << 5, // Disable manual resizing.
11091112
ImGuiTableColumnFlags_NoReorder = 1 << 6, // Disable manual reordering this column, this will also prevent other columns from crossing over this column.
11101113
ImGuiTableColumnFlags_NoHide = 1 << 7, // Disable ability to hide/disable this column.
@@ -1125,7 +1128,7 @@ enum ImGuiTableColumnFlags_
11251128
ImGuiTableColumnFlags_IsHovered = 1 << 23, // Status: is hovered by mouse
11261129

11271130
// [Internal] Combinations and masks
1128-
ImGuiTableColumnFlags_WidthMask_ = ImGuiTableColumnFlags_WidthStretch | ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_WidthAutoResize,
1131+
ImGuiTableColumnFlags_WidthMask_ = ImGuiTableColumnFlags_WidthStretch | ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_WidthAuto,
11291132
ImGuiTableColumnFlags_IndentMask_ = ImGuiTableColumnFlags_IndentEnable | ImGuiTableColumnFlags_IndentDisable,
11301133
ImGuiTableColumnFlags_StatusMask_ = ImGuiTableColumnFlags_IsEnabled | ImGuiTableColumnFlags_IsVisible | ImGuiTableColumnFlags_IsSorted | ImGuiTableColumnFlags_IsHovered,
11311134
ImGuiTableColumnFlags_NoDirectResize_ = 1 << 30 // [Internal] Disable user resizing this column directly (it may however we resized indirectly from its left edge)

imgui_demo.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3357,8 +3357,8 @@ static void EditTableColumnsFlags(ImGuiTableColumnFlags* p_flags)
33573357
*p_flags &= ~(ImGuiTableColumnFlags_WidthMask_ ^ ImGuiTableColumnFlags_WidthStretch);
33583358
if (ImGui::CheckboxFlags("_WidthFixed", p_flags, ImGuiTableColumnFlags_WidthFixed))
33593359
*p_flags &= ~(ImGuiTableColumnFlags_WidthMask_ ^ ImGuiTableColumnFlags_WidthFixed);
3360-
if (ImGui::CheckboxFlags("_WidthAutoResize", p_flags, ImGuiTableColumnFlags_WidthAutoResize))
3361-
*p_flags &= ~(ImGuiTableColumnFlags_WidthMask_ ^ ImGuiTableColumnFlags_WidthAutoResize);
3360+
if (ImGui::CheckboxFlags("_WidthAuto", p_flags, ImGuiTableColumnFlags_WidthAuto))
3361+
*p_flags &= ~(ImGuiTableColumnFlags_WidthMask_ ^ ImGuiTableColumnFlags_WidthAuto);
33623362
ImGui::CheckboxFlags("_NoResize", p_flags, ImGuiTableColumnFlags_NoResize);
33633363
ImGui::CheckboxFlags("_NoReorder", p_flags, ImGuiTableColumnFlags_NoReorder);
33643364
ImGui::CheckboxFlags("_NoHide", p_flags, ImGuiTableColumnFlags_NoHide);

imgui_tables.cpp

Lines changed: 19 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,15 @@ Index of this file:
9898
//-----------------------------------------------------------------------------
9999

100100
//-----------------------------------------------------------------------------
101-
// TABLES CULLING
101+
// TABLES CLIPPING/CULLING
102102
//-----------------------------------------------------------------------------
103103
// About clipping/culling of Rows in Tables:
104104
// - For large numbers of rows, it is recommended you use ImGuiListClipper to only submit visible rows.
105105
// ImGuiListClipper is reliant on the fact that rows are of equal height.
106106
// See 'Demo->Tables->Vertical Scrolling' or 'Demo->Tables->Advanced' for a demo of using the clipper.
107+
// - Note that columns with the ImGuiTableColumnFlags_WidthAuto policy generally don't play well with using the clipper,
108+
// and by default a table with _ScrollX but without _Resizable will have columns default to _WidthAuto.
109+
// So, if you want to use the clipper, make sure to either enable _Resizable, either setup columns explicitly with _WidthFixed.
107110
//-----------------------------------------------------------------------------
108111
// About clipping/culling of Columns in Tables:
109112
// - Case A: column is not hidden by user, and at least partially in sight (most common case).
@@ -193,7 +196,7 @@ inline ImGuiTableFlags TableFixFlags(ImGuiTableFlags flags, ImGuiWindow* outer_w
193196
{
194197
// Adjust flags: set default sizing policy
195198
if ((flags & (ImGuiTableFlags_ColumnsWidthStretch | ImGuiTableFlags_ColumnsWidthFixed)) == 0)
196-
flags |= (flags & ImGuiTableFlags_ScrollX) ? ImGuiTableFlags_ColumnsWidthFixed : ImGuiTableFlags_ColumnsWidthStretch;
199+
flags |= ((flags & ImGuiTableFlags_ScrollX) || (outer_window->Flags & ImGuiWindowFlags_AlwaysAutoResize)) ? ImGuiTableFlags_ColumnsWidthFixed : ImGuiTableFlags_ColumnsWidthStretch;
197200

198201
// Adjust flags: disable Resizable when using SameWidths (done above enforcing BordersInnerV)
199202
if (flags & ImGuiTableFlags_SameWidths)
@@ -564,14 +567,14 @@ static void TableSetupColumnFlags(ImGuiTable* table, ImGuiTableColumn* column, I
564567
// Sizing Policy
565568
if ((flags & ImGuiTableColumnFlags_WidthMask_) == 0)
566569
{
567-
// FIXME-TABLE: Inconsistent to promote columns to WidthAutoResize
570+
// FIXME-TABLE: Inconsistent to promote columns to WidthAuto
568571
if (table->Flags & ImGuiTableFlags_ColumnsWidthFixed)
569-
flags |= ((table->Flags & ImGuiTableFlags_Resizable) && !(flags & ImGuiTableColumnFlags_NoResize)) ? ImGuiTableColumnFlags_WidthFixed : ImGuiTableColumnFlags_WidthAutoResize;
572+
flags |= ((table->Flags & ImGuiTableFlags_Resizable) && !(flags & ImGuiTableColumnFlags_NoResize)) ? ImGuiTableColumnFlags_WidthFixed : ImGuiTableColumnFlags_WidthAuto;
570573
else
571574
flags |= ImGuiTableColumnFlags_WidthStretch;
572575
}
573576
IM_ASSERT(ImIsPowerOfTwo(flags & ImGuiTableColumnFlags_WidthMask_)); // Check that only 1 of each set is used.
574-
if (flags & ImGuiTableColumnFlags_WidthAutoResize)
577+
if (flags & ImGuiTableColumnFlags_WidthAuto)
575578
flags |= ImGuiTableColumnFlags_NoResize;
576579

577580
// Sorting
@@ -609,9 +612,8 @@ static void TableSetupColumnFlags(ImGuiTable* table, ImGuiTableColumn* column, I
609612

610613
// Layout columns for the frame. This is in essence the followup to BeginTable().
611614
// Runs on the first call to TableNextRow(), to give a chance for TableSetupColumn() to be called first.
612-
// FIXME-TABLE: Our width (and therefore our WorkRect) will be minimal in the first frame for WidthAutoResize
613-
// columns, increase feedback side-effect with widgets relying on WorkRect.Max.x. Maybe provide a default distribution
614-
// for WidthAutoResize columns?
615+
// FIXME-TABLE: Our width (and therefore our WorkRect) will be minimal in the first frame for _WidthAuto columns.
616+
// Increase feedback side-effect with widgets relying on WorkRect.Max.x... Maybe provide a default distribution for _WidthAuto columns?
615617
void ImGui::TableUpdateLayout(ImGuiTable* table)
616618
{
617619
ImGuiContext& g = *GImGui;
@@ -657,7 +659,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
657659
table->IsSortSpecsDirty = true;
658660

659661
bool start_auto_fit = false;
660-
if (column->Flags & (ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_WidthAutoResize))
662+
if (column->Flags & (ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_WidthAuto))
661663
start_auto_fit = column->WidthRequest < 0.0f;
662664
else
663665
start_auto_fit = column->StretchWeight < 0.0f;
@@ -739,11 +741,11 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
739741
}
740742
column->IsPreserveWidthAuto = false;
741743

742-
if (column->Flags & (ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_WidthAutoResize))
744+
if (column->Flags & (ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_WidthAuto))
743745
{
744746
// Process auto-fit for non-stretched columns
745747
// Latch initial size for fixed columns and update it constantly for auto-resizing column (unless clipped!)
746-
if ((column->AutoFitQueue != 0x00) || ((column->Flags & ImGuiTableColumnFlags_WidthAutoResize) && column->IsVisibleX))
748+
if ((column->AutoFitQueue != 0x00) || ((column->Flags & ImGuiTableColumnFlags_WidthAuto) && column->IsVisibleX))
747749
column->WidthRequest = column->WidthAuto;
748750

749751
// FIXME-TABLE: Increase minimum size during init frame to avoid biasing auto-fitting widgets
@@ -786,7 +788,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
786788
if (!(table->EnabledMaskByIndex & ((ImU64)1 << column_n)))
787789
continue;
788790
ImGuiTableColumn* column = &table->Columns[column_n];
789-
if (column->Flags & (ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_WidthAutoResize))
791+
if (column->Flags & (ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_WidthAuto))
790792
{
791793
sum_width_fixed_requests += max_width_auto - column->WidthRequest; // Update old sum
792794
column->WidthRequest = max_width_auto;
@@ -978,7 +980,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
978980

979981
// [Part 8] Detect/store when we are hovering the unused space after the right-most column (so e.g. context menus can react on it)
980982
// Clear Resizable flag if none of our column are actually resizable (either via an explicit _NoResize flag, either
981-
// because of using _WidthAutoResize/_WidthStretch). This will hide the resizing option from the context menu.
983+
// because of using _WidthAuto/_WidthStretch). This will hide the resizing option from the context menu.
982984
const float unused_x1 = ImMax(table->WorkRect.Min.x, table->Columns[table->RightMostEnabledColumn].ClipRect.Max.x);
983985
if (is_hovering_table && table->HoveredColumnBody == -1)
984986
{
@@ -1279,7 +1281,7 @@ void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, flo
12791281
table->DeclColumnsCount++;
12801282

12811283
// When passing a width automatically enforce WidthFixed policy
1282-
// (whereas TableSetupColumnFlags would default to WidthAutoResize)
1284+
// (whereas TableSetupColumnFlags would default to WidthAuto)
12831285
if ((flags & ImGuiTableColumnFlags_WidthMask_) == 0)
12841286
if ((table->Flags & ImGuiTableFlags_ColumnsWidthFixed) && (init_width_or_weight > 0.0f))
12851287
flags |= ImGuiTableColumnFlags_WidthFixed;
@@ -1871,7 +1873,7 @@ void ImGui::TableSetColumnWidth(int column_n, float width)
18711873
// Apply constraints early
18721874
// Compare both requested and actual given width to avoid overwriting requested width when column is stuck (minimum size, bounded)
18731875
const float min_width = TableGetMinColumnWidth();
1874-
const float max_width = TableGetMaxColumnWidth(table, column_n);
1876+
const float max_width = ImMax(min_width, TableGetMaxColumnWidth(table, column_n));
18751877
column_0_width = ImClamp(column_0_width, min_width, max_width);
18761878
if (column_0->WidthGiven == column_0_width || column_0->WidthRequest == column_0_width)
18771879
return;
@@ -1931,6 +1933,7 @@ void ImGui::TableSetColumnWidth(int column_n, float width)
19311933
// (old_a + old_b == new_a + new_b) --> (new_a == old_a + old_b - new_b)
19321934
float column_1_width = ImMax(column_1->WidthRequest - (column_0_width - column_0->WidthRequest), min_width);
19331935
column_0_width = column_0->WidthRequest + column_1->WidthRequest - column_1_width;
1936+
IM_ASSERT(column_0_width > 0.0f && column_1_width > 0.0f);
19341937
column_0->WidthRequest = column_0_width;
19351938
column_1->WidthRequest = column_1_width;
19361939
if ((column_0->Flags | column_1->Flags) & ImGuiTableColumnFlags_WidthStretch)
@@ -3321,7 +3324,7 @@ void ImGui::DebugNodeTable(ImGuiTable* table)
33213324
column->SortOrder, (column->SortDirection == ImGuiSortDirection_Ascending) ? " (Asc)" : (column->SortDirection == ImGuiSortDirection_Descending) ? " (Des)" : "", column->UserID, column->Flags,
33223325
(column->Flags & ImGuiTableColumnFlags_WidthStretch) ? "WidthStretch " : "",
33233326
(column->Flags & ImGuiTableColumnFlags_WidthFixed) ? "WidthFixed " : "",
3324-
(column->Flags & ImGuiTableColumnFlags_WidthAutoResize) ? "WidthAutoResize " : "",
3327+
(column->Flags & ImGuiTableColumnFlags_WidthAuto) ? "WidthAuto " : "",
33253328
(column->Flags & ImGuiTableColumnFlags_NoResize) ? "NoResize " : "");
33263329
Bullet();
33273330
Selectable(buf);

0 commit comments

Comments
 (0)