From 45a80716b19a3a8695e3fd9c0b1e0deaad97f1f7 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 18 Aug 2020 18:39:57 +0200 Subject: [PATCH] Tables: Fixed three bugs + metrics tweaks. - Fixed bug when ending a table within another (outer table column offset was overwritten instead of restored). - Fixed assert when settings data has mismatching column count. - Fixed restoring g.CurrentTable when calling EndChild() from inside table inner window. - Made inactive tables grey in metrics. - Fix warning. (amended twice) --- imgui_internal.h | 3 ++- imgui_tables.cpp | 20 ++++++++++++++------ 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/imgui_internal.h b/imgui_internal.h index 73c7ba58..ed7b465d 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -542,7 +542,7 @@ struct ImSpanAllocator int Offsets[CHUNKS]; ImSpanAllocator() { memset(this, 0, sizeof(*this)); } - inline void ReserveBytes(int n, size_t sz) { IM_ASSERT(n == CurrSpan && n < CHUNKS); Offsets[CurrSpan++] = TotalSize; TotalSize += (int)sz; } + inline void ReserveBytes(int n, size_t sz) { IM_ASSERT(n == CurrSpan && n < CHUNKS); IM_UNUSED(n); Offsets[CurrSpan++] = TotalSize; TotalSize += (int)sz; } inline int GetArenaSizeInBytes() { return TotalSize; } inline void SetArenaBasePtr(void* base_ptr) { BasePtr = (char*)base_ptr; } inline void* GetSpanPtrBegin(int n) { IM_ASSERT(n >= 0 && n < CHUNKS && CurrSpan == CHUNKS); return (void*)(BasePtr + Offsets[n]); } @@ -2004,6 +2004,7 @@ struct ImGuiTable ImRect HostBackupParentWorkRect; // Backup of InnerWindow->ParentWorkRect at the end of BeginTable() ImRect HostBackupClipRect; // Backup of InnerWindow->ClipRect during PushTableBackground()/PopTableBackground() ImVec2 HostCursorMaxPos; // Backup of InnerWindow->DC.CursorMaxPos at the end of BeginTable() + ImVec1 HostBackupColumnsOffset; // Backup of OuterWindow->ColumnsOffset at the end of BeginTable() ImGuiWindow* OuterWindow; // Parent window for the table ImGuiWindow* InnerWindow; // Window holding the table data (== OuterWindow or a child window) ImGuiTextBuffer ColumnsNames; // Contiguous buffer holding columns names diff --git a/imgui_tables.cpp b/imgui_tables.cpp index ad98797a..1d66501a 100644 --- a/imgui_tables.cpp +++ b/imgui_tables.cpp @@ -261,6 +261,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG table->HostClipRect = inner_window->ClipRect; table->HostSkipItems = inner_window->SkipItems; table->HostBackupParentWorkRect = inner_window->ParentWorkRect; + table->HostBackupColumnsOffset = outer_window->DC.ColumnsOffset; table->HostCursorMaxPos = inner_window->DC.CursorMaxPos; inner_window->ParentWorkRect = inner_window->WorkRect; @@ -305,6 +306,8 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG g.CurrentTableStack.push_back(ImGuiPtrOrIndex(g.Tables.GetIndex(table))); g.CurrentTable = table; outer_window->DC.CurrentTable = table; + if (inner_window != outer_window) // So EndChild() within the inner window can restore the table properly. + inner_window->DC.CurrentTable = table; if ((table_last_flags & ImGuiTableFlags_Reorderable) && !(flags & ImGuiTableFlags_Reorderable)) table->IsResetDisplayOrderRequest = true; @@ -1079,7 +1082,7 @@ void ImGui::EndTable() inner_window->ParentWorkRect = table->HostBackupParentWorkRect; inner_window->SkipItems = table->HostSkipItems; outer_window->DC.CursorPos = table->OuterRect.Min; - outer_window->DC.ColumnsOffset.x = 0.0f; + outer_window->DC.ColumnsOffset = table->HostBackupColumnsOffset; if (inner_window != outer_window) { EndChild(); @@ -1110,9 +1113,8 @@ void ImGui::EndTable() // Clear or restore current table, if any IM_ASSERT(g.CurrentWindow == outer_window); IM_ASSERT(g.CurrentTable == table); - outer_window->DC.CurrentTable = NULL; g.CurrentTableStack.pop_back(); - g.CurrentTable = g.CurrentTableStack.Size ? g.Tables.GetByIndex(g.CurrentTableStack.back().Index) : NULL; + outer_window->DC.CurrentTable = g.CurrentTable = g.CurrentTableStack.Size ? g.Tables.GetByIndex(g.CurrentTableStack.back().Index) : NULL; } // FIXME-TABLE: This is a mess, need to redesign how we render borders. @@ -2601,15 +2603,17 @@ void ImGui::TableLoadSettings(ImGuiTable* table) settings = TableSettingsFindByID(table->ID); if (settings == NULL) return; + if (settings->ColumnsCount != table->ColumnsCount) // Allow settings if columns count changed. We could otherwise decide to return... + table->IsSettingsDirty = true; table->SettingsOffset = g.SettingsTables.offset_from_ptr(settings); } else { settings = TableGetBoundSettings(table); } + table->SettingsLoadedFlags = settings->SaveFlags; table->RefScale = settings->RefScale; - IM_ASSERT(settings->ColumnsCount == table->ColumnsCount); // Serialize ImGuiTableSettings/ImGuiTableColumnSettings into ImGuiTable/ImGuiTableColumn ImGuiTableColumnSettings* column_settings = settings->GetColumnSettings(); @@ -2772,13 +2776,17 @@ void ImGui::DebugNodeTable(ImGuiTable* table) char buf[256]; char* p = buf; const char* buf_end = buf + IM_ARRAYSIZE(buf); - ImFormatString(p, buf_end - p, "Table 0x%08X (%d columns, in '%s')", table->ID, table->ColumnsCount, table->OuterWindow->Name); + const bool is_active = (table->LastFrameActive >= ImGui::GetFrameCount() - 2); + ImFormatString(p, buf_end - p, "Table 0x%08X (%d columns, in '%s')%s", table->ID, table->ColumnsCount, table->OuterWindow->Name, is_active ? "" : " *Inactive*"); + if (!is_active) { PushStyleColor(ImGuiCol_Text, GetStyleColorVec4(ImGuiCol_TextDisabled)); } bool open = TreeNode(table, "%s", buf); + if (!is_active) { PopStyleColor(); } if (IsItemHovered()) GetForegroundDrawList()->AddRect(table->OuterRect.Min, table->OuterRect.Max, IM_COL32(255, 255, 0, 255)); if (!open) return; - BulletText("OuterWidth: %.1f, InnerWidth: %.1f%s", table->OuterRect.GetWidth(), table->InnerWidth, table->InnerWidth == 0.0f ? " (auto)" : ""); + BulletText("OuterRect: Pos: (%.1f,%.1f) Size: (%.1f,%.1f)", table->OuterRect.Min.x, table->OuterRect.Min.y, table->OuterRect.GetWidth(), table->OuterRect.GetHeight()); + BulletText("InnerWidth: %.1f%s", table->InnerWidth, table->InnerWidth == 0.0f ? " (auto)" : ""); BulletText("ColumnsWidth: %.1f, AutoFitWidth: %.1f", table->ColumnsTotalWidth, table->ColumnsAutoFitWidth); BulletText("HoveredColumnBody: %d, HoveredColumnBorder: %d", table->HoveredColumnBody, table->HoveredColumnBorder); BulletText("ResizedColumn: %d, ReorderColumn: %d, HeldHeaderColumn: %d", table->ResizedColumn, table->ReorderColumn, table->HeldHeaderColumn);