tawasuyu

tawasuyu/llimphi

Sovereign retained-mode GPU UI framework in Rust (wgpu+vello+taffy+parley), Elm loop, 40+ widgets.

Rust 660Markdown 302TOML 157RON 312382 Definiciones

⎇ c5a232cf24788ab75a850ffe81eca5a7af50e2f8 widgets/scroll/README.md Markdown · 51 líneas · 1.8 KB Historia crudo

chore: refresco desde el monorepo — 27 crates nuevos (anim, lottie, svg, mesh, image, layer, test, wire-view, widgets rag-sidebar/router/lazy-list/rive-button) y sync de los 95 existentes 93253cc22 · Sergio ·

1# llimphi-widget-scroll
2
3Reusable vertical scroll area.
4
5Until now every app rebuilt scrolling by hand: `App::on_wheel` + an offset in the
6`Model` + `clip` + virtualization. This widget packages that pattern into a single
7builder, **with no state of its own** (the offset still lives in the `Model`,
8true to the Elm loop):
9
10- a **clipped viewport** of fixed height (`viewport_len`),
11- **content displaced** by `-offset` px (overflow clipped),
12- a **draggable scrollbar** on the right (only when the content exceeds the
13  viewport),
14- a **self-contained wheel** through `View::on_scroll`: turning the wheel with
15  the cursor over the area emits a `Msg` without the app routing anything through
16  its global `on_wheel`.
17
18The caller must know the content's **total height** (`content_len`) and the
19**visible height** (`viewport_len`) — just as `list`/`grid` already ask for the
20visible window. For uniform rows that is `n_rows * row_height`.
21
22## The `on_scroll` callback convention
23
24`on_scroll` receives the **delta in px** to add to the offset (not the absolute
25offset): both the wheel and the scrollbar drag emit deltas, and the caller
26accumulates and clamps in its `update` with `clamp_offset`. It is the same idea
27as the `splitter` (the drag handler is reused for the whole drag, so a captured
28absolute offset would go stale; a delta per event is always correct).
29
30```ignore
31// view:
32scroll_y(
33    model.offset,
34    model.rows.len() as f32 * ROW_H,
35    panel_h,
36    list_view,
37    Msg::ScrollBy,            // Fn(f32) -> Msg, arg = delta px
38    &ScrollPalette::default(),
39)
40// update:
41Msg::ScrollBy(d) => {
42    m.offset = clamp_offset(m.offset + d, content_len, viewport_len);
43}
44```
45
46To bring a selection into view (keyboard) see `ensure_visible`; for smooth or
47inertial scrolling see `approach`.
48
49---
50
51Part of **llimphi** — see [llimphi](../../README.md).

README.md

llimphi-widget-scroll

Reusable vertical scroll area.

Until now every app rebuilt scrolling by hand: App::on_wheel + an offset in the Model + clip + virtualization. This widget packages that pattern into a single builder, with no state of its own (the offset still lives in the Model, true to the Elm loop):

The caller must know the content's total height (content_len) and the visible height (viewport_len) — just as list/grid already ask for the visible window. For uniform rows that is n_rows * row_height.

The on_scroll callback convention

on_scroll receives the delta in px to add to the offset (not the absolute offset): both the wheel and the scrollbar drag emit deltas, and the caller accumulates and clamps in its update with clamp_offset. It is the same idea as the splitter (the drag handler is reused for the whole drag, so a captured absolute offset would go stale; a delta per event is always correct).

// view:
scroll_y(
    model.offset,
    model.rows.len() as f32 * ROW_H,
    panel_h,
    list_view,
    Msg::ScrollBy,            // Fn(f32) -> Msg, arg = delta px
    &ScrollPalette::default(),
)
// update:
Msg::ScrollBy(d) => {
    m.offset = clamp_offset(m.offset + d, content_len, viewport_len);
}

To bring a selection into view (keyboard) see ensure_visible; for smooth or inertial scrolling see approach.


Part of llimphi — see llimphi.