From 2a9bd053196deb7710729bc3541e7d5feb9e4856 Mon Sep 17 00:00:00 2001 From: James Campos Date: Mon, 23 Nov 2020 00:35:48 -0800 Subject: toc cursor #8 --- src/epub.rs | 2 +- src/main.rs | 5 +-- src/view.rs | 102 +++++++++++++++++++++++------------------------------------- 3 files changed, 43 insertions(+), 66 deletions(-) diff --git a/src/epub.rs b/src/epub.rs index 9c53551..496ee96 100644 --- a/src/epub.rs +++ b/src/epub.rs @@ -200,7 +200,7 @@ fn render(n: Node, c: &mut Chapter) { c.render(n, Attribute::Underlined, Attribute::NoUnderline); c.links.push((start, c.text.len(), url.to_string())); } - _ => c.render_text(n) + _ => c.render_text(n), } } "em" => c.render(n, Attribute::Italic, Attribute::NoItalic), diff --git a/src/main.rs b/src/main.rs index 0b322c8..1792dfb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -109,9 +109,9 @@ pub struct Bk<'a> { max_width: u16, // view state view: Option<&'a dyn View>, + cursor: usize, dir: Direction, meta: Vec, - nav_top: usize, query: String, } @@ -147,9 +147,9 @@ impl Bk<'_> { rows: rows as usize, max_width: args.width, view: Some(if args.toc { &Nav } else { &Page }), + cursor: 0, dir: Direction::Next, meta, - nav_top: 0, query: String::new(), }; @@ -180,6 +180,7 @@ impl Bk<'_> { for (i, line) in view.render(self).iter().enumerate() { queue!(stdout, cursor::MoveTo(self.pad(), i as u16), Print(line))?; } + queue!(stdout, cursor::MoveTo(self.pad(), self.cursor as u16))?; stdout.flush().unwrap(); match event::read()? { diff --git a/src/view.rs b/src/view.rs index 2f0ecfc..cdb2ceb 100644 --- a/src/view.rs +++ b/src/view.rs @@ -5,7 +5,7 @@ use crossterm::{ }, style::Attribute, }; -use std::cmp::{max, min, Ordering}; +use std::cmp::{min, Ordering}; use unicode_width::UnicodeWidthChar; use crate::{get_line, Bk, Direction, SearchArgs}; @@ -106,50 +106,32 @@ PageDown Right Space f l Page Down pub struct Nav; impl Nav { - fn start(&self, bk: &mut Bk) { - bk.nav_top = bk.chapter.saturating_sub(bk.rows / 2); - bk.mark('\''); - bk.view = Some(&Self); + fn prev(&self, bk: &mut Bk, n: usize) { + bk.chapter = bk.chapter.saturating_sub(n); + self.cursor(bk); } - fn prev_chapter(&self, bk: &mut Bk) { - if bk.chapter > 0 { - if bk.chapter == bk.nav_top { - bk.nav_top -= 1; - } - bk.chapter -= 1; - } + fn next(&self, bk: &mut Bk, n: usize) { + bk.chapter = min(bk.chapters.len() - 1, bk.chapter + n); + self.cursor(bk); } - fn next_chapter(&self, bk: &mut Bk) { - if bk.chapter < bk.chapters.len() - 1 { - bk.chapter += 1; - if bk.chapter == bk.nav_top + bk.rows { - bk.nav_top += 1; - } - } - } - fn scroll_down(&self, bk: &mut Bk, n: usize) { - bk.nav_top = min(bk.nav_top + n, bk.chapters.len() - 1); - bk.chapter = max(bk.chapter, bk.nav_top); - } - fn scroll_up(&self, bk: &mut Bk, n: usize) { - bk.nav_top = bk.nav_top.saturating_sub(n); - bk.chapter = min(bk.chapter, bk.nav_top + bk.rows - 1); + fn cursor(&self, bk: &mut Bk) { + bk.cursor = min(bk.rows / 2, bk.chapter); } fn click(&self, bk: &mut Bk, row: usize) { - if bk.nav_top + row < bk.chapters.len() { - bk.chapter = bk.nav_top + row; + let start = bk.chapter - bk.cursor; + if start + row < bk.chapters.len() { + bk.chapter = start + row; bk.line = 0; bk.view = Some(&Page); } } } - impl View for Nav { fn on_mouse(&self, bk: &mut Bk, e: MouseEvent) { match e { MouseEvent::Down(_, _, row, _) => self.click(bk, row as usize), - MouseEvent::ScrollDown(_, _, _) => self.scroll_down(bk, 3), - MouseEvent::ScrollUp(_, _, _) => self.scroll_up(bk, 3), + MouseEvent::ScrollDown(_, _, _) => self.next(bk, 3), + MouseEvent::ScrollUp(_, _, _) => self.prev(bk, 3), _ => (), } } @@ -163,42 +145,32 @@ impl View for Nav { bk.line = 0; bk.view = Some(&Page); } - Down | Char('j') => self.next_chapter(bk), - Up | Char('k') => self.prev_chapter(bk), - Home | Char('g') => { - bk.chapter = 0; - bk.nav_top = 0; - } - End | Char('G') => { - bk.chapter = bk.chapters.len() - 1; - bk.nav_top = bk.chapters.len().saturating_sub(bk.rows); - } - PageDown | Char('f') => self.scroll_down(bk, bk.rows), - PageUp | Char('b') => self.scroll_up(bk, bk.rows), - Char('d') => self.scroll_down(bk, bk.rows / 2), - Char('u') => self.scroll_up(bk, bk.rows / 2), + Down | Char('j') => self.next(bk, 1), + Up | Char('k') => self.prev(bk, 1), + Home | Char('g') => self.prev(bk, bk.chapters.len()), + End | Char('G') => self.next(bk, bk.chapters.len()), + PageDown | Char('f') => self.next(bk, bk.rows), + PageUp | Char('b') => self.prev(bk, bk.rows), + Char('d') => self.next(bk, bk.rows / 2), + Char('u') => self.prev(bk, bk.rows / 2), _ => (), } } fn render(&self, bk: &Bk) -> Vec { - let end = min(bk.nav_top + bk.rows, bk.chapters.len()); + let start = bk.chapter - bk.cursor; + let end = min(bk.chapters.len(), start + bk.rows); - bk.chapters[bk.nav_top..end] + let mut arr = bk.chapters[start..end] .iter() - .enumerate() - .map(|(i, chapter)| { - if bk.chapter == bk.nav_top + i { - format!( - "{}{}{}", - Attribute::Reverse, - chapter.title, - Attribute::Reset - ) - } else { - chapter.title.to_string() - } - }) - .collect() + .map(|c| c.title.clone()) + .collect::>(); + arr[bk.cursor] = format!( + "{}{}{}", + Attribute::Reverse, + arr[bk.cursor], + Attribute::Reset + ); + arr } } @@ -257,7 +229,11 @@ impl View for Page { fn on_key(&self, bk: &mut Bk, kc: KeyCode) { match kc { Esc | Char('q') => bk.view = None, - Tab => Nav.start(bk), + Tab => { + bk.mark('\''); + Nav.cursor(bk); + bk.view = Some(&Nav); + } F(_) => bk.view = Some(&Help), Char('m') => bk.view = Some(&Mark), Char('\'') => bk.view = Some(&Jump), -- cgit v1.2.3