aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJames Campos <james.r.campos@gmail.com>2020-11-23 00:35:48 -0800
committerJames Campos <james.r.campos@gmail.com>2020-11-23 00:35:48 -0800
commit2a9bd053196deb7710729bc3541e7d5feb9e4856 (patch)
treed500c8259912989184165ea461d7eaa5fff8dfcf /src
parent1df2eb16f974de2dfc31fd1b4937ecbd3f7bc3be (diff)
downloadbk-2a9bd053196deb7710729bc3541e7d5feb9e4856.tar.gz
toc cursor #8
Diffstat (limited to 'src')
-rw-r--r--src/epub.rs2
-rw-r--r--src/main.rs5
-rw-r--r--src/view.rs102
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<String>,
- 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<String> {
- 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::<Vec<String>>();
+ 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),