aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/main.rs44
-rw-r--r--src/view.rs33
2 files changed, 46 insertions, 31 deletions
diff --git a/src/main.rs b/src/main.rs
index 1b4c351..d330bf8 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,7 +1,7 @@
use anyhow::Result;
use crossterm::{
cursor,
- event::{self, DisableMouseCapture, EnableMouseCapture, Event},
+ event::{DisableMouseCapture, EnableMouseCapture, Event},
queue,
style::{self, Print},
terminal,
@@ -18,7 +18,7 @@ use std::{
use unicode_width::UnicodeWidthChar;
mod view;
-use view::{Toc, Page, Search, View};
+use view::{Page, Search, Toc, View};
mod epub;
use epub::Chapter;
@@ -97,6 +97,7 @@ enum Direction {
}
pub struct Bk<'a> {
+ quit: bool,
chapters: Vec<epub::Chapter>,
// position in the book
chapter: usize,
@@ -108,7 +109,7 @@ pub struct Bk<'a> {
rows: usize,
max_width: u16,
// view state
- view: Option<&'a dyn View>,
+ view: &'a dyn View,
cursor: usize,
dir: Direction,
meta: Vec<String>,
@@ -138,6 +139,7 @@ impl Bk<'_> {
}
let mut bk = Bk {
+ quit: false,
chapters,
chapter: args.chapter,
line: 0,
@@ -146,7 +148,7 @@ impl Bk<'_> {
cols,
rows: rows as usize,
max_width: args.width,
- view: Some(if args.toc { &Toc } else { &Page }),
+ view: if args.toc { &Toc } else { &Page },
cursor: 0,
dir: Direction::Next,
meta,
@@ -171,21 +173,31 @@ impl Bk<'_> {
)?;
terminal::enable_raw_mode()?;
- while let Some(view) = self.view {
+ let mut render = |bk: &Bk| {
queue!(
stdout,
terminal::Clear(terminal::ClearType::All),
Print(style::Attribute::Reset)
- )?;
- for (i, line) in view.render(self).iter().enumerate() {
- queue!(stdout, cursor::MoveTo(self.pad(), i as u16), Print(line))?;
+ )
+ .unwrap();
+ for (i, line) in bk.view.render(bk).iter().enumerate() {
+ queue!(stdout, cursor::MoveTo(bk.pad(), i as u16), Print(line)).unwrap();
}
- queue!(stdout, cursor::MoveTo(self.pad(), self.cursor as u16))?;
+ queue!(stdout, cursor::MoveTo(bk.pad(), bk.cursor as u16)).unwrap();
stdout.flush().unwrap();
+ };
- match event::read()? {
- Event::Key(e) => view.on_key(self, e.code),
- Event::Mouse(e) => view.on_mouse(self, e),
+ render(self);
+ loop {
+ match crossterm::event::read()? {
+ Event::Key(e) => self.view.on_key(self, e.code),
+ Event::Mouse(e) => {
+ // XXX idk seems lame
+ if e.kind == crossterm::event::MouseEventKind::Moved {
+ continue;
+ }
+ self.view.on_mouse(self, e);
+ }
Event::Resize(cols, rows) => {
self.rows = rows as usize;
if cols != self.cols {
@@ -195,10 +207,14 @@ impl Bk<'_> {
c.lines = wrap(&c.text, width);
}
}
- view.on_resize(self);
+ self.view.on_resize(self);
// XXX marks aren't updated
}
}
+ if self.quit {
+ break;
+ }
+ render(self);
}
queue!(
@@ -256,7 +272,7 @@ impl Bk<'_> {
self.mark('\'');
self.query.clear();
self.dir = dir;
- self.view = Some(&Search);
+ self.view = &Search;
}
fn search(&mut self, args: SearchArgs) -> bool {
let (start, end) = self.chap().lines[self.line];
diff --git a/src/view.rs b/src/view.rs
index 1fdb449..6d4af33 100644
--- a/src/view.rs
+++ b/src/view.rs
@@ -1,8 +1,7 @@
use crossterm::{
event::{
KeyCode::{self, *},
- MouseEvent,
- MouseEventKind,
+ MouseEvent, MouseEventKind,
},
style::Attribute,
};
@@ -25,7 +24,7 @@ impl View for Mark {
if let Char(c) = kc {
bk.mark(c)
}
- bk.view = Some(&Page)
+ bk.view = &Page
}
fn render(&self, bk: &Bk) -> Vec<String> {
Page::render(&Page, bk)
@@ -40,7 +39,7 @@ impl View for Jump {
bk.jump(pos);
}
}
- bk.view = Some(&Page);
+ bk.view = &Page;
}
fn render(&self, bk: &Bk) -> Vec<String> {
Page::render(&Page, bk)
@@ -50,7 +49,7 @@ impl View for Jump {
struct Metadata;
impl View for Metadata {
fn on_key(&self, bk: &mut Bk, _: KeyCode) {
- bk.view = Some(&Page);
+ bk.view = &Page;
}
fn render(&self, bk: &Bk) -> Vec<String> {
let lines: Vec<usize> = bk.chapters.iter().map(|c| c.lines.len()).collect();
@@ -75,7 +74,7 @@ impl View for Metadata {
struct Help;
impl View for Help {
fn on_key(&self, bk: &mut Bk, _: KeyCode) {
- bk.view = Some(&Page);
+ bk.view = &Page;
}
fn render(&self, _: &Bk) -> Vec<String> {
let text = r#"
@@ -125,7 +124,7 @@ impl Toc {
if start + row < bk.chapters.len() {
bk.chapter = start + row;
bk.line = 0;
- bk.view = Some(&Page);
+ bk.view = &Page;
}
}
}
@@ -146,12 +145,12 @@ impl View for Toc {
Esc | Tab | Left | Char('h') | Char('q') => {
bk.jump_reset();
bk.cursor = 0;
- bk.view = Some(&Page);
+ bk.view = &Page;
}
Enter | Right | Char('l') => {
bk.cursor = 0;
bk.line = 0;
- bk.view = Some(&Page);
+ bk.view = &Page;
}
Down | Char('j') => self.next(bk, 1),
Up | Char('k') => self.prev(bk, 1),
@@ -236,16 +235,16 @@ impl View for Page {
}
fn on_key(&self, bk: &mut Bk, kc: KeyCode) {
match kc {
- Esc | Char('q') => bk.view = None,
+ Esc | Char('q') => bk.quit = true,
Tab => {
bk.mark('\'');
Toc.cursor(bk);
- bk.view = Some(&Toc);
+ bk.view = &Toc;
}
- F(_) => bk.view = Some(&Help),
- Char('m') => bk.view = Some(&Mark),
- Char('\'') => bk.view = Some(&Jump),
- Char('i') => bk.view = Some(&Metadata),
+ F(_) => bk.view = &Help,
+ Char('m') => bk.view = &Mark,
+ Char('\'') => bk.view = &Jump,
+ Char('i') => bk.view = &Metadata,
Char('?') => bk.start_search(Direction::Prev),
Char('/') => bk.start_search(Direction::Next),
Char('N') => {
@@ -380,10 +379,10 @@ impl View for Search {
match kc {
Esc => {
bk.jump_reset();
- bk.view = Some(&Page);
+ bk.view = &Page;
}
Enter => {
- bk.view = Some(&Page);
+ bk.view = &Page;
}
Backspace => {
bk.query.pop();