Files
iris/examples/message_list.rs
T

83 lines
2.3 KiB
Rust

use iris::prelude::*;
use winit::{dpi::LogicalSize, window::WindowAttributes};
fn main() {
DesktopApp::<State>::run();
}
#[derive(DesktopUiState)]
struct State {
ui_state: DesktopUiState,
}
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) -> image::DynamicImage {
let hue = ((i * 47) % 255) as u8;
image::RgbaImage::from_pixel(48, 48, image::Rgba([hue, 128, 255 - hue, 255])).into()
}
fn build_row<Rsc: UiRsc + 'static>(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))
.wrap(true)
.color(text_color)
.add_strong(rsc)
.any();
let img = image::<Rsc>(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))
.wrap(true)
.color(text_color)
.pad(dp(8.0))
.background(rect(tint))
.add_strong(rsc)
.any()
}
}
impl DesktopAppState for State {
fn window_attributes() -> WindowAttributes {
WindowAttributes::default().with_inner_size(LogicalSize::new(420.0, 900.0))
}
fn new(mut ui_state: DesktopUiState, rsc: &mut StdRsc<Self>, _: Proxy<Self::Event>) -> Self {
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());
Self { ui_state }
}
}