mirror of
https://github.com/ocornut/imgui.git
synced 2024-11-27 16:29:02 +08:00
Tables: Moved TableSetupScrollFreeze(), TableUpdateDrawChannels() lower in more adequate spots.
+ rename IsFreezeRowsPassed to IsUnfrozen.
This commit is contained in:
parent
d9ca3939e1
commit
d3222086f0
@ -2276,7 +2276,7 @@ bool ImGuiListClipper::Step()
|
||||
{
|
||||
// While we are in frozen row state, keep displaying items one by one, unclipped
|
||||
// FIXME: Could be stored as a table-agnostic state.
|
||||
if (table != NULL && !table->IsFreezeRowsPassed)
|
||||
if (table != NULL && !table->IsUnfrozen)
|
||||
{
|
||||
DisplayStart = ItemsFrozen;
|
||||
DisplayEnd = ItemsFrozen + 1;
|
||||
|
@ -2037,7 +2037,7 @@ struct ImGuiTable
|
||||
bool IsSettingsDirty; // Set when table settings have changed and needs to be reported into ImGuiTableSetttings data.
|
||||
bool IsDefaultDisplayOrder; // Set when display order is unchanged from default (DisplayOrder contains 0...Count-1)
|
||||
bool IsResetDisplayOrderRequest;
|
||||
bool IsFreezeRowsPassed; // Set when we got past the frozen row.
|
||||
bool IsUnfrozen; // Set when we got past the frozen row.
|
||||
bool HostSkipItems; // Backup of InnerWindow->SkipItem at the end of BeginTable(), because we will overwrite InnerWindow->SkipItem on a per-column basis
|
||||
|
||||
ImGuiTable()
|
||||
|
126
imgui_tables.cpp
126
imgui_tables.cpp
@ -323,7 +323,7 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
|
||||
table->RowTextBaseline = 0.0f; // This will be cleared again by TableBeginRow()
|
||||
table->FreezeRowsRequest = table->FreezeRowsCount = 0; // This will be setup by TableSetupScrollFreeze(), if any
|
||||
table->FreezeColumnsRequest = table->FreezeColumnsCount = 0;
|
||||
table->IsFreezeRowsPassed = true;
|
||||
table->IsUnfrozen = true;
|
||||
table->DeclColumnsCount = 0;
|
||||
table->RightMostVisibleColumn = -1;
|
||||
|
||||
@ -498,64 +498,6 @@ void ImGui::TableBeginUpdateColumns(ImGuiTable* table)
|
||||
table->InnerWindow->SkipItems = false;
|
||||
}
|
||||
|
||||
void ImGui::TableSetupScrollFreeze(int columns, int rows)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiTable* table = g.CurrentTable;
|
||||
IM_ASSERT(table != NULL && "Need to call TableSetupColumn() after BeginTable()!");
|
||||
IM_ASSERT(table->IsLayoutLocked == false && "Need to call TableSetupColumn() before first row!");
|
||||
IM_ASSERT(columns >= 0 && columns < IMGUI_TABLE_MAX_COLUMNS);
|
||||
IM_ASSERT(rows >= 0 && rows < 128); // Arbitrary limit
|
||||
|
||||
table->FreezeColumnsRequest = (table->Flags & ImGuiTableFlags_ScrollX) ? (ImS8)columns : 0;
|
||||
table->FreezeColumnsCount = (table->InnerWindow->Scroll.x != 0.0f) ? table->FreezeColumnsRequest : 0;
|
||||
table->FreezeRowsRequest = (table->Flags & ImGuiTableFlags_ScrollY) ? (ImS8)rows : 0;
|
||||
table->FreezeRowsCount = (table->InnerWindow->Scroll.y != 0.0f) ? table->FreezeRowsRequest : 0;
|
||||
table->IsFreezeRowsPassed = (table->FreezeRowsCount == 0); // Make sure this is set before TableUpdateLayout() so ImGuiListClipper can benefit from it.b
|
||||
}
|
||||
|
||||
void ImGui::TableUpdateDrawChannels(ImGuiTable* table)
|
||||
{
|
||||
// Allocate draw channels.
|
||||
// - We allocate them following storage order instead of display order so reordering columns won't needlessly
|
||||
// increase overall dormant memory cost.
|
||||
// - We isolate headers draw commands in their own channels instead of just altering clip rects.
|
||||
// This is in order to facilitate merging of draw commands.
|
||||
// - After crossing FreezeRowsCount, all columns see their current draw channel changed to a second set of channels.
|
||||
// - We only use the dummy draw channel so we can push a null clipping rectangle into it without affecting other
|
||||
// channels, while simplifying per-row/per-cell overhead. It will be empty and discarded when merged.
|
||||
// Draw channel allocation (before merging):
|
||||
// - NoClip --> 1+1 channels: background + foreground (same clip rect == 1 draw call)
|
||||
// - Clip --> 1+N channels
|
||||
// - FreezeRows || FreezeColumns --> 1+N*2 (unless scrolling value is zero)
|
||||
// - FreezeRows && FreezeColunns --> 2+N*2 (unless scrolling value is zero)
|
||||
const int freeze_row_multiplier = (table->FreezeRowsCount > 0) ? 2 : 1;
|
||||
const int channels_for_row = (table->Flags & ImGuiTableFlags_NoClip) ? 1 : table->ColumnsVisibleCount;
|
||||
const int channels_for_background = 1;
|
||||
const int channels_for_dummy = (table->ColumnsVisibleCount < table->ColumnsCount || table->VisibleUnclippedMaskByIndex != table->VisibleMaskByIndex) ? +1 : 0;
|
||||
const int channels_total = channels_for_background + (channels_for_row * freeze_row_multiplier) + channels_for_dummy;
|
||||
table->DrawSplitter.Split(table->InnerWindow->DrawList, channels_total);
|
||||
table->DummyDrawChannel = channels_for_dummy ? (ImS8)(channels_total - 1) : -1;
|
||||
|
||||
int draw_channel_current = 1;
|
||||
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
|
||||
{
|
||||
ImGuiTableColumn* column = &table->Columns[column_n];
|
||||
if (!column->IsClipped)
|
||||
{
|
||||
column->DrawChannelFrozen = (ImS8)(draw_channel_current);
|
||||
column->DrawChannelUnfrozen = (ImS8)(draw_channel_current + (table->FreezeRowsCount > 0 ? channels_for_row : 0));
|
||||
if (!(table->Flags & ImGuiTableFlags_NoClip))
|
||||
draw_channel_current++;
|
||||
}
|
||||
else
|
||||
{
|
||||
column->DrawChannelFrozen = column->DrawChannelUnfrozen = table->DummyDrawChannel;
|
||||
}
|
||||
column->DrawChannelCurrent = column->DrawChannelFrozen;
|
||||
}
|
||||
}
|
||||
|
||||
// Adjust flags: default width mode + stretch columns are not allowed when auto extending
|
||||
static ImGuiTableColumnFlags TableFixColumnFlags(ImGuiTable* table, ImGuiTableColumnFlags flags)
|
||||
{
|
||||
@ -1363,7 +1305,49 @@ void ImGui::TableSetColumnWidth(ImGuiTable* table, ImGuiTableColumn* column_0, f
|
||||
}
|
||||
}
|
||||
|
||||
// This function reorder draw channels based on matching clip rectangle, to facilitate merging them.
|
||||
// Allocate draw channels. Called by TableUpdateLayout()
|
||||
// - We allocate them following storage order instead of display order so reordering columns won't needlessly
|
||||
// increase overall dormant memory cost.
|
||||
// - We isolate headers draw commands in their own channels instead of just altering clip rects.
|
||||
// This is in order to facilitate merging of draw commands.
|
||||
// - After crossing FreezeRowsCount, all columns see their current draw channel changed to a second set of channels.
|
||||
// - We only use the dummy draw channel so we can push a null clipping rectangle into it without affecting other
|
||||
// channels, while simplifying per-row/per-cell overhead. It will be empty and discarded when merged.
|
||||
// Draw channel allocation (before merging):
|
||||
// - NoClip --> 1+1 channels: background + foreground (same clip rect == 1 draw call)
|
||||
// - Clip --> 1+N channels
|
||||
// - FreezeRows || FreezeColumns --> 1+N*2 (unless scrolling value is zero)
|
||||
// - FreezeRows && FreezeColunns --> 2+N*2 (unless scrolling value is zero)
|
||||
void ImGui::TableUpdateDrawChannels(ImGuiTable* table)
|
||||
{
|
||||
const int freeze_row_multiplier = (table->FreezeRowsCount > 0) ? 2 : 1;
|
||||
const int channels_for_row = (table->Flags & ImGuiTableFlags_NoClip) ? 1 : table->ColumnsVisibleCount;
|
||||
const int channels_for_background = 1;
|
||||
const int channels_for_dummy = (table->ColumnsVisibleCount < table->ColumnsCount || table->VisibleUnclippedMaskByIndex != table->VisibleMaskByIndex) ? +1 : 0;
|
||||
const int channels_total = channels_for_background + (channels_for_row * freeze_row_multiplier) + channels_for_dummy;
|
||||
table->DrawSplitter.Split(table->InnerWindow->DrawList, channels_total);
|
||||
table->DummyDrawChannel = channels_for_dummy ? (ImS8)(channels_total - 1) : -1;
|
||||
|
||||
int draw_channel_current = 1;
|
||||
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
|
||||
{
|
||||
ImGuiTableColumn* column = &table->Columns[column_n];
|
||||
if (!column->IsClipped)
|
||||
{
|
||||
column->DrawChannelFrozen = (ImS8)(draw_channel_current);
|
||||
column->DrawChannelUnfrozen = (ImS8)(draw_channel_current + (table->FreezeRowsCount > 0 ? channels_for_row : 0));
|
||||
if (!(table->Flags & ImGuiTableFlags_NoClip))
|
||||
draw_channel_current++;
|
||||
}
|
||||
else
|
||||
{
|
||||
column->DrawChannelFrozen = column->DrawChannelUnfrozen = table->DummyDrawChannel;
|
||||
}
|
||||
column->DrawChannelCurrent = column->DrawChannelFrozen;
|
||||
}
|
||||
}
|
||||
|
||||
// This function reorder draw channels based on matching clip rectangle, to facilitate merging them. Called by EndTable().
|
||||
//
|
||||
// Columns where the contents didn't stray off their local clip rectangle can be merged. To achieve
|
||||
// this we merge their clip rect and make them contiguous in the channel list, so they can be merged
|
||||
@ -1619,6 +1603,22 @@ void ImGui::TableSetupColumn(const char* label, ImGuiTableColumnFlags flags,
|
||||
}
|
||||
}
|
||||
|
||||
void ImGui::TableSetupScrollFreeze(int columns, int rows)
|
||||
{
|
||||
ImGuiContext& g = *GImGui;
|
||||
ImGuiTable* table = g.CurrentTable;
|
||||
IM_ASSERT(table != NULL && "Need to call TableSetupColumn() after BeginTable()!");
|
||||
IM_ASSERT(table->IsLayoutLocked == false && "Need to call TableSetupColumn() before first row!");
|
||||
IM_ASSERT(columns >= 0 && columns < IMGUI_TABLE_MAX_COLUMNS);
|
||||
IM_ASSERT(rows >= 0 && rows < 128); // Arbitrary limit
|
||||
|
||||
table->FreezeColumnsRequest = (table->Flags & ImGuiTableFlags_ScrollX) ? (ImS8)columns : 0;
|
||||
table->FreezeColumnsCount = (table->InnerWindow->Scroll.x != 0.0f) ? table->FreezeColumnsRequest : 0;
|
||||
table->FreezeRowsRequest = (table->Flags & ImGuiTableFlags_ScrollY) ? (ImS8)rows : 0;
|
||||
table->FreezeRowsCount = (table->InnerWindow->Scroll.y != 0.0f) ? table->FreezeRowsRequest : 0;
|
||||
table->IsUnfrozen = (table->FreezeRowsCount == 0); // Make sure this is set before TableUpdateLayout() so ImGuiListClipper can benefit from it.b
|
||||
}
|
||||
|
||||
// Starts into the first cell of a new row
|
||||
void ImGui::TableNextRow(ImGuiTableRowFlags row_flags, float row_min_height)
|
||||
{
|
||||
@ -1777,8 +1777,8 @@ void ImGui::TableEndRow(ImGuiTable* table)
|
||||
}
|
||||
if (unfreeze_rows_actual)
|
||||
{
|
||||
IM_ASSERT(table->IsFreezeRowsPassed == false);
|
||||
table->IsFreezeRowsPassed = true;
|
||||
IM_ASSERT(table->IsUnfrozen == false);
|
||||
table->IsUnfrozen = true;
|
||||
table->DrawSplitter.SetCurrentChannel(window->DrawList, 0);
|
||||
|
||||
// BackgroundClipRect starts as table->InnerClipRect, reduce it now
|
||||
@ -1859,7 +1859,7 @@ void ImGui::TableEndCell(ImGuiTable* table)
|
||||
if (table->RowFlags & ImGuiTableRowFlags_Headers)
|
||||
p_max_pos_x = &column->ContentMaxXHeadersUsed; // Useful in case user submit contents in header row that is not a TableHeader() call
|
||||
else
|
||||
p_max_pos_x = table->IsFreezeRowsPassed ? &column->ContentMaxXUnfrozen : &column->ContentMaxXFrozen;
|
||||
p_max_pos_x = table->IsUnfrozen ? &column->ContentMaxXUnfrozen : &column->ContentMaxXFrozen;
|
||||
*p_max_pos_x = ImMax(*p_max_pos_x, window->DC.CursorMaxPos.x);
|
||||
table->RowPosY2 = ImMax(table->RowPosY2, window->DC.CursorMaxPos.y + table->CellPaddingY);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user