mirror of
				https://github.com/ocornut/imgui.git
				synced 2025-10-26 12:27:30 +00:00 
			
		
		
		
	Tables: extracted code for TableGetMaxColumnWidth(), fixing "stuck" resize being lossy as it used an older calculation for it and didn't honor e.g. _NoKeepColumnsVisible
This commit is contained in:
		
							
								
								
									
										2
									
								
								imgui.h
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								imgui.h
									
									
									
									
									
								
							| @@ -1079,7 +1079,7 @@ enum ImGuiTableFlags_ | ||||
|     ImGuiTableFlags_ColumnsWidthFixed               = 1 << 14,  // Default if ScrollX is on. Columns will default to use _WidthFixed or _WidthAutoResize policy (if Resizable is off). Read description above for more details. | ||||
|     ImGuiTableFlags_SameWidths                      = 1 << 15,  // Make all columns the same widths which is useful with Fixed columns policy (but granted by default with Stretch policy + no resize). Implicitly enable ImGuiTableFlags_NoKeepColumnsVisible and disable ImGuiTableFlags_Resizable. | ||||
|     ImGuiTableFlags_NoHostExtendY                   = 1 << 16,  // Disable extending table past the limit set by outer_size.y. Only meaningful when neither ScrollX nor ScrollY are set (data below the limit will be clipped and not visible) | ||||
|     ImGuiTableFlags_NoKeepColumnsVisible            = 1 << 17,  // Disable keeping column always minimally visible when ScrollX is off and table gets too small. | ||||
|     ImGuiTableFlags_NoKeepColumnsVisible            = 1 << 17,  // Disable keeping column always minimally visible when ScrollX is off and table gets too small. Not recommended if columns are resizable. | ||||
|     ImGuiTableFlags_PreciseWidths                   = 1 << 18,  // Disable distributing remainder width to stretched columns (width allocation on a 100-wide table with 3 columns: Without this flag: 33,33,34. With this flag: 33,33,33). With larger number of columns, resizing will appear to be less smooth. | ||||
|     // Clipping | ||||
|     ImGuiTableFlags_NoClip                          = 1 << 19,  // Disable clipping rectangle for every individual columns (reduce draw command count, items will be able to overflow into other columns). Generally incompatible with TableSetupScrollFreeze(). | ||||
|   | ||||
| @@ -2325,6 +2325,7 @@ namespace ImGui | ||||
|     IMGUI_API const char*   TableGetColumnName(const ImGuiTable* table, int column_n); | ||||
|     IMGUI_API ImGuiID       TableGetColumnResizeID(const ImGuiTable* table, int column_n, int instance_no = 0); | ||||
|     IMGUI_API float         TableGetMinColumnWidth(); | ||||
|     IMGUI_API float         TableGetMaxColumnWidth(const ImGuiTable* table, int column_n); | ||||
|     IMGUI_API void          TableSetColumnWidthAutoSingle(ImGuiTable* table, int column_n); | ||||
|     IMGUI_API void          TableSetColumnWidthAutoAll(ImGuiTable* table); | ||||
|     IMGUI_API void          TableRemove(ImGuiTable* table); | ||||
|   | ||||
| @@ -703,7 +703,6 @@ void ImGui::TableUpdateLayout(ImGuiTable* table) | ||||
|  | ||||
|     // [Part 3] Fix column flags. Calculate ideal width for columns. Count how many fixed/stretch columns we have and sum of weights. | ||||
|     const float min_column_width = TableGetMinColumnWidth(); | ||||
|     const float min_column_distance = min_column_width + table->CellPaddingX * 2.0f + table->CellSpacingX1 + table->CellSpacingX2; | ||||
|     int count_fixed = 0;                    // Number of columns that have fixed sizing policy (not stretched sizing policy) (this is NOT the opposite of count_resizable!) | ||||
|     int count_resizable = 0;                // Number of columns the user can resize (this is NOT the opposite of count_fixed!) | ||||
|     float sum_weights_stretched = 0.0f;     // Sum of all weights for weighted columns. | ||||
| @@ -895,42 +894,20 @@ void ImGui::TableUpdateLayout(ImGuiTable* table) | ||||
|         if (is_hovering_table && g.IO.MousePos.x >= column->ClipRect.Min.x && g.IO.MousePos.x < column->ClipRect.Max.x) | ||||
|             table->HoveredColumnBody = (ImGuiTableColumnIdx)column_n; | ||||
|  | ||||
|         // Maximum width | ||||
|         float max_width = FLT_MAX; | ||||
|         if (table->Flags & ImGuiTableFlags_ScrollX) | ||||
|         { | ||||
|             // Frozen columns can't reach beyond visible width else scrolling will naturally break. | ||||
|             if (order_n < table->FreezeColumnsRequest) | ||||
|             { | ||||
|                 max_width = (table->InnerClipRect.Max.x - (table->FreezeColumnsRequest - order_n) * min_column_distance) - offset_x; | ||||
|                 max_width = max_width - table->OuterPaddingX - table->CellPaddingX - table->CellSpacingX2; | ||||
|             } | ||||
|         } | ||||
|         else if ((table->Flags & ImGuiTableFlags_NoKeepColumnsVisible) == 0) | ||||
|         { | ||||
|             // If horizontal scrolling if disabled, we apply a final lossless shrinking of columns in order to make | ||||
|             // sure they are all visible. Because of this we also know that all of the columns will always fit in | ||||
|             // table->WorkRect and therefore in table->InnerRect (because ScrollX is off) | ||||
|             // FIXME-TABLE: This is solved incorrectly but also quite a difficult problem to fix as we also want ClipRect width to match. | ||||
|             // See "table_width_distrib" and "table_width_keep_visible" tests | ||||
|             max_width = table->WorkRect.Max.x - (table->ColumnsEnabledCount - column->IndexWithinEnabledSet - 1) * min_column_distance - offset_x; | ||||
|             //max_width -= table->CellSpacingX1; | ||||
|             max_width -= table->CellSpacingX2; | ||||
|             max_width -= table->CellPaddingX * 2.0f; | ||||
|             max_width -= table->OuterPaddingX; | ||||
|         } | ||||
|         // Lock start position | ||||
|         column->MinX = offset_x; | ||||
|  | ||||
|         // Lock width based on start position and minimum/maximum width for this position | ||||
|         float max_width = TableGetMaxColumnWidth(table, column_n); | ||||
|         column->WidthGiven = ImMin(column->WidthGiven, max_width); | ||||
|  | ||||
|         // Minimum width | ||||
|         column->WidthGiven = ImMax(column->WidthGiven, ImMin(column->WidthRequest, min_column_width)); | ||||
|         column->MaxX = offset_x + column->WidthGiven + table->CellSpacingX1 + table->CellSpacingX2 + table->CellPaddingX * 2.0f; | ||||
|  | ||||
|         // Lock all our positions | ||||
|         // Lock other positions | ||||
|         // - ClipRect.Min.x: Because merging draw commands doesn't compare min boundaries, we make ClipRect.Min.x match left bounds to be consistent regardless of merging. | ||||
|         // - ClipRect.Max.x: using WorkMaxX instead of MaxX (aka including padding) makes things more consistent when resizing down, tho slightly detrimental to visibility in very-small column. | ||||
|         // - ClipRect.Max.x: using MaxX makes it easier for header to receive hover highlight with no discontinuity and display sorting arrow. | ||||
|         // - FIXME-TABLE: We want equal width columns to have equal (ClipRect.Max.x - WorkMinX) width, which means ClipRect.max.x cannot stray off host_clip_rect.Max.x else right-most column may appear shorter. | ||||
|         column->MinX = offset_x; | ||||
|         column->MaxX = offset_x + column->WidthGiven + table->CellSpacingX1 + table->CellSpacingX2 + table->CellPaddingX * 2.0f; | ||||
|         column->WorkMinX = column->MinX + table->CellPaddingX + table->CellSpacingX1; | ||||
|         column->WorkMaxX = column->MaxX - table->CellPaddingX - table->CellSpacingX2; // Expected max | ||||
|         column->ItemWidth = ImFloor(column->WidthGiven * 0.65f); | ||||
| @@ -1835,6 +1812,7 @@ void ImGui::TableEndCell(ImGuiTable* table) | ||||
| // [SECTION] Tables: Columns width management | ||||
| //------------------------------------------------------------------------- | ||||
| // - TableGetMinColumnWidth() [Internal] | ||||
| // - TableGetMaxColumnWidth() [Internal] | ||||
| // - TableSetColumnWidth() | ||||
| // - TableSetColumnWidthAutoSingle() [Internal] | ||||
| // - TableSetColumnWidthAutoAll() [Internal] | ||||
| @@ -1849,6 +1827,37 @@ float ImGui::TableGetMinColumnWidth() | ||||
|     return g.Style.FramePadding.x * 1.0f; | ||||
| } | ||||
|  | ||||
| // Maximum column content width given current layout. Use column->MinX so this value on a per-column basis. | ||||
| float ImGui::TableGetMaxColumnWidth(const ImGuiTable* table, int column_n) | ||||
| { | ||||
|     const ImGuiTableColumn* column = &table->Columns[column_n]; | ||||
|     float max_width = FLT_MAX; | ||||
|     const float min_column_distance = TableGetMinColumnWidth() + table->CellPaddingX * 2.0f + table->CellSpacingX1 + table->CellSpacingX2; | ||||
|     if (table->Flags & ImGuiTableFlags_ScrollX) | ||||
|     { | ||||
|         // Frozen columns can't reach beyond visible width else scrolling will naturally break. | ||||
|         if (column->DisplayOrder < table->FreezeColumnsRequest) | ||||
|         { | ||||
|             max_width = (table->InnerClipRect.Max.x - (table->FreezeColumnsRequest - column->DisplayOrder) * min_column_distance) - column->MinX; | ||||
|             max_width = max_width - table->OuterPaddingX - table->CellPaddingX - table->CellSpacingX2; | ||||
|         } | ||||
|     } | ||||
|     else if ((table->Flags & ImGuiTableFlags_NoKeepColumnsVisible) == 0) | ||||
|     { | ||||
|         // If horizontal scrolling if disabled, we apply a final lossless shrinking of columns in order to make | ||||
|         // sure they are all visible. Because of this we also know that all of the columns will always fit in | ||||
|         // table->WorkRect and therefore in table->InnerRect (because ScrollX is off) | ||||
|         // FIXME-TABLE: This is solved incorrectly but also quite a difficult problem to fix as we also want ClipRect width to match. | ||||
|         // See "table_width_distrib" and "table_width_keep_visible" tests | ||||
|         max_width = table->WorkRect.Max.x - (table->ColumnsEnabledCount - column->IndexWithinEnabledSet - 1) * min_column_distance - column->MinX; | ||||
|         //max_width -= table->CellSpacingX1; | ||||
|         max_width -= table->CellSpacingX2; | ||||
|         max_width -= table->CellPaddingX * 2.0f; | ||||
|         max_width -= table->OuterPaddingX; | ||||
|     } | ||||
|     return max_width; | ||||
| } | ||||
|  | ||||
| // 'width' = inner column width, without padding | ||||
| void ImGui::TableSetColumnWidth(int column_n, float width) | ||||
| { | ||||
| @@ -1859,14 +1868,11 @@ void ImGui::TableSetColumnWidth(int column_n, float width) | ||||
|     ImGuiTableColumn* column_0 = &table->Columns[column_n]; | ||||
|     float column_0_width = width; | ||||
|  | ||||
|     // Constraints | ||||
|     const float min_width = TableGetMinColumnWidth(); | ||||
|     float max_width_0 = FLT_MAX; | ||||
|     if (!(table->Flags & ImGuiTableFlags_ScrollX)) | ||||
|         max_width_0 = (table->WorkRect.Max.x - column_0->MinX) - (table->ColumnsEnabledCount - (column_0->IndexWithinEnabledSet + 1)) * min_width; | ||||
|     column_0_width = ImClamp(column_0_width, min_width, max_width_0); | ||||
|  | ||||
|     // Apply constraints early | ||||
|     // Compare both requested and actual given width to avoid overwriting requested width when column is stuck (minimum size, bounded) | ||||
|     const float min_width = TableGetMinColumnWidth(); | ||||
|     const float max_width = TableGetMaxColumnWidth(table, column_n); | ||||
|     column_0_width = ImClamp(column_0_width, min_width, max_width); | ||||
|     if (column_0->WidthGiven == column_0_width || column_0->WidthRequest == column_0_width) | ||||
|         return; | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 ocornut
					ocornut