mirror of
https://github.com/Drezil/imgui.git
synced 2024-11-15 01:17:00 +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:
parent
1aa59f90d0
commit
972ca8166f
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_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_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_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.
|
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
|
// 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().
|
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 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 ImGuiID TableGetColumnResizeID(const ImGuiTable* table, int column_n, int instance_no = 0);
|
||||||
IMGUI_API float TableGetMinColumnWidth();
|
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 TableSetColumnWidthAutoSingle(ImGuiTable* table, int column_n);
|
||||||
IMGUI_API void TableSetColumnWidthAutoAll(ImGuiTable* table);
|
IMGUI_API void TableSetColumnWidthAutoAll(ImGuiTable* table);
|
||||||
IMGUI_API void TableRemove(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.
|
// [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_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_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!)
|
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.
|
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)
|
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;
|
table->HoveredColumnBody = (ImGuiTableColumnIdx)column_n;
|
||||||
|
|
||||||
// Maximum width
|
// Lock start position
|
||||||
float max_width = FLT_MAX;
|
column->MinX = offset_x;
|
||||||
if (table->Flags & ImGuiTableFlags_ScrollX)
|
|
||||||
{
|
// Lock width based on start position and minimum/maximum width for this position
|
||||||
// Frozen columns can't reach beyond visible width else scrolling will naturally break.
|
float max_width = TableGetMaxColumnWidth(table, column_n);
|
||||||
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;
|
|
||||||
}
|
|
||||||
column->WidthGiven = ImMin(column->WidthGiven, max_width);
|
column->WidthGiven = ImMin(column->WidthGiven, max_width);
|
||||||
|
|
||||||
// Minimum width
|
|
||||||
column->WidthGiven = ImMax(column->WidthGiven, ImMin(column->WidthRequest, min_column_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.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 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.
|
// - 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.
|
// - 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->WorkMinX = column->MinX + table->CellPaddingX + table->CellSpacingX1;
|
||||||
column->WorkMaxX = column->MaxX - table->CellPaddingX - table->CellSpacingX2; // Expected max
|
column->WorkMaxX = column->MaxX - table->CellPaddingX - table->CellSpacingX2; // Expected max
|
||||||
column->ItemWidth = ImFloor(column->WidthGiven * 0.65f);
|
column->ItemWidth = ImFloor(column->WidthGiven * 0.65f);
|
||||||
@ -1835,6 +1812,7 @@ void ImGui::TableEndCell(ImGuiTable* table)
|
|||||||
// [SECTION] Tables: Columns width management
|
// [SECTION] Tables: Columns width management
|
||||||
//-------------------------------------------------------------------------
|
//-------------------------------------------------------------------------
|
||||||
// - TableGetMinColumnWidth() [Internal]
|
// - TableGetMinColumnWidth() [Internal]
|
||||||
|
// - TableGetMaxColumnWidth() [Internal]
|
||||||
// - TableSetColumnWidth()
|
// - TableSetColumnWidth()
|
||||||
// - TableSetColumnWidthAutoSingle() [Internal]
|
// - TableSetColumnWidthAutoSingle() [Internal]
|
||||||
// - TableSetColumnWidthAutoAll() [Internal]
|
// - TableSetColumnWidthAutoAll() [Internal]
|
||||||
@ -1849,6 +1827,37 @@ float ImGui::TableGetMinColumnWidth()
|
|||||||
return g.Style.FramePadding.x * 1.0f;
|
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
|
// 'width' = inner column width, without padding
|
||||||
void ImGui::TableSetColumnWidth(int column_n, float width)
|
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];
|
ImGuiTableColumn* column_0 = &table->Columns[column_n];
|
||||||
float column_0_width = width;
|
float column_0_width = width;
|
||||||
|
|
||||||
// Constraints
|
// Apply constraints early
|
||||||
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);
|
|
||||||
|
|
||||||
// Compare both requested and actual given width to avoid overwriting requested width when column is stuck (minimum size, bounded)
|
// 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)
|
if (column_0->WidthGiven == column_0_width || column_0->WidthRequest == column_0_width)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user