diff options
author | Canop <cano.petrole@gmail.com> | 2019-02-12 18:22:46 +0100 |
---|---|---|
committer | Canop <cano.petrole@gmail.com> | 2019-02-12 18:22:46 +0100 |
commit | 0df47bef86caf3f20ebc294a7151af5502828a10 (patch) | |
tree | a2f65cf82ccc3124d27b69cde7b4267599c68b99 | |
parent | 644071f3b60cefb0e88288bde8374decac772403 (diff) |
add a scrollbar on help screen
-rw-r--r-- | src/screen_text.rs | 26 | ||||
-rw-r--r-- | src/screens.rs | 46 |
2 files changed, 25 insertions, 47 deletions
diff --git a/src/screen_text.rs b/src/screen_text.rs index 046e5bd..97d5d13 100644 --- a/src/screen_text.rs +++ b/src/screen_text.rs @@ -4,7 +4,7 @@ //! broot are implemented. use regex::Regex; -use std::io; +use std::io::{self, Write}; use termion::{color, style}; use crate::screens::{Screen, ScreenArea}; @@ -54,8 +54,30 @@ impl Text { pub fn push(&mut self, line: String) { self.lines.push(line); } + // write the text in the area, taking into account the scrolled amount + // and drawing a vertical scrollbar at the right if needed pub fn write(&self, screen: &mut Screen, area: &ScreenArea) -> io::Result<()> { - screen.write_lines(area, &self.lines) + let scrollbar = area.scrollbar(); + let mut i = area.scroll as usize; + for y in area.top..=area.bottom { + write!( + screen.stdout, + "{}{}", + termion::cursor::Goto(1, y), + termion::clear::CurrentLine, + )?; + if i < self.lines.len() { + write!(screen.stdout, "{}", &self.lines[i],)?; + i += 1; + } + if let Some((sctop, scbottom)) = scrollbar { + if sctop <= y && y <= scbottom { + write!(screen.stdout, "{}▐", termion::cursor::Goto(screen.w, y),)?; + } + } + } + screen.stdout.flush()?; + Ok(()) } } diff --git a/src/screens.rs b/src/screens.rs index 3965954..952cca2 100644 --- a/src/screens.rs +++ b/src/screens.rs @@ -1,5 +1,4 @@ use std::io::{self, stdout, Write}; -use termion::color; use termion::raw::{IntoRawMode, RawTerminal}; use termion::screen::AlternateScreen; @@ -32,23 +31,6 @@ impl Screen { self.h = h; Ok(()) } - pub fn write_lines(&mut self, area: &ScreenArea, lines: &[String]) -> io::Result<()> { - let mut i = area.scroll as usize; - for y in area.top..=area.bottom { - write!( - self.stdout, - "{}{}", - termion::cursor::Goto(1, y), - termion::clear::CurrentLine, - )?; - if i < lines.len() { - write!(self.stdout, "{}", &lines[i],)?; - i += 1; - } - } - self.stdout.flush()?; - Ok(()) - } } impl Drop for Screen { @@ -78,32 +60,6 @@ impl ScreenArea { self.scroll = self.content_length - 1; } } - // draw a scrollbar at the righ, above content. - // clears nothing before. - // (note that this may lead to flickering) - #[allow(dead_code)] - pub fn draw_scrollbar(&self, screen: &mut Screen) -> io::Result<()> { - let h = i32::from(self.bottom) - i32::from(self.top) + 1; - if self.content_length > h { - let sbh = h * h / self.content_length; - let sc = i32::from(self.top) + self.scroll * h / self.content_length; - write!( - screen.stdout, - "{}", - color::Fg(color::AnsiValue::grayscale(9)), - )?; - for y in 0..sbh { - write!( - screen.stdout, - "{}▐", - termion::cursor::Goto(screen.w, ((y + sc) as u16).min(self.bottom - 1)), - )?; - } - write!(screen.stdout, "{}", color::Fg(color::Reset),)?; - } - Ok(()) - } - // returns the top and bottom of the scrollbar, if any pub fn scrollbar(&self) -> Option<(u16, u16)> { let h = (self.bottom as i32) - (self.top as i32) + 1; if self.content_length <= h { @@ -111,6 +67,6 @@ impl ScreenArea { } let sbh = h * h / self.content_length; let sc = i32::from(self.top) + self.scroll * h / self.content_length; - Some((sc as u16, (sc + sbh).min(i32::from(self.bottom) - 1) as u16)) + Some((sc as u16, (sc + sbh - 1).min(i32::from(self.bottom)) as u16)) } } |