@ -315,7 +315,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
return false ;
// 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 )
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 )
{
// 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 ( 1 , columns_count * sizeof ( ImGuiTableColumnIdx ) ) ;
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 ( ) ) ;
memset ( table - > RawData , 0 , span_allocator . GetArenaSizeInBytes ( ) ) ;
span_allocator . SetArenaBasePtr ( table - > RawData ) ;
span_allocator . GetSpan ( 0 , & table - > Columns ) ;
span_allocator . GetSpan ( 1 , & table - > DisplayOrderToIndex ) ;
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
@ -729,8 +735,8 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
const ImGuiTableFlags table_sizing_policy = ( table - > Flags & ImGuiTableFlags_SizingMask_ ) ;
table - > IsDefaultDisplayOrder = true ;
table - > ColumnsEnabledCount = 0 ;
table - > EnabledMaskByIndex = 0x00 ;
table - > EnabledMaskByDisplayOrder = 0x00 ;
ImBitArrayClearAllBits ( table - > EnabledMaskByIndex , table - > ColumnsCount ) ;
ImBitArrayClearAllBits ( table - > EnabledMaskByDisplayOrder , table - > ColumnsCount ) ;
table - > LeftMostEnabledColumn = - 1 ;
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
table - > LeftMostEnabledColumn = ( ImGuiTableColumnIdx ) column_n ;
column - > IndexWithinEnabledSet = table - > ColumnsEnabledCount + + ;
table - > EnabledMaskByIndex | = ( ImU64 ) 1 < < column_n ;
table - > EnabledMaskByDisplayOrder | = ( ImU64 ) 1 < < column - > DisplayOrder ;
ImBitArraySetBit ( table - > EnabledMaskByIndex , column_n ) ;
ImBitArraySetBit ( table - > EnabledMaskByDisplayOrder , column - > DisplayOrder ) ;
prev_visible_column_idx = column_n ;
IM_ASSERT ( column - > IndexWithinEnabledSet < = column - > DisplayOrder ) ;
@ -844,7 +850,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
table - > LeftMostStretchedColumn = table - > RightMostStretchedColumn = - 1 ;
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 ;
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 ;
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 ;
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 ) )
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 ;
ImGuiTableColumn * column = & table - > Columns [ table - > DisplayOrderToIndex [ order_n ] ] ;
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 ;
ImRect host_clip_rect = table - > InnerClipRect ;
//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 + + )
{
const int column_n = table - > DisplayOrderToIndex [ order_n ] ;
@ -983,7 +989,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
// Clear status flags
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.
// 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);
const bool is_visible = column - > IsVisibleX ; //&& column->IsVisibleY;
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.
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 + + )
{
if ( ! ( table - > EnabledMaskByDisplayOrder & ( ( ImU64 ) 1 < < order_n ) ) )
if ( ! IM_BITARRAY_TESTBIT ( table - > EnabledMaskByDisplayOrder , order_n ) )
continue ;
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_min = 0.0f ;
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 ] ;
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 ;
if ( column_n = = - 1 )
column_n = table - > CurrentColumn ;
if ( ( table - > VisibleMaskByIndex & ( ( ImU64 ) 1 < < column_n ) ) = = 0 )
if ( ! IM_BITARRAY_TESTBIT ( table - > VisibleMaskByIndex , column_n ) )
return ;
if ( table - > RowCellDataCurrent < 0 | | table - > RowCellData [ table - > RowCellDataCurrent ] . Column ! = column_n )
table - > RowCellDataCurrent + + ;
@ -2288,7 +2294,7 @@ void ImGui::TableSetupDrawChannels(ImGuiTable* table)
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_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 ;
table - > DrawSplitter - > Split ( table - > InnerWindow - > DrawList , channels_total ) ;
table - > DummyDrawChannel = ( ImGuiTableDrawChannelIdx ) ( ( channels_for_dummy > 0 ) ? channels_total - 1 : - 1 ) ;
@ -2364,17 +2370,24 @@ void ImGui::TableMergeDrawChannels(ImGuiTable* table)
{
ImRect ClipRect ;
int ChannelsCount ;
ImBitArray < IMGUI_TABLE_MAX_DRAW_CHANNELS > ChannelsMask ;
MergeGroup ( ) { ChannelsCount = 0 ; }
ImBitArrayPtr ChannelsMask ;
} ;
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
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 ;
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 ) ;
IM_ASSERT ( channel_no < IMGUI_TABLE_MAX_DRAW_CHANNELS ) ;
IM_ASSERT ( channel_no < max_draw_channels ) ;
MergeGroup * merge_group = & merge_groups [ merge_group_n ] ;
if ( merge_group - > ChannelsCount = = 0 )
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 - > ClipRect . Add ( src_channel - > _CmdBuffer [ 0 ] . ClipRect ) ;
merge_group_mask | = ( 1 < < merge_group_n ) ;
@ -2446,9 +2459,8 @@ void ImGui::TableMergeDrawChannels(ImGuiTable* table)
const int LEADING_DRAW_CHANNELS = 2 ;
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 . SetBitRange ( LEADING_DRAW_CHANNELS , splitter - > _Count ) ;
remaining_mask . ClearBit ( table - > Bg2DrawChannelUnfrozen ) ;
ImBitArraySetBitRange ( remaining_mask , LEADING_DRAW_CHANNELS , splitter - > _Count ) ;
ImBitArrayClearBit ( remaining_mask , table - > Bg2DrawChannelUnfrozen ) ;
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 ) ;
//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 ) ) ;
# endif
remaining_count - = merge_group - > ChannelsCount ;
for ( int n = 0 ; n < IM_ARRAYSIZE ( remaining_mask . Storage ) ; n + + )
remaining_mask . Storage [ n ] & = ~ merge_group - > ChannelsMask . Storage [ n ] ;
for ( int n = 0 ; n < ( size_for_masks_bitarrays_one > > 2 ) ; n + + )
remaining_mask [ n ] & = ~ merge_group - > ChannelsMask [ n ] ;
for ( int n = 0 ; n < splitter - > _Count & & merge_channels_count ! = 0 ; n + + )
{
// Copy + overwrite new clip rect
if ( ! merge_group - > ChannelsMask . TestBit ( n ) )
if ( ! IM_BITARRAY_TESTBIT ( merge_group - > ChannelsMask , n ) )
continue ;
merge_group - > ChannelsMask . ClearBit ( n ) ;
IM_BITARRAY_CLEARBIT ( merge_group - > ChannelsMask , n ) ;
merge_channels_count - - ;
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
for ( int n = 0 ; n < splitter - > _Count & & remaining_count ! = 0 ; n + + )
{
if ( ! remaining_mask . TestBit ( n ) )
if ( ! IM_BITARRAY_TESTBIT ( remaining_mask , n ) )
continue ;
ImDrawChannel * channel = & splitter - > _Channels [ n ] ;
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 + + )
{
if ( ! ( table - > EnabledMaskByDisplayOrder & ( ( ImU64 ) 1 < < order_n ) ) )
if ( ! IM_BITARRAY_TESTBIT ( table - > EnabledMaskByDisplayOrder , order_n ) )
continue ;
const int column_n = table - > DisplayOrderToIndex [ order_n ] ;