LEEME.md
llimphi-widget-lazy-list
Read this in English: README.md.
Lista perezosa llave-en-mano.
Bloque 22 de PLAN-NUCLEO-RETENIDO.md. Ataca la Brecha #2 (scroll sin
lazy): hoy list/grid/table construyen todas las filas que se les
pasan, y scroll_y recibe el contenido ya construido — así, montar
1M de filas mide ~4 s/frame porque el árbol entero se rearma cada cuadro
(ver el baseline del Bloque 21).
Este widget invierte el contrato: en vez de un content: View ya armado,
recibe un builder item: Fn(usize) -> View<Msg> + total, y sólo
llama item(i) para la ventana visible + overscan. Las filas fuera de
pantalla no existen: no se construyen, no se montan, no se layoutean. El
costo por frame pasa a ser ∝ lo visible, no ∝ el total.
Fiel al bucle Elm, es sin estado: el offset (px) vive en el Model
del caller, igual que en llimphi_widget_scroll, cuya barra/física
(thumb, page-jump, fling, rubber-band) se reusa tal cual — este crate sólo
agrega la virtualización real que faltaba.
Dos modelos de extent:
lazy_list_fixed— filas de alto uniforme (item_h). Ventana O(1). Cubre el 90% (logs, filas de tabla, file-lists).lazy_list_varied— alto por fila, vía un arreglo de offsets acumulados precomputado por el caller (offsets[i]= tope de la filaien coords de contenido;offsets[total]= alto total). Ventana O(log n) por búsqueda binaria; el caller reconstruyeoffsetscuando cambian los datos/alturas, no por frame.
// view (item_h fijo):
lazy_list_fixed(
model.rows.len(), // total
28.0, // item_h
model.offset, // offset px (en el Model)
panel_h, // viewport_h
DEFAULT_OVERSCAN,
|i| fila_view(&model.rows[i]), // sólo se llama para lo visible
Msg::ScrollBy, // Fn(f32)->Msg, delta px
&ScrollPalette::default(),
)
// update:
Msg::ScrollBy(d) => {
m.offset = clamp_offset(m.offset + d, m.rows.len() as f32 * 28.0, panel_h);
}
Parte de llimphi — ver llimphi.