Skip to content

Commit

Permalink
Tables: Frozen rows/columns in nav menu layer, fixed conflict between…
Browse files Browse the repository at this point in the history
… column id and holding child id.
  • Loading branch information
ocornut committed Oct 30, 2020
1 parent abf16e5 commit cf8175b
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 17 deletions.
3 changes: 2 additions & 1 deletion imgui_internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -1928,6 +1928,7 @@ struct ImGuiTableColumn
bool IsVisibleNextFrame;
bool IsClipped; // Set when not overlapping the host window clipping rectangle.
bool SkipItems;
ImGuiNavLayer NavLayerCurrent;
ImS8 DisplayOrder; // Index within Table's IndexToDisplayOrder[] (column may be reordered by users)
ImS8 IndexWithinVisibleSet; // Index within visible set (<= IndexToDisplayOrder)
ImS8 DrawChannelCurrent; // Index within DrawSplitter.Channels[]
Expand Down Expand Up @@ -2051,7 +2052,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 (the first one).
bool IsFreezeRowsPassed; // 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()
Expand Down
40 changes: 24 additions & 16 deletions imgui_widgets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8465,12 +8465,13 @@ bool ImGui::BeginTableEx(const char* name, ImGuiID id, int columns_count, ImG
if (override_content_size.x != FLT_MAX || override_content_size.y != FLT_MAX)
SetNextWindowContentSize(ImVec2(override_content_size.x != FLT_MAX ? override_content_size.x : 0.0f, override_content_size.y != FLT_MAX ? override_content_size.y : 0.0f));

// Create scrolling region (without border = zero window padding)
// Create scrolling region (without border and zero window padding)
ImGuiWindowFlags child_flags = (flags & ImGuiTableFlags_ScrollX) ? ImGuiWindowFlags_HorizontalScrollbar : ImGuiWindowFlags_None;
BeginChildEx(name, instance_id, table->OuterRect.GetSize(), false, child_flags);
table->InnerWindow = g.CurrentWindow;
table->WorkRect = table->InnerWindow->WorkRect;
table->OuterRect = table->InnerWindow->Rect();
IM_ASSERT(table->InnerWindow->WindowPadding.x == 0.0f && table->InnerWindow->WindowPadding.y == 0.0f && table->InnerWindow->WindowBorderSize == 0.0f);
}

// Push a standardized ID for both child and not-child using tables, equivalent to BeginTable() doing PushID(label) matching
Expand Down Expand Up @@ -8709,15 +8710,15 @@ 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 call TableSetupColumn() before first row!");
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);
table->IsFreezeRowsPassed = (table->FreezeRowsCount == 0); // Make sure this is set before TableUpdateLayout() so ImGuiListClipper can benefit from it.b
}

void ImGui::TableUpdateDrawChannels(ImGuiTable* table)
Expand Down Expand Up @@ -9008,6 +9009,8 @@ void ImGui::TableUpdateLayout(ImGuiTable* table)
const int column_n = table->DisplayOrderToIndex[order_n];
ImGuiTableColumn* column = &table->Columns[column_n];

column->NavLayerCurrent = (table->FreezeRowsCount > 0 || column_n < table->FreezeColumnsCount) ? ImGuiNavLayer_Menu : ImGuiNavLayer_Main;

if (table->FreezeColumnsCount > 0 && table->FreezeColumnsCount == visible_n)
offset_x += work_rect.Min.x - table->OuterRect.Min.x;

Expand Down Expand Up @@ -9901,12 +9904,12 @@ void ImGui::TableEndRow(ImGuiTable* table)
const float bg_y1 = table->RowPosY1;
const float bg_y2 = table->RowPosY2;

const bool unfreeze_rows = (table->CurrentRow + 1 == table->FreezeRowsCount && table->FreezeRowsCount > 0);

const bool unfreeze_rows_actual = (table->CurrentRow + 1 == table->FreezeRowsCount);
const bool unfreeze_rows_request = (table->CurrentRow + 1 == table->FreezeRowsRequest);
if (table->CurrentRow == 0)
table->LastFirstRowHeight = bg_y2 - bg_y1;

