From 104ec408a890a56778e9980dd5ae3790b71ab4cf Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 6 Feb 2020 18:34:37 +0100 Subject: [PATCH] Tables: Fixed content size calculation creating feedback loops. Fixed handling of _DefaultSort with _PreferSortXXXflags (@parbo). Comments. --- imgui.h | 4 ++-- imgui_demo.cpp | 2 +- imgui_tables.cpp | 13 ++++++++++--- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/imgui.h b/imgui.h index 47dfe1b9b..3be894f89 100644 --- a/imgui.h +++ b/imgui.h @@ -1066,9 +1066,9 @@ enum ImGuiTableColumnFlags_ ImGuiTableColumnFlags_None = 0, ImGuiTableColumnFlags_DefaultHide = 1 << 0, // Default as a hidden column. ImGuiTableColumnFlags_DefaultSort = 1 << 1, // Default as a sorting column. - ImGuiTableColumnFlags_WidthFixed = 1 << 2, // Column will keep a fixed size, preferable with horizontal scrolling enabled (default if table sizing policy is SizingPolicyFixedX). + ImGuiTableColumnFlags_WidthFixed = 1 << 2, // Column will keep a fixed size, preferable with horizontal scrolling enabled (default if table sizing policy is SizingPolicyFixedX and table is resizable). ImGuiTableColumnFlags_WidthStretch = 1 << 3, // Column will stretch, preferable with horizontal scrolling disabled (default if table sizing policy is SizingPolicyStretchX). - ImGuiTableColumnFlags_WidthAlwaysAutoResize = 1 << 4, // Column will keep resizing based on submitted contents (with a one frame delay) == Fixed with auto resize + ImGuiTableColumnFlags_WidthAlwaysAutoResize = 1 << 4, // Column will keep resizing based on submitted contents (with a one frame delay) == Fixed with auto resize (default if table sizing policy is SizingPolicyFixedX and table is not resizable). ImGuiTableColumnFlags_NoResize = 1 << 5, // Disable manual resizing. ImGuiTableColumnFlags_NoClipX = 1 << 6, // Disable clipping for this column (all NoClipX columns will render in a same draw command). ImGuiTableColumnFlags_NoSort = 1 << 7, // Disable ability to sort on this field (even if ImGuiTableFlags_Sortable is set on the table). diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 4ee5b0f75..22338f79c 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -3795,7 +3795,7 @@ static void ShowDemoWindowTables() case CT_LongText: ImGui::Text("Some longer text %d,%d\nOver two lines..", row, column); break; case CT_Button: ImGui::Button(label); break; case CT_StretchButton: ImGui::Button(label, ImVec2(-FLT_MIN, 0.0f)); break; - case CT_InputText: ImGui::SetNextItemWidth(-FLT_MIN); ImGui::InputText(label, text_buf, IM_ARRAYSIZE(text_buf)); break; + case CT_InputText: ImGui::SetNextItemWidth(-FLT_MIN); ImGui::InputText("##", text_buf, IM_ARRAYSIZE(text_buf)); break; } } } diff --git a/imgui_tables.cpp b/imgui_tables.cpp index 0f3475bb7..9798f432f 100644 --- a/imgui_tables.cpp +++ b/imgui_tables.cpp @@ -487,6 +487,7 @@ static ImGuiTableColumnFlags TableFixColumnFlags(ImGuiTable* table, ImGuiTableCo // Sizing Policy if ((flags & ImGuiTableColumnFlags_WidthMask_) == 0) { + // FIXME-TABLE: Inconsistent to promote columns to WidthAlwaysAutoResize if (table->Flags & ImGuiTableFlags_SizingPolicyFixedX) flags |= ((table->Flags & ImGuiTableFlags_Resizable) && !(flags & ImGuiTableColumnFlags_NoResize)) ? ImGuiTableColumnFlags_WidthFixed : ImGuiTableColumnFlags_WidthAlwaysAutoResize; else @@ -536,7 +537,7 @@ void ImGui::TableUpdateLayout(ImGuiTable* table) // Compute offset, clip rect for the frame const ImRect work_rect = table->WorkRect; - const float padding_auto_x = table->CellPaddingX1; // Can't make auto padding larger than what WorkRect knows about so right-alignment matches. + const float padding_auto_x = table->CellPaddingX2; // Can't make auto padding larger than what WorkRect knows about so right-alignment matches. const float min_column_width = TableGetMinColumnWidth(); int count_fixed = 0; @@ -595,12 +596,13 @@ void ImGui::TableUpdateLayout(ImGuiTable* table) } // 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); float width_avail; if ((table->Flags & ImGuiTableFlags_ScrollX) && (table->InnerWidth == 0.0f)) width_avail = table->InnerClipRect.GetWidth() - width_spacings - 1.0f; else - width_avail = work_rect.GetWidth() - width_spacings - 1.0f; // Remove -1.0f to cancel out the +1.0f we are doing in EndTable() to make last column line visible + width_avail = work_rect.GetWidth() - width_spacings - 1.0f; const float width_avail_for_stretched_columns = width_avail - width_fixed; float width_remaining_for_stretched_columns = width_avail_for_stretched_columns; @@ -1406,7 +1408,10 @@ void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags, if (flags & ImGuiTableColumnFlags_DefaultHide) column->IsActive = column->NextIsActive = false; if (flags & ImGuiTableColumnFlags_DefaultSort) + { column->SortOrder = 0; // Multiple columns using _DefaultSort will be reordered when building the sort specs. + column->SortDirection = (column->Flags & ImGuiTableColumnFlags_PreferSortDescending) ? (ImS8)ImGuiSortDirection_Descending : (ImU8)(ImGuiSortDirection_Ascending); + } } // Store name (append with zero-terminator in contiguous buffer) @@ -2090,7 +2095,7 @@ void ImGui::TableSortSpecsClickColumn(ImGuiTable* table, ImGuiTableColumn* click table->IsSortSpecsDirty = true; } -// Return NULL if no sort specs. +// Return NULL if no sort specs (most often when ImGuiTableFlags_Sortable is not set) // You can sort your data again when 'SpecsChanged == true'. It will be true with sorting specs have changed since last call, or the first time. // Lifetime: don't hold on this pointer over multiple frames or past any subsequent call to BeginTable()! const ImGuiTableSortSpecs* ImGui::TableGetSortSpecs() @@ -2439,10 +2444,12 @@ void ImGui::DebugNodeTable(ImGuiTable* table) BulletText("Column %d order %d name '%s': +%.1f to +%.1f\n" "Active: %d, Clipped: %d, DrawChannels: %d,%d\n" "WidthGiven/Requested: %.1f/%.1f, Weight: %.2f\n" + "ContentWidth: RowsFrozen %d, RowsUnfrozen %d, HeadersUsed/Desired %d/%d\n" "UserID: 0x%08X, Flags: 0x%04X: %s%s%s%s..", n, column->IndexDisplayOrder, name ? name : "NULL", column->MinX - table->WorkRect.Min.x, column->MaxX - table->WorkRect.Min.x, column->IsActive, column->IsClipped, column->DrawChannelRowsBeforeFreeze, column->DrawChannelRowsAfterFreeze, column->WidthGiven, column->WidthRequested, column->ResizeWeight, + column->ContentWidthRowsFrozen, column->ContentWidthRowsUnfrozen, column->ContentWidthHeadersUsed, column->ContentWidthHeadersDesired, column->UserID, column->Flags, (column->Flags & ImGuiTableColumnFlags_WidthFixed) ? "WidthFixed " : "", (column->Flags & ImGuiTableColumnFlags_WidthStretch) ? "WidthStretch " : "",