mirror of https://github.com/ocornut/imgui
Tables: Try to report contents width to outer window, generally better auto-fit.
This commit is contained in:
parent
466b6e619a
commit
dff26191bd
|
@ -3570,6 +3570,24 @@ static void ShowDemoWindowTables()
|
|||
}
|
||||
ImGui::EndTable();
|
||||
}
|
||||
|
||||
if (ImGui::BeginTable("##table2", 3, flags | ImGuiTableFlags_SizingPolicyFixedX))
|
||||
{
|
||||
ImGui::TableSetupColumn("One");
|
||||
ImGui::TableSetupColumn("Two");
|
||||
ImGui::TableSetupColumn("Three");
|
||||
ImGui::TableAutoHeaders();
|
||||
for (int row = 0; row < 6; row++)
|
||||
{
|
||||
ImGui::TableNextRow();
|
||||
for (int column = 0; column < 3; column++)
|
||||
{
|
||||
ImGui::TableSetColumnIndex(column);
|
||||
ImGui::Text("Fixed %d,%d", row, column);
|
||||
}
|
||||
}
|
||||
ImGui::EndTable();
|
||||
}
|
||||
ImGui::TreePop();
|
||||
}
|
||||
|
||||
|
|
|
@ -1981,9 +1981,9 @@ struct ImGuiTable
|
|||
float CellSpacingX; // Spacing between non-bordered cells
|
||||
float LastOuterHeight; // Outer height from last frame
|
||||
float LastFirstRowHeight; // Height of first row from last frame
|
||||
float ColumnsTotalWidth;
|
||||
float InnerWidth; // User value passed to BeginTable(), see comments at the top of BeginTable() for details.
|
||||
float IdealTotalWidth; // Sum of ideal column width for nothing to be clipped
|
||||
float ColumnsTotalWidth; // Sum of current column width
|
||||
float ColumnsAutoFitWidth; // Sum of ideal column width in order nothing to be clipped, used for auto-fitting and content width submission in outer window
|
||||
float ResizedColumnNextWidth;
|
||||
ImRect OuterRect; // Note: OuterRect.Max.y is often FLT_MAX until EndTable(), unless a height has been specified in BeginTable().
|
||||
ImRect WorkRect;
|
||||
|
|
|
@ -558,13 +558,14 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
|||
// (can't make auto padding larger than what WorkRect knows about so right-alignment matches)
|
||||
const ImRect work_rect = table->WorkRect;
|
||||
const float padding_auto_x = table->CellPaddingX2;
|
||||
const float spacing_auto_x = table->CellSpacingX * (1.0f + 2.0f); // CellSpacingX is >0.0f when there's no vertical border, in which case we add two extra CellSpacingX to make auto-fit look nice instead of cramped. We may want to expose this somehow.
|
||||
const float min_column_width = TableGetMinColumnWidth();
|
||||
|
||||
int count_fixed = 0;
|
||||
float width_fixed = 0.0f;
|
||||
float total_weights = 0.0f;
|
||||
table->LeftMostStretchedColumnDisplayOrder = -1;
|
||||
table->IdealTotalWidth = 0.0f;
|
||||
table->ColumnsAutoFitWidth = 0.0f;
|
||||
for (int order_n = 0; order_n < table->ColumnsCount; order_n++)
|
||||
{
|
||||
if (!(table->ActiveMaskByDisplayOrder & ((ImU64)1 << order_n)))
|
||||
|
@ -591,7 +592,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
|||
if (!(table->Flags & ImGuiTableFlags_NoHeadersWidth) && !(column->Flags & ImGuiTableColumnFlags_NoHeaderWidth))
|
||||
column_width_ideal = ImMax(column_width_ideal, column_content_width_headers);
|
||||
column_width_ideal = ImMax(column_width_ideal + padding_auto_x, min_column_width);
|
||||
table->IdealTotalWidth += column_width_ideal;
|
||||
table->ColumnsAutoFitWidth += column_width_ideal;
|
||||
|
||||
if (column->Flags & (ImGuiTableColumnFlags_WidthAlwaysAutoResize | ImGuiTableColumnFlags_WidthFixed))
|
||||
{
|
||||
|
@ -623,6 +624,10 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
|
|||
}
|
||||
}
|
||||
|
||||
// CellSpacingX is >0.0f when there's no vertical border, in which case we add two extra CellSpacingX to make auto-fit look nice instead of cramped.
|
||||
// We may want to expose this somehow.
|
||||
table->ColumnsAutoFitWidth += spacing_auto_x * (table->ColumnsActiveCount - 1);
|
||||
|
||||
// Layout
|
||||
// Remove -1.0f to cancel out the +1.0f we are doing in EndTable() to make last column line visible
|
||||
const float width_spacings = table->CellSpacingX * (table->ColumnsActiveCount - 1);
|
||||
|
@ -956,28 +961,6 @@ void ImGui::EndTable()
|
|||
table->WorkRect.Max.y = ImMax(table->WorkRect.Max.y, table->OuterRect.Max.y);
|
||||
table->LastOuterHeight = table->OuterRect.GetHeight();
|
||||
|
||||
// Store content width reference for each column
|
||||
float max_pos_x = inner_window->DC.CursorMaxPos.x;
|
||||
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
|
||||
{
|
||||
ImGuiTableColumn* column = &table->Columns[column_n];
|
||||
|
||||
// Store content width (for both Headers and Rows)
|
||||
//float ref_x = column->MinX;
|
||||
float ref_x_rows = column->StartXRows - table->CellPaddingX1;
|
||||
float ref_x_headers = column->StartXHeaders - table->CellPaddingX1;
|
||||
column->ContentWidthRowsFrozen = (ImS16)ImMax(0.0f, column->ContentMaxPosRowsFrozen - ref_x_rows);
|
||||
column->ContentWidthRowsUnfrozen = (ImS16)ImMax(0.0f, column->ContentMaxPosRowsUnfrozen - ref_x_rows);
|
||||
column->ContentWidthHeadersUsed = (ImS16)ImMax(0.0f, column->ContentMaxPosHeadersUsed - ref_x_headers);
|
||||
column->ContentWidthHeadersIdeal = (ImS16)ImMax(0.0f, column->ContentMaxPosHeadersIdeal - ref_x_headers);
|
||||
|
||||
// Add an extra 1 pixel so we can see the last column vertical line if it lies on the right-most edge.
|
||||
if (table->ActiveMaskByIndex & ((ImU64)1 << column_n))
|
||||
max_pos_x = ImMax(max_pos_x, column->MaxX + 1.0f);
|
||||
}
|
||||
|
||||
inner_window->DC.CursorMaxPos.x = max_pos_x;
|
||||
|
||||
if (!(flags & ImGuiTableFlags_NoClipX))
|
||||
inner_window->DrawList->PopClipRect();
|
||||
inner_window->ClipRect = inner_window->DrawList->_ClipRectStack.back();
|
||||
|
@ -1015,16 +998,16 @@ void ImGui::EndTable()
|
|||
}
|
||||
|
||||
// Layout in outer window
|
||||
const float backup_outer_cursor_pos_x = outer_window->DC.CursorPos.x;
|
||||
const float backup_outer_max_pos_x = outer_window->DC.CursorMaxPos.x;
|
||||
const float backup_inner_max_pos_x = inner_window->DC.CursorMaxPos.x;
|
||||
inner_window->WorkRect = table->HostWorkRect;
|
||||
inner_window->SkipItems = table->HostSkipItems;
|
||||
outer_window->DC.CursorPos = table->OuterRect.Min;
|
||||
outer_window->DC.ColumnsOffset.x = 0.0f;
|
||||
if (inner_window != outer_window)
|
||||
{
|
||||
// Override EndChild's ItemSize with our own to enable auto-resize on the X axis when possible
|
||||
float backup_outer_cursor_pos_x = outer_window->DC.CursorPos.x;
|
||||
EndChild();
|
||||
outer_window->DC.CursorMaxPos.x = backup_outer_cursor_pos_x + table->ColumnsTotalWidth + 1.0f + inner_window->ScrollbarSizes.x;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1034,6 +1017,38 @@ void ImGui::EndTable()
|
|||
ItemSize(item_size);
|
||||
}
|
||||
|
||||
// Store content width reference for each column
|
||||
float max_pos_x = backup_inner_max_pos_x;
|
||||
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
|
||||
{
|
||||
ImGuiTableColumn* column = &table->Columns[column_n];
|
||||
|
||||
// Store content width (for both Headers and Rows)
|
||||
//float ref_x = column->MinX;
|
||||
float ref_x_rows = column->StartXRows - table->CellPaddingX1;
|
||||
float ref_x_headers = column->StartXHeaders - table->CellPaddingX1;
|
||||
column->ContentWidthRowsFrozen = (ImS16)ImMax(0.0f, column->ContentMaxPosRowsFrozen - ref_x_rows);
|
||||
column->ContentWidthRowsUnfrozen = (ImS16)ImMax(0.0f, column->ContentMaxPosRowsUnfrozen - ref_x_rows);
|
||||
column->ContentWidthHeadersUsed = (ImS16)ImMax(0.0f, column->ContentMaxPosHeadersUsed - ref_x_headers);
|
||||
column->ContentWidthHeadersIdeal = (ImS16)ImMax(0.0f, column->ContentMaxPosHeadersIdeal - ref_x_headers);
|
||||
|
||||
// Add an extra 1 pixel so we can see the last column vertical line if it lies on the right-most edge.
|
||||
if (table->ActiveMaskByIndex & ((ImU64)1 << column_n))
|
||||
max_pos_x = ImMax(max_pos_x, column->MaxX + 1.0f);
|
||||
}
|
||||
|
||||
// Override EndChild/ItemSize max extent with our own to enable auto-resize on the X axis when possible
|
||||
// FIXME-TABLE: This can be improved (e.g. for Fixed columns we don't want to auto AutoFitWidth? or propagate window auto-fit to table?)
|
||||
if (table->Flags & ImGuiTableFlags_ScrollX)
|
||||
{
|
||||
inner_window->DC.CursorMaxPos.x = max_pos_x; // Set contents width for scrolling
|
||||
outer_window->DC.CursorMaxPos.x = ImMax(backup_outer_max_pos_x, backup_outer_cursor_pos_x + table->ColumnsTotalWidth + 1.0f + inner_window->ScrollbarSizes.x); // For auto-fit
|
||||
}
|
||||
else
|
||||
{
|
||||
outer_window->DC.CursorMaxPos.x = ImMax(backup_outer_max_pos_x, table->WorkRect.Min.x + table->ColumnsAutoFitWidth); // For auto-fit
|
||||
}
|
||||
|
||||
// Save settings
|
||||
if (table->IsSettingsDirty)
|
||||
TableSaveSettings(table);
|
||||
|
@ -2571,7 +2586,7 @@ void ImGui::DebugNodeTable(ImGuiTable* table)
|
|||
GetForegroundDrawList()->AddRect(table->OuterRect.Min, table->OuterRect.Max, IM_COL32(255, 255, 0, 255));
|
||||
if (!open)
|
||||
return;
|
||||
BulletText("OuterWidth: %.1f, InnerWidth: %.1f%s, IdealWidth: %.1f", table->OuterRect.GetWidth(), table->InnerWidth, table->InnerWidth == 0.0f ? " (auto)" : "", table->IdealTotalWidth);
|
||||
BulletText("OuterWidth: %.1f, InnerWidth: %.1f%s, ColumnsWidth: %.1f, AutoFitWidth: %.1f", table->OuterRect.GetWidth(), table->InnerWidth, table->InnerWidth == 0.0f ? " (auto)" : "", table->ColumnsTotalWidth, table->ColumnsAutoFitWidth);
|
||||
for (int n = 0; n < table->ColumnsCount; n++)
|
||||
{
|
||||
ImGuiTableColumn* column = &table->Columns[n];
|
||||
|
|
Loading…
Reference in New Issue