From 3fbb928c9f91c80b4ae7de679bf80f078d4fdf6e Mon Sep 17 00:00:00 2001 From: ocornut Date: Wed, 23 Dec 2020 12:11:39 +0100 Subject: [PATCH] Tables: explicit/custom width in TableSetupColumn() is reapplied when table or column becomes not resizable. Comments. --- imgui.h | 3 ++- imgui_demo.cpp | 1 + imgui_tables.cpp | 42 +++++++++++++++++++++++++++--------------- 3 files changed, 30 insertions(+), 16 deletions(-) diff --git a/imgui.h b/imgui.h index f3d05e62..43a05ed3 100644 --- a/imgui.h +++ b/imgui.h @@ -1049,11 +1049,12 @@ enum ImGuiTabItemFlags_ // The typical use of mixing sizing policies is: any number of LEADING Fixed columns, followed by one or two TRAILING Stretch columns. // (this is because the visible order of columns have subtle but necessary effects on how they react to manual resizing). // - When ScrollX is on: -// - Table defaults to ImGuiTableFlags_ColumnsWidthFixed -> all Columns defaults to ImGuiTableColumnFlags_WidthFixed or ImGuiTableColumnFlags_WidthAuto +// - Table defaults to ImGuiTableFlags_ColumnsWidthFixed -> all Columns defaults to ImGuiTableColumnFlags_WidthFixed or ImGuiTableColumnFlags_WidthAuto. // - Columns sizing policy allowed: Fixed/Auto mostly. // - Fixed Columns can be enlarged as needed. Table will show an horizontal scrollbar if needed. // - Using Stretch columns OFTEN DOES NOT MAKE SENSE if ScrollX is on, UNLESS you have specified a value for 'inner_width' in BeginTable(). // If you specify a value for 'inner_width' then effectively the scrolling space is known and Stretch or mixed Fixed/Stretch columns become meaningful again. +// - Read on documentation at the top of imgui_tables.cpp for details. enum ImGuiTableFlags_ { // Features diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 804fa084..2e2ee67c 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -3912,6 +3912,7 @@ static void ShowDemoWindowTables() static int freeze_rows = 1; PushStyleCompact(); + ImGui::CheckboxFlags("ImGuiTableFlags_Resizable", &flags, ImGuiTableFlags_Resizable); ImGui::CheckboxFlags("ImGuiTableFlags_ScrollX", &flags, ImGuiTableFlags_ScrollX); ImGui::CheckboxFlags("ImGuiTableFlags_ScrollY", &flags, ImGuiTableFlags_ScrollY); ImGui::SetNextItemWidth(ImGui::GetFrameHeight()); diff --git a/imgui_tables.cpp b/imgui_tables.cpp index f03c99e6..a508dde5 100644 --- a/imgui_tables.cpp +++ b/imgui_tables.cpp @@ -97,6 +97,25 @@ Index of this file: // of what the value does. //----------------------------------------------------------------------------- +//----------------------------------------------------------------------------- +// COLUMNS SIZING POLICIES +//----------------------------------------------------------------------------- +// About overriding column width/weight with TableSetupColumn(): +// We use a default parameter of 'init_width_or_weight == -1'. +// - With ImGuiTableColumnFlags_WidthAuto, init_width (ignored) --> width is automatic +// - With ImGuiTableColumnFlags_WidthFixed, init_width <= 0 (default) --> width is automatic +// - With ImGuiTableColumnFlags_WidthFixed, init_width > 0 (explicit) --> width is custom +// - With ImGuiTableColumnFlags_WidthStretch, init_weight <= 0 (default) --> weight is 1.0f +// - With ImGuiTableColumnFlags_WidthStretch, init_weight > 0 (explicit) --> weight is custom +// Widths are specified _without_ CellPadding. If you specify a width of 100.0f, the column will be cover (100.0f + Padding * 2.0f) +// and you can fit a 100.0f wide item in it without clipping and with full padding. +//----------------------------------------------------------------------------- +// About default width policy (if you don't specify a ImGuiTableColumnFlags_WidthXXXX flag) +// - When Table policy ImGuiTableFlags_ColumnsWidthStretch --> default Column policy is ImGuiTableColumnFlags_WidthStretch +// - When Table policy ImGuiTableFlags_ColumnsWidthFixed and (Table is Resizable or init_width > 0) --> default Column policy is ImGuiTableColumnFlags_WidthFixed +// - When Table policy ImGuiTableFlags_ColumnsWidthFixed and (Table is not Resizable and init_width <= 0) --> default Column policy is ImGuiTableColumnFlags_WidthAuto +//----------------------------------------------------------------------------- + //----------------------------------------------------------------------------- // TABLES CLIPPING/CULLING //----------------------------------------------------------------------------- @@ -730,19 +749,17 @@ void ImGui::TableUpdateLayout(ImGuiTable* table) float width_auto = content_width_body; if (!(column->Flags & ImGuiTableColumnFlags_NoHeaderWidth)) width_auto = ImMax(width_auto, content_width_headers); - width_auto = ImMax(width_auto, min_column_width); - - // Non-resizable columns also submit their requested width - if ((column->Flags & ImGuiTableColumnFlags_WidthFixed) && column->InitStretchWeightOrWidth > 0.0f) - if (!(table->Flags & ImGuiTableFlags_Resizable) || (column->Flags & ImGuiTableColumnFlags_NoResize)) - width_auto = ImMax(width_auto, column->InitStretchWeightOrWidth); - - column->WidthAuto = width_auto; + column->WidthAuto = ImMax(width_auto, min_column_width); } column->IsPreserveWidthAuto = false; if (column->Flags & (ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_WidthAuto)) { + // Non-resizable columns keep their requested width + if ((column->Flags & ImGuiTableColumnFlags_WidthFixed) && column->InitStretchWeightOrWidth > 0.0f) + if (!(table->Flags & ImGuiTableFlags_Resizable) || (column->Flags & ImGuiTableColumnFlags_NoResize)) + column->WidthRequest = column->WidthAuto = ImMax(column->WidthAuto, column->InitStretchWeightOrWidth); + // Process auto-fit for non-stretched columns // Latch initial size for fixed columns and update it constantly for auto-resizing column (unless clipped!) if ((column->AutoFitQueue != 0x00) || ((column->Flags & ImGuiTableColumnFlags_WidthAuto) && column->IsVisibleX)) @@ -1258,12 +1275,7 @@ void ImGui::EndTable() outer_window->DC.CurrentTableIdx = g.CurrentTable ? g.Tables.GetIndex(g.CurrentTable) : -1; } -// We use a default parameter of 'init_width_or_weight == -1', -// - with ImGuiTableColumnFlags_WidthFixed, width <= 0 --> init width == auto -// - with ImGuiTableColumnFlags_WidthFixed, width > 0 --> init width == manual -// - with ImGuiTableColumnFlags_WidthStretch, weight < 0 --> init weight == 1.0f -// - with ImGuiTableColumnFlags_WidthStretch, weight >= 0 --> init weight == custom -// Widths are specified _without_ CellPadding. So if you specify a width of 100.0f the column will be 100.0f+Padding*2.0f and you can fit a 100.0-wide item in it. +// See "COLUMN SIZING POLICIES" comments at the top of this file void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, float init_width_or_weight, ImGuiID user_id) { ImGuiContext& g = *GImGui; @@ -1281,7 +1293,7 @@ void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, flo table->DeclColumnsCount++; // When passing a width automatically enforce WidthFixed policy - // (whereas TableSetupColumnFlags would default to WidthAuto) + // (whereas TableSetupColumnFlags would default to WidthAuto if table is not Resizable) if ((flags & ImGuiTableColumnFlags_WidthMask_) == 0) if ((table->Flags & ImGuiTableFlags_ColumnsWidthFixed) && (init_width_or_weight > 0.0f)) flags |= ImGuiTableColumnFlags_WidthFixed;