use iris::prelude::*; const ROWS: usize = 800; const IMAGE_EVERY: usize = 12; fn row_text(i: usize) -> String { const SENTENCE: &str = "Iris lays out this row once and moves it on scroll, never re-laying it out. "; let repeats = 1 + (i * 7) % 5; format!("Message {i}: {}", SENTENCE.repeat(repeats)) } fn row_image(i: usize) -> iris::image::DynamicImage { let hue = ((i * 47) % 255) as u8; iris::image::RgbaImage::from_pixel(48, 48, iris::image::Rgba([hue, 128, 255 - hue, 255])).into() } fn build_row(rsc: &mut Rsc, i: usize) -> StrongWidget { let tint = if i.is_multiple_of(2) { Srgba8::rgb(120, 130, 170) } else { Srgba8::rgb(70, 80, 140) }; let text_color = PaintId::BLACK; if i.is_multiple_of(IMAGE_EVERY) { let text = wtext(row_text(i)) .overflow(TextOverflow::Wrap) .color(text_color) .add_strong(rsc) .any(); let img = image::(row_image(i))(rsc); let img = rsc.widgets_mut().add_strong(img).any(); let mut span = Span::empty(Dir::DOWN); span.push(text); span.push(img); span.pad(dp(8.0)) .background(rect(tint)) .add_strong(rsc) .any() } else { wtext(row_text(i)) .overflow(TextOverflow::Wrap) .color(text_color) .pad(dp(8.0)) .background(rect(tint)) .add_strong(rsc) .any() } } pub(crate) fn build(rsc: &mut Rsc, ui_state: &mut impl HasRoot) { let mut list = LazySpan::new(Dir::DOWN, Pin::End); for i in 0..ROWS { let row = build_row(rsc, i); list.push_back(LazyItem::new(i as u64, row)); } let root = list .scrollable() .masked() .background(rect(PaintId::WHITE)) .add_strong(rsc); ui_state.set_root(rsc, root.any()); }