const bool is_visible = table->CurrentRow >= 0 && bg_y2 >= table->InnerClipRect.Min.y && bg_y1 <= table->InnerClipRect.Max.y;
const bool is_visible = (bg_y2 >= table->InnerClipRect.Min.y && bg_y1 <= table->InnerClipRect.Max.y);
if (is_visible)
{
// Decide of background color for the row
Expand Down Expand Up @@ -9940,7 +9943,7 @@ void ImGui::TableEndRow(ImGuiTable* table)
}

const bool draw_cell_bg_color = table->RowCellDataCurrent >= 0;
const bool draw_strong_bottom_border = unfreeze_rows;// || (table->RowFlags & ImGuiTableRowFlags_Headers);
const bool draw_strong_bottom_border = unfreeze_rows_actual;// || (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
Expand Down Expand Up @@ -9987,18 +9990,22 @@ void ImGui::TableEndRow(ImGuiTable* table)
// End frozen rows (when we are past the last frozen row line, teleport cursor and alter clipping rectangle)
// We need to do that in TableEndRow() instead of TableBeginRow() so the list clipper can mark end of row and
// get the new cursor position.
if (unfreeze_rows)
if (unfreeze_rows_request)
for (int column_n = 0; column_n < table->ColumnsCount; column_n++)
{
ImGuiTableColumn* column = &table->Columns[column_n];
column->NavLayerCurrent = (column_n < table->FreezeColumnsCount) ? ImGuiNavLayer_Menu : ImGuiNavLayer_Main;
}
if (unfreeze_rows_actual)
{
IM_ASSERT(table->IsFreezeRowsPassed == false);
table->IsFreezeRowsPassed = true;
table->DrawSplitter.SetCurrentChannel(window->DrawList, 0);

ImRect r;
r.Min.x = table->InnerClipRect.Min.x;
r.Min.y = ImMax(table->RowPosY2 + 1, window->InnerClipRect.Min.y);
r.Max.x = table->InnerClipRect.Max.x;
r.Max.y = window->InnerClipRect.Max.y;
table->BackgroundClipRect = r;
// BackgroundClipRect starts as table->InnerClipRect, reduce it now
float y0 = ImMax(table->RowPosY2 + 1, window->InnerClipRect.Min.y);
table->BackgroundClipRect.Min.y = y0;
table->BackgroundClipRect.Max.y = window->InnerClipRect.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;
Expand All @@ -10007,7 +10014,7 @@ void ImGui::TableEndRow(ImGuiTable* table)
{
ImGuiTableColumn* column = &table->Columns[column_n];
column->DrawChannelCurrent = column->DrawChannelRowsAfterFreeze;
column->ClipRect.Min.y = r.Min.y;
column->ClipRect.Min.y = table->BackgroundClipRect.Min.y;
}

// Update cliprect ahead of TableBeginCell() so clipper can access to new ClipRect->Min.y
Expand Down Expand Up @@ -10040,6 +10047,7 @@ void ImGui::TableBeginCell(ImGuiTable* table, int column_n)
window->DC.ColumnsOffset.x = start_x - window->Pos.x - window->DC.Indent.x; // FIXME-WORKRECT
window->DC.CurrLineTextBaseOffset = table->RowTextBaseline;
window->DC.LastItemId = 0;
window->DC.NavLayerCurrent = column->NavLayerCurrent;

window->WorkRect.Min.y = window->DC.CursorPos.y;
window->WorkRect.Min.x = column->MinX + table->CellPaddingX1;
Expand Down Expand Up @@ -10194,7 +10202,7 @@ const char* ImGui::TableGetColumnName(const ImGuiTable* table, int column_n)
ImGuiID ImGui::TableGetColumnResizeID(const ImGuiTable* table, int column_n, int instance_no)
{
IM_ASSERT(column_n < table->ColumnsCount);
ImGuiID id = table->ID + (instance_no * table->ColumnsCount) + column_n;
ImGuiID id = table->ID + 1 + (instance_no * table->ColumnsCount) + column_n;
return id;
}

Expand Down

0 comments on commit cf8175b

Please sign in to comment.