From 416e9bb38d14b52f624ee6f878da670a612bbaa8 Mon Sep 17 00:00:00 2001 From: omar Date: Fri, 3 Jan 2020 00:31:06 +0100 Subject: [PATCH] Tables: Clarify internal calculations of row height so that TableGetCellRect() include expected paddings. Add demo code. Comments. Remove misleading commented-out flags for now. --- imgui.h | 4 ---- imgui_demo.cpp | 21 +++++++++++++++++++++ imgui_tables.cpp | 20 ++++++++++++-------- 3 files changed, 33 insertions(+), 12 deletions(-) diff --git a/imgui.h b/imgui.h index 006f4ee9c..3577fe285 100644 --- a/imgui.h +++ b/imgui.h @@ -1081,10 +1081,6 @@ enum ImGuiTableColumnFlags_ // [Internal] Combinations and masks ImGuiTableColumnFlags_WidthMask_ = ImGuiTableColumnFlags_WidthFixed | ImGuiTableColumnFlags_WidthStretch | ImGuiTableColumnFlags_WidthAlwaysAutoResize, ImGuiTableColumnFlags_NoDirectResize_ = 1 << 20 // [Internal] Disable user resizing this column directly (it may however we resized indirectly from its left edge) - //ImGuiTableColumnFlags_AlignLeft = 1 << 14, - //ImGuiTableColumnFlags_AlignCenter = 1 << 15, - //ImGuiTableColumnFlags_AlignRight = 1 << 16, - //ImGuiTableColumnFlags_AlignMask_ = ImGuiTableColumnFlags_AlignLeft | ImGuiTableColumnFlags_AlignCenter | ImGuiTableColumnFlags_AlignRight }; // Flags for ImGui::TableNextRow() diff --git a/imgui_demo.cpp b/imgui_demo.cpp index 10c67cbf9..25d035b5e 100644 --- a/imgui_demo.cpp +++ b/imgui_demo.cpp @@ -3842,6 +3842,27 @@ static void ShowDemoWindowTables() ImGui::TreePop(); } + if (open_action != -1) + ImGui::SetNextItemOpen(open_action != 0); + if (ImGui::TreeNode("Row height")) + { + HelpMarker("You can pass a 'min_row_height' to TableNextRow().\n\nRows are padded with 'style.CellPadding.y' on top and bottom, so effectively the minimum row height will always be >= 'style.CellPadding.y * 2.0f'.\n\nWe cannot honor a _maximum_ row height as that would requires a unique clipping rectangle per row."); + if (ImGui::BeginTable("##2ways", 2, ImGuiTableFlags_Borders)) + { + float min_row_height = ImGui::GetFontSize() + ImGui::GetStyle().CellPadding.y * 2.0f; + ImGui::TableNextRow(ImGuiTableRowFlags_None, min_row_height); + ImGui::Text("min_row_height = %.2f", min_row_height); + for (int row = 0; row < 10; row++) + { + min_row_height = (float)(int)(ImGui::GetFontSize() * 0.30f * row); + ImGui::TableNextRow(ImGuiTableRowFlags_None, min_row_height); + ImGui::Text("min_row_height = %.2f", min_row_height); + } + ImGui::EndTable(); + } + ImGui::TreePop(); + } + static const char* template_items_names[] = { "Banana", "Apple", "Cherry", "Watermelon", "Grapefruit", "Strawberry", "Mango", diff --git a/imgui_tables.cpp b/imgui_tables.cpp index 2bac1155c..d33654c9f 100644 --- a/imgui_tables.cpp +++ b/imgui_tables.cpp @@ -724,9 +724,9 @@ void ImGui::TableUpdateLayout(ImGuiTable* table) // FIXME-TABLE: This align based on the whole column width, not per-cell, and therefore isn't useful in many cases. // (To be able to honor this we might be able to store a log of cells width, per row, for visible rows, but nav/programmatic scroll would have visible artifacts.) //if (column->Flags & ImGuiTableColumnFlags_AlignRight) - // column->StartXRows = ImMax(column->StartXRows, column->MaxX - column->WidthContent[0]); + // column->StartXRows = ImMax(column->StartXRows, column->MaxX - column->ContentWidthRowsUnfrozen); //else if (column->Flags & ImGuiTableColumnFlags_AlignCenter) - // column->StartXRows = ImLerp(column->StartXRows, ImMax(column->StartXRows, column->MaxX - column->WidthContent[0]), 0.5f); + // column->StartXRows = ImLerp(column->StartXRows, ImMax(column->StartXRows, column->MaxX - column->ContentWidthRowsUnfrozen), 0.5f); // Reset content width variables const float initial_max_pos_x = column->MinX + table->CellPaddingX1; @@ -1401,8 +1401,10 @@ void ImGui::TableNextRow(ImGuiTableRowFlags row_flags, float min_row_height) table->RowFlags = row_flags; TableBeginRow(table); - // We honor min_height requested by user, but cannot guarantee per-row maximum height as that would essentially require a unique clipping rectangle per-cell. - table->RowPosY2 += min_row_height; + // We honor min_row_height requested by user, but cannot guarantee per-row maximum height, + // because that would essentially require a unique clipping rectangle per-cell. + table->RowPosY2 += table->CellPaddingY * 2.0f; + table->RowPosY2 = ImMax(table->RowPosY2, table->RowPosY1 + min_row_height); TableBeginCell(table, 0); } @@ -1447,8 +1449,6 @@ void ImGui::TableEndRow(ImGuiTable* table) TableEndCell(table); - table->RowPosY2 += table->CellPaddingY; - // Position cursor at the bottom of our row so it can be used for e.g. clipping calculation. // However it is likely that the next call to TableBeginCell() will reposition the cursor to take account of vertical padding. window->DC.CursorPos.y = table->RowPosY2; @@ -1605,7 +1605,7 @@ void ImGui::TableEndCell(ImGuiTable* table) else p_max_pos_x = table->IsFreezeRowsPassed ? &column->ContentMaxPosRowsUnfrozen : &column->ContentMaxPosRowsFrozen; *p_max_pos_x = ImMax(*p_max_pos_x, window->DC.CursorMaxPos.x); - table->RowPosY2 = ImMax(table->RowPosY2, window->DC.CursorMaxPos.y); + table->RowPosY2 = ImMax(table->RowPosY2, window->DC.CursorMaxPos.y + table->CellPaddingY); // Propagate text baseline for the entire row // FIXME-TABLE: Here we propagate text baseline from the last line of the cell.. instead of the first one. @@ -1682,6 +1682,9 @@ bool ImGui::TableSetColumnIndex(int column_idx) return (table->VisibleMaskByIndex & ((ImU64)1 << column_idx)) != 0; } +// Return the cell rectangle based on currently known height. +// Important: we generally don't know our row height until the end of the row, so Max.y will be incorrect in many situations. +// The only case where this is correct is if we provided a min_row_height to TableNextRow() and don't go below it. ImRect ImGui::TableGetCellRect() { ImGuiContext& g = *GImGui; @@ -1805,7 +1808,7 @@ void ImGui::TableAutoHeaders() ImGuiTable* table = g.CurrentTable; IM_ASSERT(table != NULL && "Need to call TableAutoHeaders() after BeginTable()!"); - TableNextRow(ImGuiTableRowFlags_Headers, GetTextLineHeight()); + TableNextRow(ImGuiTableRowFlags_Headers, GetTextLineHeight() + g.Style.CellPadding.y * 2.0f); if (window->SkipItems) return; @@ -1909,6 +1912,7 @@ void ImGui::TableHeader(const char* label) float row_height = GetTextLineHeight(); ImRect cell_r = TableGetCellRect(); + //GetForegroundDrawList()->AddRect(cell_r.Min, cell_r.Max, IM_COL32(255, 0, 0, 255)); // [DEBUG] ImRect work_r = cell_r; work_r.Min.x = window->DC.CursorPos.x; work_r.Max.y = work_r.Min.y + row_height;