mirror of
https://github.com/Drezil/imgui.git
synced 2024-11-15 01:17:00 +00:00
Tables: increase table columns limit from 64 to 512 using bit array allocated in contiguous memory +. (#6094, #5305, #4876, #3572)
This commit is contained in:
parent
14908cba8f
commit
91667430a8
@ -37,6 +37,9 @@ HOW TO UPDATE?
|
|||||||
|
|
||||||
All changes:
|
All changes:
|
||||||
|
|
||||||
|
- Tables: Raised max Columns count from 64 to 512. (#6094, #5305, #4876, #3572)
|
||||||
|
The previous limit was due to using 64-bit integers but we moved to bits-array
|
||||||
|
and tweaked the system enough to ensure no performance loss.
|
||||||
- Text: Fixed layouting of wrapped-text block skipping successive empty lines,
|
- Text: Fixed layouting of wrapped-text block skipping successive empty lines,
|
||||||
regression from the fix in 1.89.2. (#5720, #5919)
|
regression from the fix in 1.89.2. (#5720, #5919)
|
||||||
- Text: Fix clipping of single-character "..." ellipsis (U+2026 or U+0085) when font
|
- Text: Fix clipping of single-character "..." ellipsis (U+2026 or U+0085) when font
|
||||||
|
2
imgui.h
2
imgui.h
@ -23,7 +23,7 @@
|
|||||||
// Library Version
|
// Library Version
|
||||||
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM > 12345')
|
// (Integer encoded as XYYZZ for use in #if preprocessor conditionals, e.g. '#if IMGUI_VERSION_NUM > 12345')
|
||||||
#define IMGUI_VERSION "1.89.3 WIP"
|
#define IMGUI_VERSION "1.89.3 WIP"
|
||||||
#define IMGUI_VERSION_NUM 18922
|
#define IMGUI_VERSION_NUM 18923
|
||||||
#define IMGUI_HAS_TABLE
|
#define IMGUI_HAS_TABLE
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -551,6 +551,9 @@ struct IMGUI_API ImRect
|
|||||||
|
|
||||||
// Helper: ImBitArray
|
// Helper: ImBitArray
|
||||||
#define IM_BITARRAY_TESTBIT(_ARRAY, _N) ((_ARRAY[(_N) >> 5] & ((ImU32)1 << ((_N) & 31))) != 0) // Macro version of ImBitArrayTestBit(): ensure args have side-effect or are costly!
|
#define IM_BITARRAY_TESTBIT(_ARRAY, _N) ((_ARRAY[(_N) >> 5] & ((ImU32)1 << ((_N) & 31))) != 0) // Macro version of ImBitArrayTestBit(): ensure args have side-effect or are costly!
|
||||||
|
#define IM_BITARRAY_CLEARBIT(_ARRAY, _N) ((_ARRAY[(_N) >> 5] &= ~((ImU32)1 << ((_N) & 31)))) // Macro version of ImBitArrayClearBit(): ensure args have side-effect or are costly!
|
||||||
|
inline size_t ImBitArrayGetStorageSizeInBytes(int bitcount) { return (size_t)((bitcount + 31) >> 5) << 2; }
|
||||||
|
inline void ImBitArrayClearAllBits(ImU32* arr, int bitcount){ memset(arr, 0, ImBitArrayGetStorageSizeInBytes(bitcount)); }
|
||||||
inline bool ImBitArrayTestBit(const ImU32* arr, int n) { ImU32 mask = (ImU32)1 << (n & 31); return (arr[n >> 5] & mask) != 0; }
|
inline bool ImBitArrayTestBit(const ImU32* arr, int n) { ImU32 mask = (ImU32)1 << (n & 31); return (arr[n >> 5] & mask) != 0; }
|
||||||
inline void ImBitArrayClearBit(ImU32* arr, int n) { ImU32 mask = (ImU32)1 << (n & 31); arr[n >> 5] &= ~mask; }
|
inline void ImBitArrayClearBit(ImU32* arr, int n) { ImU32 mask = (ImU32)1 << (n & 31); arr[n >> 5] &= ~mask; }
|
||||||
inline void ImBitArraySetBit(ImU32* arr, int n) { ImU32 mask = (ImU32)1 << (n & 31); arr[n >> 5] |= mask; }
|
inline void ImBitArraySetBit(ImU32* arr, int n) { ImU32 mask = (ImU32)1 << (n & 31); arr[n >> 5] |= mask; }
|
||||||
@ -567,6 +570,8 @@ inline void ImBitArraySetBitRange(ImU32* arr, int n, int n2) // Works on ran
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef ImU32* ImBitArrayPtr; // Name for use in structs
|
||||||
|
|
||||||
// Helper: ImBitArray class (wrapper over ImBitArray functions)
|
// Helper: ImBitArray class (wrapper over ImBitArray functions)
|
||||||
// Store 1-bit per value.
|
// Store 1-bit per value.
|
||||||
template<int BITCOUNT, int OFFSET = 0>
|
template<int BITCOUNT, int OFFSET = 0>
|
||||||
@ -2440,12 +2445,11 @@ struct IMGUI_API ImGuiTabBar
|
|||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
#define IM_COL32_DISABLE IM_COL32(0,0,0,1) // Special sentinel code which cannot be used as a regular color.
|
#define IM_COL32_DISABLE IM_COL32(0,0,0,1) // Special sentinel code which cannot be used as a regular color.
|
||||||
#define IMGUI_TABLE_MAX_COLUMNS 64 // sizeof(ImU64) * 8. This is solely because we frequently encode columns set in a ImU64.
|
#define IMGUI_TABLE_MAX_COLUMNS 512 // May be further lifted
|
||||||
#define IMGUI_TABLE_MAX_DRAW_CHANNELS (4 + 64 * 2) // See TableSetupDrawChannels()
|
|
||||||
|
|
||||||
// Our current column maximum is 64 but we may raise that in the future.
|
// Our current column maximum is 64 but we may raise that in the future.
|
||||||
typedef ImS8 ImGuiTableColumnIdx;
|
typedef ImS16 ImGuiTableColumnIdx;
|
||||||
typedef ImU8 ImGuiTableDrawChannelIdx;
|
typedef ImU16 ImGuiTableDrawChannelIdx;
|
||||||
|
|
||||||
// [Internal] sizeof() ~ 104
|
// [Internal] sizeof() ~ 104
|
||||||
// We use the terminology "Enabled" to refer to a column that is not Hidden by user/api.
|
// We use the terminology "Enabled" to refer to a column that is not Hidden by user/api.
|
||||||
@ -2536,9 +2540,9 @@ struct IMGUI_API ImGuiTable
|
|||||||
ImSpan<ImGuiTableColumn> Columns; // Point within RawData[]
|
ImSpan<ImGuiTableColumn> Columns; // Point within RawData[]
|
||||||
ImSpan<ImGuiTableColumnIdx> DisplayOrderToIndex; // Point within RawData[]. Store display order of columns (when not reordered, the values are 0...Count-1)
|
ImSpan<ImGuiTableColumnIdx> DisplayOrderToIndex; // Point within RawData[]. Store display order of columns (when not reordered, the values are 0...Count-1)
|
||||||
ImSpan<ImGuiTableCellData> RowCellData; // Point within RawData[]. Store cells background requests for current row.
|
ImSpan<ImGuiTableCellData> RowCellData; // Point within RawData[]. Store cells background requests for current row.
|
||||||
ImU64 EnabledMaskByDisplayOrder; // Column DisplayOrder -> IsEnabled map
|
ImBitArrayPtr EnabledMaskByDisplayOrder; // Column DisplayOrder -> IsEnabled map
|
||||||
ImU64 EnabledMaskByIndex; // Column Index -> IsEnabled map (== not hidden by user/api) in a format adequate for iterating column without touching cold data
|
ImBitArrayPtr EnabledMaskByIndex; // Column Index -> IsEnabled map (== not hidden by user/api) in a format adequate for iterating column without touching cold data
|
||||||
ImU64 VisibleMaskByIndex; // Column Index -> IsVisibleX|IsVisibleY map (== not hidden by user/api && not hidden by scrolling/cliprect)
|
ImBitArrayPtr VisibleMaskByIndex; // Column Index -> IsVisibleX|IsVisibleY map (== not hidden by user/api && not hidden by scrolling/cliprect)
|
||||||
ImGuiTableFlags SettingsLoadedFlags; // Which data were loaded from the .ini file (e.g. when order is not altered we won't save order)
|
ImGuiTableFlags SettingsLoadedFlags; // Which data were loaded from the .ini file (e.g. when order is not altered we won't save order)
|
||||||
int SettingsOffset; // Offset in g.SettingsTables
|
int SettingsOffset; // Offset in g.SettingsTables
|
||||||
int LastFrameActive;
|
int LastFrameActive;
|
||||||
|
@ -315,7 +315,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Sanity checks
|
// Sanity checks
|
||||||
IM_ASSERT(columns_count > 0 && columns_count <= IMGUI_TABLE_MAX_COLUMNS && "Only 1..64 columns allowed!");
|
IM_ASSERT(columns_count > 0 && columns_count < IMGUI_TABLE_MAX_COLUMNS);
|
||||||
if (flags & ImGuiTableFlags_ScrollX)
|
if (flags & ImGuiTableFlags_ScrollX)
|
||||||
IM_ASSERT(inner_width >= 0.0f);
|
IM_ASSERT(inner_width >= 0.0f);
|
||||||
|
|
||||||
@ -581,16 +581,22 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
|
|||||||
void ImGui::TableBeginInitMemory(ImGuiTable* table, int columns_count)
|
void ImGui::TableBeginInitMemory(ImGuiTable* table, int columns_count)
|
||||||
{
|
{
|
||||||
// Allocate single buffer for our arrays
|
// Allocate single buffer for our arrays
|
||||||
ImSpanAllocator<3> span_allocator;
|
const int columns_bit_array_size = (int)ImBitArrayGetStorageSizeInBytes(columns_count);
|
||||||
|
ImSpanAllocator<6> span_allocator;
|
||||||
span_allocator.Reserve(0, columns_count * sizeof(ImGuiTableColumn));
|
span_allocator.Reserve(0, columns_count * sizeof(ImGuiTableColumn));
|
||||||
span_allocator.Reserve(1, columns_count * sizeof(ImGuiTableColumnIdx));
|
span_allocator.Reserve(1, columns_count * sizeof(ImGuiTableColumnIdx));
|
||||||
span_allocator.Reserve(2, columns_count * sizeof(ImGuiTableCellData), 4);
|
span_allocator.Reserve(2, columns_count * sizeof(ImGuiTableCellData), 4);
|
||||||
|
for (int n = 3; n < 6; n++)
|
||||||
|
span_allocator.Reserve(n, columns_bit_array_size);
|
||||||
table->RawData = IM_ALLOC(span_allocator.GetArenaSizeInBytes());
|
table->RawData = IM_ALLOC(span_allocator.GetArenaSizeInBytes());
|
||||||
memset(table->RawData, 0, span_allocator.GetArenaSizeInBytes());
|
memset(table->RawData, 0, span_allocator.GetArenaSizeInBytes());
|
||||||
span_allocator.SetArenaBasePtr(table->RawData);
|
span_allocator.SetArenaBasePtr(table->RawData);
|
||||||
span_allocator.GetSpan(0, &table->Columns);
|
span_allocator.GetSpan(0, &table->Columns);
|
||||||
span_allocator.GetSpan(1, &table->DisplayOrderToIndex);
|
span_allocator.GetSpan(1, &table->DisplayOrderToIndex);
|
||||||
span_allocator.GetSpan(2, &table->RowCellData);
|
span_allocator.GetSpan(2, &table->RowCellData);
|
||||||
|
table->EnabledMaskByDisplayOrder = (ImU32*)span_allocator.GetSpanPtrBegin(3);
|
||||||
|
table->EnabledMaskByIndex = (ImU32*)span_allocator.GetSpanPtrBegin(4);
|
||||||
|
table->VisibleMaskByIndex = (ImU32*)span_allocator.GetSpanPtrBegin(5);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply queued resizing/reordering/hiding requests
|
// Apply queued resizing/reordering/hiding requests
|
||||||
@ -729,8 +735,8 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
|||||||
const ImGuiTableFlags table_sizing_policy = (table->Flags & ImGuiTableFlags_SizingMask_);
|
const ImGuiTableFlags table_sizing_policy = (table->Flags & ImGuiTableFlags_SizingMask_);
|
||||||
table->IsDefaultDisplayOrder = true;
|
table->IsDefaultDisplayOrder = true;
|
||||||
table->ColumnsEnabledCount = 0;
|
table->ColumnsEnabledCount = 0;
|
||||||
table->EnabledMaskByIndex = 0x00;
|
ImBitArrayClearAllBits(table->EnabledMaskByIndex, table->ColumnsCount);
|
||||||
table->EnabledMaskByDisplayOrder = 0x00;
|
ImBitArrayClearAllBits(table->EnabledMaskByDisplayOrder, table->ColumnsCount);
|
||||||
table->LeftMostEnabledColumn = -1;
|
table->LeftMostEnabledColumn = -1;
|
||||||
table->MinColumnWidth = ImMax(1.0f, g.Style.FramePadding.x * 1.0f); // g.Style.ColumnsMinSpacing; // FIXME-TABLE
|
table->MinColumnWidth = ImMax(1.0f, g.Style.FramePadding.x * 1.0f); // g.Style.ColumnsMinSpacing; // FIXME-TABLE
|
||||||
|
|
||||||
@ -795,8 +801,8 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
|||||||
else
|
else
|
||||||
table->LeftMostEnabledColumn = (ImGuiTableColumnIdx)column_n;
|
table->LeftMostEnabledColumn = (ImGuiTableColumnIdx)column_n;
|
||||||
column->IndexWithinEnabledSet = table->ColumnsEnabledCount++;
|
column->IndexWithinEnabledSet = table->ColumnsEnabledCount++;
|
||||||
table->EnabledMaskByIndex |= (ImU64)1 << column_n;
|
ImBitArraySetBit(table->EnabledMaskByIndex, column_n);
|
||||||
table->EnabledMaskByDisplayOrder |= (ImU64)1 << column->DisplayOrder;
|
ImBitArraySetBit(table->EnabledMaskByDisplayOrder, column->DisplayOrder);
|
||||||
prev_visible_column_idx = column_n;
|
prev_visible_column_idx = column_n;
|
||||||
IM_ASSERT(column->IndexWithinEnabledSet <= column->DisplayOrder);
|
IM_ASSERT(column->IndexWithinEnabledSet <= column->DisplayOrder);
|
||||||
|
|
||||||
@ -844,7 +850,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
|||||||
table->LeftMostStretchedColumn = table->RightMostStretchedColumn = -1;
|
table->LeftMostStretchedColumn = table->RightMostStretchedColumn = -1;
|
||||||
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
|
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
|
||||||
{
|
{
|
||||||
if (!(table->EnabledMaskByIndex & ((ImU64)1 << column_n)))
|
if (!IM_BITARRAY_TESTBIT(table->EnabledMaskByIndex, column_n))
|
||||||
continue;
|
continue;
|
||||||
ImGuiTableColumn* column = &table->Columns[column_n];
|
ImGuiTableColumn* column = &table->Columns[column_n];
|
||||||
|
|
||||||
@ -908,7 +914,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
|||||||
table->ColumnsGivenWidth = width_spacings + (table->CellPaddingX * 2.0f) * table->ColumnsEnabledCount;
|
table->ColumnsGivenWidth = width_spacings + (table->CellPaddingX * 2.0f) * table->ColumnsEnabledCount;
|
||||||
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
|
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
|
||||||
{
|
{
|
||||||
if (!(table->EnabledMaskByIndex & ((ImU64)1 << column_n)))
|
if (!IM_BITARRAY_TESTBIT(table->EnabledMaskByIndex, column_n))
|
||||||
continue;
|
continue;
|
||||||
ImGuiTableColumn* column = &table->Columns[column_n];
|
ImGuiTableColumn* column = &table->Columns[column_n];
|
||||||
|
|
||||||
@ -935,7 +941,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
|||||||
if (width_remaining_for_stretched_columns >= 1.0f && !(table->Flags & ImGuiTableFlags_PreciseWidths))
|
if (width_remaining_for_stretched_columns >= 1.0f && !(table->Flags & ImGuiTableFlags_PreciseWidths))
|
||||||
for (int order_n = table->ColumnsCount - 1; stretch_sum_weights > 0.0f && width_remaining_for_stretched_columns >= 1.0f && order_n >= 0; order_n--)
|
for (int order_n = table->ColumnsCount - 1; stretch_sum_weights > 0.0f && width_remaining_for_stretched_columns >= 1.0f && order_n >= 0; order_n--)
|
||||||
{
|
{
|
||||||
if (!(table->EnabledMaskByDisplayOrder & ((ImU64)1 << order_n)))
|
if (!IM_BITARRAY_TESTBIT(table->EnabledMaskByDisplayOrder, order_n))
|
||||||
continue;
|
continue;
|
||||||
ImGuiTableColumn* column = &table->Columns[table->DisplayOrderToIndex[order_n]];
|
ImGuiTableColumn* column = &table->Columns[table->DisplayOrderToIndex[order_n]];
|
||||||
if (!(column->Flags & ImGuiTableColumnFlags_WidthStretch))
|
if (!(column->Flags & ImGuiTableColumnFlags_WidthStretch))
|
||||||
@ -966,7 +972,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
|||||||
float offset_x = ((table->FreezeColumnsCount > 0) ? table->OuterRect.Min.x : work_rect.Min.x) + table->OuterPaddingX - table->CellSpacingX1;
|
float offset_x = ((table->FreezeColumnsCount > 0) ? table->OuterRect.Min.x : work_rect.Min.x) + table->OuterPaddingX - table->CellSpacingX1;
|
||||||
ImRect host_clip_rect = table->InnerClipRect;
|
ImRect host_clip_rect = table->InnerClipRect;
|
||||||
//host_clip_rect.Max.x += table->CellPaddingX + table->CellSpacingX2;
|
//host_clip_rect.Max.x += table->CellPaddingX + table->CellSpacingX2;
|
||||||
table->VisibleMaskByIndex = 0x00;
|
ImBitArrayClearAllBits(table->VisibleMaskByIndex, table->ColumnsCount);
|
||||||
for (int order_n = 0; order_n < table->ColumnsCount; order_n++)
|
for (int order_n = 0; order_n < table->ColumnsCount; order_n++)
|
||||||
{
|
{
|
||||||
const int column_n = table->DisplayOrderToIndex[order_n];
|
const int column_n = table->DisplayOrderToIndex[order_n];
|
||||||
@ -983,7 +989,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
|||||||
// Clear status flags
|
// Clear status flags
|
||||||
column->Flags &= ~ImGuiTableColumnFlags_StatusMask_;
|
column->Flags &= ~ImGuiTableColumnFlags_StatusMask_;
|
||||||
|
|
||||||
if ((table->EnabledMaskByDisplayOrder & ((ImU64)1 << order_n)) == 0)
|
if (!IM_BITARRAY_TESTBIT(table->EnabledMaskByDisplayOrder, order_n))
|
||||||
{
|
{
|
||||||
// Hidden column: clear a few fields and we are done with it for the remainder of the function.
|
// Hidden column: clear a few fields and we are done with it for the remainder of the function.
|
||||||
// We set a zero-width clip rect but set Min.y/Max.y properly to not interfere with the clipper.
|
// We set a zero-width clip rect but set Min.y/Max.y properly to not interfere with the clipper.
|
||||||
@ -1036,7 +1042,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
|||||||
column->IsVisibleY = true; // (column->ClipRect.Max.y > column->ClipRect.Min.y);
|
column->IsVisibleY = true; // (column->ClipRect.Max.y > column->ClipRect.Min.y);
|
||||||
const bool is_visible = column->IsVisibleX; //&& column->IsVisibleY;
|
const bool is_visible = column->IsVisibleX; //&& column->IsVisibleY;
|
||||||
if (is_visible)
|
if (is_visible)
|
||||||
table->VisibleMaskByIndex |= ((ImU64)1 << column_n);
|
ImBitArraySetBit(table->VisibleMaskByIndex, column_n);
|
||||||
|
|
||||||
// Mark column as requesting output from user. Note that fixed + non-resizable sets are auto-fitting at all times and therefore always request output.
|
// Mark column as requesting output from user. Note that fixed + non-resizable sets are auto-fitting at all times and therefore always request output.
|
||||||
column->IsRequestOutput = is_visible || column->AutoFitQueue != 0 || column->CannotSkipItemsQueue != 0;
|
column->IsRequestOutput = is_visible || column->AutoFitQueue != 0 || column->CannotSkipItemsQueue != 0;
|
||||||
@ -1166,7 +1172,7 @@ void ImGui::TableUpdateBorders(ImGuiTable* table)
|
|||||||
|
|
||||||
for (int order_n = 0; order_n < table->ColumnsCount; order_n++)
|
for (int order_n = 0; order_n < table->ColumnsCount; order_n++)
|
||||||
{
|
{
|
||||||
if (!(table->EnabledMaskByDisplayOrder & ((ImU64)1 << order_n)))
|
if (!IM_BITARRAY_TESTBIT(table->EnabledMaskByDisplayOrder, order_n))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const int column_n = table->DisplayOrderToIndex[order_n];
|
const int column_n = table->DisplayOrderToIndex[order_n];
|
||||||
@ -1302,7 +1308,7 @@ void ImGui::EndTable()
|
|||||||
float auto_fit_width_for_stretched = 0.0f;
|
float auto_fit_width_for_stretched = 0.0f;
|
||||||
float auto_fit_width_for_stretched_min = 0.0f;
|
float auto_fit_width_for_stretched_min = 0.0f;
|
||||||
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
|
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
|
||||||
if (table->EnabledMaskByIndex & ((ImU64)1 << column_n))
|
if (IM_BITARRAY_TESTBIT(table->EnabledMaskByIndex, column_n))
|
||||||
{
|
{
|
||||||
ImGuiTableColumn* column = &table->Columns[column_n];
|
ImGuiTableColumn* column = &table->Columns[column_n];
|
||||||
float column_width_request = ((column->Flags & ImGuiTableColumnFlags_WidthFixed) && !(column->Flags & ImGuiTableColumnFlags_NoResize)) ? column->WidthRequest : TableGetColumnWidthAuto(table, column);
|
float column_width_request = ((column->Flags & ImGuiTableColumnFlags_WidthFixed) && !(column->Flags & ImGuiTableColumnFlags_NoResize)) ? column->WidthRequest : TableGetColumnWidthAuto(table, column);
|
||||||
@ -1648,7 +1654,7 @@ void ImGui::TableSetBgColor(ImGuiTableBgTarget target, ImU32 color, int column_n
|
|||||||
return;
|
return;
|
||||||
if (column_n == -1)
|
if (column_n == -1)
|
||||||
column_n = table->CurrentColumn;
|
column_n = table->CurrentColumn;
|
||||||
if ((table->VisibleMaskByIndex & ((ImU64)1 << column_n)) == 0)
|
if (!IM_BITARRAY_TESTBIT(table->VisibleMaskByIndex, column_n))
|
||||||
return;
|
return;
|
||||||
if (table->RowCellDataCurrent < 0 || table->RowCellData[table->RowCellDataCurrent].Column != column_n)
|
if (table->RowCellDataCurrent < 0 || table->RowCellData[table->RowCellDataCurrent].Column != column_n)
|
||||||
table->RowCellDataCurrent++;
|
table->RowCellDataCurrent++;
|
||||||
@ -2288,7 +2294,7 @@ void ImGui::TableSetupDrawChannels(ImGuiTable* table)
|
|||||||
const int freeze_row_multiplier = (table->FreezeRowsCount > 0) ? 2 : 1;
|
const int freeze_row_multiplier = (table->FreezeRowsCount > 0) ? 2 : 1;
|
||||||
const int channels_for_row = (table->Flags & ImGuiTableFlags_NoClip) ? 1 : table->ColumnsEnabledCount;
|
const int channels_for_row = (table->Flags & ImGuiTableFlags_NoClip) ? 1 : table->ColumnsEnabledCount;
|
||||||
const int channels_for_bg = 1 + 1 * freeze_row_multiplier;
|
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_for_dummy = (table->ColumnsEnabledCount < table->ColumnsCount || (memcmp(table->VisibleMaskByIndex, table->EnabledMaskByIndex, ImBitArrayGetStorageSizeInBytes(table->ColumnsCount)) != 0)) ? +1 : 0;
|
||||||
const int channels_total = channels_for_bg + (channels_for_row * freeze_row_multiplier) + channels_for_dummy;
|
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->DummyDrawChannel = (ImGuiTableDrawChannelIdx)((channels_for_dummy > 0) ? channels_total - 1 : -1);
|
||||||
@ -2362,19 +2368,26 @@ void ImGui::TableMergeDrawChannels(ImGuiTable* table)
|
|||||||
// Track which groups we are going to attempt to merge, and which channels goes into each group.
|
// Track which groups we are going to attempt to merge, and which channels goes into each group.
|
||||||
struct MergeGroup
|
struct MergeGroup
|
||||||
{
|
{
|
||||||
ImRect ClipRect;
|
ImRect ClipRect;
|
||||||
int ChannelsCount;
|
int ChannelsCount;
|
||||||
ImBitArray<IMGUI_TABLE_MAX_DRAW_CHANNELS> ChannelsMask;
|
ImBitArrayPtr ChannelsMask;
|
||||||
|
|
||||||
MergeGroup() { ChannelsCount = 0; }
|
|
||||||
};
|
};
|
||||||
int merge_group_mask = 0x00;
|
int merge_group_mask = 0x00;
|
||||||
MergeGroup merge_groups[4];
|
MergeGroup merge_groups[4] = {};
|
||||||
|
|
||||||
|
// Use a reusable temp buffer for the merge masks as they are dynamically sized.
|
||||||
|
const int max_draw_channels = (4 + table->ColumnsCount * 2);
|
||||||
|
const int size_for_masks_bitarrays_one = (int)ImBitArrayGetStorageSizeInBytes(max_draw_channels);
|
||||||
|
g.TempBuffer.reserve(size_for_masks_bitarrays_one * 5);
|
||||||
|
memset(g.TempBuffer.Data, 0, size_for_masks_bitarrays_one * 5);
|
||||||
|
for (int n = 0; n < IM_ARRAYSIZE(merge_groups); n++)
|
||||||
|
merge_groups[n].ChannelsMask = (ImBitArrayPtr)(void*)(g.TempBuffer.Data + (size_for_masks_bitarrays_one * n));
|
||||||
|
ImBitArrayPtr remaining_mask = (ImBitArrayPtr)(void*)(g.TempBuffer.Data + (size_for_masks_bitarrays_one * 4));
|
||||||
|
|
||||||
// 1. Scan channels and take note of those which can be merged
|
// 1. Scan channels and take note of those which can be merged
|
||||||
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
|
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
|
||||||
{
|
{
|
||||||
if ((table->VisibleMaskByIndex & ((ImU64)1 << column_n)) == 0)
|
if (!IM_BITARRAY_TESTBIT(table->VisibleMaskByIndex, column_n))
|
||||||
continue;
|
continue;
|
||||||
ImGuiTableColumn* column = &table->Columns[column_n];
|
ImGuiTableColumn* column = &table->Columns[column_n];
|
||||||
|
|
||||||
@ -2406,11 +2419,11 @@ void ImGui::TableMergeDrawChannels(ImGuiTable* table)
|
|||||||
}
|
}
|
||||||
|
|
||||||
const int merge_group_n = (has_freeze_h && column_n < table->FreezeColumnsCount ? 0 : 1) + (has_freeze_v && merge_group_sub_n == 0 ? 0 : 2);
|
const int merge_group_n = (has_freeze_h && column_n < table->FreezeColumnsCount ? 0 : 1) + (has_freeze_v && merge_group_sub_n == 0 ? 0 : 2);
|
||||||
IM_ASSERT(channel_no < IMGUI_TABLE_MAX_DRAW_CHANNELS);
|
IM_ASSERT(channel_no < max_draw_channels);
|
||||||
MergeGroup* merge_group = &merge_groups[merge_group_n];
|
MergeGroup* merge_group = &merge_groups[merge_group_n];
|
||||||
if (merge_group->ChannelsCount == 0)
|
if (merge_group->ChannelsCount == 0)
|
||||||
merge_group->ClipRect = ImRect(+FLT_MAX, +FLT_MAX, -FLT_MAX, -FLT_MAX);
|
merge_group->ClipRect = ImRect(+FLT_MAX, +FLT_MAX, -FLT_MAX, -FLT_MAX);
|
||||||
merge_group->ChannelsMask.SetBit(channel_no);
|
ImBitArraySetBit(merge_group->ChannelsMask, channel_no);
|
||||||
merge_group->ChannelsCount++;
|
merge_group->ChannelsCount++;
|
||||||
merge_group->ClipRect.Add(src_channel->_CmdBuffer[0].ClipRect);
|
merge_group->ClipRect.Add(src_channel->_CmdBuffer[0].ClipRect);
|
||||||
merge_group_mask |= (1 << merge_group_n);
|
merge_group_mask |= (1 << merge_group_n);
|
||||||
@ -2446,9 +2459,8 @@ void ImGui::TableMergeDrawChannels(ImGuiTable* table)
|
|||||||
const int LEADING_DRAW_CHANNELS = 2;
|
const int LEADING_DRAW_CHANNELS = 2;
|
||||||
g.DrawChannelsTempMergeBuffer.resize(splitter->_Count - LEADING_DRAW_CHANNELS); // Use shared temporary storage so the allocation gets amortized
|
g.DrawChannelsTempMergeBuffer.resize(splitter->_Count - LEADING_DRAW_CHANNELS); // Use shared temporary storage so the allocation gets amortized
|
||||||
ImDrawChannel* dst_tmp = g.DrawChannelsTempMergeBuffer.Data;
|
ImDrawChannel* dst_tmp = g.DrawChannelsTempMergeBuffer.Data;
|
||||||
ImBitArray<IMGUI_TABLE_MAX_DRAW_CHANNELS> remaining_mask; // We need 132-bit of storage
|
ImBitArraySetBitRange(remaining_mask, LEADING_DRAW_CHANNELS, splitter->_Count);
|
||||||
remaining_mask.SetBitRange(LEADING_DRAW_CHANNELS, splitter->_Count);
|
ImBitArrayClearBit(remaining_mask, table->Bg2DrawChannelUnfrozen);
|
||||||
remaining_mask.ClearBit(table->Bg2DrawChannelUnfrozen);
|
|
||||||
IM_ASSERT(has_freeze_v == false || table->Bg2DrawChannelUnfrozen != TABLE_DRAW_CHANNEL_BG2_FROZEN);
|
IM_ASSERT(has_freeze_v == false || table->Bg2DrawChannelUnfrozen != TABLE_DRAW_CHANNEL_BG2_FROZEN);
|
||||||
int remaining_count = splitter->_Count - (has_freeze_v ? LEADING_DRAW_CHANNELS + 1 : LEADING_DRAW_CHANNELS);
|
int remaining_count = splitter->_Count - (has_freeze_v ? LEADING_DRAW_CHANNELS + 1 : LEADING_DRAW_CHANNELS);
|
||||||
//ImRect host_rect = (table->InnerWindow == table->OuterWindow) ? table->InnerClipRect : table->HostClipRect;
|
//ImRect host_rect = (table->InnerWindow == table->OuterWindow) ? table->InnerClipRect : table->HostClipRect;
|
||||||
@ -2481,14 +2493,14 @@ void ImGui::TableMergeDrawChannels(ImGuiTable* table)
|
|||||||
GetOverlayDrawList()->AddLine(merge_group->ClipRect.Max, merge_clip_rect.Max, IM_COL32(255, 100, 0, 200));
|
GetOverlayDrawList()->AddLine(merge_group->ClipRect.Max, merge_clip_rect.Max, IM_COL32(255, 100, 0, 200));
|
||||||
#endif
|
#endif
|
||||||
remaining_count -= merge_group->ChannelsCount;
|
remaining_count -= merge_group->ChannelsCount;
|
||||||
for (int n = 0; n < IM_ARRAYSIZE(remaining_mask.Storage); n++)
|
for (int n = 0; n < (size_for_masks_bitarrays_one >> 2); n++)
|
||||||
remaining_mask.Storage[n] &= ~merge_group->ChannelsMask.Storage[n];
|
remaining_mask[n] &= ~merge_group->ChannelsMask[n];
|
||||||
for (int n = 0; n < splitter->_Count && merge_channels_count != 0; n++)
|
for (int n = 0; n < splitter->_Count && merge_channels_count != 0; n++)
|
||||||
{
|
{
|
||||||
// Copy + overwrite new clip rect
|
// Copy + overwrite new clip rect
|
||||||
if (!merge_group->ChannelsMask.TestBit(n))
|
if (!IM_BITARRAY_TESTBIT(merge_group->ChannelsMask, n))
|
||||||
continue;
|
continue;
|
||||||
merge_group->ChannelsMask.ClearBit(n);
|
IM_BITARRAY_CLEARBIT(merge_group->ChannelsMask, n);
|
||||||
merge_channels_count--;
|
merge_channels_count--;
|
||||||
|
|
||||||
ImDrawChannel* channel = &splitter->_Channels[n];
|
ImDrawChannel* channel = &splitter->_Channels[n];
|
||||||
@ -2506,7 +2518,7 @@ void ImGui::TableMergeDrawChannels(ImGuiTable* table)
|
|||||||
// Append unmergeable channels that we didn't reorder at the end of the list
|
// Append unmergeable channels that we didn't reorder at the end of the list
|
||||||
for (int n = 0; n < splitter->_Count && remaining_count != 0; n++)
|
for (int n = 0; n < splitter->_Count && remaining_count != 0; n++)
|
||||||
{
|
{
|
||||||
if (!remaining_mask.TestBit(n))
|
if (!IM_BITARRAY_TESTBIT(remaining_mask, n))
|
||||||
continue;
|
continue;
|
||||||
ImDrawChannel* channel = &splitter->_Channels[n];
|
ImDrawChannel* channel = &splitter->_Channels[n];
|
||||||
memcpy(dst_tmp++, channel, sizeof(ImDrawChannel));
|
memcpy(dst_tmp++, channel, sizeof(ImDrawChannel));
|
||||||
@ -2538,7 +2550,7 @@ void ImGui::TableDrawBorders(ImGuiTable* table)
|
|||||||
{
|
{
|
||||||
for (int order_n = 0; order_n < table->ColumnsCount; order_n++)
|
for (int order_n = 0; order_n < table->ColumnsCount; order_n++)
|
||||||
{
|
{
|
||||||
if (!(table->EnabledMaskByDisplayOrder & ((ImU64)1 << order_n)))
|
if (!IM_BITARRAY_TESTBIT(table->EnabledMaskByDisplayOrder, order_n))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
const int column_n = table->DisplayOrderToIndex[order_n];
|
const int column_n = table->DisplayOrderToIndex[order_n];
|
||||||
|
Loading…
Reference in New Issue
Block a user