Skip to content

Commit 7a61f34

Browse files
committed
Tables: support internal TableResetSettings(), clarify lifetime, fixed missing auto-fit on column unhidden after first run, fixed resize assert when changing column sizing policy to stretch mid-frame (before of -1.0f weight)
1 parent b194df4 commit 7a61f34

File tree

3 files changed

+62
-31
lines changed

3 files changed

+62
-31
lines changed

imgui.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11086,8 +11086,6 @@ void ImGui::DebugNodeDrawList(ImGuiWindow*, const ImDrawList*, const char*) {}
1108611086
void ImGui::DebugNodeDrawCmdShowMeshAndBoundingBox(ImGuiWindow*, const ImDrawList*, const ImDrawCmd*, bool, bool) {}
1108711087
void ImGui::DebugNodeStorage(ImGuiStorage*, const char*) {}
1108811088
void ImGui::DebugNodeTabBar(ImGuiTabBar*, const char*) {}
11089-
void ImGui::DebugNodeTable(ImGuiTable*) {}
11090-
void ImGui::DebugNodeTableSettings(ImGuiTableSettings*) {}
1109111089
void ImGui::DebugNodeWindow(ImGuiWindow*, const char*) {}
1109211090
void ImGui::DebugNodeWindowSettings(ImGuiWindowSettings*) {}
1109311091
void ImGui::DebugNodeWindowsList(ImVector<ImGuiWindow*>*, const char*) {}

imgui_internal.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1936,6 +1936,7 @@ struct ImGuiTableColumn
19361936
bool IsVisibleY;
19371937
bool IsRequestOutput; // Return value for TableSetColumnIndex() / TableNextColumn(): whether we request user to output contents or not.
19381938
bool IsSkipItems; // Do we want item submissions to this column to be completely ignored (no layout will happen).
1939+
bool IsPreserveWidthAuto;
19391940
ImS8 NavLayerCurrent; // ImGuiNavLayer in 1 byte
19401941
ImS8 SortDirection; // ImGuiSortDirection_Ascending or ImGuiSortDirection_Descending
19411942
ImU8 AutoFitQueue; // Queue of 8 values for the next 8 frames to request auto-fit
@@ -1946,7 +1947,6 @@ struct ImGuiTableColumn
19461947
memset(this, 0, sizeof(*this));
19471948
StretchWeight = WidthRequest = -1.0f;
19481949
NameOffset = -1;
1949-
IsEnabled = IsEnabledNextFrame = true;
19501950
DisplayOrder = IndexWithinEnabledSet = -1;
19511951
PrevEnabledColumn = NextEnabledColumn = -1;
19521952
SortOrder = -1;
@@ -2062,6 +2062,7 @@ struct ImGuiTable
20622062
bool IsSettingsRequestLoad;
20632063
bool IsSettingsDirty; // Set when table settings have changed and needs to be reported into ImGuiTableSetttings data.
20642064
bool IsDefaultDisplayOrder; // Set when display order is unchanged from default (DisplayOrder contains 0...Count-1)
2065+
bool IsResetAllRequest;
20652066
bool IsResetDisplayOrderRequest;
20662067
bool IsUnfrozen; // Set when we got past the frozen row.
20672068
bool MemoryCompacted;
@@ -2319,11 +2320,11 @@ namespace ImGui
23192320
// Tables: Settings
23202321
IMGUI_API void TableLoadSettings(ImGuiTable* table);
23212322
IMGUI_API void TableSaveSettings(ImGuiTable* table);
2323+
IMGUI_API void TableResetSettings(ImGuiTable* table);
23222324
IMGUI_API ImGuiTableSettings* TableGetBoundSettings(ImGuiTable* table);
23232325
IMGUI_API void TableSettingsInstallHandler(ImGuiContext* context);
23242326
IMGUI_API ImGuiTableSettings* TableSettingsCreate(ImGuiID id, int columns_count);
23252327
IMGUI_API ImGuiTableSettings* TableSettingsFindByID(ImGuiID id);
2326-
IMGUI_API void TableSettingsClearByID(ImGuiID id);
23272328

23282329
// Tab Bars
23292330
IMGUI_API bool BeginTabBarEx(ImGuiTabBar* tab_bar, const ImRect& bb, ImGuiTabBarFlags flags);

