From a13f63f34272889239d1e0fcd37f9c4fb5ec983a Mon Sep 17 00:00:00 2001 From: lukeflo Date: Fri, 27 Sep 2024 23:48:46 +0200 Subject: implement scroll action for info box --- Cargo.toml | 3 ++- src/frontend/app.rs | 48 ++++++++++-------------------------------------- src/frontend/handler.rs | 2 +- src/frontend/ui.rs | 22 +++++++++++++++++++++- src/main.rs | 5 +---- 5 files changed, 35 insertions(+), 45 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index d2a78e2..7983fbc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,8 @@ biblatex = "0.9.3" crossterm = { version = "0.28.1", features = ["event-stream"] } futures = "0.3.30" itertools = "0.13.0" -ratatui = "0.28.1" +# ratatui = "0.28.1" +ratatui = { version = "0.28.1", features = ["unstable-rendered-line-info"]} regex = "1.10.6" sarge = "7.2.5" tokio = { version = "1.39.3", features = ["full"] } diff --git a/src/frontend/app.rs b/src/frontend/app.rs index 7a211e8..1a8eab7 100644 --- a/src/frontend/app.rs +++ b/src/frontend/app.rs @@ -42,9 +42,9 @@ pub struct App { pub main_biblio: BibiMain, // bibliographic data pub biblio_data: BibiData, - // list + // tag list pub tag_list: TagList, - // TODO: table items + // table items pub entry_table: EntryTable, // scroll state info buffer pub scroll_info: u16, @@ -59,14 +59,7 @@ pub struct TagList { pub tag_list_state: ListState, } -// Structure of the list items. Can be a simple string or something more elaborated -// eg: -// struct TagListItem { -// todo: String, -// info: String, -// status: Status, -// } -// where Status has to be defined explicitly somewhere else +// Structure of the list items. #[derive(Debug)] pub struct TagListItem { pub info: String, @@ -81,13 +74,10 @@ impl TagListItem { } } -// INFO: in the original template it was <&'static str> instead of impl FromIterator for TagList { - // INFO: Here to originally <&'static str> fn from_iter>(iter: I) -> Self { let tag_list_items = iter .into_iter() - // INFO: here originally not borrowed (without Ampersand'&') .map(|info| TagListItem::new(&info)) .collect(); let tag_list_state = ListState::default(); // for preselection: .with_selected(Some(0)); @@ -98,31 +88,9 @@ impl FromIterator for TagList { } } -// Iterate over vector fields with entries data to create TableItems -// Number of Strings has to match number of fields -// impl FromIterator<[String; 5]> for EntryTable { -// fn from_iter>(iter: T) -> Self { -// // Has to be Vev -// let entry_table_items = iter -// .into_iter() -// // fields in map must not be named specific -// .map(|[authors, title, year, pubtype, citekey]| { -// EntryTableItem::new(&authors, &title, &year, &pubtype, &citekey) -// }) -// .sorted_by(|a, b| a.authors.cmp(&b.authors)) -// .collect(); -// let entry_table_state = TableState::default().with_selected(0); -// Self { -// entry_table_items, -// entry_table_state, -// } -// } -// } - -// // Also possible with vector. TODO: Decide whats better +// // Also possible with vector. impl FromIterator> for EntryTable { fn from_iter>>(iter: T) -> Self { - // Has to be Vev let entry_table_items = iter .into_iter() .sorted() @@ -235,14 +203,14 @@ impl App { } pub fn scroll_info_down(&mut self) { - self.scroll_info = (self.scroll_info + 1) % 10; + self.scroll_info = (self.scroll_info + 1); } pub fn scroll_info_up(&mut self) { if self.scroll_info == 0 { {} } else { - self.scroll_info = (self.scroll_info - 1) % 10; + self.scroll_info = (self.scroll_info - 1); } } @@ -255,6 +223,7 @@ impl App { } pub fn select_next(&mut self) { + self.scroll_info = 0; match self.current_area { CurrentArea::EntryArea => self.entry_table.entry_table_state.select_next(), CurrentArea::TagArea => self.tag_list.tag_list_state.select_next(), @@ -262,6 +231,7 @@ impl App { // self.tag_list.tag_list_state.select_next(); } pub fn select_previous(&mut self) { + self.scroll_info = 0; match self.current_area { CurrentArea::EntryArea => self.entry_table.entry_table_state.select_previous(), CurrentArea::TagArea => self.tag_list.tag_list_state.select_previous(), @@ -270,6 +240,7 @@ impl App { } pub fn select_first(&mut self) { + self.scroll_info = 0; match self.current_area { CurrentArea::EntryArea => self.entry_table.entry_table_state.select_first(), CurrentArea::TagArea => self.tag_list.tag_list_state.select_first(), @@ -278,6 +249,7 @@ impl App { } pub fn select_last(&mut self) { + self.scroll_info = 0; match self.current_area { CurrentArea::EntryArea => self.entry_table.entry_table_state.select_last(), CurrentArea::TagArea => self.tag_list.tag_list_state.select_last(), diff --git a/src/frontend/handler.rs b/src/frontend/handler.rs index a9b79a0..73f30ae 100644 --- a/src/frontend/handler.rs +++ b/src/frontend/handler.rs @@ -25,7 +25,7 @@ pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> { // Keycodes activated for every area (high priority) match key_event.code { // Exit application on `ESC` or `q` - KeyCode::Esc | KeyCode::Char('q') => { + KeyCode::Char('Q') | KeyCode::Char('q') => { app.quit(); } // Exit application on `Ctrl-C` diff --git a/src/frontend/ui.rs b/src/frontend/ui.rs index 8d5dcd8..5413194 100644 --- a/src/frontend/ui.rs +++ b/src/frontend/ui.rs @@ -229,12 +229,32 @@ impl App { .bg(Color::Black) .padding(Padding::horizontal(1)); + // INFO: '.line_count' method only possible with unstable-rendered-line-info feature -> API might change: https://github.com/ratatui/ratatui/issues/293#ref-pullrequest-2027056434 + let box_height = Paragraph::new(info.clone()) + .block(block.clone()) + .wrap(Wrap { trim: false }) + .line_count(area.width); + // Make sure to allow scroll only if text is larger than the rendered area and stop scrolling when last line is reached + let scroll_height = { + if self.scroll_info == 0 { + self.scroll_info + } else if area.height > box_height as u16 { + self.scroll_info = 0; + self.scroll_info + } else if self.scroll_info > (box_height as u16 + 1 - area.height) { + self.scroll_info = box_height as u16 + 1 - area.height; + self.scroll_info + } else { + self.scroll_info + } + }; + // We can now render the item info Paragraph::new(info) .block(block) // .fg(TEXT_FG_COLOR) .wrap(Wrap { trim: false }) - .scroll((self.scroll_info, 0)) + .scroll((scroll_height, 0)) .render(area, buf); } diff --git a/src/main.rs b/src/main.rs index 6ffff25..cf7375f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -17,10 +17,7 @@ use std::io; -use backend::{ - bib::{BibiData, BibiMain}, - cliargs::{self, CLIArgs}, -}; +use backend::cliargs::{self, CLIArgs}; use ratatui::{backend::CrosstermBackend, Terminal}; use crate::{ -- cgit v1.2.3