rs-calendar/src/ui/list.rs

66 lines
1.6 KiB
Rust

trait ListContentProvider<Item> {
/// Get the number of items provided
fn get_count(&self) -> i64;
fn get_item(&self, index: i64) -> Item;
}
trait ListLabelProvider<Item> {
fn get_label(&self, item: &Item) -> str;
}
trait CellRenderer {
fn new() -> Self;
/// Get the height of a single cell
fn height(&self) -> i64;
}
struct ListView<'a, Item, R: CellRenderer> {
content_provider: &'a dyn ListContentProvider<Item>,
label_provider: &'a dyn ListLabelProvider<Item>,
cell_renderer: R,
x: i64,
}
/// A ListView is responsible for:
/// - get number of objects from the content provider
/// - manage the range of visible objects
/// - retrieve objects to be rendered from the content provider
///
impl<'a, Item, R: CellRenderer> ListView<'a, Item, R> {
pub fn new(content_provider: &'a dyn ListContentProvider<Item>, label_provider: &'a dyn ListLabelProvider<Item>) -> Self {
ListView::<'a, Item, R> {
content_provider,
label_provider,
cell_renderer: CellRenderer::new(),
x: 0,
}
}
pub fn refresh(&mut self) {
let list_height = self.content_provider.get_count() * self.cell_renderer.height();
if self.x > list_height {
self.x = list_height;
}
}
pub fn top_item(&self) -> Item {
let index = self.x / self.cell_renderer.height();
self.content_provider.get_item(index)
}
/// move the viewport on the list by the given amount
pub fn move_by(&mut self, delta: i64) {
self.x += delta;
self.refresh();
}
}