Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/wolfpld/tracy.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBartosz Taudul <wolf@nereid.pl>2021-05-25 23:21:54 +0300
committerBartosz Taudul <wolf@nereid.pl>2021-05-25 23:21:54 +0300
commit688a9722c70d8e8373ffb901a42b7fd0d842a5f3 (patch)
tree5c2b659ff748bc1457bff9dd834034dc0dbb5a37 /imgui/imgui_tables.cpp
parent4fc02f5680c7ff3499d869f131cf8f8cd50f8cf5 (diff)
Update ImGui to 1.83 + docking.
Diffstat (limited to 'imgui/imgui_tables.cpp')
-rw-r--r--imgui/imgui_tables.cpp221
1 files changed, 148 insertions, 73 deletions
diff --git a/imgui/imgui_tables.cpp b/imgui/imgui_tables.cpp
index b6d11749..ce0d5603 100644
--- a/imgui/imgui_tables.cpp
+++ b/imgui/imgui_tables.cpp
@@ -1,4 +1,4 @@
-// dear imgui, v1.82
+// dear imgui, v1.83
// (tables and columns code)
/*
@@ -8,6 +8,7 @@ Index of this file:
// [SECTION] Commentary
// [SECTION] Header mess
// [SECTION] Tables: Main code
+// [SECTION] Tables: Simple accessors
// [SECTION] Tables: Row changes
// [SECTION] Tables: Columns changes
// [SECTION] Tables: Columns width management
@@ -73,7 +74,7 @@ Index of this file:
// (Read carefully because this is subtle but it does make sense!)
//-----------------------------------------------------------------------------
// About 'outer_size':
-// Its meaning needs to differ slightly depending of if we are using ScrollX/ScrollY flags.
+// Its meaning needs to differ slightly depending on if we are using ScrollX/ScrollY flags.
// Default value is ImVec2(0.0f, 0.0f).
// X
// - outer_size.x <= 0.0f -> Right-align from window/work-rect right-most edge. With -FLT_MIN or 0.0f will align exactly on right-most edge.
@@ -90,7 +91,7 @@ Index of this file:
// Outer size is also affected by the NoHostExtendX/NoHostExtendY flags.
// Important to that note how the two flags have slightly different behaviors!
// - ImGuiTableFlags_NoHostExtendX -> Make outer width auto-fit to columns (overriding outer_size.x value). Only available when ScrollX/ScrollY are disabled and Stretch columns are not used.
-// - ImGuiTableFlags_NoHostExtendY -> Make outer height stop exactly at outer_size.y (prevent auto-extending table past the limit). Only available when ScrollX/ScrollY are disabled. Data below the limit will be clipped and not visible.
+// - ImGuiTableFlags_NoHostExtendY -> Make outer height stop exactly at outer_size.y (prevent auto-extending table past the limit). Only available when ScrollX/ScrollY is disabled. Data below the limit will be clipped and not visible.
// In theory ImGuiTableFlags_NoHostExtendY could be the default and any non-scrolling tables with outer_size.y != 0.0f would use exact height.
// This would be consistent but perhaps less useful and more confusing (as vertically clipped items are not easily noticeable)
//-----------------------------------------------------------------------------
@@ -132,7 +133,7 @@ Index of this file:
// - the typical use of mixing sizing policies is: any number of LEADING Fixed columns, followed by one or two TRAILING Stretch columns.
// - using mixed policies with ScrollX does not make much sense, as using Stretch columns with ScrollX does not make much sense in the first place!
// that is, unless 'inner_width' is passed to BeginTable() to explicitly provide a total width to layout columns in.
-// - when using ImGuiTableFlags_SizingFixedSame with mixed columns, only the Fixed/Auto columns will match their widths to the maximum contents width.
+// - when using ImGuiTableFlags_SizingFixedSame with mixed columns, only the Fixed/Auto columns will match their widths to the width of the maximum contents.
// - when using ImGuiTableFlags_SizingStretchSame with mixed columns, only the Stretch columns will match their weight/widths.
//-----------------------------------------------------------------------------
// About using column width:
@@ -140,9 +141,9 @@ Index of this file:
// - you may use GetContentRegionAvail().x to query the width available in a given column.
// - right-side alignment features such as SetNextItemWidth(-x) or PushItemWidth(-x) will rely on this width.
// If the column is not resizable and has no width specified with TableSetupColumn():
-// - its width will be automatic and be the set to the max of items submitted.
+// - its width will be automatic and be set to the max of items submitted.
// - therefore you generally cannot have ALL items of the columns use e.g. SetNextItemWidth(-FLT_MIN).
-// - but if the column has one or more item of known/fixed size, this will become the reference width used by SetNextItemWidth(-FLT_MIN).
+// - but if the column has one or more items of known/fixed size, this will become the reference width used by SetNextItemWidth(-FLT_MIN).
//-----------------------------------------------------------------------------
@@ -161,7 +162,7 @@ Index of this file:
// - Both TableSetColumnIndex() and TableNextColumn() return true when the column is visible or performing
// width measurements. Otherwise, you may skip submitting the contents of a cell/column, BUT ONLY if you know
// it is not going to contribute to row height.
-// In many situations, you may skip submitting contents for every columns but one (e.g. the first one).
+// In many situations, you may skip submitting contents for every column but one (e.g. the first one).
// - Case A: column is not hidden by user, and at least partially in sight (most common case).
// - Case B: column is clipped / out of sight (because of scrolling or parent ClipRect): TableNextColumn() return false as a hint but we still allow layout output.
// - Case C: column is hidden explicitly by the user (e.g. via the context menu, or _DefaultHide column flag, etc.).
@@ -172,7 +173,7 @@ Index of this file:
// ClipRect: normal zero-width zero-width -> [internal] when ClipRect is zero, ItemAdd() will return false and most widgets will early out mid-way.
// ImDrawList output: normal dummy dummy -> [internal] when using the dummy channel, ImDrawList submissions (if any) will be wasted (because cliprect is zero-width anyway).
//
-// - We need distinguish those cases because non-hidden columns that are clipped outside of scrolling bounds should still contribute their height to the row.
+// - We need to distinguish those cases because non-hidden columns that are clipped outside of scrolling bounds should still contribute their height to the row.
// However, in the majority of cases, the contribution to row height is the same for all columns, or the tallest cells are known by the programmer.
//-----------------------------------------------------------------------------
// About clipping/culling of whole Tables:
@@ -209,6 +210,8 @@ Index of this file:
#if defined(_MSC_VER) && _MSC_VER >= 1922 // MSVC 2019 16.2 or later
#pragma warning (disable: 5054) // operator '|': deprecated between enumerations of different types
#endif
+#pragma warning (disable: 26451) // [Static Analyzer] Arithmetic overflow : Using operator 'xxx' on a 4 byte value and then casting the result to a 8 byte value. Cast the value to the wider type before calling operator 'xxx' to avoid overflow(io.2).
+#pragma warning (disable: 26812) // [Static Analyzer] The enum type 'xxx' is unscoped. Prefer 'enum class' over 'enum' (Enum.3).
#endif
// Clang/GCC warnings with -Weverything
@@ -235,6 +238,19 @@ Index of this file:
//-----------------------------------------------------------------------------
// [SECTION] Tables: Main code
//-----------------------------------------------------------------------------
+// - TableFixFlags() [Internal]
+// - TableFindByID() [Internal]
+// - BeginTable()
+// - BeginTableEx() [Internal]
+// - TableBeginInitMemory() [Internal]
+// - TableBeginApplyRequests() [Internal]
+// - TableSetupColumnFlags() [Internal]
+// - TableUpdateLayout() [Internal]
+// - TableUpdateBorders() [Internal]
+// - EndTable()
+// - TableSetupColumn()
+// - TableSetupScrollFreeze()
+//-----------------------------------------------------------------------------
// Configuration
static const int TABLE_DRAW_CHANNEL_BG0 = 0;
@@ -322,6 +338,16 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
if (instance_no > 0)
IM_ASSERT(table->ColumnsCount == columns_count && "BeginTable(): Cannot change columns count mid-frame while preserving same ID");
+ // Acquire temporary buffers
+ const int table_idx = g.Tables.GetIndex(table);
+ g.CurrentTableStackIdx++;
+ if (g.CurrentTableStackIdx + 1 > g.TablesTempDataStack.Size)
+ g.TablesTempDataStack.resize(g.CurrentTableStackIdx + 1, ImGuiTableTempData());
+ ImGuiTableTempData* temp_data = table->TempData = &g.TablesTempDataStack[g.CurrentTableStackIdx];
+ temp_data->TableIndex = table_idx;
+ table->DrawSplitter = &table->TempData->DrawSplitter;
+ table->DrawSplitter->Clear();
+
// Fix flags
table->IsDefaultSizingPolicy = (flags & ImGuiTableFlags_SizingMask_) == 0;
flags = TableFixFlags(flags, outer_window);
@@ -335,7 +361,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
table->ColumnsCount = columns_count;
table->IsLayoutLocked = false;
table->InnerWidth = inner_width;
- table->UserOuterSize = outer_size;
+ temp_data->UserOuterSize = outer_size;
// When not using a child window, WorkRect.Max will grow as we append contents.
if (use_child_window)
@@ -384,14 +410,14 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
table->HostIndentX = inner_window->DC.Indent.x;
table->HostClipRect = inner_window->ClipRect;
table->HostSkipItems = inner_window->SkipItems;
- table->HostBackupWorkRect = inner_window->WorkRect;
- table->HostBackupParentWorkRect = inner_window->ParentWorkRect;
- table->HostBackupColumnsOffset = outer_window->DC.ColumnsOffset;
- table->HostBackupPrevLineSize = inner_window->DC.PrevLineSize;
- table->HostBackupCurrLineSize = inner_window->DC.CurrLineSize;
- table->HostBackupCursorMaxPos = inner_window->DC.CursorMaxPos;
- table->HostBackupItemWidth = outer_window->DC.ItemWidth;
- table->HostBackupItemWidthStackSize = outer_window->DC.ItemWidthStack.Size;
+ temp_data->HostBackupWorkRect = inner_window->WorkRect;
+ temp_data->HostBackupParentWorkRect = inner_window->ParentWorkRect;
+ temp_data->HostBackupColumnsOffset = outer_window->DC.ColumnsOffset;
+ temp_data->HostBackupPrevLineSize = inner_window->DC.PrevLineSize;
+ temp_data->HostBackupCurrLineSize = inner_window->DC.CurrLineSize;
+ temp_data->HostBackupCursorMaxPos = inner_window->DC.CursorMaxPos;
+ temp_data->HostBackupItemWidth = outer_window->DC.ItemWidth;
+ temp_data->HostBackupItemWidthStackSize = outer_window->DC.ItemWidthStack.Size;
inner_window->DC.PrevLineSize = inner_window->DC.CurrLineSize = ImVec2(0.0f, 0.0f);
// Padding and Spacing
@@ -434,8 +460,6 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
table->BorderColorLight = GetColorU32(ImGuiCol_TableBorderLight);
// Make table current
- const int table_idx = g.Tables.GetIndex(table);
- g.CurrentTableStack.push_back(ImGuiPtrOrIndex(table_idx));
g.CurrentTable = table;
outer_window->DC.CurrentTableIdx = table_idx;
if (inner_window != outer_window) // So EndChild() within the inner window can restore the table properly.
@@ -448,13 +472,18 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
if (table_idx >= g.TablesLastTimeActive.Size)
g.TablesLastTimeActive.resize(table_idx + 1, -1.0f);
g.TablesLastTimeActive[table_idx] = (float)g.Time;
+ temp_data->LastTimeActive = (float)g.Time;
table->MemoryCompacted = false;
// Setup memory buffer (clear data if columns count changed)
- const int stored_size = table->Columns.size();
- if (stored_size != 0 && stored_size != columns_count)
- {
- IM_FREE(table->RawData);
+ ImGuiTableColumn* old_columns_to_preserve = NULL;
+ void* old_columns_raw_data = NULL;
+ const int old_columns_count = table->Columns.size();
+ if (old_columns_count != 0 && old_columns_count != columns_count)
+ {
+ // Attempt to preserve width on column count change (#4046)
+ old_columns_to_preserve = table->Columns.Data;
+ old_columns_raw_data = table->RawData;
table->RawData = NULL;
}
if (table->RawData == NULL)
@@ -477,14 +506,24 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
for (int n = 0; n < columns_count; n++)
{
ImGuiTableColumn* column = &table->Columns[n];
- float width_auto = column->WidthAuto;
- *column = ImGuiTableColumn();
- column->WidthAuto = width_auto;
- column->IsPreserveWidthAuto = true; // Preserve WidthAuto when reinitializing a live table: not technically necessary but remove a visible flicker
+ if (old_columns_to_preserve && n < old_columns_count)
+ {
+ // FIXME: We don't attempt to preserve column order in this path.
+ *column = old_columns_to_preserve[n];
+ }
+ else
+ {
+ float width_auto = column->WidthAuto;
+ *column = ImGuiTableColumn();
+ column->WidthAuto = width_auto;
+ column->IsPreserveWidthAuto = true; // Preserve WidthAuto when reinitializing a live table: not technically necessary but remove a visible flicker
+ column->IsEnabled = column->IsEnabledNextFrame = true;
+ }
column->DisplayOrder = table->DisplayOrderToIndex[n] = (ImGuiTableColumnIdx)n;
- column->IsEnabled = column->IsEnabledNextFrame = true;
}
}
+ if (old_columns_raw_data)
+ IM_FREE(old_columns_raw_data);
// Load settings
if (table->IsSettingsRequestLoad)
@@ -1082,7 +1121,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
// Initial state
ImGuiWindow* inner_window = table->InnerWindow;
if (table->Flags & ImGuiTableFlags_NoClip)
- table->DrawSplitter.SetCurrentChannel(inner_window->DrawList, TABLE_DRAW_CHANNEL_NOCLIP);
+ table->DrawSplitter->SetCurrentChannel(inner_window->DrawList, TABLE_DRAW_CHANNEL_NOCLIP);
else
inner_window->DrawList->PushClipRect(inner_window->ClipRect.Min, inner_window->ClipRect.Max, false);
}
@@ -1170,6 +1209,7 @@ void ImGui::EndTable()
const ImGuiTableFlags flags = table->Flags;
ImGuiWindow* inner_window = table->InnerWindow;
ImGuiWindow* outer_window = table->OuterWindow;
+ ImGuiTableTempData* temp_data = table->TempData;
IM_ASSERT(inner_window == g.CurrentWindow);
IM_ASSERT(outer_window == inner_window || outer_window == inner_window->ParentWindow);
@@ -1182,9 +1222,9 @@ void ImGui::EndTable()
TableOpenContextMenu((int)table->HoveredColumnBody);
// Finalize table height
- inner_window->DC.PrevLineSize = table->HostBackupPrevLineSize;
- inner_window->DC.CurrLineSize = table->HostBackupCurrLineSize;
- inner_window->DC.CursorMaxPos = table->HostBackupCursorMaxPos;
+ inner_window->DC.PrevLineSize = temp_data->HostBackupPrevLineSize;
+ inner_window->DC.CurrLineSize = temp_data->HostBackupCurrLineSize;
+ inner_window->DC.CursorMaxPos = temp_data->HostBackupCursorMaxPos;
const float inner_content_max_y = table->RowPosY2;
IM_ASSERT(table->RowPosY2 == inner_window->DC.CursorPos.y);
if (inner_window != outer_window)
@@ -1231,10 +1271,11 @@ void ImGui::EndTable()
#endif
// Flatten channels and merge draw calls
- table->DrawSplitter.SetCurrentChannel(inner_window->DrawList, 0);
+ ImDrawListSplitter* splitter = table->DrawSplitter;
+ splitter->SetCurrentChannel(inner_window->DrawList, 0);
if ((table->Flags & ImGuiTableFlags_NoClip) == 0)
TableMergeDrawChannels(table);
- table->DrawSplitter.Merge(inner_window->DrawList);
+ splitter->Merge(inner_window->DrawList);
// Update ColumnsAutoFitWidth to get us ahead for host using our size to auto-resize without waiting for next BeginTable()
const float width_spacings = (table->OuterPaddingX * 2.0f) + (table->CellSpacingX1 + table->CellSpacingX2) * (table->ColumnsEnabledCount - 1);
@@ -1276,18 +1317,18 @@ void ImGui::EndTable()
// Pop from id stack
IM_ASSERT_USER_ERROR(inner_window->IDStack.back() == table->ID + table->InstanceCurrent, "Mismatching PushID/PopID!");
- IM_ASSERT_USER_ERROR(outer_window->DC.ItemWidthStack.Size >= table->HostBackupItemWidthStackSize, "Too many PopItemWidth!");
+ IM_ASSERT_USER_ERROR(outer_window->DC.ItemWidthStack.Size >= temp_data->HostBackupItemWidthStackSize, "Too many PopItemWidth!");
PopID();
// Restore window data that we modified
const ImVec2 backup_outer_max_pos = outer_window->DC.CursorMaxPos;
- inner_window->WorkRect = table->HostBackupWorkRect;
- inner_window->ParentWorkRect = table->HostBackupParentWorkRect;
+ inner_window->WorkRect = temp_data->HostBackupWorkRect;
+ inner_window->ParentWorkRect = temp_data->HostBackupParentWorkRect;
inner_window->SkipItems = table->HostSkipItems;
outer_window->DC.CursorPos = table->OuterRect.Min;
- outer_window->DC.ItemWidth = table->HostBackupItemWidth;
- outer_window->DC.ItemWidthStack.Size = table->HostBackupItemWidthStackSize;
- outer_window->DC.ColumnsOffset = table->HostBackupColumnsOffset;
+ outer_window->DC.ItemWidth = temp_data->HostBackupItemWidth;
+ outer_window->DC.ItemWidthStack.Size = temp_data->HostBackupItemWidthStackSize;
+ outer_window->DC.ColumnsOffset = temp_data->HostBackupColumnsOffset;
// Layout in outer window
// (FIXME: To allow auto-fit and allow desirable effect of SameLine() we dissociate 'used' vs 'ideal' size by overriding
@@ -1310,20 +1351,20 @@ void ImGui::EndTable()
IM_ASSERT((table->Flags & ImGuiTableFlags_ScrollX) == 0);
outer_window->DC.CursorMaxPos.x = ImMax(backup_outer_max_pos.x, table->OuterRect.Min.x + table->ColumnsAutoFitWidth);
}
- else if (table->UserOuterSize.x <= 0.0f)
+ else if (temp_data->UserOuterSize.x <= 0.0f)
{
const float decoration_size = (table->Flags & ImGuiTableFlags_ScrollX) ? inner_window->ScrollbarSizes.x : 0.0f;
- outer_window->DC.IdealMaxPos.x = ImMax(outer_window->DC.IdealMaxPos.x, table->OuterRect.Min.x + table->ColumnsAutoFitWidth + decoration_size - table->UserOuterSize.x);
+ outer_window->DC.IdealMaxPos.x = ImMax(outer_window->DC.IdealMaxPos.x, table->OuterRect.Min.x + table->ColumnsAutoFitWidth + decoration_size - temp_data->UserOuterSize.x);
outer_window->DC.CursorMaxPos.x = ImMax(backup_outer_max_pos.x, ImMin(table->OuterRect.Max.x, table->OuterRect.Min.x + table->ColumnsAutoFitWidth));
}
else
{
outer_window->DC.CursorMaxPos.x = ImMax(backup_outer_max_pos.x, table->OuterRect.Max.x);
}
- if (table->UserOuterSize.y <= 0.0f)
+ if (temp_data->UserOuterSize.y <= 0.0f)
{
const float decoration_size = (table->Flags & ImGuiTableFlags_ScrollY) ? inner_window->ScrollbarSizes.y : 0.0f;
- outer_window->DC.IdealMaxPos.y = ImMax(outer_window->DC.IdealMaxPos.y, inner_content_max_y + decoration_size - table->UserOuterSize.y);
+ outer_window->DC.IdealMaxPos.y = ImMax(outer_window->DC.IdealMaxPos.y, inner_content_max_y + decoration_size - temp_data->UserOuterSize.y);
outer_window->DC.CursorMaxPos.y = ImMax(backup_outer_max_pos.y, ImMin(table->OuterRect.Max.y, inner_content_max_y));
}
else
@@ -1339,8 +1380,15 @@ void ImGui::EndTable()
// Clear or restore current table, if any
IM_ASSERT(g.CurrentWindow == outer_window && g.CurrentTable == table);
- g.CurrentTableStack.pop_back();
- g.CurrentTable = g.CurrentTableStack.Size ? g.Tables.GetByIndex(g.CurrentTableStack.back().Index) : NULL;
+ IM_ASSERT(g.CurrentTableStackIdx >= 0);
+ g.CurrentTableStackIdx--;
+ temp_data = g.CurrentTableStackIdx >= 0 ? &g.TablesTempDataStack[g.CurrentTableStackIdx] : NULL;
+ g.CurrentTable = temp_data ? g.Tables.GetByIndex(temp_data->TableIndex) : NULL;
+ if (g.CurrentTable)
+ {
+ g.CurrentTable->TempData = temp_data;
+ g.CurrentTable->DrawSplitter = &temp_data->DrawSplitter;
+ }
outer_window->DC.CurrentTableIdx = g.CurrentTable ? g.Tables.GetIndex(g.CurrentTable) : -1;
}
@@ -1430,6 +1478,20 @@ void ImGui::TableSetupScrollFreeze(int columns, int rows)
table->IsUnfrozenRows = (table->FreezeRowsCount == 0); // Make sure this is set before TableUpdateLayout() so ImGuiListClipper can benefit from it.b
}
+//-----------------------------------------------------------------------------
+// [SECTION] Tables: Simple accessors
+//-----------------------------------------------------------------------------
+// - TableGetColumnCount()
+// - TableGetColumnName()
+// - TableGetColumnName() [Internal]
+// - TableSetColumnEnabled() [Internal]
+// - TableGetColumnFlags()
+// - TableGetCellBgRect() [Internal]
+// - TableGetColumnResizeID() [Internal]
+// - TableGetHoveredColumn() [Internal]
+// - TableSetBgColor()
+//-----------------------------------------------------------------------------
+
int ImGui::TableGetColumnCount()
{
ImGuiContext& g = *GImGui;
@@ -1458,6 +1520,9 @@ const char* ImGui::TableGetColumnName(const ImGuiTable* table, int column_n)
return &table->ColumnsNames.Buf[column->NameOffset];
}
+// Request enabling/disabling a column (often perceived as "showing/hiding" from users point of view)
+// Note that end-user can use the context menu to change this themselves (right-click in headers, or right-click in columns body with ImGuiTableFlags_ContextMenuInBody)
+// Request will be applied during next layout, which happens on the first call to TableNextRow() after BeginTable()
// For the getter you can use (TableGetColumnFlags() & ImGuiTableColumnFlags_IsEnabled)
void ImGui::TableSetColumnEnabled(int column_n, bool enabled)
{
@@ -1696,7 +1761,7 @@ void ImGui::TableEndRow(ImGuiTable* table)
// always followed by a change of clipping rectangle we perform the smallest overwrite possible here.
if ((table->Flags & ImGuiTableFlags_NoClip) == 0)
window->DrawList->_CmdHeader.ClipRect = table->Bg0ClipRectForDrawCmd.ToVec4();
- table->DrawSplitter.SetCurrentChannel(window->DrawList, TABLE_DRAW_CHANNEL_BG0);
+ table->DrawSplitter->SetCurrentChannel(window->DrawList, TABLE_DRAW_CHANNEL_BG0);
}
// Draw row background
@@ -1768,7 +1833,7 @@ void ImGui::TableEndRow(ImGuiTable* table)
// Update cliprect ahead of TableBeginCell() so clipper can access to new ClipRect->Min.y
SetWindowClipRectBeforeSetChannel(window, table->Columns[0].ClipRect);
- table->DrawSplitter.SetCurrentChannel(window->DrawList, table->Columns[0].DrawChannelCurrent);
+ table->DrawSplitter->SetCurrentChannel(window->DrawList, table->Columns[0].DrawChannelCurrent);
}
if (!(table->RowFlags & ImGuiTableRowFlags_Headers))
@@ -1883,14 +1948,14 @@ void ImGui::TableBeginCell(ImGuiTable* table, int column_n)
if (table->Flags & ImGuiTableFlags_NoClip)
{
// FIXME: if we end up drawing all borders/bg in EndTable, could remove this and just assert that channel hasn't changed.
- table->DrawSplitter.SetCurrentChannel(window->DrawList, TABLE_DRAW_CHANNEL_NOCLIP);
+ table->DrawSplitter->SetCurrentChannel(window->DrawList, TABLE_DRAW_CHANNEL_NOCLIP);
//IM_ASSERT(table->DrawSplitter._Current == TABLE_DRAW_CHANNEL_NOCLIP);
}
else
{
// FIXME-TABLE: Could avoid this if draw channel is dummy channel?
SetWindowClipRectBeforeSetChannel(window, column->ClipRect);
- table->DrawSplitter.SetCurrentChannel(window->DrawList, column->DrawChannelCurrent);
+ table->DrawSplitter->SetCurrentChannel(window->DrawList, column->DrawChannelCurrent);
}
// Logging
@@ -2138,7 +2203,7 @@ void ImGui::TablePushBackgroundChannel()
// Optimization: avoid SetCurrentChannel() + PushClipRect()
table->HostBackupInnerClipRect = window->ClipRect;
SetWindowClipRectBeforeSetChannel(window, table->Bg2ClipRectForDrawCmd);
- table->DrawSplitter.SetCurrentChannel(window->DrawList, table->Bg2DrawChannelCurrent);
+ table->DrawSplitter->SetCurrentChannel(window->DrawList, table->Bg2DrawChannelCurrent);
}
void ImGui::TablePopBackgroundChannel()
@@ -2150,7 +2215,7 @@ void ImGui::TablePopBackgroundChannel()
// Optimization: avoid PopClipRect() + SetCurrentChannel()
SetWindowClipRectBeforeSetChannel(window, table->HostBackupInnerClipRect);
- table->DrawSplitter.SetCurrentChannel(window->DrawList, column->DrawChannelCurrent);
+ table->DrawSplitter->SetCurrentChannel(window->DrawList, column->DrawChannelCurrent);
}
// Allocate draw channels. Called by TableUpdateLayout()
@@ -2176,7 +2241,7 @@ void ImGui::TableSetupDrawChannels(ImGuiTable* table)
const int channels_for_bg = 1 + 1 * freeze_row_multiplier;
const int channels_for_dummy = (table->ColumnsEnabledCount < table->ColumnsCount || table->VisibleMaskByIndex != table->EnabledMaskByIndex) ? +1 : 0;
const int channels_total = channels_for_bg + (channels_for_row * freeze_row_multiplier) + channels_for_dummy;
- table->DrawSplitter.Split(table->InnerWindow->DrawList, channels_total);
+ table->DrawSplitter->Split(table->InnerWindow->DrawList, channels_total);
table->DummyDrawChannel = (ImGuiTableDrawChannelIdx)((channels_for_dummy > 0) ? channels_total - 1 : -1);
table->Bg2DrawChannelCurrent = TABLE_DRAW_CHANNEL_BG2_FROZEN;
table->Bg2DrawChannelUnfrozen = (ImGuiTableDrawChannelIdx)((table->FreezeRowsCount > 0) ? 2 + channels_for_row : TABLE_DRAW_CHANNEL_BG2_FROZEN);
@@ -2240,7 +2305,7 @@ void ImGui::TableSetupDrawChannels(ImGuiTable* table)
void ImGui::TableMergeDrawChannels(ImGuiTable* table)
{
ImGuiContext& g = *GImGui;
- ImDrawListSplitter* splitter = &table->DrawSplitter;
+ ImDrawListSplitter* splitter = table->DrawSplitter;
const bool has_freeze_v = (table->FreezeRowsCount > 0);
const bool has_freeze_h = (table->FreezeColumnsCount > 0);
IM_ASSERT(splitter->_Current == 0);
@@ -2251,10 +2316,11 @@ void ImGui::TableMergeDrawChannels(ImGuiTable* table)
ImRect ClipRect;
int ChannelsCount;
ImBitArray<IMGUI_TABLE_MAX_DRAW_CHANNELS> ChannelsMask;
+
+ MergeGroup() { ChannelsCount = 0; }
};
int merge_group_mask = 0x00;
MergeGroup merge_groups[4];
- memset(merge_groups, 0, sizeof(merge_groups));
// 1. Scan channels and take note of those which can be merged
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
@@ -2332,7 +2398,6 @@ void ImGui::TableMergeDrawChannels(ImGuiTable* table)
g.DrawChannelsTempMergeBuffer.resize(splitter->_Count - LEADING_DRAW_CHANNELS); // Use shared temporary storage so the allocation gets amortized
ImDrawChannel* dst_tmp = g.DrawChannelsTempMergeBuffer.Data;
ImBitArray<IMGUI_TABLE_MAX_DRAW_CHANNELS> remaining_mask; // We need 132-bit of storage
- remaining_mask.ClearAllBits();
remaining_mask.SetBitRange(LEADING_DRAW_CHANNELS, splitter->_Count);
remaining_mask.ClearBit(table->Bg2DrawChannelUnfrozen);
IM_ASSERT(has_freeze_v == false || table->Bg2DrawChannelUnfrozen != TABLE_DRAW_CHANNEL_BG2_FROZEN);
@@ -2411,7 +2476,7 @@ void ImGui::TableDrawBorders(ImGuiTable* table)
return;
ImDrawList* inner_drawlist = inner_window->DrawList;
- table->DrawSplitter.SetCurrentChannel(inner_drawlist, TABLE_DRAW_CHANNEL_BG0);
+ table->DrawSplitter->SetCurrentChannel(inner_drawlist, TABLE_DRAW_CHANNEL_BG0);
inner_drawlist->PushClipRect(table->Bg0ClipRectForDrawCmd.Min, table->Bg0ClipRectForDrawCmd.Max, false);
// Draw inner border and resizing feedback
@@ -2671,20 +2736,22 @@ void ImGui::TableSortSpecsBuild(ImGuiTable* table)
TableSortSpecsSanitize(table);
// Write output
- table->SortSpecsMulti.resize(table->SortSpecsCount <= 1 ? 0 : table->SortSpecsCount);
- ImGuiTableColumnSortSpecs* sort_specs = (table->SortSpecsCount == 0) ? NULL : (table->SortSpecsCount == 1) ? &table->SortSpecsSingle : table->SortSpecsMulti.Data;
- for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
- {
- ImGuiTableColumn* column = &table->Columns[column_n];
- if (column->SortOrder == -1)
- continue;
- IM_ASSERT(column->SortOrder < table->SortSpecsCount);
- ImGuiTableColumnSortSpecs* sort_spec = &sort_specs[column->SortOrder];
- sort_spec->ColumnUserID = column->UserID;
- sort_spec->ColumnIndex = (ImGuiTableColumnIdx)column_n;
- sort_spec->SortOrder = (ImGuiTableColumnIdx)column->SortOrder;
- sort_spec->SortDirection = column->SortDirection;
- }
+ ImGuiTableTempData* temp_data = table->TempData;
+ temp_data->SortSpecsMulti.resize(table->SortSpecsCount <= 1 ? 0 : table->SortSpecsCount);
+ ImGuiTableColumnSortSpecs* sort_specs = (table->SortSpecsCount == 0) ? NULL : (table->SortSpecsCount == 1) ? &temp_data->SortSpecsSingle : temp_data->SortSpecsMulti.Data;
+ if (sort_specs != NULL)
+ for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
+ {
+ ImGuiTableColumn* column = &table->Columns[column_n];
+ if (column->SortOrder == -1)
+ continue;
+ IM_ASSERT(column->SortOrder < table->SortSpecsCount);
+ ImGuiTableColumnSortSpecs* sort_spec = &sort_specs[column->SortOrder];
+ sort_spec->ColumnUserID = column->UserID;
+ sort_spec->ColumnIndex = (ImGuiTableColumnIdx)column_n;
+ sort_spec->SortOrder = (ImGuiTableColumnIdx)column->SortOrder;
+ sort_spec->SortDirection = column->SortDirection;
+ }
table->SortSpecs.Specs = sort_specs;
table->SortSpecs.SpecsCount = table->SortSpecsCount;
table->SortSpecs.SpecsDirty = true; // Mark as dirty for user
@@ -3313,6 +3380,9 @@ static void TableSettingsHandler_WriteAll(ImGuiContext* ctx, ImGuiSettingsHandle
for (int column_n = 0; column_n < settings->ColumnsCount; column_n++, column++)
{
// "Column 0 UserID=0x42AD2D21 Width=100 Visible=1 Order=0 Sort=0v"
+ bool save_column = column->UserID != 0 || save_size || save_visible || save_order || (save_sort && column->SortOrder != -1);
+ if (!save_column)
+ continue;
buf->appendf("Column %-2d", column_n);
if (column->UserID != 0) buf->appendf(" UserID=%08X", column->UserID);
if (save_size && column->IsStretch) buf->appendf(" Weight=%.4f", column->WidthOrWeight);
@@ -3366,8 +3436,6 @@ void ImGui::TableGcCompactTransientBuffers(ImGuiTable* table)
//IMGUI_DEBUG_LOG("TableGcCompactTransientBuffers() id=0x%08X\n", table->ID);
ImGuiContext& g = *GImGui;
IM_ASSERT(table->MemoryCompacted == false);
- table->DrawSplitter.ClearFreeMemory();
- table->SortSpecsMulti.clear();
table->SortSpecs.Specs = NULL;
table->IsSortSpecsDirty = true;
table->ColumnsNames.clear();
@@ -3377,6 +3445,13 @@ void ImGui::TableGcCompactTransientBuffers(ImGuiTable* table)
g.TablesLastTimeActive[g.Tables.GetIndex(table)] = -1.0f;
}
+void ImGui::TableGcCompactTransientBuffers(ImGuiTableTempData* temp_data)
+{
+ temp_data->DrawSplitter.ClearFreeMemory();
+ temp_data->SortSpecsMulti.clear();
+ temp_data->LastTimeActive = -1.0f;
+}
+
// Compact and remove unused settings data (currently only used by TestEngine)
void ImGui::TableGcCompactSettings()
{