Tables: Added TableSetBgColor() api with color for RowBg and CellBg colors.

This commit is contained in:
omar
2020-07-28 15:53:14 +02:00
committed by ocornut
parent b6405a291d
commit 9d8b40414a
4 changed files with 172 additions and 26 deletions

View File

@ -307,13 +307,15 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
if (table->RawData.Size == 0)
{
// Allocate single buffer for our arrays
ImSpanAllocator<2> span_allocator;
ImSpanAllocator<3> span_allocator;
span_allocator.ReserveBytes(0, columns_count * sizeof(ImGuiTableColumn));
span_allocator.ReserveBytes(1, columns_count * sizeof(ImS8));
span_allocator.ReserveBytes(2, columns_count * sizeof(ImGuiTableCellData));
table->RawData.resize(span_allocator.GetArenaSizeInBytes());
span_allocator.SetArenaBasePtr(table->RawData.Data);
span_allocator.GetSpan(0, &table->Columns);
span_allocator.GetSpan(1, &table->DisplayOrderToIndex);
span_allocator.GetSpan(2, &table->RowCellData);
for (int n = 0; n < columns_count; n++)
{
@ -1609,7 +1611,8 @@ void ImGui::TableBeginRow(ImGuiTable* table)
// New row
table->CurrentRow++;
table->CurrentColumn = -1;
table->RowBgColor = IM_COL32_DISABLE;
table->RowBgColor[0] = table->RowBgColor[1] = IM_COL32_DISABLE;
table->RowCellDataCount = 0;
table->IsInsideRow = true;
// Begin frozen rows
@ -1626,7 +1629,7 @@ void ImGui::TableBeginRow(ImGuiTable* table)
// Making the header BG color non-transparent will allow us to overlay it multiple times when handling smooth dragging.
if (table->RowFlags & ImGuiTableRowFlags_Headers)
{
table->RowBgColor = GetColorU32(ImGuiCol_TableHeaderBg);
TableSetBgColor(ImGuiTableBgTarget_RowBg0, GetColorU32(ImGuiCol_TableHeaderBg));
if (table->CurrentRow == 0)
table->IsUsingHeaders = true;
}
@ -1655,14 +1658,18 @@ void ImGui::TableEndRow(ImGuiTable* table)
if (table->CurrentRow == 0)
table->LastFirstRowHeight = bg_y2 - bg_y1;
if (table->CurrentRow >= 0 && bg_y2 >= table->InnerClipRect.Min.y && bg_y1 <= table->InnerClipRect.Max.y)
const bool is_visible = table->CurrentRow >= 0 && bg_y2 >= table->InnerClipRect.Min.y && bg_y1 <= table->InnerClipRect.Max.y;
if (is_visible)
{
// Decide of background color for the row
ImU32 bg_col = 0;
if (table->RowBgColor != IM_COL32_DISABLE)
bg_col = table->RowBgColor;
ImU32 bg_col0 = 0;
ImU32 bg_col1 = 0;
if (table->RowBgColor[0] != IM_COL32_DISABLE)
bg_col0 = table->RowBgColor[0];
else if (table->Flags & ImGuiTableFlags_RowBg)
bg_col = GetColorU32((table->RowBgColorCounter & 1) ? ImGuiCol_TableRowBgAlt : ImGuiCol_TableRowBg);
bg_col0 = GetColorU32((table->RowBgColorCounter & 1) ? ImGuiCol_TableRowBgAlt : ImGuiCol_TableRowBg);
if (table->RowBgColor[1] != IM_COL32_DISABLE)
bg_col1 = table->RowBgColor[1];
// Decide of top border color
ImU32 border_col = 0;
@ -1684,8 +1691,9 @@ void ImGui::TableEndRow(ImGuiTable* table)
}
}
const bool draw_stong_bottom_border = unfreeze_rows;// || (table->RowFlags & ImGuiTableRowFlags_Headers);
if (bg_col != 0 || border_col != 0 || draw_stong_bottom_border)
const bool draw_cell_bg_color = table->RowCellDataCount > 0;
const bool draw_strong_bottom_border = unfreeze_rows;// || (table->RowFlags & ImGuiTableRowFlags_Headers);
if ((bg_col0 | bg_col1 | border_col) != 0 || draw_strong_bottom_border || draw_cell_bg_color)
{
// In theory we could call SetWindowClipRectBeforeChannelChange() but since we know TableEndRow() is
// always followed by a change of clipping rectangle we perform the smallest overwrite possible here.
@ -1693,14 +1701,29 @@ void ImGui::TableEndRow(ImGuiTable* table)
table->DrawSplitter.SetCurrentChannel(window->DrawList, 0);
}
// Draw background
// Draw row background
// We soft/cpu clip this so all backgrounds and borders can share the same clipping rectangle
if (bg_col)
if (bg_col0 || bg_col1)
{
ImRect bg_rect(table->WorkRect.Min.x, bg_y1, table->WorkRect.Max.x, bg_y2);
bg_rect.ClipWith(table->BackgroundClipRect);
if (bg_rect.Min.y < bg_rect.Max.y)
window->DrawList->AddRectFilledMultiColor(bg_rect.Min, bg_rect.Max, bg_col, bg_col, bg_col, bg_col);
ImRect row_rect(table->WorkRect.Min.x, bg_y1, table->WorkRect.Max.x, bg_y2);
row_rect.ClipWith(table->BackgroundClipRect);
if (bg_col0 != 0 && row_rect.Min.y < row_rect.Max.y)
window->DrawList->AddRectFilled(row_rect.Min, row_rect.Max, bg_col0);
if (bg_col1 != 0 && row_rect.Min.y < row_rect.Max.y)
window->DrawList->AddRectFilled(row_rect.Min, row_rect.Max, bg_col1);
}
// Draw cell background color
if (draw_cell_bg_color)
{
ImGuiTableCellData* cell_data_end = &table->RowCellData[table->RowCellDataCount - 1];
for (ImGuiTableCellData* cell_data = &table->RowCellData[0]; cell_data <= cell_data_end; cell_data++)
{
ImGuiTableColumn* column = &table->Columns[cell_data->Column];
ImRect cell_rect(column->MinX - table->CellSpacingX, bg_y1, column->MaxX, bg_y2); // FIXME-TABLE: Padding currently wrong until we finish the padding refactor
cell_rect.ClipWith(table->BackgroundClipRect);
window->DrawList->AddRectFilled(cell_rect.Min, cell_rect.Max, cell_data->BgColor);
}
}
// Draw top border
@ -1708,7 +1731,7 @@ void ImGui::TableEndRow(ImGuiTable* table)
window->DrawList->AddLine(ImVec2(table->BorderX1, bg_y1), ImVec2(table->BorderX2, bg_y1), border_col, border_size);
// Draw bottom border at the row unfreezing mark (always strong)
if (draw_stong_bottom_border)
if (draw_strong_bottom_border)
if (bg_y2 >= table->BackgroundClipRect.Min.y && bg_y2 < table->BackgroundClipRect.Max.y)
window->DrawList->AddLine(ImVec2(table->BorderX1, bg_y2), ImVec2(table->BorderX2, bg_y2), table->BorderColorStrong, border_size);
}
@ -2305,6 +2328,46 @@ int ImGui::TableGetHoveredColumn()
return (int)table->HoveredColumnBody;
}
void ImGui::TableSetBgColor(ImGuiTableBgTarget bg_target, ImU32 color, int column_n)
{
ImGuiContext& g = *GImGui;
ImGuiTable* table = g.CurrentTable;
IM_ASSERT(bg_target != ImGuiTableBgTarget_None);
if (color == IM_COL32_DISABLE)
color = 0;
// We cannot draw neither the cell or row background immediately as we don't know the row height at this point in time.
switch (bg_target)
{
case ImGuiTableBgTarget_CellBg:
{
if (table->RowPosY1 > table->InnerClipRect.Max.y) // Discard
return;
if (column_n == -1)
column_n = table->CurrentColumn;
if ((table->VisibleUnclippedMaskByIndex & ((ImU64)1 << column_n)) == 0)
return;
ImGuiTableCellData* cell_data = &table->RowCellData[table->RowCellDataCount++];
cell_data->BgColor = color;
cell_data->Column = (ImS8)column_n;
break;
}
case ImGuiTableBgTarget_RowBg0:
case ImGuiTableBgTarget_RowBg1:
{
if (table->RowPosY1 > table->InnerClipRect.Max.y) // Discard
return;
IM_ASSERT(column_n == -1);
int bg_idx = (bg_target == ImGuiTableBgTarget_RowBg1) ? 1 : 0;
table->RowBgColor[bg_idx] = color;
break;
}
default:
IM_ASSERT(0);
}
}
void ImGui::TableSortSpecsSanitize(ImGuiTable* table)
{
IM_ASSERT(table->Flags & ImGuiTableFlags_Sortable);