|
64 | 64 | // Typical call flow: (root level is public API):
|
65 | 65 | // - BeginTable() user begin into a table
|
66 | 66 | // | BeginChild() - (if ScrollX/ScrollY is set)
|
67 |
| -// | TableBeginUpdateColumns() - apply resize/order requests, lock columns active state, order |
| 67 | +// | TableBeginApplyRequests() - apply queued resizing/reordering/hiding requests |
68 | 68 | // | - TableSetColumnWidth() - apply resizing width (for mouse resize, often requested by previous frame)
|
69 | 69 | // | - TableUpdateColumnsWeightFromWidth()- recompute columns weights (of stretch columns) from their respective width
|
70 | 70 | // - TableSetupColumn() user submit columns details (optional)
|
@@ -273,7 +273,6 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
|
273 | 273 | table->LastFrameActive = g.FrameCount;
|
274 | 274 | table->OuterWindow = table->InnerWindow = outer_window;
|
275 | 275 | table->ColumnsCount = columns_count;
|
276 |
| - table->ColumnsNames.Buf.resize(0); |
277 | 276 | table->IsInitializing = false;
|
278 | 277 | table->IsLayoutLocked = false;
|
279 | 278 | table->InnerWidth = inner_width;
|
@@ -431,13 +430,26 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
|
431 | 430 | // Because we cannot safely assert in EndTable() when no rows have been created, this seems like our best option.
|
432 | 431 | inner_window->SkipItems = true;
|
433 | 432 |
|
434 |
| - // Update/lock which columns will be Visible for the frame |
435 |
| - TableBeginUpdateColumns(table); |
| 433 | + // Clear names |
| 434 | + // FIXME-TABLES: probably could be done differently... |
| 435 | + if (table->ColumnsNames.Buf.Size > 0) |
| 436 | + { |
| 437 | + table->ColumnsNames.Buf.resize(0); |
| 438 | + for (int column_n = 0; column_n < table->ColumnsCount; column_n++) |
| 439 | + { |
| 440 | + ImGuiTableColumn* column = &table->Columns[column_n]; |
| 441 | + column->NameOffset = -1; |
| 442 | + } |
| 443 | + } |
| 444 | + |
| 445 | + // Apply queued resizing/reordering/hiding requests |
| 446 | + TableBeginApplyRequests(table); |
436 | 447 |
|
437 | 448 | return true;
|
438 | 449 | }
|
439 | 450 |
|
440 |
| -void ImGui::TableBeginUpdateColumns(ImGuiTable* table) |
| 451 | +// Apply queued resizing/reordering/hiding requests |
| 452 | +void ImGui::TableBeginApplyRequests(ImGuiTable* table) |
441 | 453 | {
|
442 | 454 | // Handle resizing request
|
443 | 455 | // (We process this at the first TableBegin of the frame)
|
@@ -504,67 +516,6 @@ void ImGui::TableBeginUpdateColumns(ImGuiTable* table)
|
504 | 516 | table->IsResetDisplayOrderRequest = false;
|
505 | 517 | table->IsSettingsDirty = true;
|
506 | 518 | }
|
507 |
| - |
508 |
| - // Lock Visible state and Order |
509 |
| - table->ColumnsEnabledCount = 0; |
510 |
| - table->IsDefaultDisplayOrder = true; |
511 |
| - ImGuiTableColumn* last_visible_column = NULL; |
512 |
| - bool want_column_auto_fit = false; |
513 |
| - for (int order_n = 0; order_n < table->ColumnsCount; order_n++) |
514 |
| - { |
515 |
| - const int column_n = table->DisplayOrderToIndex[order_n]; |
516 |
| - if (column_n != order_n) |
517 |
| - table->IsDefaultDisplayOrder = false; |
518 |
| - ImGuiTableColumn* column = &table->Columns[column_n]; |
519 |
| - column->NameOffset = -1; |
520 |
| - if (!(table->Flags & ImGuiTableFlags_Hideable) || (column->Flags & ImGuiTableColumnFlags_NoHide)) |
521 |
| - column->IsEnabledNextFrame = true; |
522 |
| - if (column->IsEnabled != column->IsEnabledNextFrame) |
523 |
| - { |
524 |
| - column->IsEnabled = column->IsEnabledNextFrame; |
525 |
| - table->IsSettingsDirty = true; |
526 |
| - if (!column->IsEnabled && column->SortOrder != -1) |
527 |
| - table->IsSortSpecsDirty = true; |
528 |
| - } |
529 |
| - if (column->SortOrder > 0 && !(table->Flags & ImGuiTableFlags_MultiSortable)) |
530 |
| - table->IsSortSpecsDirty = true; |
531 |
| - if (column->AutoFitQueue != 0x00) |
532 |
| - want_column_auto_fit = true; |
533 |
| - |
534 |
| - ImU64 index_mask = (ImU64)1 << column_n; |
535 |
| - ImU64 display_order_mask = (ImU64)1 << column->DisplayOrder; |
536 |
| - if (column->IsEnabled) |
537 |
| - { |
538 |
| - column->PrevEnabledColumn = column->NextEnabledColumn = -1; |
539 |
| - if (last_visible_column) |
540 |
| - { |
541 |
| - last_visible_column->NextEnabledColumn = (ImS8)column_n; |
542 |
| - column->PrevEnabledColumn = (ImS8)table->Columns.index_from_ptr(last_visible_column); |
543 |
| - } |
544 |
| - column->IndexWithinEnabledSet = table->ColumnsEnabledCount; |
545 |
| - table->ColumnsEnabledCount++; |
546 |
| - table->EnabledMaskByIndex |= index_mask; |
547 |
| - table->EnabledMaskByDisplayOrder |= display_order_mask; |
548 |
| - last_visible_column = column; |
549 |
| - } |
550 |
| - else |
551 |
| - { |
552 |
| - column->IndexWithinEnabledSet = -1; |
553 |
| - table->EnabledMaskByIndex &= ~index_mask; |
554 |
| - table->EnabledMaskByDisplayOrder &= ~display_order_mask; |
555 |
| - } |
556 |
| - IM_ASSERT(column->IndexWithinEnabledSet <= column->DisplayOrder); |
557 |
| - } |
558 |
| - table->EnabledUnclippedMaskByIndex = table->EnabledMaskByIndex; // Columns will be masked out by TableUpdateLayout() when Clipped |
559 |
| - table->RightMostEnabledColumn = (ImS8)(last_visible_column ? table->Columns.index_from_ptr(last_visible_column) : -1); |
560 |
| - |
561 |
| - // Disable child window clipping while fitting columns. This is not strictly necessary but makes it possible to avoid |
562 |
| - // the column fitting to wait until the first visible frame of the child container (may or not be a good thing). |
563 |
| - if (want_column_auto_fit && table->OuterWindow != table->InnerWindow) |
564 |
| - table->InnerWindow->SkipItems = false; |
565 |
| - |
566 |
| - if (want_column_auto_fit) |
567 |
| - table->IsSettingsDirty = true; |
568 | 519 | }
|
569 | 520 |
|
570 | 521 | // Adjust flags: default width mode + stretch columns are not allowed when auto extending
|
@@ -629,6 +580,65 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
629 | 580 | table->HoveredColumnBody = -1;
|
630 | 581 | table->HoveredColumnBorder = -1;
|
631 | 582 |
|
| 583 | + // Lock Enabled state and Order |
| 584 | + ImGuiTableColumn* last_visible_column = NULL; |
| 585 | + bool want_column_auto_fit = false; |
| 586 | + table->IsDefaultDisplayOrder = true; |
| 587 | + table->ColumnsEnabledCount = 0; |
| 588 | + for (int order_n = 0; order_n < table->ColumnsCount; order_n++) |
| 589 | + { |
| 590 | + const int column_n = table->DisplayOrderToIndex[order_n]; |
| 591 | + if (column_n != order_n) |
| 592 | + table->IsDefaultDisplayOrder = false; |
| 593 | + ImGuiTableColumn* column = &table->Columns[column_n]; |
| 594 | + if (!(table->Flags & ImGuiTableFlags_Hideable) || (column->Flags & ImGuiTableColumnFlags_NoHide)) |
| 595 | + column->IsEnabledNextFrame = true; |
| 596 | + if (column->IsEnabled != column->IsEnabledNextFrame) |
| 597 | + { |
| 598 | + column->IsEnabled = column->IsEnabledNextFrame; |
| 599 | + table->IsSettingsDirty = true; |
| 600 | + if (!column->IsEnabled && column->SortOrder != -1) |
| 601 | + table->IsSortSpecsDirty = true; |
| 602 | + } |
| 603 | + if (column->SortOrder > 0 && !(table->Flags & ImGuiTableFlags_MultiSortable)) |
| 604 | + table->IsSortSpecsDirty = true; |
| 605 | + if (column->AutoFitQueue != 0x00) |
| 606 | + want_column_auto_fit = true; |
| 607 | + |
| 608 | + ImU64 index_mask = (ImU64)1 << column_n; |
| 609 | + ImU64 display_order_mask = (ImU64)1 << column->DisplayOrder; |
| 610 | + if (column->IsEnabled) |
| 611 | + { |
| 612 | + column->PrevEnabledColumn = column->NextEnabledColumn = -1; |
| 613 | + if (last_visible_column) |
| 614 | + { |
| 615 | + last_visible_column->NextEnabledColumn = (ImS8)column_n; |
| 616 | + column->PrevEnabledColumn = (ImS8)table->Columns.index_from_ptr(last_visible_column); |
| 617 | + } |
| 618 | + column->IndexWithinEnabledSet = table->ColumnsEnabledCount; |
| 619 | + table->ColumnsEnabledCount++; |
| 620 | + table->EnabledMaskByIndex |= index_mask; |
| 621 | + table->EnabledMaskByDisplayOrder |= display_order_mask; |
| 622 | + last_visible_column = column; |
| 623 | + } |
| 624 | + else |
| 625 | + { |
| 626 | + column->IndexWithinEnabledSet = -1; |
| 627 | + table->EnabledMaskByIndex &= ~index_mask; |
| 628 | + table->EnabledMaskByDisplayOrder &= ~display_order_mask; |
| 629 | + } |
| 630 | + IM_ASSERT(column->IndexWithinEnabledSet <= column->DisplayOrder); |
| 631 | + } |
| 632 | + table->EnabledUnclippedMaskByIndex = table->EnabledMaskByIndex; // Columns will be masked out below when Clipped |
| 633 | + table->RightMostEnabledColumn = (ImS8)(last_visible_column ? table->Columns.index_from_ptr(last_visible_column) : -1); |
| 634 | + |
| 635 | + // Disable child window clipping while fitting columns. This is not strictly necessary but makes it possible to avoid |
| 636 | + // the column fitting to wait until the first visible frame of the child container (may or not be a good thing). |
| 637 | + if (want_column_auto_fit && table->OuterWindow != table->InnerWindow) |
| 638 | + table->InnerWindow->SkipItems = false; |
| 639 | + if (want_column_auto_fit) |
| 640 | + table->IsSettingsDirty = true; |
| 641 | + |
632 | 642 | // Compute offset, clip rect for the frame
|
633 | 643 | // (can't make auto padding larger than what WorkRect knows about so right-alignment matches)
|
634 | 644 | const ImRect work_rect = table->WorkRect;
|
@@ -1715,7 +1725,7 @@ void ImGui::TableNextRow(ImGuiTableRowFlags row_flags, float row_min_height)
|
1715 | 1725 | ImGuiContext& g = *GImGui;
|
1716 | 1726 | ImGuiTable* table = g.CurrentTable;
|
1717 | 1727 |
|
1718 |
| - if (table->CurrentRow == -1) |
| 1728 | + if (!table->IsLayoutLocked) |
1719 | 1729 | TableUpdateLayout(table);
|
1720 | 1730 | if (table->IsInsideRow)
|
1721 | 1731 | TableEndRow(table);
|
@@ -2509,6 +2519,10 @@ ImGuiTableSortSpecs* ImGui::TableGetSortSpecs()
|
2509 | 2519 | if (!(table->Flags & ImGuiTableFlags_Sortable))
|
2510 | 2520 | return NULL;
|
2511 | 2521 |
|
| 2522 | + // Require layout (in case TableHeadersRow() hasn't been called) as it may alter IsSortSpecsDirty in some paths. |
| 2523 | + if (!table->IsLayoutLocked) |
| 2524 | + TableUpdateLayout(table); |
| 2525 | + |
2512 | 2526 | if (table->IsSortSpecsDirty)
|
2513 | 2527 | TableSortSpecsBuild(table);
|
2514 | 2528 |
|
|
0 commit comments