Tables: store LeftMostUnfrozenOrder and amend TableQueueSetColumnDisplayOrder(). (#9312)

This commit is contained in:
ocornut
2026-03-24 16:02:20 +01:00
parent 7be8076e9b
commit ed4cffece7
2 changed files with 9 additions and 4 deletions

View File

@@ -3055,6 +3055,7 @@ struct IMGUI_API ImGuiTable
ImGuiTableColumnIdx FreezeRowsCount; // Actual frozen row count (== FreezeRowsRequest, or == 0 when no scrolling offset)
ImGuiTableColumnIdx FreezeColumnsRequest; // Requested frozen columns count
ImGuiTableColumnIdx FreezeColumnsCount; // Actual frozen columns count (== FreezeColumnsRequest, or == 0 when no scrolling offset)
ImGuiTableColumnIdx LeftMostUnfrozenOrder; // Display order of the left-most unfrozen column, which is used to determine where the freezing line should be.
ImGuiTableColumnIdx RowCellDataCurrent; // Index of current RowCellData[] entry in current row
ImGuiTableDrawChannelIdx DummyDrawChannel; // Redirect non-visible columns here.
ImGuiTableDrawChannelIdx Bg2DrawChannelCurrent; // For Selectable() and other widgets drawing across columns after the freezing line. Index within DrawSplitter.Channels[]

View File

@@ -754,10 +754,9 @@ void ImGui::TableQueueSetColumnDisplayOrder(ImGuiTable* table, int src_order, in
ImGuiTableColumn* dst_column = &table->Columns[table->DisplayOrderToIndex[dst_order]];
if ((src_column->Flags | dst_column->Flags) & ImGuiTableColumnFlags_NoReorder) // FIXME: Perform a sweep test?
return;
int src_i = (src_column->IndexWithinEnabledSet != -1) ? src_column->IndexWithinEnabledSet : table->Columns.index_from_ptr(src_column); // FIXME: Hidden columns don't count into the FreezeColumns count, so what to do here is ill-defined. For now we use regular index.
int dst_i = (dst_column->IndexWithinEnabledSet != -1) ? dst_column->IndexWithinEnabledSet : table->Columns.index_from_ptr(dst_column);
if ((src_i < table->FreezeColumnsRequest) != (dst_i < table->FreezeColumnsRequest))
return;
if (src_column->IsUserEnabled)
if ((src_order < table->LeftMostUnfrozenOrder) != (dst_order < table->LeftMostUnfrozenOrder))
return;
table->ReorderColumnSrcOrder = (ImGuiTableColumnIdx)src_order;
table->ReorderColumnDstOrder = (ImGuiTableColumnIdx)dst_order;
}
@@ -833,6 +832,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
ImBitArrayClearAllBits(table->EnabledMaskByIndex, table->ColumnsCount);
ImBitArrayClearAllBits(table->EnabledMaskByDisplayOrder, table->ColumnsCount);
table->LeftMostEnabledColumn = -1;
table->LeftMostUnfrozenOrder = -1;
table->MinColumnWidth = ImMax(1.0f, g.Style.FramePadding.x * 1.0f); // g.Style.ColumnsMinSpacing; // FIXME-TABLE
// [Part 1] Apply/lock Enabled and Order states. Calculate auto/ideal width for columns. Count fixed/stretch columns.
@@ -896,6 +896,8 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
else
table->LeftMostEnabledColumn = (ImGuiTableColumnIdx)column_n;
column->IndexWithinEnabledSet = table->ColumnsEnabledCount++;
if (table->ColumnsEnabledCount == table->FreezeColumnsRequest)
table->LeftMostUnfrozenOrder = (ImGuiTableColumnIdx)(order_n + 1);
ImBitArraySetBit(table->EnabledMaskByIndex, column_n);
ImBitArraySetBit(table->EnabledMaskByDisplayOrder, column->DisplayOrder);
prev_visible_column_idx = column_n;
@@ -929,6 +931,8 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
if ((table->Flags & ImGuiTableFlags_Sortable) && table->SortSpecsCount == 0 && !(table->Flags & ImGuiTableFlags_SortTristate))
table->IsSortSpecsDirty = true;
table->RightMostEnabledColumn = (ImGuiTableColumnIdx)prev_visible_column_idx;
if (table->LeftMostUnfrozenOrder == -1)
table->LeftMostUnfrozenOrder = table->ColumnsEnabledCount;
IM_ASSERT(table->LeftMostEnabledColumn >= 0 && table->RightMostEnabledColumn >= 0);
// [Part 2] Disable child window clipping while fitting columns. This is not strictly necessary but makes it possible to avoid