mirror of
				https://github.com/Drezil/imgui.git
				synced 2025-10-31 05:01:05 +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; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user