Expand description
Virtualized list — a thin binding over gpui’s uniform_list, and a bridge
that lets crate::scroll::scrollbar report on one.
Thin on purpose: gpui already does the hard part, and a wrapper that only re-exported it with extra steps would be worse than none. This module exists for two things it can guarantee that a caller otherwise has to know.
The row height. uniform_list measures the first row it renders and
lays every other one out at that height. Hand it rows of different heights
and nothing errors — the content simply overlaps, at a size nobody chose.
virtual_list takes the height and applies it to every row it hands back,
so that cannot happen by accident.
The scroll handle. A UniformListScrollHandle wraps a real
ScrollHandle and gpui registers it as the list’s tracked handle, so the
bar’s geometry is all there — behind handle.0.borrow().base_handle, which
is not something a consumer should have to find by reading gpui’s source.
scroll_handle is that reach, named.
§Why not gpui’s list()
gpui has a second virtualizer for rows of varying height, and it cannot
carry a proportional scrollbar: ListState speaks in ListOffset { item_ix, offset_in_item } — logical position, not pixels — with no maximum offset
and no viewport. A thumb’s length is the visible share of a total height, and
a variable-height list cannot know its total without measuring every row,
which is the work virtualization exists to skip. A list of thousands of rows
wants a bar; a list that needs varying heights is a different component, and
nothing has asked for one yet.
div().relative().h(px(240.0))
.child(virtual_list("rows", rows.len(), px(28.0), &self.rows_scroll, {
let rows = rows.clone();
move |range, _, _| range.map(|ix| row(&rows[ix])).collect()
}))
.child(scroll::scrollbar("rows-bar", &list::scroll_handle(&self.rows_scroll), &self.rows_bar))Functions§
- scroll_
handle - The pixel-space scroll handle inside a
UniformListScrollHandle. - virtual_
list - A list that builds only the rows on screen.