Fix layouting of huge ListView with millions of items

The problem is that the precision of f32 for coordinate wouldn't be
accurate enough with such big viewport to put the elements so that they
are next to eachother.
So put the elements relative to the Flickable instead of relative to the
created moving viewport Rectangle.

Fixes #3700

Note that the ListView still use f32 for the scrollbar value, meaning
that at some point, the wheel stops working as the wheel increment is
smaller than the f32 increment, and scrolling becomes somehow fuzzy.
But this only happens after one more billions pixels now, so one can
have more than 50 millions of elements without much problems
This commit is contained in:
Olivier Goffart 2025-01-20 10:51:03 +01:00
parent 387e4202ea
commit 4da79ac69a
5 changed files with 204 additions and 26 deletions

View file

@ -1190,13 +1190,13 @@ public:
void ensure_updated_listview(const Parent *parent,
const private_api::Property<float> *viewport_width,
const private_api::Property<float> *viewport_height,
[[maybe_unused]] const private_api::Property<float> *viewport_y,
const private_api::Property<float> *viewport_y,
float listview_width, [[maybe_unused]] float listview_height) const
{
// TODO: the rust code in model.rs try to only allocate as many items as visible items
ensure_updated(parent);
float h = compute_layout_listview(viewport_width, listview_width);
float h = compute_layout_listview(viewport_width, listview_width, viewport_y->get());
viewport_height->set(h);
}
@ -1234,9 +1234,9 @@ public:
}
float compute_layout_listview(const private_api::Property<float> *viewport_width,
float listview_width) const
float listview_width, float viewport_y) const
{
float offset = 0;
float offset = viewport_y;
viewport_width->set(listview_width);
if (!inner)
return offset;