imgui_tables.cpp

Lines changed: 59 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,6 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
271271

272272
// Acquire storage for the table
273273
ImGuiTable* table = g.Tables.GetOrAddByKey(id);
274-
const bool table_is_new = (table->ID == 0);
275274
const int instance_no = (table->LastFrameActive != g.FrameCount) ? 0 : table->InstanceCurrent + 1;
276275
const ImGuiID instance_id = id + instance_no;
277276
const ImGuiTableFlags table_last_flags = table->Flags;
@@ -288,7 +287,6 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
288287
table->LastFrameActive = g.FrameCount;
289288
table->OuterWindow = table->InnerWindow = outer_window;
290289
table->ColumnsCount = columns_count;
291-
table->IsInitializing = false;
292290
table->IsLayoutLocked = false;
293291
table->InnerWidth = inner_width;
294292
table->OuterRect = outer_rect;
@@ -415,10 +413,25 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
415413
if (table->RawData == NULL)
416414
{
417415
TableBeginInitMemory(table, columns_count);
418-
if (table_is_new)
419-
table->IsInitializing = true;
420-
table->IsSortSpecsDirty = table->IsSettingsRequestLoad = true;
416+
table->IsInitializing = table->IsSettingsRequestLoad = true;
417+
}
418+
if (table->IsResetAllRequest)
419+
TableResetSettings(table);
420+
if (table->IsInitializing)
421+
{
422+
// Initialize for new settings
421423
table->SettingsOffset = -1;
424+
table->IsSortSpecsDirty = true;
425+
for (int n = 0; n < columns_count; n++)
426+
{
427+
ImGuiTableColumn* column = &table->Columns[n];
428+
float width_auto = column->WidthAuto;
429+
*column = ImGuiTableColumn();
430+
column->WidthAuto = width_auto;
431+
column->IsPreserveWidthAuto = true; // Preserve WidthAuto when reinitializing a live table: not technically necessary but remove a visible flicker
432+
column->DisplayOrder = table->DisplayOrderToIndex[n] = (ImGuiTableColumnIdx)n;
433+
column->IsEnabled = column->IsEnabledNextFrame = true;
434+
}
422435
}
423436

424437
// Load settings
@@ -479,19 +492,11 @@ void ImGui::TableBeginInitMemory(ImGuiTable* table, int columns_count)
479492
span_allocator.ReserveBytes(1, columns_count * sizeof(ImGuiTableColumnIdx));
480493
span_allocator.ReserveBytes(2, columns_count * sizeof(ImGuiTableCellData));
481494
table->RawData = IM_ALLOC(span_allocator.GetArenaSizeInBytes());
495+
memset(table->RawData, 0, span_allocator.GetArenaSizeInBytes());
482496
span_allocator.SetArenaBasePtr(table->RawData);
483497
span_allocator.GetSpan(0, &table->Columns);
484498
span_allocator.GetSpan(1, &table->DisplayOrderToIndex);
485499
span_allocator.GetSpan(2, &table->RowCellData);
486-
487-
memset(table->RowCellData.Data, 0, table->RowCellData.size_in_bytes());
488-
for (int n = 0; n < columns_count; n++)
489-
{
490-
ImGuiTableColumn* column = &table->Columns[n];
491-
*column = ImGuiTableColumn();
492-
column->DisplayOrder = table->DisplayOrderToIndex[n] = (ImGuiTableColumnIdx)n;
493-
column->AutoFitQueue = column->CannotSkipItemsQueue = (1 << 3) - 1; // Fit for three frames
494-
}
495500
}
496501

