Tables: Fixes to support any number of frozen rows (over modifications to clipper code in master) + make clipper run eval after clipect update

docking
omar 4 years ago committed by ocornut
parent cc12ea084b
commit 25b5cc2f95

@ -2237,6 +2237,7 @@ void ImGuiListClipper::Begin(int items_count, float items_height)
StartPosY = window->DC.CursorPos.y; StartPosY = window->DC.CursorPos.y;
ItemsHeight = items_height; ItemsHeight = items_height;
ItemsCount = items_count; ItemsCount = items_count;
ItemsFrozen = 0;
StepNo = 0; StepNo = 0;
DisplayStart = -1; DisplayStart = -1;
DisplayEnd = 0; DisplayEnd = 0;
@ -2249,7 +2250,7 @@ void ImGuiListClipper::End()
// In theory here we should assert that ImGui::GetCursorPosY() == StartPosY + DisplayEnd * ItemsHeight, but it feels saner to just seek at the end and not assert/crash the user. // In theory here we should assert that ImGui::GetCursorPosY() == StartPosY + DisplayEnd * ItemsHeight, but it feels saner to just seek at the end and not assert/crash the user.
if (ItemsCount < INT_MAX && DisplayStart >= 0) if (ItemsCount < INT_MAX && DisplayStart >= 0)
SetCursorPosYAndSetupForPrevLine(StartPosY + ItemsCount * ItemsHeight, ItemsHeight); SetCursorPosYAndSetupForPrevLine(StartPosY + (ItemsCount - ItemsFrozen) * ItemsHeight, ItemsHeight);
ItemsCount = -1; ItemsCount = -1;
StepNo = 3; StepNo = 3;
} }
@ -2273,12 +2274,22 @@ bool ImGuiListClipper::Step()
// Step 0: Let you process the first element (regardless of it being visible or not, so we can measure the element height) // Step 0: Let you process the first element (regardless of it being visible or not, so we can measure the element height)
if (StepNo == 0) if (StepNo == 0)
{ {
// 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)
{
DisplayStart = ItemsFrozen;
DisplayEnd = ItemsFrozen + 1;
ItemsFrozen++;
return true;
}
StartPosY = window->DC.CursorPos.y; StartPosY = window->DC.CursorPos.y;
if (ItemsHeight <= 0.0f) if (ItemsHeight <= 0.0f)
{ {
// Submit the first item so we can measure its height (generally it is 0..1) // Submit the first item so we can measure its height (generally it is 0..1)
DisplayStart = 0; DisplayStart = ItemsFrozen;
DisplayEnd = 1; DisplayEnd = ItemsFrozen + 1;
StepNo = 1; StepNo = 1;
return true; return true;
} }
@ -2319,7 +2330,7 @@ bool ImGuiListClipper::Step()
// Seek cursor // Seek cursor
if (DisplayStart > already_submitted) if (DisplayStart > already_submitted)
SetCursorPosYAndSetupForPrevLine(StartPosY + DisplayStart * ItemsHeight, ItemsHeight); SetCursorPosYAndSetupForPrevLine(StartPosY + (DisplayStart - ItemsFrozen) * ItemsHeight, ItemsHeight);
StepNo = 3; StepNo = 3;
return true; return true;
@ -2331,7 +2342,7 @@ bool ImGuiListClipper::Step()
{ {
// Seek cursor // Seek cursor
if (ItemsCount < INT_MAX) if (ItemsCount < INT_MAX)
SetCursorPosYAndSetupForPrevLine(StartPosY + ItemsCount * ItemsHeight, ItemsHeight); // advance cursor SetCursorPosYAndSetupForPrevLine(StartPosY + (ItemsCount - ItemsFrozen) * ItemsHeight, ItemsHeight); // advance cursor
ItemsCount = -1; ItemsCount = -1;
return false; return false;
} }

@ -2092,6 +2092,7 @@ struct ImGuiListClipper
// [Internal] // [Internal]
int ItemsCount; int ItemsCount;
int StepNo; int StepNo;
int ItemsFrozen;
float ItemsHeight; float ItemsHeight;
float StartPosY; float StartPosY;

@ -1774,6 +1774,10 @@ void ImGui::TableEndRow(ImGuiTable* table)
column->DrawChannelCurrent = column->DrawChannelRowsAfterFreeze; column->DrawChannelCurrent = column->DrawChannelRowsAfterFreeze;
column->ClipRect.Min.y = r.Min.y; column->ClipRect.Min.y = r.Min.y;
} }
// Update cliprect ahead of TableBeginCell() so clipper can access to new ClipRect->Min.y
SetWindowClipRectBeforeSetChannel(window, table->Columns[0].ClipRect);
table->DrawSplitter.SetCurrentChannel(window->DrawList, table->Columns[0].DrawChannelCurrent);
} }
if (!(table->RowFlags & ImGuiTableRowFlags_Headers)) if (!(table->RowFlags & ImGuiTableRowFlags_Headers))

Loading…
Cancel
Save