pub fn list(
ui: &mut Ui<'_>,
label: &str,
spec: NodeSpec,
heights: &mut RowHeights,
measure: impl FnMut(&mut Ui<'_>, usize, f32) -> f32,
row: impl FnMut(&mut Ui<'_>, usize),
) -> KeyExpand description
A vertically scrolling column of rows of different heights that builds
only the visible ones — uniform_list where no single stride
describes the list.
measure(ui, i, width) returns row i’s height at that content width,
and is called only for rows the frame is about to build that heights
has no number for; ui.measure_text(.., Some(width)) is layout’s own
answer for a text row, wrap and all, and shapes through the same cache
the row’s draw will hit. What it returns is the height the row gets:
each row’s node is fixed to it, so the arithmetic above and below can
never disagree with the layout, the way uniform_list’s stride cannot.
A row that would rather size itself has to say what that size is here.
row(ui, i) declares row i inside that node, exactly as
uniform_list’s does, and rows are opened with Ui::open_indexed at
their data index, so a row keeps its hover, focus, edit buffer and tweens
as the built range slides over it.
What it does that the uniform one never has to: every row not yet
measured stands at the mean of the ones that are, so measuring the rows
this frame builds changes the height of every row it does not — the ones
above the window included. Left alone that slides the content out from
under the pointer on the frame it learns anything. So the widget takes
the row the window starts in and how far into it, measures, and then puts
that pair back: Core::set_scroll from inside a view lands on the frame
being built (the positions pass reads the store after the view has run),
so the corrected frame is the only one ever seen. What does move is the
scrollbar, which is the honest thing to move — the list really did just
learn it is a different length.
Returns the container’s key, for set_scroll — and “scroll to row i”
is set_scroll(key, Vec2::new(0.0, heights.offset_of(i))), exact for a
measured row and converging over a frame or two for one that is not.