From dcaf8a8df90b7460080bfd4e8d8f7559600d52e5 Mon Sep 17 00:00:00 2001 From: Fabrizio Iannetti Date: Sat, 28 Jan 2023 09:31:22 +0100 Subject: [PATCH] ui: add experimental list view element (not used) Signed-off-by: Fabrizio Iannetti --- src/ui.rs | 3 ++- src/ui/list.rs | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 src/ui/list.rs diff --git a/src/ui.rs b/src/ui.rs index 0032523..b405d4a 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -1,2 +1,3 @@ pub mod calendar; -pub mod basics; \ No newline at end of file +pub mod basics; +pub mod list; \ No newline at end of file diff --git a/src/ui/list.rs b/src/ui/list.rs new file mode 100644 index 0000000..a9e7993 --- /dev/null +++ b/src/ui/list.rs @@ -0,0 +1,65 @@ + +trait ListContentProvider { + + /// Get the number of items provided + fn get_count(&self) -> i64; + + fn get_item(&self, index: i64) -> Item; +} + +trait ListLabelProvider { + + 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, + label_provider: &'a dyn ListLabelProvider, + 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, label_provider: &'a dyn ListLabelProvider) -> 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(); + } + +}