@ -5,7 +5,7 @@
Index of this file :
// [SECTION] Tables: BeginTable, EndTable, etc.
// [SECTION] Tables: Main code
// [SECTION] Tables: Drawing
// [SECTION] Tables: Sorting
// [SECTION] Tables: Headers
@ -17,6 +17,39 @@ Index of this file:
*/
//-----------------------------------------------------------------------------
// Typical tables call flow: (root level is generally public API):
//-----------------------------------------------------------------------------
// - BeginTable() user begin into a table
// | BeginChild() - (if ScrollX/ScrollY is set)
// | TableBeginApplyRequests() - apply queued resizing/reordering/hiding requests
// | - TableSetColumnWidth() - apply resizing width (for mouse resize, often requested by previous frame)
// | - TableUpdateColumnsWeightFromWidth()- recompute columns weights (of stretch columns) from their respective width
// - TableSetupColumn() user submit columns details (optional)
// - TableSetupScrollFreeze() user submit scroll freeze information (optional)
// - TableUpdateLayout() [Internal] automatically called by the FIRST call to TableNextRow() or TableHeadersRow(): lock all widths, columns positions, clipping rectangles
// | TableSetupDrawChannels() - setup ImDrawList channels
// | TableUpdateBorders() - detect hovering columns for resize, ahead of contents submission
// | TableDrawContextMenu() - draw right-click context menu
//-----------------------------------------------------------------------------
// - TableHeadersRow() or TableHeader() user submit a headers row (optional)
// | TableSortSpecsClickColumn() - when left-clicked: alter sort order and sort direction
// | TableOpenContextMenu() - when right-clicked: trigger opening of the default context menu
// - TableGetSortSpecs() user queries updated sort specs (optional, generally after submitting headers)
// - TableNextRow() user begin into a new row (also automatically called by TableHeadersRow())
// | TableEndRow() - finish existing row
// | TableBeginRow() - add a new row
// - TableSetColumnIndex() / TableNextColumn() user begin into a cell
// | TableEndCell() - close existing column/cell
// | TableBeginCell() - enter into current column/cell
// - [...] user emit contents
//-----------------------------------------------------------------------------
// - EndTable() user ends the table
// | TableDrawBorders() - draw outer borders, inner vertical borders
// | TableMergeDrawChannels() - merge draw channels if clipping isn't required
// | EndChild() - (if ScrollX/ScrollY is set)
//-----------------------------------------------------------------------------
# if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS)
# define _CRT_SECURE_NO_WARNINGS
# endif
@ -71,37 +104,7 @@ Index of this file:
# endif
//-----------------------------------------------------------------------------
// [SECTION] Tables: BeginTable, EndTable, etc.
//-----------------------------------------------------------------------------
// Typical call flow: (root level is public API):
// - BeginTable() user begin into a table
// | BeginChild() - (if ScrollX/ScrollY is set)
// | TableBeginApplyRequests() - apply queued resizing/reordering/hiding requests
// | - TableSetColumnWidth() - apply resizing width (for mouse resize, often requested by previous frame)
// | - TableUpdateColumnsWeightFromWidth()- recompute columns weights (of stretch columns) from their respective width
// - TableSetupColumn() user submit columns details (optional)
// - TableSetupScrollFreeze() user submit scroll freeze information (optional)
// - TableUpdateLayout() [Internal] automatically called by the FIRST call to TableNextRow() or TableHeadersRow(): lock all widths, columns positions, clipping rectangles
// | TableSetupDrawChannels() - setup ImDrawList channels
// | TableUpdateBorders() - detect hovering columns for resize, ahead of contents submission
// | TableDrawContextMenu() - draw right-click context menu
//-----------------------------------------------------------------------------
// - TableHeadersRow() or TableHeader() user submit a headers row (optional)
// | TableSortSpecsClickColumn() - when left-clicked: alter sort order and sort direction
// | TableOpenContextMenu() - when right-clicked: trigger opening of the default context menu
// - TableGetSortSpecs() user queries updated sort specs (optional, generally after submitting headers)
// - TableNextRow() user begin into a new row (also automatically called by TableHeadersRow())
// | TableEndRow() - finish existing row
// | TableBeginRow() - add a new row
// - TableSetColumnIndex() / TableNextColumn() user begin into a cell
// | TableEndCell() - close existing column/cell
// | TableBeginCell() - enter into current column/cell
// - [...] user emit contents
//-----------------------------------------------------------------------------
// - EndTable() user ends the table
// | TableDrawBorders() - draw outer borders, inner vertical borders
// | TableMergeDrawChannels() - merge draw channels if clipping isn't required
// | EndChild() - (if ScrollX/ScrollY is set)
// [SECTION] Tables: Main code
//-----------------------------------------------------------------------------
// Configuration
@ -155,12 +158,6 @@ inline ImGuiTableFlags TableFixFlags(ImGuiTableFlags flags, ImGuiWindow* outer_w
return flags ;
}
ImGuiTable * ImGui : : TableFindByID ( ImGuiID id )
{
ImGuiContext & g = * GImGui ;
return g . Tables . GetByKey ( id ) ;
}
ImGuiTable : : ImGuiTable ( )
{
memset ( this , 0 , sizeof ( * this ) ) ;
@ -180,6 +177,12 @@ ImGuiTable::~ImGuiTable()
IM_FREE ( RawData ) ;
}
ImGuiTable * ImGui : : TableFindByID ( ImGuiID id )
{
ImGuiContext & g = * GImGui ;
return g . Tables . GetByKey ( id ) ;
}
// (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:
// X:
@ -212,37 +215,6 @@ bool ImGui::BeginTable(const char* str_id, int columns_count, ImGuiTableFlags
return BeginTableEx ( str_id , id , columns_count , flags , outer_size , inner_width ) ;
}
// For reference, the average total _allocation count_ for a table is:
// + 0 (for ImGuiTable instance, we are pooling allocations in g.Tables)
// + 1 (for table->RawData allocated below)
// + 1 (for table->ColumnsNames, if names are used)
// + 1 (for table->Splitter._Channels)
// + 2 * active_channels_count (for ImDrawCmd and ImDrawIdx buffers inside channels)
// Where active_channels_count is variable but often == columns_count or columns_count + 1, see TableUpdateDrawChannels() for details.
// Unused channels don't perform their +2 allocations.
static void TableBeginInitMemory ( ImGuiTable * table , int columns_count )
{
// Allocate single buffer for our arrays
ImSpanAllocator < 3 > span_allocator ;
span_allocator . ReserveBytes ( 0 , columns_count * sizeof ( ImGuiTableColumn ) ) ;
span_allocator . ReserveBytes ( 1 , columns_count * sizeof ( ImS8 ) ) ;
span_allocator . ReserveBytes ( 2 , columns_count * sizeof ( ImGuiTableCellData ) ) ;
table - > RawData = IM_ALLOC ( 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 ) ;
memset ( table - > RowCellData . Data , 0 , table - > RowCellData . size_in_bytes ( ) ) ;
for ( int n = 0 ; n < columns_count ; n + + )
{
ImGuiTableColumn * column = & table - > Columns [ n ] ;
* column = ImGuiTableColumn ( ) ;
column - > DisplayOrder = table - > DisplayOrderToIndex [ n ] = ( ImS8 ) n ;
column - > AutoFitQueue = column - > CannotSkipItemsQueue = ( 1 < < 3 ) - 1 ; // Fit for three frames
}
}
bool ImGui : : BeginTableEx ( const char * name , ImGuiID id , int columns_count , ImGuiTableFlags flags , const ImVec2 & outer_size , float inner_width )
{
ImGuiContext & g = * GImGui ;
@ -460,6 +432,37 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
return true ;
}
// For reference, the average total _allocation count_ for a table is:
// + 0 (for ImGuiTable instance, we are pooling allocations in g.Tables)
// + 1 (for table->RawData allocated below)
// + 1 (for table->ColumnsNames, if names are used)
// + 1 (for table->Splitter._Channels)
// + 2 * active_channels_count (for ImDrawCmd and ImDrawIdx buffers inside channels)
// Where active_channels_count is variable but often == columns_count or columns_count + 1, see TableSetupDrawChannels() for details.
// Unused channels don't perform their +2 allocations.
void ImGui : : TableBeginInitMemory ( ImGuiTable * table , int columns_count )
{
// Allocate single buffer for our arrays
ImSpanAllocator < 3 > span_allocator ;
span_allocator . ReserveBytes ( 0 , columns_count * sizeof ( ImGuiTableColumn ) ) ;
span_allocator . ReserveBytes ( 1 , columns_count * sizeof ( ImS8 ) ) ;
span_allocator . ReserveBytes ( 2 , columns_count * sizeof ( ImGuiTableCellData ) ) ;
table - > RawData = IM_ALLOC ( 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 ) ;
memset ( table - > RowCellData . Data , 0 , table - > RowCellData . size_in_bytes ( ) ) ;
for ( int n = 0 ; n < columns_count ; n + + )
{
ImGuiTableColumn * column = & table - > Columns [ n ] ;
* column = ImGuiTableColumn ( ) ;
column - > DisplayOrder = table - > DisplayOrderToIndex [ n ] = ( ImS8 ) n ;
column - > AutoFitQueue = column - > CannotSkipItemsQueue = ( 1 < < 3 ) - 1 ; // Fit for three frames
}
}
// Apply queued resizing/reordering/hiding requests
void ImGui : : TableBeginApplyRequests ( ImGuiTable * table )
{
@ -1367,6 +1370,7 @@ void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags,
}
}
// [Public]
void ImGui : : TableSetupScrollFreeze ( int columns , int rows )
{
ImGuiContext & g = * GImGui ;
@ -1383,7 +1387,7 @@ void ImGui::TableSetupScrollFreeze(int columns, int rows)
table - > IsUnfrozen = ( table - > FreezeRowsCount = = 0 ) ; // Make sure this is set before TableUpdateLayout() so ImGuiListClipper can benefit from it.b
}
// Starts into the first cell of a new row
// [Public] Starts into the first cell of a new row
void ImGui : : TableNextRow ( ImGuiTableRowFlags row_flags , float row_min_height )
{
ImGuiContext & g = * GImGui ;
@ -1640,7 +1644,7 @@ void ImGui::TableEndCell(ImGuiTable* table)
table - > RowTextBaseline = ImMax ( table - > RowTextBaseline , window - > DC . PrevLineTextBaseOffset ) ;
}
// Append into the next column/cell
// [Public] Append into the next column/cell
bool ImGui : : TableNextColumn ( )
{
ImGuiContext & g = * GImGui ;
@ -1665,6 +1669,7 @@ bool ImGui::TableNextColumn()
return ( table - > EnabledUnclippedMaskByIndex & ( ( ImU64 ) 1 < < column_n ) ) ! = 0 ;
}
// [Public] Append into a specific column
bool ImGui : : TableSetColumnIndex ( int column_n )
{
ImGuiContext & g = * GImGui ;
@ -1860,7 +1865,7 @@ void ImGui::TableSetBgColor(ImGuiTableBgTarget bg_target, ImU32 color, int colum
// - TablePushBackgroundChannel() [Internal]
// - TablePopBackgroundChannel() [Internal]
// - TableSetupDrawChannels() [Internal]
// - Table ReorderDrawChannelsForMerge () [Internal]
// - Table MergeDrawChannels () [Internal]
// - TableDrawBorders() [Internal]
//-------------------------------------------------------------------------
@ -2053,7 +2058,7 @@ void ImGui::TableMergeDrawChannels(ImGuiTable* table)
// 2. Rewrite channel list in our preferred order
if ( merge_group_mask ! = 0 )
{
// We skip channel 0 (Bg0) and 1 (Bg1 frozen) from the shuffling since they won't move - see channels allocation in Table Update DrawChannels().
// We skip channel 0 (Bg0) and 1 (Bg1 frozen) from the shuffling since they won't move - see channels allocation in Table Setup DrawChannels().
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 ;
@ -3620,7 +3625,6 @@ void ImGui::Columns(int columns_count, const char* id, bool border)
BeginColumns ( id , columns_count , flags ) ;
}
//-------------------------------------------------------------------------
# endif // #ifndef IMGUI_DISABLE