Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ListClipper jumps back when scrolls down to bottom #7798

Closed
kaiplanning opened this issue Jul 16, 2024 · 3 comments
Closed

ListClipper jumps back when scrolls down to bottom #7798

kaiplanning opened this issue Jul 16, 2024 · 3 comments

Comments

@kaiplanning
Copy link

kaiplanning commented Jul 16, 2024

Version/Branch of Dear ImGui:

Version 1.90, Branch: master

Back-ends:

imgui_impl_dx11.cpp + imgui_impl_win32.cpp

Compiler, OS:

MSVC 2022

Full config/build information:

No response

Details:

I have a vector of items (roughly 586k) and use clipper to display that. When I try to scroll down to the bottom (until some point) it just jumps back up a lot. Sorry I have no idea how to really describe the problem, so a video might help to tell.

Screenshots/Video:

Recording.2024-07-16.145021.online-video-cutter.com.mp4

Example code:

// The plotFont is just a custom function where I use ImGui::Text to show some text and change font size and color.

if (ImGui::BeginTable("Trades", 16, ImGuiTableFlags_ScrollX | ImGuiTableFlags_ScrollY | ImGuiTableFlags_BordersV | ImGuiTableFlags_SizingStretchProp,
				ImVec2(ImGui::GetWindowWidth() * 0.98, ImGui::GetWindowHeight() * 0.98))) {
				ImGui::TableSetupScrollFreeze(0, 1); // Fix header in place
				ImGui::PushStyleVar(ImGuiStyleVar_CellPadding, ImVec2(4.0f, 8.0f));
				ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(255, 255, 255, 255));

                                // Setup header
				ImGui::TableSetupColumn("Ticket");
				....
				ImGui::TableHeadersRow();

				ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0, IM_COL32(163, 176, 199, 255));
				ImGui::PopStyleColor();
				ImGui::PopStyleVar();

                                // Table body
				ImGui::PushStyleColor(ImGuiCol_Text, IM_COL32(0, 0, 0, 255));
				ImGuiListClipper clipper;
				clipper.Begin(tradeRecords.size());
				while (clipper.Step()) {
					for (size_t i = clipper.DisplayStart; i < clipper.DisplayEnd; i++) {
						// Row color settings
						auto color = i % 2 ? IM_COL32(244, 246, 248, 255) : IM_COL32(255, 255, 255, 255);

						ImGui::TableNextRow(0, 31.f);
						ImGui::TableSetBgColor(ImGuiTableBgTarget_RowBg0, color);

						ImGui::TableNextColumn();
						plotFont(1.f, std::to_string(tradeRecords[i].order));

						.....
						ImGui::TableNextColumn();
						plotFont(1.f, tradeRecords[i].comment);
					}
				}
				ImGui::PopStyleColor();
			}
			ImGui::EndTable();
		}
@GamingMinds-DanielC
Copy link
Contributor

This looks like a single precision floating point issue. At least that's part of it, the jumps in your video look a bit too big to be that alone.

It is important for this to know how floating point types work. 32 bit floats can represent integer values exactly up to 16777216, after that they increment in steps of 2 (for a while, then 4 and so on). With 586k rows of 31 pixels height each you are exceeding this limit. If you scroll down far enough, the very first row that the list clipper asks for cannot be measured exactly due to this imprecision. You can circumvent this part of the problem if you give an explicit item height to the clipper in advance. It might also help if you can increase the row height slightly to 32 (a power of 2).

@ocornut: small suggestion, if the list clipper has a height (measured or explicitly given), it could assert on each subsequent Step() if the submitted combined height since the previous Step() equals the number of items requested multiplied by the item height. Issues like this should be easy to detect this way.

@ocornut
Copy link
Owner

ocornut commented Jul 16, 2024

The clipper has mechanism to deal a little better with precision loss but it's not perfect.
I agree with Daniel that if you provide an explicit height to it is likely to help.

You may use Tools->Debug Log->Clipper to logs clipper step, by Shift+clicking on [X] Clipper to enable logging for a single spam maybe. Based on that (but also experiment with suggestions above and below) you may try to make a standalone repro.

Generally speaking, although in principle I agree we should improve this (and I eventually aim to), it's not actually meaningfully useful to browse a 500k list without filter.

There's however another issue with scrollbar themselves (#3609?). Please note that since 1.90.8 we changed scrollbar logic to make clicks outside the scroll grab to scroll by a single page. This may or not also work better in your situation.

@kaiplanning
Copy link
Author

@GamingMinds-DanielC @ocornut

Giving an explicit height to the clipper helps solve this issue.

Thanks for the explanation and help! I will now close this issue as it's already solved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants