Still needs flickering reduction
This commit is contained in:
parent
7fb37a8f35
commit
2c98b3b3a6
156
src/lib.rs
156
src/lib.rs
|
@ -145,6 +145,12 @@ pub struct Tile {
|
||||||
|
|
||||||
/// Coordinates of the tile.
|
/// Coordinates of the tile.
|
||||||
pub coords: (u16, u16),
|
pub coords: (u16, u16),
|
||||||
|
|
||||||
|
/// The number of lines that the stdout is scrolled.
|
||||||
|
pub scroll: isize,
|
||||||
|
|
||||||
|
/// The number of lines that stdout will print.
|
||||||
|
pub max_scroll: isize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Tile {
|
impl Tile {
|
||||||
|
@ -158,6 +164,8 @@ impl Tile {
|
||||||
stdout: vec![],
|
stdout: vec![],
|
||||||
sender,
|
sender,
|
||||||
coords: (i, j),
|
coords: (i, j),
|
||||||
|
scroll: 0,
|
||||||
|
max_scroll: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -234,7 +242,7 @@ impl Tile {
|
||||||
}
|
}
|
||||||
|
|
||||||
sender
|
sender
|
||||||
.send(Msg::Stdout(coords.0, coords.1, String::new()))
|
.send(Msg::Stdout(coords.0, coords.1, String::from("\n")))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let code = child.wait().unwrap().code().unwrap();
|
let code = child.wait().unwrap().code().unwrap();
|
||||||
|
@ -312,38 +320,35 @@ impl<W: Write> Multiview<W> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Draws a box from (x1, y1) to (x2, y2).
|
/// Draws a box from (x1, y1) to (x2, y2).
|
||||||
pub fn rect(&mut self, (x1, y1): (u16, u16), (x2, y2): (u16, u16)) -> io::Result<()> {
|
pub fn rect(&mut self, (x1, y1): (u16, u16), (x2, y2): (u16, u16)) -> String {
|
||||||
write!(self.stdout, "{}┌", cursor::Goto(x1, y1))?;
|
let mut buffer = vec![];
|
||||||
|
|
||||||
|
buffer.push(format!("{}┌", cursor::Goto(x1, y1)));
|
||||||
|
|
||||||
for _ in (x1 + 1)..x2 {
|
for _ in (x1 + 1)..x2 {
|
||||||
write!(self.stdout, "─")?;
|
buffer.push(format!("─"));
|
||||||
}
|
}
|
||||||
|
|
||||||
write!(self.stdout, "┐")?;
|
buffer.push(format!("┐"));
|
||||||
|
|
||||||
for y in (y1 + 1)..y2 {
|
for y in (y1 + 1)..y2 {
|
||||||
write!(self.stdout, "{}│", cursor::Goto(x1, y))?;
|
buffer.push(format!("{}│", cursor::Goto(x1, y)));
|
||||||
write!(self.stdout, "{}│", cursor::Goto(x2, y))?;
|
buffer.push(format!("{}│", cursor::Goto(x2, y)));
|
||||||
}
|
}
|
||||||
|
|
||||||
write!(self.stdout, "{}└", cursor::Goto(x1, y2))?;
|
buffer.push(format!("{}└", cursor::Goto(x1, y2)));
|
||||||
|
|
||||||
for _ in (x1 + 1)..x2 {
|
for _ in (x1 + 1)..x2 {
|
||||||
write!(self.stdout, "─")?;
|
buffer.push(format!("─"));
|
||||||
}
|
}
|
||||||
|
|
||||||
write!(self.stdout, "┘")?;
|
buffer.push(format!("┘"));
|
||||||
|
|
||||||
Ok(())
|
buffer.join("")
|
||||||
}
|
|
||||||
|
|
||||||
/// Clears stdout.
|
|
||||||
pub fn clear(&mut self) -> io::Result<()> {
|
|
||||||
write!(self.stdout, "{}", clear::All)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Renders the (x, y) tile.
|
/// Renders the (x, y) tile.
|
||||||
pub fn render_tile(&mut self, (i, j): (u16, u16), term_size: (u16, u16)) -> io::Result<()> {
|
pub fn render_tile(&mut self, (i, j): (u16, u16), term_size: (u16, u16)) -> String {
|
||||||
let w = term_size.0 / self.tiles[0].len() as u16;
|
let w = term_size.0 / self.tiles[0].len() as u16;
|
||||||
let h = term_size.1 / self.tiles.len() as u16;
|
let h = term_size.1 / self.tiles.len() as u16;
|
||||||
|
|
||||||
|
@ -356,6 +361,8 @@ impl<W: Write> Multiview<W> {
|
||||||
let tile = &self.tile((i, j));
|
let tile = &self.tile((i, j));
|
||||||
let command_str = tile.command.join(" ");
|
let command_str = tile.command.join(" ");
|
||||||
|
|
||||||
|
let mut buffer = vec![];
|
||||||
|
|
||||||
// TODO: find a way to avoid this copy
|
// TODO: find a way to avoid this copy
|
||||||
let lines = tile
|
let lines = tile
|
||||||
.stdout
|
.stdout
|
||||||
|
@ -371,8 +378,12 @@ impl<W: Write> Multiview<W> {
|
||||||
command_str
|
command_str
|
||||||
};
|
};
|
||||||
|
|
||||||
write!(
|
let mut counting = true;
|
||||||
self.stdout,
|
let mut line_index = 0;
|
||||||
|
let mut current_char_index = 0;
|
||||||
|
let scroll = tile.scroll as u16;
|
||||||
|
|
||||||
|
buffer.push(format!(
|
||||||
"{}{} {}Command: {}{}{}",
|
"{}{} {}Command: {}{}{}",
|
||||||
color::Reset.fg_str(),
|
color::Reset.fg_str(),
|
||||||
cursor::Goto(x1 + 1, y1 + 1),
|
cursor::Goto(x1 + 1, y1 + 1),
|
||||||
|
@ -380,11 +391,7 @@ impl<W: Write> Multiview<W> {
|
||||||
command_str,
|
command_str,
|
||||||
style::Reset,
|
style::Reset,
|
||||||
cursor::Goto(x1 + 2, y1 + 3),
|
cursor::Goto(x1 + 2, y1 + 3),
|
||||||
)?;
|
));
|
||||||
|
|
||||||
let mut counting = true;
|
|
||||||
let mut line_index = 0;
|
|
||||||
let mut current_char_index = 0;
|
|
||||||
|
|
||||||
for line in lines {
|
for line in lines {
|
||||||
for c in line.chars() {
|
for c in line.chars() {
|
||||||
|
@ -396,20 +403,32 @@ impl<W: Write> Multiview<W> {
|
||||||
'\n' => {
|
'\n' => {
|
||||||
line_index += 1;
|
line_index += 1;
|
||||||
current_char_index = 0;
|
current_char_index = 0;
|
||||||
write!(
|
|
||||||
self.stdout,
|
if line_index >= scroll && line_index < h + scroll {
|
||||||
"{}",
|
if current_char_index < w {
|
||||||
cursor::Goto(x1 + 2, y1 + 3 + line_index as u16)
|
let mut spaces = String::new();
|
||||||
)?;
|
for _ in 0..w - current_char_index {
|
||||||
|
spaces.push(' ');
|
||||||
|
}
|
||||||
|
buffer.push(spaces);
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer.push(format!(
|
||||||
|
"{}",
|
||||||
|
cursor::Goto(x1 + 2, y1 + 3 + line_index as u16 - scroll)
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
'\r' => {
|
'\r' => {
|
||||||
current_char_index = 0;
|
current_char_index = 0;
|
||||||
write!(
|
|
||||||
self.stdout,
|
if line_index >= scroll && line_index < h + scroll {
|
||||||
"{}",
|
buffer.push(format!(
|
||||||
cursor::Goto(x1 + 2, y1 + 3 + line_index as u16)
|
"{}",
|
||||||
)?;
|
cursor::Goto(x1 + 2, y1 + 3 + line_index as u16 - scroll)
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
|
@ -420,13 +439,18 @@ impl<W: Write> Multiview<W> {
|
||||||
if current_char_index == w - 3 {
|
if current_char_index == w - 3 {
|
||||||
line_index += 1;
|
line_index += 1;
|
||||||
current_char_index = 1;
|
current_char_index = 1;
|
||||||
write!(
|
|
||||||
self.stdout,
|
if line_index >= scroll && line_index < h + scroll {
|
||||||
"{}",
|
buffer.push(format!(
|
||||||
cursor::Goto(x1 + 2, y1 + 3 + line_index as u16)
|
"{}",
|
||||||
)?;
|
cursor::Goto(x1 + 2, y1 + 3 + line_index as u16 - scroll)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if line_index >= scroll && line_index < h + scroll {
|
||||||
|
buffer.push(format!("{}", c));
|
||||||
}
|
}
|
||||||
write!(self.stdout, "{}", c)?;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -436,35 +460,57 @@ impl<W: Write> Multiview<W> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.selected == (i, j) {
|
let tile = self.tile_mut((i, j));
|
||||||
write!(self.stdout, "{}", color::Green.fg_str())?;
|
if tile.max_scroll != line_index as isize {
|
||||||
|
tile.max_scroll = line_index as isize;
|
||||||
|
tile.scroll = tile.max_scroll - h as isize + 5;
|
||||||
|
if tile.scroll < 0 {
|
||||||
|
tile.scroll = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
self.rect((x1, y1), (x2, y2))?;
|
|
||||||
write!(self.stdout, "{}├", cursor::Goto(x1, y1 + 2))?;
|
if self.selected == (i, j) {
|
||||||
|
buffer.push(format!("{}", color::Green.fg_str()));
|
||||||
|
}
|
||||||
|
buffer.push(self.rect((x1, y1), (x2, y2)));
|
||||||
|
buffer.push(format!("{}├", cursor::Goto(x1, y1 + 2)));
|
||||||
|
|
||||||
for _ in (x1 + 1)..x2 {
|
for _ in (x1 + 1)..x2 {
|
||||||
write!(self.stdout, "─")?;
|
buffer.push(format!("─"));
|
||||||
}
|
}
|
||||||
|
|
||||||
write!(self.stdout, "{}┤", cursor::Goto(x2, y1 + 2))?;
|
buffer.push(format!("{}┤", cursor::Goto(x2, y1 + 2)));
|
||||||
|
|
||||||
Ok(())
|
buffer.join("")
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Renders all the tiles of the multiview.
|
/// Renders all the tiles of the multiview.
|
||||||
pub fn render(&mut self, term_size: (u16, u16)) -> io::Result<()> {
|
pub fn render(&mut self, term_size: (u16, u16)) -> io::Result<()> {
|
||||||
self.clear()?;
|
let mut buffer = vec![];
|
||||||
|
|
||||||
for i in 0..self.tiles.len() {
|
for i in 0..self.tiles.len() {
|
||||||
for j in 0..self.tiles[0].len() {
|
for j in 0..self.tiles[0].len() {
|
||||||
self.render_tile((i as u16, j as u16), term_size)?;
|
buffer.push(self.render_tile((i as u16, j as u16), term_size));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
write!(self.stdout, "{}", buffer.join(""))?;
|
||||||
self.stdout.flush()?;
|
self.stdout.flush()?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Scrolls down the current selected tile.
|
||||||
|
pub fn scroll_down(&mut self) {
|
||||||
|
self.tile_mut(self.selected).scroll += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Scrolls up the current selected tile.
|
||||||
|
pub fn scroll_up(&mut self) {
|
||||||
|
let tile = self.tile_mut(self.selected);
|
||||||
|
if tile.scroll > 0 {
|
||||||
|
tile.scroll -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<W: Write> Drop for Multiview<W> {
|
impl<W: Write> Drop for Multiview<W> {
|
||||||
|
@ -484,6 +530,12 @@ pub enum Msg {
|
||||||
/// A click occured.
|
/// A click occured.
|
||||||
Click(u16, u16),
|
Click(u16, u16),
|
||||||
|
|
||||||
|
/// Scroll up one line.
|
||||||
|
ScrollUp,
|
||||||
|
|
||||||
|
/// Scroll down one line.
|
||||||
|
ScrollDown,
|
||||||
|
|
||||||
/// The program was asked to exit.
|
/// The program was asked to exit.
|
||||||
Exit,
|
Exit,
|
||||||
}
|
}
|
||||||
|
@ -532,6 +584,8 @@ pub fn main() -> io::Result<()> {
|
||||||
let evt = c.unwrap();
|
let evt = c.unwrap();
|
||||||
match evt {
|
match evt {
|
||||||
Event::Key(Key::Char('q')) => sender.send(Msg::Exit).unwrap(),
|
Event::Key(Key::Char('q')) => sender.send(Msg::Exit).unwrap(),
|
||||||
|
Event::Key(Key::Down) => sender.send(Msg::ScrollDown).unwrap(),
|
||||||
|
Event::Key(Key::Up) => sender.send(Msg::ScrollUp).unwrap(),
|
||||||
|
|
||||||
Event::Mouse(me) => match me {
|
Event::Mouse(me) => match me {
|
||||||
MouseEvent::Press(_, x, y) => sender.send(Msg::Click(x, y)).unwrap(),
|
MouseEvent::Press(_, x, y) => sender.send(Msg::Click(x, y)).unwrap(),
|
||||||
|
@ -548,6 +602,8 @@ pub fn main() -> io::Result<()> {
|
||||||
Ok(Msg::Stdout(i, j, line)) => multiview.tile_mut((i, j)).stdout.push(line),
|
Ok(Msg::Stdout(i, j, line)) => multiview.tile_mut((i, j)).stdout.push(line),
|
||||||
Ok(Msg::Stderr(i, j, line)) => multiview.tile_mut((i, j)).stdout.push(line),
|
Ok(Msg::Stderr(i, j, line)) => multiview.tile_mut((i, j)).stdout.push(line),
|
||||||
Ok(Msg::Click(x, y)) => multiview.select_tile((x, y), term_size),
|
Ok(Msg::Click(x, y)) => multiview.select_tile((x, y), term_size),
|
||||||
|
Ok(Msg::ScrollDown) => multiview.scroll_down(),
|
||||||
|
Ok(Msg::ScrollUp) => multiview.scroll_up(),
|
||||||
Ok(Msg::Exit) => break,
|
Ok(Msg::Exit) => break,
|
||||||
Err(_) => (),
|
Err(_) => (),
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue