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)
This commit is contained in:
ocornut 2020-08-18 18:39:57 +02:00
parent 9372601322
commit 45a80716b1
2 changed files with 16 additions and 7 deletions

View File

@ -542,7 +542,7 @@ struct ImSpanAllocator
int Offsets[CHUNKS]; int Offsets[CHUNKS];
ImSpanAllocator() { memset(this, 0, sizeof(*this)); } 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 int GetArenaSizeInBytes() { return TotalSize; }
inline void SetArenaBasePtr(void* base_ptr) { BasePtr = (char*)base_ptr; } 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]); } 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 HostBackupParentWorkRect; // Backup of InnerWindow->ParentWorkRect at the end of BeginTable()
ImRect HostBackupClipRect; // Backup of InnerWindow->ClipRect during PushTableBackground()/PopTableBackground() ImRect HostBackupClipRect; // Backup of InnerWindow->ClipRect during PushTableBackground()/PopTableBackground()
ImVec2 HostCursorMaxPos; // Backup of InnerWindow->DC.CursorMaxPos at the end of BeginTable() 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* OuterWindow; // Parent window for the table
ImGuiWindow* InnerWindow; // Window holding the table data (== OuterWindow or a child window) ImGuiWindow* InnerWindow; // Window holding the table data (== OuterWindow or a child window)
ImGuiTextBuffer ColumnsNames; // Contiguous buffer holding columns names ImGuiTextBuffer ColumnsNames; // Contiguous buffer holding columns names

View File

@ -261,6 +261,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
table->HostClipRect = inner_window->ClipRect; table->HostClipRect = inner_window->ClipRect;
table->HostSkipItems = inner_window->SkipItems; table->HostSkipItems = inner_window->SkipItems;
table->HostBackupParentWorkRect = inner_window->ParentWorkRect; table->HostBackupParentWorkRect = inner_window->ParentWorkRect;
table->HostBackupColumnsOffset = outer_window->DC.ColumnsOffset;
table->HostCursorMaxPos = inner_window->DC.CursorMaxPos; table->HostCursorMaxPos = inner_window->DC.CursorMaxPos;
inner_window->ParentWorkRect = inner_window->WorkRect; 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.CurrentTableStack.push_back(ImGuiPtrOrIndex(g.Tables.GetIndex(table)));
g.CurrentTable = table; g.CurrentTable = table;
outer_window->DC.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)) if ((table_last_flags & ImGuiTableFlags_Reorderable) && !(flags & ImGuiTableFlags_Reorderable))
table->IsResetDisplayOrderRequest = true; table->IsResetDisplayOrderRequest = true;
@ -1079,7 +1082,7 @@ void ImGui::EndTable()
inner_window->ParentWorkRect = table->HostBackupParentWorkRect; inner_window->ParentWorkRect = table->HostBackupParentWorkRect;
inner_window->SkipItems = table->HostSkipItems; inner_window->SkipItems = table->HostSkipItems;
outer_window->DC.CursorPos = table->OuterRect.Min; 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) if (inner_window != outer_window)
{ {
EndChild(); EndChild();
@ -1110,9 +1113,8 @@ void ImGui::EndTable()
// Clear or restore current table, if any // Clear or restore current table, if any
IM_ASSERT(g.CurrentWindow == outer_window); IM_ASSERT(g.CurrentWindow == outer_window);
IM_ASSERT(g.CurrentTable == table); IM_ASSERT(g.CurrentTable == table);
outer_window->DC.CurrentTable = NULL;
g.CurrentTableStack.pop_back(); 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. // 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); settings = TableSettingsFindByID(table->ID);
if (settings == NULL) if (settings == NULL)
return; 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); table->SettingsOffset = g.SettingsTables.offset_from_ptr(settings);
} }
else else
{ {
settings = TableGetBoundSettings(table); settings = TableGetBoundSettings(table);
} }
table->SettingsLoadedFlags = settings->SaveFlags; table->SettingsLoadedFlags = settings->SaveFlags;
table->RefScale = settings->RefScale; table->RefScale = settings->RefScale;
IM_ASSERT(settings->ColumnsCount == table->ColumnsCount);
// Serialize ImGuiTableSettings/ImGuiTableColumnSettings into ImGuiTable/ImGuiTableColumn // Serialize ImGuiTableSettings/ImGuiTableColumnSettings into ImGuiTable/ImGuiTableColumn
ImGuiTableColumnSettings* column_settings = settings->GetColumnSettings(); ImGuiTableColumnSettings* column_settings = settings->GetColumnSettings();
@ -2772,13 +2776,17 @@ void ImGui::DebugNodeTable(ImGuiTable* table)
char buf[256]; char buf[256];
char* p = buf; char* p = buf;
const char* buf_end = buf + IM_ARRAYSIZE(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); bool open = TreeNode(table, "%s", buf);
if (!is_active) { PopStyleColor(); }
if (IsItemHovered()) if (IsItemHovered())
GetForegroundDrawList()->AddRect(table->OuterRect.Min, table->OuterRect.Max, IM_COL32(255, 255, 0, 255)); GetForegroundDrawList()->AddRect(table->OuterRect.Min, table->OuterRect.Max, IM_COL32(255, 255, 0, 255));
if (!open) if (!open)
return; 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("ColumnsWidth: %.1f, AutoFitWidth: %.1f", table->ColumnsTotalWidth, table->ColumnsAutoFitWidth);
BulletText("HoveredColumnBody: %d, HoveredColumnBorder: %d", table->HoveredColumnBody, table->HoveredColumnBorder); BulletText("HoveredColumnBody: %d, HoveredColumnBorder: %d", table->HoveredColumnBody, table->HoveredColumnBorder);
BulletText("ResizedColumn: %d, ReorderColumn: %d, HeldHeaderColumn: %d", table->ResizedColumn, table->ReorderColumn, table->HeldHeaderColumn); BulletText("ResizedColumn: %d, ReorderColumn: %d, HeldHeaderColumn: %d", table->ResizedColumn, table->ReorderColumn, table->HeldHeaderColumn);