497502
// Apply queued resizing/reordering/hiding requests
@@ -513,7 +518,6 @@ void ImGui::TableBeginApplyRequests(ImGuiTable* table)
513518
// FIXME-TABLE: Would be nice to redistribute available stretch space accordingly to other weights, instead of giving it all to siblings.
514519
if (table->AutoFitSingleStretchColumn != -1)
515520
{
516-
table->Columns[table->AutoFitSingleStretchColumn].AutoFitQueue = 0x00;
517521
TableSetColumnWidth(table->AutoFitSingleStretchColumn, table->Columns[table->AutoFitSingleStretchColumn].WidthAuto);
518522
table->AutoFitSingleStretchColumn = -1;
519523
}
@@ -635,6 +639,15 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
635639
}
636640
if (column->SortOrder > 0 && !(table->Flags & ImGuiTableFlags_MultiSortable))
637641
table->IsSortSpecsDirty = true;
642+
643+
bool start_auto_fit = false;
644+
if (column->Flags & (ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_WidthAutoResize))
645+
start_auto_fit = column->WidthRequest < 0.0f;
646+
else
647+
start_auto_fit = column->StretchWeight < 0.0f;
648+
if (start_auto_fit)
649+
column->AutoFitQueue = column->CannotSkipItemsQueue = (1 << 3) - 1; // Fit for three frames
650+
638651
if (column->AutoFitQueue != 0x00)
639652
want_column_auto_fit = true;
640653

@@ -698,6 +711,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
698711

699712
// Calculate ideal/auto column width (that's the width required for all contents to be visible without clipping)
700713
// Combine width from regular rows + width from headers unless requested not to.
714+
if (!column->IsPreserveWidthAuto)
701715
{
702716
const float content_width_body = (float)ImMax(column->ContentMaxXFrozen, column->ContentMaxXUnfrozen) - column->WorkMinX;
703717
const float content_width_headers = (float)column->ContentMaxXHeadersIdeal - column->WorkMinX;
@@ -708,11 +722,12 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
708722

709723
// Non-resizable columns also submit their requested width
710724
if ((column->Flags & ImGuiTableColumnFlags_WidthFixed) && column->InitStretchWeightOrWidth > 0.0f)
711-
if (!(table->Flags & ImGuiTableFlags_Resizable) || !(column->Flags & ImGuiTableColumnFlags_NoResize))
725+
if (!(table->Flags & ImGuiTableFlags_Resizable) || (column->Flags & ImGuiTableColumnFlags_NoResize))
712726
width_auto = ImMax(width_auto, column->InitStretchWeightOrWidth);
713727

714728
column->WidthAuto = width_auto;
715729
}
730+
column->IsPreserveWidthAuto = false;
716731

717732
if (column->Flags & (ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_WidthAutoResize))
718733
{
@@ -734,9 +749,8 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
734749
else
735750
{
736751
IM_ASSERT(column->Flags & ImGuiTableColumnFlags_WidthStretch);
737-
const float default_weight = (column->InitStretchWeightOrWidth > 0.0f) ? column->InitStretchWeightOrWidth : 1.0f;
738-
if (column->AutoFitQueue != 0x00)
739-
column->StretchWeight = default_weight;
752+
if (column->StretchWeight < 0.0f)
753+
column->StretchWeight = 1.0f;
740754
sum_weights_stretched += column->StretchWeight;
741755
if (table->LeftMostStretchedColumnDisplayOrder == -1 || table->LeftMostStretchedColumnDisplayOrder > column->DisplayOrder)
742756
table->LeftMostStretchedColumnDisplayOrder = column->DisplayOrder;
@@ -1232,6 +1246,7 @@ void ImGui::EndTable()
12321246
// Save settings
12331247
if (table->IsSettingsDirty)
12341248
TableSaveSettings(table);
1249+
table->IsInitializing = false;
12351250

12361251
// Clear or restore current table, if any
12371252
IM_ASSERT(g.CurrentWindow == outer_window && g.CurrentTable == table);
@@ -2731,6 +2746,10 @@ void ImGui::TableDrawContextMenu(ImGuiTable* table)
27312746
want_separator = true;
27322747
}
27332748

2749+
// Reset all (should work but seems unnecessary/noisy to expose?)
2750+
//if (MenuItem("Reset all"))
2751+
// table->IsResetAllRequest = true;
2752+
27342753
// Sorting
27352754
// (modify TableOpenContextMenu() to add _Sortable flag if enabling this)
27362755
#if 0
@@ -2777,12 +2796,14 @@ void ImGui::TableDrawContextMenu(ImGuiTable* table)
27772796
//-------------------------------------------------------------------------
27782797
// [SECTION] Tables: Settings (.ini data)
27792798
//-------------------------------------------------------------------------
2799+
// FIXME: The binding/finding/creating flow are too confusing.
2800+
//-------------------------------------------------------------------------
27802801
// - TableSettingsInit() [Internal]
27812802
// - TableSettingsCalcChunkSize() [Internal]
27822803
// - TableSettingsCreate() [Internal]
27832804
// - TableSettingsFindByID() [Internal]
2784-
// - TableSettingsClearByID() [Internal]
27852805
// - TableGetBoundSettings() [Internal]
2806+
// - TableResetSettings()
27862807
// - TableSaveSettings() [Internal]
27872808
// - TableLoadSettings() [Internal]
27882809
// - TableSettingsHandler_ClearAll() [Internal]
@@ -2835,12 +2856,6 @@ ImGuiTableSettings* ImGui::TableSettingsFindByID(ImGuiID id)
28352856
return NULL;
28362857
}
28372858

