adapter_sim/
adapter_sim.rs

1// Example: adapter-style walkthrough (events, pinned header, measurement, disabling).
2use std::sync::Arc;
3use std::sync::atomic::{AtomicU64, Ordering};
4
5use virtualizer::{Align, Range, Rect, Virtualizer, VirtualizerOptions};
6
7fn main() {
8    // Simulate a framework adapter that owns the scroll state.
9    let saved_scroll = Arc::new(AtomicU64::new(120));
10
11    let opts = VirtualizerOptions::new(1000, |_| 1)
12        .with_initial_rect(Some(Rect {
13            main: 10,
14            cross: 80,
15        }))
16        .with_initial_offset_provider({
17            let saved_scroll = Arc::clone(&saved_scroll);
18            move || saved_scroll.load(Ordering::Relaxed)
19        })
20        .with_scroll_margin(5)
21        .with_range_extractor(Some(|r: Range, emit: &mut dyn FnMut(usize)| {
22            // Pin a "sticky header" at index 0, regardless of scroll position.
23            let mut e = virtualizer::IndexEmitter::new(r, emit);
24            e.emit_pinned(0);
25            e.emit_visible();
26        }));
27
28    let mut v = Virtualizer::new(opts);
29
30    // First render: scroll offset comes from the provider.
31    println!("initial scroll_offset={}", v.scroll_offset());
32    println!("initial scroll_rect={:?}", v.scroll_rect());
33
34    // Adapter updates rect + scroll offset on events.
35    v.apply_scroll_frame(
36        Rect {
37            main: 12,
38            cross: 80,
39        },
40        200,
41        0,
42    );
43
44    let mut items = Vec::new();
45    v.for_each_virtual_item_keyed(|it| items.push(it));
46    println!(
47        "is_scrolling={}, visible_range={:?}, items_len={}",
48        v.is_scrolling(),
49        v.visible_range(),
50        items.len()
51    );
52    println!("first_item={:?}", items.first());
53
54    // Demonstrate scroll-to helpers.
55    let target = v.scroll_to_index_offset(500, Align::Start);
56    v.set_scroll_offset_clamped(target);
57    println!("after scroll_to_index: scroll_offset={}", v.scroll_offset());
58
59    // Demonstrate dynamic measurement + scroll adjustment.
60    let applied = v.resize_item(0, 20);
61    println!("resize_item applied_scroll_adjustment={applied}");
62
63    // Simulate reorder: change key mapping. This automatically rebuilds per-index sizes from the
64    // key-based measurement cache. In real apps, you usually keep `get_item_key` stable and call
65    // `sync_item_keys()` when your dataset is reordered while `count` stays the same.
66    v.set_get_item_key(|i| if i == 0 { 1 } else { i as u64 });
67
68    // Debounced scrolling reset without relying on a native scrollend event.
69    v.update_scrolling(200);
70    println!("after update_scrolling: is_scrolling={}", v.is_scrolling());
71
72    // Toggle enabled to disable all queries.
73    v.set_enabled(false);
74    let mut disabled_len = 0usize;
75    v.for_each_virtual_item(|_| disabled_len += 1);
76    println!(
77        "disabled total_size={}, items_len={}",
78        v.total_size(),
79        disabled_len
80    );
81}