summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCanop <cano.petrole@gmail.com>2019-02-12 18:22:46 +0100
committerCanop <cano.petrole@gmail.com>2019-02-12 18:22:46 +0100
commit0df47bef86caf3f20ebc294a7151af5502828a10 (patch)
treea2f65cf82ccc3124d27b69cde7b4267599c68b99
parent644071f3b60cefb0e88288bde8374decac772403 (diff)
add a scrollbar on help screen
-rw-r--r--src/screen_text.rs26
-rw-r--r--src/screens.rs46
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))
}
}