@@ -492,8 +492,7 @@ void ImGui::TableBeginApplyRequests(ImGuiTable* table)
492
492
{
493
493
// Handle resizing request
494
494
// (We process this at the first TableBegin of the frame)
495
- // FIXME-TABLE: Preserve contents width _while resizing down_ until releasing.
496
- // FIXME-TABLE: Contains columns if our work area doesn't allow for scrolling.
495
+ // FIXME-TABLE: Contains columns if our work area doesn't allow for scrolling?
497
496
if (table->InstanceCurrent == 0 )
498
497
{
499
498
if (table->ResizedColumn != -1 && table->ResizedColumnNextWidth != FLT_MAX)
@@ -691,6 +690,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
691
690
if ((table->Flags & ImGuiTableFlags_Sortable) && table->SortSpecsCount == 0 && !(table->Flags & ImGuiTableFlags_SortTristate))
692
691
table->IsSortSpecsDirty = true ;
693
692
table->RightMostEnabledColumn = (ImGuiTableColumnIdx)last_visible_column_idx;
693
+ IM_ASSERT (table->RightMostEnabledColumn >= 0 );
694
694
695
695
// [Part 2] Disable child window clipping while fitting columns. This is not strictly necessary but makes it possible
696
696
// to avoid the column fitting to wait until the first visible frame of the child container (may or not be a good thing).
@@ -1014,9 +1014,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
1014
1014
// because of using _WidthAutoResize/_WidthStretch). This will hide the resizing option from the context menu.
1015
1015
if (is_hovering_table && table->HoveredColumnBody == -1 )
1016
1016
{
1017
- float unused_x1 = table->WorkRect .Min .x ;
1018
- if (table->RightMostEnabledColumn != -1 )
1019
- unused_x1 = ImMax (unused_x1, table->Columns [table->RightMostEnabledColumn ].ClipRect .Max .x );
1017
+ float unused_x1 = ImMax (table->WorkRect .Min .x , table->Columns [table->RightMostEnabledColumn ].ClipRect .Max .x );
1020
1018
if (g.IO .MousePos .x >= unused_x1)
1021
1019
table->HoveredColumnBody = (ImGuiTableColumnIdx)table->ColumnsCount ;
1022
1020
}
@@ -1109,6 +1107,8 @@ void ImGui::TableUpdateBorders(ImGuiTable* table)
1109
1107
}
1110
1108
if (held)
1111
1109
{
1110
+ if (table->LastResizedColumn == -1 )
1111
+ table->ResizeLockMinContentsX2 = table->RightMostEnabledColumn != -1 ? table->Columns [table->RightMostEnabledColumn ].MaxX : -FLT_MAX;
1112
1112
table->ResizedColumn = (ImGuiTableColumnIdx)column_n;
1113
1113
table->InstanceInteracted = table->InstanceCurrent ;
1114
1114
}
@@ -1182,6 +1182,8 @@ void ImGui::EndTable()
1182
1182
float max_pos_x = backup_inner_max_pos_x;
1183
1183
if (table->RightMostEnabledColumn != -1 )
1184
1184
max_pos_x = ImMax (max_pos_x, table->Columns [table->RightMostEnabledColumn ].MaxX );
1185
+ if (table->ResizedColumn != -1 )
1186
+ max_pos_x = ImMax (max_pos_x, table->ResizeLockMinContentsX2 );
1185
1187
1186
1188
#if 0
1187
1189
// Strip out dummy channel draw calls
@@ -1861,7 +1863,12 @@ void ImGui::TableSetColumnWidth(int column_n, float width)
1861
1863
1862
1864
ImGuiTableColumn* column_1 = (column_0->NextEnabledColumn != -1 ) ? &table->Columns [column_0->NextEnabledColumn ] : NULL ;
1863
1865
1864
- // In this surprisingly not simple because of how we support mixing Fixed and Stretch columns.
1866
+ // In this surprisingly not simple because of how we support mixing Fixed and multiple Stretch columns.
1867
+ // - All fixed: easy.
1868
+ // - All stretch: easy.
1869
+ // - One or more fixed + one stretch: easy.
1870
+ // - One or more fixed + more than one stretch: A MESS
1871
+
1865
1872
// When forwarding resize from Wn| to Fn+1| we need to be considerate of the _NoResize flag on Fn+1.
1866
1873
// FIXME-TABLE: Find a way to rewrite all of this so interactions feel more consistent for the user.
1867
1874
// Scenarios:
@@ -2638,6 +2645,26 @@ void ImGui::TableHeader(const char* label)
2638
2645
ImRect cell_r = TableGetCellBgRect (table, column_n);
2639
2646
float label_height = ImMax (label_size.y , table->RowMinHeight - table->CellPaddingY * 2 .0f );
2640
2647
2648
+ // Calculate ideal size for sort order arrow
2649
+ float w_arrow = 0 .0f ;
2650
+ float w_sort_text = 0 .0f ;
2651
+ char sort_order_suf[4 ] = " " ;
2652
+ const float ARROW_SCALE = 0 .65f ;
2653
+ if ((table->Flags & ImGuiTableFlags_Sortable) && !(column->Flags & ImGuiTableColumnFlags_NoSort))
2654
+ {
2655
+ w_arrow = ImFloor (g.FontSize * ARROW_SCALE + g.Style .FramePadding .x );// table->CellPadding.x);
2656
+ if (column->SortOrder > 0 )
2657
+ {
2658
+ ImFormatString (sort_order_suf, IM_ARRAYSIZE (sort_order_suf), " %d" , column->SortOrder + 1 );
2659
+ w_sort_text = g.Style .ItemInnerSpacing .x + CalcTextSize (sort_order_suf).x ;
2660
+ }
2661
+ }
2662
+
2663
+ // We feed our unclipped width to the column without writing on CursorMaxPos, so that column is still considering for merging.
2664
+ float max_pos_x = label_pos.x + label_size.x + w_sort_text + w_arrow;
2665
+ column->ContentMaxXHeadersUsed = ImMax (column->ContentMaxXHeadersUsed , column->WorkMaxX );
2666
+ column->ContentMaxXHeadersIdeal = ImMax (column->ContentMaxXHeadersIdeal , max_pos_x);
2667
+
2641
2668
// Keep header highlighted when context menu is open.
2642
2669
const bool selected = (table->IsContextPopupOpen && table->ContextPopupColumn == column_n && table->InstanceInteracted == table->InstanceCurrent );
2643
2670
ImGuiID id = window->GetID (label);
@@ -2692,36 +2719,21 @@ void ImGui::TableHeader(const char* label)
2692
2719
}
2693
2720
2694
2721
// Sort order arrow
2695
- float w_arrow = 0 .0f ;
2696
- float w_sort_text = 0 .0f ;
2697
- float ellipsis_max = cell_r.Max .x ;
2722
+ const float ellipsis_max = cell_r.Max .x - w_arrow - w_sort_text;
2698
2723
if ((table->Flags & ImGuiTableFlags_Sortable) && !(column->Flags & ImGuiTableColumnFlags_NoSort))
2699
2724
{
2700
- const float ARROW_SCALE = 0 .65f ;
2701
- w_arrow = ImFloor (g.FontSize * ARROW_SCALE + g.Style .FramePadding .x );// table->CellPadding.x);
2702
2725
if (column->SortOrder != -1 )
2703
2726
{
2704
- char sort_order_suf[8 ];
2705
- w_sort_text = 0 .0f ;
2706
- if (column->SortOrder > 0 )
2707
- {
2708
- ImFormatString (sort_order_suf, IM_ARRAYSIZE (sort_order_suf), " %d" , column->SortOrder + 1 );
2709
- w_sort_text = g.Style .ItemInnerSpacing .x + CalcTextSize (sort_order_suf).x ;
2710
- }
2711
-
2712
2727
float x = ImMax (cell_r.Min .x , cell_r.Max .x - w_arrow - w_sort_text);
2713
- ellipsis_max -= w_arrow + w_sort_text;
2714
-
2715
2728
float y = label_pos.y ;
2716
- ImU32 col = GetColorU32 (ImGuiCol_Text);
2717
2729
if (column->SortOrder > 0 )
2718
2730
{
2719
2731
PushStyleColor (ImGuiCol_Text, GetColorU32 (ImGuiCol_Text, 0 .70f ));
2720
2732
RenderText (ImVec2 (x + g.Style .ItemInnerSpacing .x , y), sort_order_suf);
2721
2733
PopStyleColor ();
2722
2734
x += w_sort_text;
2723
2735
}
2724
- RenderArrow (window->DrawList , ImVec2 (x, y), col , column->SortDirection == ImGuiSortDirection_Ascending ? ImGuiDir_Up : ImGuiDir_Down, ARROW_SCALE);
2736
+ RenderArrow (window->DrawList , ImVec2 (x, y), GetColorU32 (ImGuiCol_Text) , column->SortDirection == ImGuiSortDirection_Ascending ? ImGuiDir_Up : ImGuiDir_Down, ARROW_SCALE);
2725
2737
}
2726
2738
2727
2739
// Handle clicking on column header to adjust Sort Order
@@ -2741,11 +2753,6 @@ void ImGui::TableHeader(const char* label)
2741
2753
if (text_clipped && hovered && g.HoveredIdNotActiveTimer > g.TooltipSlowDelay )
2742
2754
SetTooltip (" %.*s" , (int )(label_end - label), label);
2743
2755
2744
- // We feed our unclipped width to the column without writing on CursorMaxPos, so that column is still considering for merging.
2745
- float max_pos_x = label_pos.x + label_size.x + w_sort_text + w_arrow;
2746
- column->ContentMaxXHeadersUsed = ImMax (column->ContentMaxXHeadersUsed , column->WorkMaxX );
2747
- column->ContentMaxXHeadersIdeal = ImMax (column->ContentMaxXHeadersIdeal , max_pos_x);
2748
-
2749
2756
// We don't use BeginPopupContextItem() because we want the popup to stay up even after the column is hidden
2750
2757
if (IsMouseReleased (1 ) && IsItemHovered ())
2751
2758
TableOpenContextMenu (column_n);
0 commit comments