mirror of
				https://github.com/Drezil/imgui.git
				synced 2025-11-03 22:51:06 +01:00 
			
		
		
		
	Internals: ImGuiListClipper using absolute coordinate (instead of relative one). Minor no-op tweaks + ImDrawListSplitter assert
This commit is contained in:
		
							
								
								
									
										31
									
								
								imgui.cpp
									
									
									
									
									
								
							
							
						
						
									
										31
									
								
								imgui.cpp
									
									
									
									
									
								
							@@ -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;
 | 
			
		||||
 
 | 
			
		||||
@@ -4022,7 +4022,7 @@ static void ShowExampleAppLongText(bool* p_open)
 | 
			
		||||
    static ImGuiTextBuffer log;
 | 
			
		||||
    static int lines = 0;
 | 
			
		||||
    ImGui::Text("Printing unusually long amount of text.");
 | 
			
		||||
    ImGui::Combo("Test type", &test_type, "Single call to TextUnformatted()\0Multiple calls to Text(), clipped manually\0Multiple calls to Text(), not clipped (slow)\0");
 | 
			
		||||
    ImGui::Combo("Test type", &test_type, "Single call to TextUnformatted()\0Multiple calls to Text(), clipped\0Multiple calls to Text(), not clipped (slow)\0");
 | 
			
		||||
    ImGui::Text("Buffer contents: %d lines, %d bytes", lines, log.size());
 | 
			
		||||
    if (ImGui::Button("Clear")) { log.clear(); lines = 0; }
 | 
			
		||||
    ImGui::SameLine();
 | 
			
		||||
 
 | 
			
		||||
@@ -1304,7 +1304,7 @@ void ImDrawListSplitter::Merge(ImDrawList* draw_list)
 | 
			
		||||
 | 
			
		||||
void ImDrawListSplitter::SetCurrentChannel(ImDrawList* draw_list, int idx)
 | 
			
		||||
{
 | 
			
		||||
    IM_ASSERT(idx < _Count);
 | 
			
		||||
    IM_ASSERT(idx >= 0 && idx < _Count);
 | 
			
		||||
    if (_Current == idx) 
 | 
			
		||||
        return;
 | 
			
		||||
    // Overwrite ImVector (12/16 bytes), four times. This is merely a silly optimization instead of doing .swap()
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user