@ -64,7 +64,7 @@
// Typical call flow: (root level is public API):
// - BeginTable() user begin into a table
// | BeginChild() - (if ScrollX/ScrollY is set)
// | TableBegin UpdateColumns() - apply resize/order requests, lock columns active state, order
// | TableBegin ApplyRequests() - 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)
@ -273,7 +273,6 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
table - > LastFrameActive = g . FrameCount ;
table - > OuterWindow = table - > InnerWindow = outer_window ;
table - > ColumnsCount = columns_count ;
table - > ColumnsNames . Buf . resize ( 0 ) ;
table - > IsInitializing = false ;
table - > IsLayoutLocked = false ;
table - > InnerWidth = inner_width ;
@ -431,13 +430,26 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
// Because we cannot safely assert in EndTable() when no rows have been created, this seems like our best option.
inner_window - > SkipItems = true ;
// Update/lock which columns will be Visible for the frame
TableBeginUpdateColumns ( table ) ;
// Clear names
// FIXME-TABLES: probably could be done differently...
if ( table - > ColumnsNames . Buf . Size > 0 )
{
table - > ColumnsNames . Buf . resize ( 0 ) ;
for ( int column_n = 0 ; column_n < table - > ColumnsCount ; column_n + + )
{
ImGuiTableColumn * column = & table - > Columns [ column_n ] ;
column - > NameOffset = - 1 ;
}
}
// Apply queued resizing/reordering/hiding requests
TableBeginApplyRequests ( table ) ;
return true ;
}
void ImGui : : TableBeginUpdateColumns ( ImGuiTable * table )
// Apply queued resizing/reordering/hiding requests
void ImGui : : TableBeginApplyRequests ( ImGuiTable * table )
{
// Handle resizing request
// (We process this at the first TableBegin of the frame)
@ -504,67 +516,6 @@ void ImGui::TableBeginUpdateColumns(ImGuiTable* table)
table - > IsResetDisplayOrderRequest = false ;
table - > IsSettingsDirty = true ;
}
// Lock Visible state and Order
table - > ColumnsEnabledCount = 0 ;
table - > IsDefaultDisplayOrder = true ;
ImGuiTableColumn * last_visible_column = NULL ;
bool want_column_auto_fit = false ;
for ( int order_n = 0 ; order_n < table - > ColumnsCount ; order_n + + )
{
const int column_n = table - > DisplayOrderToIndex [ order_n ] ;
if ( column_n ! = order_n )
table - > IsDefaultDisplayOrder = false ;
ImGuiTableColumn * column = & table - > Columns [ column_n ] ;
column - > NameOffset = - 1 ;
if ( ! ( table - > Flags & ImGuiTableFlags_Hideable ) | | ( column - > Flags & ImGuiTableColumnFlags_NoHide ) )
column - > IsEnabledNextFrame = true ;
if ( column - > IsEnabled ! = column - > IsEnabledNextFrame )
{
column - > IsEnabled = column - > IsEnabledNextFrame ;
table - > IsSettingsDirty = true ;
if ( ! column - > IsEnabled & & column - > SortOrder ! = - 1 )
table - > IsSortSpecsDirty = true ;
}
if ( column - > SortOrder > 0 & & ! ( table - > Flags & ImGuiTableFlags_MultiSortable ) )
table - > IsSortSpecsDirty = true ;
if ( column - > AutoFitQueue ! = 0x00 )
want_column_auto_fit = true ;
ImU64 index_mask = ( ImU64 ) 1 < < column_n ;
ImU64 display_order_mask = ( ImU64 ) 1 < < column - > DisplayOrder ;
if ( column - > IsEnabled )
{
column - > PrevEnabledColumn = column - > NextEnabledColumn = - 1 ;
if ( last_visible_column )
{
last_visible_column - > NextEnabledColumn = ( ImS8 ) column_n ;
column - > PrevEnabledColumn = ( ImS8 ) table - > Columns . index_from_ptr ( last_visible_column ) ;
}
column - > IndexWithinEnabledSet = table - > ColumnsEnabledCount ;
table - > ColumnsEnabledCount + + ;
table - > EnabledMaskByIndex | = index_mask ;
table - > EnabledMaskByDisplayOrder | = display_order_mask ;
last_visible_column = column ;
}
else
{
column - > IndexWithinEnabledSet = - 1 ;
table - > EnabledMaskByIndex & = ~ index_mask ;
table - > EnabledMaskByDisplayOrder & = ~ display_order_mask ;
}
IM_ASSERT ( column - > IndexWithinEnabledSet < = column - > DisplayOrder ) ;
}
table - > EnabledUnclippedMaskByIndex = table - > EnabledMaskByIndex ; // Columns will be masked out by TableUpdateLayout() when Clipped
table - > RightMostEnabledColumn = ( ImS8 ) ( last_visible_column ? table - > Columns . index_from_ptr ( last_visible_column ) : - 1 ) ;
// Disable child window clipping while fitting columns. This is not strictly necessary but makes it possible to avoid
// the column fitting to wait until the first visible frame of the child container (may or not be a good thing).
if ( want_column_auto_fit & & table - > OuterWindow ! = table - > InnerWindow )
table - > InnerWindow - > SkipItems = false ;
if ( want_column_auto_fit )
table - > IsSettingsDirty = true ;
}
// Adjust flags: default width mode + stretch columns are not allowed when auto extending
@ -629,6 +580,65 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
table - > HoveredColumnBody = - 1 ;
table - > HoveredColumnBorder = - 1 ;
// Lock Enabled state and Order
ImGuiTableColumn * last_visible_column = NULL ;
bool want_column_auto_fit = false ;
table - > IsDefaultDisplayOrder = true ;
table - > ColumnsEnabledCount = 0 ;
for ( int order_n = 0 ; order_n < table - > ColumnsCount ; order_n + + )
{
const int column_n = table - > DisplayOrderToIndex [ order_n ] ;
if ( column_n ! = order_n )
table - > IsDefaultDisplayOrder = false ;
ImGuiTableColumn * column = & table - > Columns [ column_n ] ;
if ( ! ( table - > Flags & ImGuiTableFlags_Hideable ) | | ( column - > Flags & ImGuiTableColumnFlags_NoHide ) )
column - > IsEnabledNextFrame = true ;
if ( column - > IsEnabled ! = column - > IsEnabledNextFrame )
{
column - > IsEnabled = column - > IsEnabledNextFrame ;
table - > IsSettingsDirty = true ;
if ( ! column - > IsEnabled & & column - > SortOrder ! = - 1 )
table - > IsSortSpecsDirty = true ;
}
if ( column - > SortOrder > 0 & & ! ( table - > Flags & ImGuiTableFlags_MultiSortable ) )
table - > IsSortSpecsDirty = true ;
if ( column - > AutoFitQueue ! = 0x00 )
want_column_auto_fit = true ;
ImU64 index_mask = ( ImU64 ) 1 < < column_n ;
ImU64 display_order_mask = ( ImU64 ) 1 < < column - > DisplayOrder ;
if ( column - > IsEnabled )
{
column - > PrevEnabledColumn = column - > NextEnabledColumn = - 1 ;
if ( last_visible_column )
{
last_visible_column - > NextEnabledColumn = ( ImS8 ) column_n ;
column - > PrevEnabledColumn = ( ImS8 ) table - > Columns . index_from_ptr ( last_visible_column ) ;
}
column - > IndexWithinEnabledSet = table - > ColumnsEnabledCount ;
table - > ColumnsEnabledCount + + ;
table - > EnabledMaskByIndex | = index_mask ;
table - > EnabledMaskByDisplayOrder | = display_order_mask ;
last_visible_column = column ;
}
else
{
column - > IndexWithinEnabledSet = - 1 ;
table - > EnabledMaskByIndex & = ~ index_mask ;
table - > EnabledMaskByDisplayOrder & = ~ display_order_mask ;
}
IM_ASSERT ( column - > IndexWithinEnabledSet < = column - > DisplayOrder ) ;
}
table - > EnabledUnclippedMaskByIndex = table - > EnabledMaskByIndex ; // Columns will be masked out below when Clipped
table - > RightMostEnabledColumn = ( ImS8 ) ( last_visible_column ? table - > Columns . index_from_ptr ( last_visible_column ) : - 1 ) ;
// Disable child window clipping while fitting columns. This is not strictly necessary but makes it possible to avoid
// the column fitting to wait until the first visible frame of the child container (may or not be a good thing).
if ( want_column_auto_fit & & table - > OuterWindow ! = table - > InnerWindow )
table - > InnerWindow - > SkipItems = false ;
if ( want_column_auto_fit )
table - > IsSettingsDirty = true ;
// Compute offset, clip rect for the frame
// (can't make auto padding larger than what WorkRect knows about so right-alignment matches)
const ImRect work_rect = table - > WorkRect ;
@ -1715,7 +1725,7 @@ void ImGui::TableNextRow(ImGuiTableRowFlags row_flags, float row_min_height)
ImGuiContext & g = * GImGui ;
ImGuiTable * table = g . CurrentTable ;
if ( table - > CurrentRow = = - 1 )
if ( ! table - > IsLayoutLocked )
TableUpdateLayout ( table ) ;
if ( table - > IsInsideRow )
TableEndRow ( table ) ;
@ -2509,6 +2519,10 @@ ImGuiTableSortSpecs* ImGui::TableGetSortSpecs()
if ( ! ( table - > Flags & ImGuiTableFlags_Sortable ) )
return NULL ;
// Require layout (in case TableHeadersRow() hasn't been called) as it may alter IsSortSpecsDirty in some paths.
if ( ! table - > IsLayoutLocked )
TableUpdateLayout ( table ) ;
if ( table - > IsSortSpecsDirty )
TableSortSpecsBuild ( table ) ;