mirror of
https://github.com/ocornut/imgui.git
synced 2024-11-27 16:29:02 +08:00
Tables: work on background draw channel handling (amend "create a separate background draw channel") + Selectable disable spacing when spanning.
This commit is contained in:
parent
fe6131168a
commit
507db499e4
@ -10522,7 +10522,7 @@ void ImGui::ShowMetricsWindow(bool* p_open)
|
||||
else if (rect_type == TRT_WorkRect) { return table->WorkRect; }
|
||||
else if (rect_type == TRT_HostClipRect) { return table->HostClipRect; }
|
||||
else if (rect_type == TRT_InnerClipRect) { return table->InnerClipRect; }
|
||||
else if (rect_type == TRT_BackgroundClipRect) { return table->BackgroundClipRect; }
|
||||
else if (rect_type == TRT_BackgroundClipRect) { return table->BgClipRect; }
|
||||
else if (rect_type == TRT_ColumnsRect) { ImGuiTableColumn* c = &table->Columns[n]; return ImRect(c->MinX, table->InnerClipRect.Min.y, c->MaxX, table->InnerClipRect.Min.y + table->LastOuterHeight); }
|
||||
else if (rect_type == TRT_ColumnsClipRect) { ImGuiTableColumn* c = &table->Columns[n]; return c->ClipRect; }
|
||||
else if (rect_type == TRT_ColumnsContentHeadersUsed){ ImGuiTableColumn* c = &table->Columns[n]; return ImRect(c->ContentMinX, table->InnerClipRect.Min.y, c->ContentMaxXHeadersUsed, table->InnerClipRect.Min.y + table->LastFirstRowHeight); } // Note: y1/y2 not always accurate
|
||||
|
@ -2000,7 +2000,8 @@ struct ImGuiTable
|
||||
ImRect OuterRect; // Note: OuterRect.Max.y is often FLT_MAX until EndTable(), unless a height has been specified in BeginTable().
|
||||
ImRect WorkRect;
|
||||
ImRect InnerClipRect;
|
||||
ImRect BackgroundClipRect; // We use this to cpu-clip cell background color fill
|
||||
ImRect BgClipRect; // We use this to cpu-clip cell background color fill
|
||||
ImRect BgClipRectForDrawCmd;
|
||||
ImRect HostClipRect; // This is used to check if we can eventually merge our columns draw calls into the current draw call of the current window.
|
||||
ImRect HostBackupWorkRect; // Backup of InnerWindow->WorkRect at the end of BeginTable()
|
||||
ImRect HostBackupParentWorkRect; // Backup of InnerWindow->ParentWorkRect at the end of BeginTable()
|
||||
|
@ -319,8 +319,14 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
|
||||
table->InnerClipRect.ClipWith(table->WorkRect); // We need this to honor inner_width
|
||||
table->InnerClipRect.ClipWithFull(table->HostClipRect);
|
||||
table->InnerClipRect.Max.y = (flags & ImGuiTableFlags_NoHostExtendY) ? ImMin(table->InnerClipRect.Max.y, inner_window->WorkRect.Max.y) : inner_window->ClipRect.Max.y;
|
||||
table->BackgroundClipRect = table->InnerClipRect;
|
||||
IM_ASSERT(table->BackgroundClipRect.Min.y <= table->BackgroundClipRect.Max.y);
|
||||
|
||||
// Initial draw cmd starts with a BgClipRect that matches the one of its host, to facilitate merge draw commands by default.
|
||||
// This is because all our cell highlight are manually clipped with BgClipRect
|
||||
// Larger at first, if/after unfreezing will become same as tight
|
||||
table->BgClipRect = table->InnerClipRect;
|
||||
table->BgClipRectForDrawCmd = table->HostClipRect;
|
||||
IM_ASSERT(table->BgClipRect.Min.y <= table->BgClipRect.Max.y);
|
||||
|
||||
table->RowPosY1 = table->RowPosY2 = table->WorkRect.Min.y; // This is needed somehow
|
||||
table->RowTextBaseline = 0.0f; // This will be cleared again by TableBeginRow()
|
||||
table->FreezeRowsRequest = table->FreezeRowsCount = 0; // This will be setup by TableSetupScrollFreeze(), if any
|
||||
@ -1203,7 +1209,7 @@ void ImGui::TableDrawBorders(ImGuiTable* table)
|
||||
// Draw bottom-most row border
|
||||
// FIXME-TABLE: could use AddRect or explicit VLine/HLine helper?
|
||||
const float border_y = table->RowPosY2;
|
||||
if (border_y >= table->BackgroundClipRect.Min.y && border_y < table->BackgroundClipRect.Max.y)
|
||||
if (border_y >= table->BgClipRect.Min.y && border_y < table->BgClipRect.Max.y)
|
||||
inner_drawlist->AddLine(ImVec2(table->BorderX1, border_y), ImVec2(table->BorderX2, border_y), table->BorderColorLight, border_size);
|
||||
}
|
||||
}
|
||||
@ -1495,6 +1501,8 @@ void ImGui::TableReorderDrawChannelsForMerge(ImGuiTable* table)
|
||||
remaining_mask.SetBitRange(1, splitter->_Count - 1); // Background channel 0 == table->BgDrawChannlFrozen, not part of the merge (see channel allocation in TableUpdateDrawChannels)
|
||||
remaining_mask.ClearBit(table->BgDrawChannelUnfrozen);
|
||||
int remaining_count = splitter->_Count - ((table->BgDrawChannelUnfrozen == 0) ? 1 : 2);
|
||||
//ImRect host_rect = (table->InnerWindow == table->OuterWindow) ? table->InnerClipRect : table->HostClipRect;
|
||||
ImRect host_rect = table->HostClipRect;
|
||||
for (int merge_group_n = 0; merge_group_n < IM_ARRAYSIZE(merge_groups); merge_group_n++)
|
||||
{
|
||||
if (int merge_channels_count = merge_groups[merge_group_n].ChannelsCount)
|
||||
@ -1510,13 +1518,13 @@ void ImGui::TableReorderDrawChannelsForMerge(ImGuiTable* table)
|
||||
// FIXME-TABLE FIXME-WORKRECT: We are wasting a merge opportunity on tables without scrolling if column doesn't fit
|
||||
// within host clip rect, solely because of the half-padding difference between window->WorkRect and window->InnerClipRect.
|
||||
if ((merge_group_n & 1) == 0 || !has_freeze_h)
|
||||
merge_clip_rect.Min.x = ImMin(merge_clip_rect.Min.x, table->HostClipRect.Min.x);
|
||||
merge_clip_rect.Min.x = ImMin(merge_clip_rect.Min.x, host_rect.Min.x);
|
||||
if ((merge_group_n & 2) == 0 || !has_freeze_v)
|
||||
merge_clip_rect.Min.y = ImMin(merge_clip_rect.Min.y, table->HostClipRect.Min.y);
|
||||
merge_clip_rect.Min.y = ImMin(merge_clip_rect.Min.y, host_rect.Min.y);
|
||||
if ((merge_group_n & 1) != 0)
|
||||
merge_clip_rect.Max.x = ImMax(merge_clip_rect.Max.x, table->HostClipRect.Max.x);
|
||||
merge_clip_rect.Max.x = ImMax(merge_clip_rect.Max.x, host_rect.Max.x);
|
||||
if ((merge_group_n & 2) != 0 && (table->Flags & ImGuiTableFlags_NoHostExtendY) == 0)
|
||||
merge_clip_rect.Max.y = ImMax(merge_clip_rect.Max.y, table->HostClipRect.Max.y);
|
||||
merge_clip_rect.Max.y = ImMax(merge_clip_rect.Max.y, host_rect.Max.y);
|
||||
#if 0
|
||||
GetOverlayDrawList()->AddRect(merge_group->ClipRect.Min, merge_group->ClipRect.Max, IM_COL32(255, 0, 0, 200), 0.0f, ~0, 1.0f);
|
||||
GetOverlayDrawList()->AddLine(merge_group->ClipRect.Min, merge_clip_rect.Min, IM_COL32(255, 100, 0, 200));
|
||||
@ -1757,7 +1765,7 @@ void ImGui::TableEndRow(ImGuiTable* table)
|
||||
// In theory we could call SetWindowClipRectBeforeSetChannel() but since we know TableEndRow() is
|
||||
// always followed by a change of clipping rectangle we perform the smallest overwrite possible here.
|
||||
if ((table->Flags & ImGuiTableFlags_NoClip) == 0)
|
||||
window->DrawList->_CmdHeader.ClipRect = ((table->IsUnfrozen && table->BgDrawChannelUnfrozen != 0) ? table->BackgroundClipRect : table->HostClipRect).ToVec4();
|
||||
window->DrawList->_CmdHeader.ClipRect = table->BgClipRectForDrawCmd.ToVec4();
|
||||
table->DrawSplitter.SetCurrentChannel(window->DrawList, table->IsUnfrozen ? table->BgDrawChannelUnfrozen : 0);
|
||||
}
|
||||
|
||||
@ -1766,7 +1774,7 @@ void ImGui::TableEndRow(ImGuiTable* table)
|
||||
if (bg_col0 || bg_col1)
|
||||
{
|
||||
ImRect row_rect(table->WorkRect.Min.x, bg_y1, table->WorkRect.Max.x, bg_y2);
|
||||
row_rect.ClipWith(table->BackgroundClipRect);
|
||||
row_rect.ClipWith(table->BgClipRect);
|
||||
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)
|
||||
@ -1780,7 +1788,7 @@ void ImGui::TableEndRow(ImGuiTable* table)
|
||||
for (ImGuiTableCellData* cell_data = &table->RowCellData[0]; cell_data <= cell_data_end; cell_data++)
|
||||
{
|
||||
ImRect cell_bg_rect = TableGetCellBgRect(table, cell_data->Column);
|
||||
cell_bg_rect.ClipWith(table->BackgroundClipRect);
|
||||
cell_bg_rect.ClipWith(table->BgClipRect);
|
||||
cell_bg_rect.Min.x = ImMax(cell_bg_rect.Min.x, table->Columns[cell_data->Column].ClipRect.Min.x);
|
||||
cell_bg_rect.Max.x = ImMin(cell_bg_rect.Max.x, table->Columns[cell_data->Column].ClipRect.Max.x);
|
||||
window->DrawList->AddRectFilled(cell_bg_rect.Min, cell_bg_rect.Max, cell_data->BgColor);
|
||||
@ -1788,13 +1796,12 @@ void ImGui::TableEndRow(ImGuiTable* table)
|
||||
}
|
||||
|
||||
// Draw top border
|
||||
if (border_col && bg_y1 >= table->BackgroundClipRect.Min.y && bg_y1 < table->BackgroundClipRect.Max.y)
|
||||
if (border_col && bg_y1 >= table->BgClipRect.Min.y && bg_y1 < table->BgClipRect.Max.y)
|
||||
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_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);
|
||||
if (draw_strong_bottom_border && bg_y2 >= table->BgClipRect.Min.y && bg_y2 < table->BgClipRect.Max.y)
|
||||
window->DrawList->AddLine(ImVec2(table->BorderX1, bg_y2), ImVec2(table->BorderX2, bg_y2), table->BorderColorStrong, border_size);
|
||||
}
|
||||
|
||||
// End frozen rows (when we are past the last frozen row line, teleport cursor and alter clipping rectangle)
|
||||
@ -1812,11 +1819,11 @@ void ImGui::TableEndRow(ImGuiTable* table)
|
||||
table->IsUnfrozen = true;
|
||||
table->DrawSplitter.SetCurrentChannel(window->DrawList, table->BgDrawChannelUnfrozen);
|
||||
|
||||
// BackgroundClipRect starts as table->InnerClipRect, reduce it now
|
||||
// BgClipRect starts as table->InnerClipRect, reduce it now and make BgClipRectForDrawCmd == BgClipRect
|
||||
float y0 = ImMax(table->RowPosY2 + 1, window->InnerClipRect.Min.y);
|
||||
table->BackgroundClipRect.Min.y = ImMin(y0, window->InnerClipRect.Max.y);
|
||||
table->BackgroundClipRect.Max.y = window->InnerClipRect.Max.y;
|
||||
IM_ASSERT(table->BackgroundClipRect.Min.y <= table->BackgroundClipRect.Max.y);
|
||||
table->BgClipRect.Min.y = table->BgClipRectForDrawCmd.Min.y = ImMin(y0, window->InnerClipRect.Max.y);
|
||||
table->BgClipRect.Max.y = table->BgClipRectForDrawCmd.Max.y = window->InnerClipRect.Max.y;
|
||||
IM_ASSERT(table->BgClipRectForDrawCmd.Min.y <= table->BgClipRectForDrawCmd.Max.y);
|
||||
|
||||
float row_height = table->RowPosY2 - table->RowPosY1;
|
||||
table->RowPosY2 = window->DC.CursorPos.y = table->WorkRect.Min.y + table->RowPosY2 - table->OuterRect.Min.y;
|
||||
@ -1825,7 +1832,7 @@ void ImGui::TableEndRow(ImGuiTable* table)
|
||||
{
|
||||
ImGuiTableColumn* column = &table->Columns[column_n];
|
||||
column->DrawChannelCurrent = column->DrawChannelUnfrozen;
|
||||
column->ClipRect.Min.y = table->BackgroundClipRect.Min.y;
|
||||
column->ClipRect.Min.y = table->BgClipRectForDrawCmd.Min.y;
|
||||
}
|
||||
|
||||
// Update cliprect ahead of TableBeginCell() so clipper can access to new ClipRect->Min.y
|
||||
@ -2034,8 +2041,7 @@ void ImGui::PushTableBackground()
|
||||
|
||||
// Optimization: avoid SetCurrentChannel() + PushClipRect()
|
||||
table->HostBackupClipRect = window->ClipRect;
|
||||
SetWindowClipRectBeforeSetChannel(window, table->BackgroundClipRect);
|
||||
//SetWindowClipRectBeforeSetChannel(window, table->HostClipRect);
|
||||
SetWindowClipRectBeforeSetChannel(window, table->BgClipRectForDrawCmd);
|
||||
table->DrawSplitter.SetCurrentChannel(window->DrawList, table->IsUnfrozen ? table->BgDrawChannelUnfrozen : 0);
|
||||
}
|
||||
|
||||
|
@ -5953,7 +5953,7 @@ bool ImGui::Selectable(const char* label, bool selected, ImGuiSelectableFlags fl
|
||||
ImRect bb(min_x, pos.y, text_max.x, text_max.y);
|
||||
if ((flags & ImGuiSelectableFlags_NoPadWithHalfSpacing) == 0)
|
||||
{
|
||||
const float spacing_x = style.ItemSpacing.x;
|
||||
const float spacing_x = span_all_columns ? 0.0f : style.ItemSpacing.x;
|
||||
const float spacing_y = style.ItemSpacing.y;
|
||||
const float spacing_L = IM_FLOOR(spacing_x * 0.50f);
|
||||
const float spacing_U = IM_FLOOR(spacing_y * 0.50f);
|
||||
|
Loading…
Reference in New Issue
Block a user