mirror of
https://github.com/Drezil/imgui.git
synced 2025-07-04 03:58:47 +02:00
Columns: Lower overhead on column switches and switching to background channel. (second attempt for 9b3ce49
)
Internals: Bits, comments, added ImRect::ToVec4()
This commit is contained in:
@ -7398,6 +7398,7 @@ bool ImGui::TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb,
|
||||
// [SECTION] Widgets: Columns, BeginColumns, EndColumns, etc.
|
||||
// In the current version, Columns are very weak. Needs to be replaced with a more full-featured system.
|
||||
//-------------------------------------------------------------------------
|
||||
// - SetWindowClipRectBeforeSetChannel() [Internal]
|
||||
// - GetColumnIndex()
|
||||
// - GetColumnCount()
|
||||
// - GetColumnOffset()
|
||||
@ -7415,6 +7416,18 @@ bool ImGui::TabItemLabelAndCloseButton(ImDrawList* draw_list, const ImRect& bb,
|
||||
// - Columns()
|
||||
//-------------------------------------------------------------------------
|
||||
|
||||
// [Internal] Small optimization to avoid calls to PopClipRect/SetCurrentChannel/PushClipRect in sequences,
|
||||
// they would meddle many times with the underlying ImDrawCmd.
|
||||
// Instead, we do a preemptive overwrite of clipping rectangle _without_ altering the command-buffer and let
|
||||
// the subsequent single call to SetCurrentChannel() does it things once.
|
||||
void ImGui::SetWindowClipRectBeforeSetChannel(ImGuiWindow* window, const ImRect& clip_rect)
|
||||
{
|
||||
ImVec4 clip_rect_vec4 = clip_rect.ToVec4();
|
||||
window->ClipRect = clip_rect;
|
||||
window->DrawList->_CmdHeader.ClipRect = clip_rect_vec4;
|
||||
window->DrawList->_ClipRectStack.Data[window->DrawList->_ClipRectStack.Size - 1] = clip_rect_vec4;
|
||||
}
|
||||
|
||||
int ImGui::GetColumnIndex()
|
||||
{
|
||||
ImGuiWindow* window = GetCurrentWindowRead();
|
||||
@ -7549,11 +7562,11 @@ void ImGui::PushColumnsBackground()
|
||||
ImGuiColumns* columns = window->DC.CurrentColumns;
|
||||
if (columns->Count == 1)
|
||||
return;
|
||||
|
||||
// Optimization: avoid SetCurrentChannel() + PushClipRect()
|
||||
columns->HostBackupClipRect = window->ClipRect;
|
||||
SetWindowClipRectBeforeSetChannel(window, columns->HostInitialClipRect);
|
||||
columns->Splitter.SetCurrentChannel(window->DrawList, 0);
|
||||
int cmd_size = window->DrawList->CmdBuffer.Size;
|
||||
PushClipRect(columns->HostClipRect.Min, columns->HostClipRect.Max, false);
|
||||
IM_UNUSED(cmd_size);
|
||||
IM_ASSERT(cmd_size >= window->DrawList->CmdBuffer.Size); // Being in channel 0 this should not have created an ImDrawCmd
|
||||
}
|
||||
|
||||
void ImGui::PopColumnsBackground()
|
||||
@ -7562,8 +7575,10 @@ void ImGui::PopColumnsBackground()
|
||||
ImGuiColumns* columns = window->DC.CurrentColumns;
|
||||
if (columns->Count == 1)
|
||||
return;
|
||||
|
||||
// Optimization: avoid PopClipRect() + SetCurrentChannel()
|
||||
SetWindowClipRectBeforeSetChannel(window, columns->HostBackupClipRect);
|
||||
columns->Splitter.SetCurrentChannel(window->DrawList, columns->Current + 1);
|
||||
PopClipRect();
|
||||
}
|
||||
|
||||
ImGuiColumns* ImGui::FindOrCreateColumns(ImGuiWindow* window, ImGuiID id)
|
||||
@ -7611,7 +7626,7 @@ void ImGui::BeginColumns(const char* str_id, int columns_count, ImGuiColumnsFlag
|
||||
|
||||
columns->HostCursorPosY = window->DC.CursorPos.y;
|
||||
columns->HostCursorMaxPosX = window->DC.CursorMaxPos.x;
|
||||
columns->HostClipRect = window->ClipRect;
|
||||
columns->HostInitialClipRect = window->ClipRect;
|
||||
columns->HostWorkRect = window->WorkRect;
|
||||
|
||||
// Set state for first column
|
||||
@ -7683,25 +7698,31 @@ void ImGui::NextColumn()
|
||||
IM_ASSERT(columns->Current == 0);
|
||||
return;
|
||||
}
|
||||
|
||||
// Next column
|
||||
if (++columns->Current == columns->Count)
|
||||
columns->Current = 0;
|
||||
|
||||
PopItemWidth();
|
||||
PopClipRect();
|
||||
|
||||
// Optimization: avoid PopClipRect() + SetCurrentChannel() + PushClipRect()
|
||||
// (which would needlessly attempt to update commands in the wrong channel, then pop or overwrite them),
|
||||
ImGuiColumnData* column = &columns->Columns[columns->Current];
|
||||
SetWindowClipRectBeforeSetChannel(window, column->ClipRect);
|
||||
columns->Splitter.SetCurrentChannel(window->DrawList, columns->Current + 1);
|
||||
|
||||
const float column_padding = g.Style.ItemSpacing.x;
|
||||
columns->LineMaxY = ImMax(columns->LineMaxY, window->DC.CursorPos.y);
|
||||
if (++columns->Current < columns->Count)
|
||||
if (columns->Current > 0)
|
||||
{
|
||||
// Columns 1+ ignore IndentX (by canceling it out)
|
||||
// FIXME-COLUMNS: Unnecessary, could be locked?
|
||||
window->DC.ColumnsOffset.x = GetColumnOffset(columns->Current) - window->DC.Indent.x + column_padding;
|
||||
columns->Splitter.SetCurrentChannel(window->DrawList, columns->Current + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
// New row/line
|
||||
// Column 0 honor IndentX
|
||||
// New row/line: column 0 honor IndentX.
|
||||
window->DC.ColumnsOffset.x = ImMax(column_padding - window->WindowPadding.x, 0.0f);
|
||||
columns->Splitter.SetCurrentChannel(window->DrawList, 1);
|
||||
columns->Current = 0;
|
||||
columns->LineMinY = columns->LineMaxY;
|
||||
}
|
||||
window->DC.CursorPos.x = IM_FLOOR(window->Pos.x + window->DC.Indent.x + window->DC.ColumnsOffset.x);
|
||||
@ -7709,8 +7730,6 @@ void ImGui::NextColumn()
|
||||
window->DC.CurrLineSize = ImVec2(0.0f, 0.0f);
|
||||
window->DC.CurrLineTextBaseOffset = 0.0f;
|
||||
|
||||
PushColumnClipRect(columns->Current); // FIXME-COLUMNS: Could it be an overwrite?
|
||||
|
||||
// FIXME-COLUMNS: Share code with BeginColumns() - move code on columns setup.
|
||||
float offset_0 = GetColumnOffset(columns->Current);
|
||||
float offset_1 = GetColumnOffset(columns->Current + 1);
|
||||
|
Reference in New Issue
Block a user