2838-
void ImGui::TableSettingsClearByID(ImGuiID id)
2839-
{
2840-
if (ImGuiTableSettings* settings = TableSettingsFindByID(id))
2841-
settings->ID = 0;
2842-
}
2843-
28442859
// Get settings for a given table, NULL if none
28452860
ImGuiTableSettings* ImGui::TableGetBoundSettings(ImGuiTable* table)
28462861
{
@@ -2856,6 +2871,15 @@ ImGuiTableSettings* ImGui::TableGetBoundSettings(ImGuiTable* table)
28562871
return NULL;
28572872
}
28582873

2874+
// Restore initial state of table (with or without saved settings)
2875+
void ImGui::TableResetSettings(ImGuiTable* table)
2876+
{
2877+
table->IsInitializing = table->IsSettingsDirty = true;
2878+
table->IsResetAllRequest = false;
2879+
table->IsSettingsRequestLoad = false; // Don't reload from ini
2880+
table->SettingsLoadedFlags = ImGuiTableFlags_None; // Mark as nothing loaded so our initialized data becomes authoritative
2881+
}
2882+
28592883
void ImGui::TableSaveSettings(ImGuiTable* table)
28602884
{
28612885
table->IsSettingsDirty = false;
@@ -3163,6 +3187,7 @@ void ImGui::DebugNodeTable(ImGuiTable* table)
31633187
GetForegroundDrawList()->AddRect(table->OuterRect.Min, table->OuterRect.Max, IM_COL32(255, 255, 0, 255));
31643188
if (!open)
31653189
return;
3190+
bool clear_settings = SmallButton("Clear settings");
31663191
BulletText("OuterRect: Pos: (%.1f,%.1f) Size: (%.1f,%.1f)", table->OuterRect.Min.x, table->OuterRect.Min.y, table->OuterRect.GetWidth(), table->OuterRect.GetHeight());
31673192
BulletText("ColumnsWidth: %.1f, AutoFitWidth: %.1f, InnerWidth: %.1f%s", table->ColumnsTotalWidth, table->ColumnsAutoFitWidth, table->InnerWidth, table->InnerWidth == 0.0f ? " (auto)" : "");
31683193
BulletText("CellPaddingX: %.1f, CellSpacingX: %.1f/%.1f, OuterPaddingX: %.1f", table->CellPaddingX, table->CellSpacingX1, table->CellSpacingX2, table->OuterPaddingX);
@@ -3200,6 +3225,8 @@ void ImGui::DebugNodeTable(ImGuiTable* table)
32003225
}
32013226
if (ImGuiTableSettings* settings = TableGetBoundSettings(table))
32023227
DebugNodeTableSettings(settings);
3228+
if (clear_settings)
3229+
table->IsResetAllRequest = true;
32033230
TreePop();
32043231
}
32053232

@@ -3221,7 +3248,12 @@ void ImGui::DebugNodeTableSettings(ImGuiTableSettings* settings)
32213248
TreePop();
32223249
}
32233250

3224-
#endif // #ifndef IMGUI_DISABLE_METRICS_WINDOW
3251+
#else // #ifndef IMGUI_DISABLE_METRICS_WINDOW
3252+
3253+
void ImGui::DebugNodeTable(ImGuiTable*) {}
3254+
void ImGui::DebugNodeTableSettings(ImGuiTableSettings*) {}
3255+
3256+
#endif
32253257

32263258

32273259
//-------------------------------------------------------------------------

0 commit comments

Comments
 (0)