From b7fa96679e96e46c968df66f4204668b2aec2d0d Mon Sep 17 00:00:00 2001 From: omar Date: Thu, 19 Mar 2020 14:55:42 +0100 Subject: [PATCH] Tables: Locking IndentX per-row so multiple columns with IndentEnabled don't get indent shearing. --- imgui_internal.h | 8 ++++---- imgui_tables.cpp | 26 ++++++++++++++------------ 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/imgui_internal.h b/imgui_internal.h index 789e71a10..bb4e4b2ec 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -1941,7 +1941,6 @@ struct ImGuiTableColumn } }; -// FIXME-OPT: Since CountColumns is invariant, we could use a single alloc for ImGuiTable + the three vectors it is carrying. struct ImGuiTable { ImGuiID ID; @@ -1965,6 +1964,7 @@ struct ImGuiTable float RowPosY2; float RowMinHeight; // Height submitted to TableNextRow() float RowTextBaseline; + float RowIndentOffsetX; ImGuiTableRowFlags RowFlags : 16; // Current row flags, see ImGuiTableRowFlags_ ImGuiTableRowFlags LastRowFlags : 16; int RowBgColorCounter; // Counter for alternating background colors (can be fast-forwarded by e.g clipper) @@ -2259,11 +2259,11 @@ namespace ImGui IMGUI_API void TableSortSpecsSanitize(ImGuiTable* table); IMGUI_API void TableBeginRow(ImGuiTable* table); IMGUI_API void TableEndRow(ImGuiTable* table); - IMGUI_API void TableBeginCell(ImGuiTable* table, int column_no); + IMGUI_API void TableBeginCell(ImGuiTable* table, int column_n); IMGUI_API void TableEndCell(ImGuiTable* table); IMGUI_API ImRect TableGetCellRect(); - IMGUI_API const char* TableGetColumnName(ImGuiTable* table, int column_no); - IMGUI_API void TableSetColumnAutofit(ImGuiTable* table, int column_no); + IMGUI_API const char* TableGetColumnName(ImGuiTable* table, int column_n); + IMGUI_API void TableSetColumnAutofit(ImGuiTable* table, int column_n); IMGUI_API void PushTableBackground(); IMGUI_API void PopTableBackground(); IMGUI_API void TableLoadSettings(ImGuiTable* table); diff --git a/imgui_tables.cpp b/imgui_tables.cpp index f79bc73d7..123b886de 100644 --- a/imgui_tables.cpp +++ b/imgui_tables.cpp @@ -1492,6 +1492,7 @@ void ImGui::TableBeginRow(ImGuiTable* table) table->RowPosY1 = table->RowPosY2 = next_y1; table->RowTextBaseline = 0.0f; + table->RowIndentOffsetX = window->DC.Indent.x - table->HostIndentX; // Lock indent window->DC.PrevLineTextBaseOffset = 0.0f; window->DC.CursorMaxPos.y = next_y1; @@ -1611,25 +1612,26 @@ void ImGui::TableEndRow(ImGuiTable* table) table->IsInsideRow = false; } -// [Internal] Called by TableNextRow()TableNextCell()! -// This is called a lot, so we need to be mindful of unnecessary overhead. +// [Internal] Called by TableNextCell()! +// This is called very frequently, so we need to be mindful of unnecessary overhead. // FIXME-TABLE FIXME-OPT: Could probably shortcut some things for non-active or clipped columns. -void ImGui::TableBeginCell(ImGuiTable* table, int column_no) +void ImGui::TableBeginCell(ImGuiTable* table, int column_n) { - table->CurrentColumn = column_no; - ImGuiTableColumn* column = &table->Columns[column_no]; + table->CurrentColumn = column_n; + ImGuiTableColumn* column = &table->Columns[column_n]; ImGuiWindow* window = table->InnerWindow; + // Start position is roughly ~~ CellRect.Min + CellPadding + Indent float start_x = (table->RowFlags & ImGuiTableRowFlags_Headers) ? column->StartXHeaders : column->StartXRows; if (column->Flags & ImGuiTableColumnFlags_IndentEnable) - start_x += window->DC.Indent.x - table->HostIndentX; + start_x += table->RowIndentOffsetX; // ~~ += window.DC.Indent.x - table->HostIndentX, except we locked it for the row. - window->DC.LastItemId = 0; window->DC.CursorPos.x = start_x; window->DC.CursorPos.y = table->RowPosY1 + table->CellPaddingY; window->DC.CursorMaxPos.x = window->DC.CursorPos.x; window->DC.ColumnsOffset.x = start_x - window->Pos.x - window->DC.Indent.x; // FIXME-WORKRECT window->DC.CurrLineTextBaseOffset = table->RowTextBaseline; + window->DC.LastItemId = 0; window->WorkRect.Min.y = window->DC.CursorPos.y; window->WorkRect.Min.x = column->MinX + table->CellPaddingX1; @@ -1653,7 +1655,7 @@ void ImGui::TableBeginCell(ImGuiTable* table, int column_no) //window->DrawList->UpdateClipRect(); window->DrawList->PopClipRect(); window->DrawList->PushClipRect(column->ClipRect.Min, column->ClipRect.Max, false); - //IMGUI_DEBUG_LOG("%d (%.0f,%.0f)(%.0f,%.0f)\n", column_no, column->ClipRect.Min.x, column->ClipRect.Min.y, column->ClipRect.Max.x, column->ClipRect.Max.y); + //IMGUI_DEBUG_LOG("%d (%.0f,%.0f)(%.0f,%.0f)\n", column_n, column->ClipRect.Min.x, column->ClipRect.Min.y, column->ClipRect.Max.x, column->ClipRect.Max.y); window->ClipRect = window->DrawList->_ClipRectStack.back(); } } @@ -1759,19 +1761,19 @@ ImRect ImGui::TableGetCellRect() return ImRect(column->MinX, table->RowPosY1, column->MaxX, table->RowPosY2); } -const char* ImGui::TableGetColumnName(ImGuiTable* table, int column_no) +const char* ImGui::TableGetColumnName(ImGuiTable* table, int column_n) { - ImGuiTableColumn* column = &table->Columns[column_no]; + ImGuiTableColumn* column = &table->Columns[column_n]; if (column->NameOffset == -1) return NULL; return &table->ColumnsNames.Buf[column->NameOffset]; } -void ImGui::TableSetColumnAutofit(ImGuiTable* table, int column_no) +void ImGui::TableSetColumnAutofit(ImGuiTable* table, int column_n) { // Disable clipping then auto-fit, will take 2 frames // (we don't take a shortcut for unclipped columns to reduce inconsistencies when e.g. resizing multiple columns) - ImGuiTableColumn* column = &table->Columns[column_no]; + ImGuiTableColumn* column = &table->Columns[column_n]; column->CannotSkipItemsQueue = (1 << 0); column->AutoFitQueue = (1 << 1); }