|
@@ -2239,7 +2239,8 @@ void ImGuiTextBuffer::appendfv(const char* fmt, va_list args)
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
|
// [SECTION] ImGuiListClipper
|
|
|
-// This is currently not as flexible/powerful as it should be, needs some rework (see TODO)
|
|
|
+// This is currently not as flexible/powerful as it should be and really confusing/spaghetti, mostly because we changed
|
|
|
+// the API mid-way through development and support two ways to using the clipper, needs some rework (see TODO)
|
|
|
//-----------------------------------------------------------------------------
|
|
|
|
|
|
static void SetCursorPosYAndSetupDummyPrevLine(float pos_y, float line_height)
|
|
@@ -2247,12 +2248,14 @@ static void SetCursorPosYAndSetupDummyPrevLine(float pos_y, float line_height)
|
|
|
// Set cursor position and a few other things so that SetScrollHereY() and Columns() can work when seeking cursor.
|
|
|
// FIXME: It is problematic that we have to do that here, because custom/equivalent end-user code would stumble on the same issue.
|
|
|
// The clipper should probably have a 4th step to display the last item in a regular manner.
|
|
|
- ImGui::SetCursorPosY(pos_y);
|
|
|
- ImGuiWindow* window = ImGui::GetCurrentWindow();
|
|
|
- window->DC.CursorPosPrevLine.y = window->DC.CursorPos.y - line_height; // Setting those fields so that SetScrollHereY() can properly function after the end of our clipper usage.
|
|
|
- window->DC.PrevLineSize.y = (line_height - GImGui->Style.ItemSpacing.y); // If we end up needing more accurate data (to e.g. use SameLine) we may as well make the clipper have a fourth step to let user process and display the last item in their list.
|
|
|
+ ImGuiContext& g = *GImGui;
|
|
|
+ ImGuiWindow* window = g.CurrentWindow;
|
|
|
+ window->DC.CursorPos.y = pos_y;
|
|
|
+ window->DC.CursorMaxPos.y = ImMax(window->DC.CursorMaxPos.y, pos_y);
|
|
|
+ window->DC.CursorPosPrevLine.y = window->DC.CursorPos.y - line_height; // Setting those fields so that SetScrollHereY() can properly function after the end of our clipper usage.
|
|
|
+ window->DC.PrevLineSize.y = (line_height - g.Style.ItemSpacing.y); // If we end up needing more accurate data (to e.g. use SameLine) we may as well make the clipper have a fourth step to let user process and display the last item in their list.
|
|
|
if (ImGuiColumns* columns = window->DC.CurrentColumns)
|
|
|
- columns->LineMinY = window->DC.CursorPos.y; // Setting this so that cell Y position are set properly
|
|
|
+ columns->LineMinY = window->DC.CursorPos.y; // Setting this so that cell Y position are set properly
|
|
|
}
|
|
|
|
|
|
// Use case A: Begin() called from constructor with items_height<0, then called again from Sync() in StepNo 1
|
|
@@ -2260,7 +2263,10 @@ static void SetCursorPosYAndSetupDummyPrevLine(float pos_y, float line_height)
|
|
|
// FIXME-LEGACY: Ideally we should remove the Begin/End functions but they are part of the legacy API we still support. This is why some of the code in Step() calling Begin() and reassign some fields, spaghetti style.
|
|
|
void ImGuiListClipper::Begin(int count, float items_height)
|
|
|
{
|
|
|
- StartPosY = ImGui::GetCursorPosY();
|
|
|
+ ImGuiContext& g = *GImGui;
|
|
|
+ ImGuiWindow* window = g.CurrentWindow;
|
|
|
+
|
|
|
+ StartPosY = window->DC.CursorPos.y;
|
|
|
ItemsHeight = items_height;
|
|
|
ItemsCount = count;
|
|
|
StepNo = 0;
|
|
@@ -2287,7 +2293,10 @@ void ImGuiListClipper::End()
|
|
|
|
|
|
bool ImGuiListClipper::Step()
|
|
|
{
|
|
|
- if (ItemsCount == 0 || ImGui::GetCurrentWindowRead()->SkipItems)
|
|
|
+ ImGuiContext& g = *GImGui;
|
|
|
+ ImGuiWindow* window = g.CurrentWindow;
|
|
|
+
|
|
|
+ if (ItemsCount == 0 || window->SkipItems)
|
|
|
{
|
|
|
ItemsCount = -1;
|
|
|
return false;
|
|
@@ -2296,16 +2305,16 @@ bool ImGuiListClipper::Step()
|
|
|
{
|
|
|
DisplayStart = 0;
|
|
|
DisplayEnd = 1;
|
|
|
- StartPosY = ImGui::GetCursorPosY();
|
|
|
+ StartPosY = window->DC.CursorPos.y;
|
|
|
StepNo = 1;
|
|
|
return true;
|
|
|
}
|
|
|
if (StepNo == 1) // Step 1: the clipper infer height from first element, calculate the actual range of elements to display, and position the cursor before the first element.
|
|
|
{
|
|
|
if (ItemsCount == 1) { ItemsCount = -1; return false; }
|
|
|
- float items_height = ImGui::GetCursorPosY() - StartPosY;
|
|
|
+ float items_height = window->DC.CursorPos.y - StartPosY;
|
|
|
IM_ASSERT(items_height > 0.0f); // If this triggers, it means Item 0 hasn't moved the cursor vertically
|
|
|
- Begin(ItemsCount-1, items_height);
|
|
|
+ Begin(ItemsCount - 1, items_height);
|
|
|
DisplayStart++;
|
|
|
DisplayEnd++;
|
|
|
StepNo = 3;
|