From 9cd395d8f77134b6c041739a8f89d3d18a3f6a7e Mon Sep 17 00:00:00 2001 From: rabite Date: Mon, 4 Feb 2019 18:51:07 +0100 Subject: [PATCH] prototype async previews --- src/coordinates.rs | 12 ++-- src/file_browser.rs | 1 + src/files.rs | 2 +- src/hbox.rs | 142 +++++++++++++++++++++++------------------- src/listview.rs | 1 + src/main.rs | 1 + src/miller_columns.rs | 36 +++++------ src/preview.rs | 52 +++++++++++++--- src/textview.rs | 6 +- src/widget.rs | 2 +- 10 files changed, 155 insertions(+), 100 deletions(-) diff --git a/src/coordinates.rs b/src/coordinates.rs index 6b79823..56cfe40 100644 --- a/src/coordinates.rs +++ b/src/coordinates.rs @@ -17,9 +17,9 @@ impl Coordinates { } } - // pub fn size(&self) -> &Size { - // &self.size - // } + pub fn size(&self) -> &Size { + &self.size + } pub fn xsize(&self) -> u16 { self.size.xsize() @@ -59,7 +59,7 @@ impl Position { pub fn x(&self) -> u16 { (self.0).1 } - // pub fn y(&self) -> u16 { - // (self.0).1 - // } + pub fn y(&self) -> u16 { + (self.0).1 + } } diff --git a/src/file_browser.rs b/src/file_browser.rs index 1f2493b..f7fd5ad 100644 --- a/src/file_browser.rs +++ b/src/file_browser.rs @@ -9,6 +9,7 @@ use crate::listview::ListView; use crate::miller_columns::MillerColumns; use crate::widget::Widget; +#[derive(PartialEq)] pub struct FileBrowser { pub columns: MillerColumns>, } diff --git a/src/files.rs b/src/files.rs index 774ab25..0c01124 100644 --- a/src/files.rs +++ b/src/files.rs @@ -6,7 +6,7 @@ use std::time::SystemTime; use lscolors::LsColors; use mime_detective; -use rayon::prelude::*; + lazy_static! { static ref COLORS: LsColors = LsColors::from_env().unwrap(); diff --git a/src/hbox.rs b/src/hbox.rs index 330bb0e..ab40da7 100644 --- a/src/hbox.rs +++ b/src/hbox.rs @@ -3,62 +3,74 @@ use termion::event::{Event}; use crate::widget::Widget; use crate::coordinates::{Coordinates, Size, Position}; -// pub struct Child { -// widget: T, -// position: (u16, u16), -// size: (u16, u16), -// active: bool -// } - -pub struct HBox { - dimensions: (u16, u16), - position: (u16, u16), - coordinates: Coordinates, - children: Vec>, - active: usize +#[derive(PartialEq)] +pub struct HBox { + pub coordinates: Coordinates, + pub widgets: Vec, + pub active: Option, } -impl HBox { - pub fn new(widgets: Vec>, - dimensions: (u16, u16), - coordinates: Coordinates, - position: (u16, u16), - main: usize) -> HBox { - let mut hbox = HBox { - dimensions: dimensions, - coordinates: Coordinates { size: Size (dimensions), - position: Position (position), - parent: None }, - position: position, - children: widgets, - active: main - }; - hbox.resize_children(); - hbox - } +impl HBox where T: Widget { + pub fn new() -> HBox { + HBox { coordinates: Coordinates::new(), + widgets: vec![], + active: None + } + } pub fn resize_children(&mut self) { - let hbox_size = dbg!(self.dimensions); - let hbox_position = dbg!(self.position); - let cell_size = dbg!(hbox_size.0 / self.children.len() as u16); - let mut current_pos = dbg!(hbox_position.1); - - for widget in &mut self.children { - widget.set_size(Size ( (cell_size, hbox_size.1)) ); - widget.set_position(dbg!((current_pos, hbox_position.1))); - widget.refresh(); - dbg!(current_pos += cell_size); + let coords: Vec + = self.widgets.iter().map( + |w| + self.calculate_coordinates(w)).collect(); + for (widget, coord) in self.widgets.iter_mut().zip(coords.iter()) { + widget.set_coordinates(coord); } } - // pub fn widget(&self, index: usize) -> &Box { - // &self.children[index] - // } + pub fn push_widget(&mut self, widget: T) where T: PartialEq { + self.widgets.push(widget); + self.resize_children(); + self.refresh(); + } - pub fn active_widget(&self) -> &Box { - &self.children[self.active] + pub fn pop_widget(&mut self) -> Option { + let widget = self.widgets.pop(); + self.resize_children(); + self.refresh(); + widget + } + + pub fn prepend_widget(&mut self, widget: T) { + self.widgets.insert(0, widget); + self.resize_children(); + self.refresh(); + } + + pub fn calculate_coordinates(&self, widget: &T) + -> Coordinates where T: PartialEq { + let xsize = self.coordinates.xsize(); + let ysize = self.coordinates.ysize(); + let top = self.coordinates.top().x(); + + let pos = self.widgets.iter().position(|w | w == widget).unwrap(); + let num = self.widgets.len(); + + let widget_xsize = (xsize / num as u16) + 1; + let widget_xpos = widget_xsize * pos as u16; + + Coordinates { + size: Size((widget_xsize, + ysize)), + position: Position((widget_xpos, + top)) + } + } + + pub fn active_widget(&self) -> &T { + &self.widgets.last().unwrap() } } @@ -66,43 +78,47 @@ impl HBox { -impl Widget for HBox { - fn render(&self) -> Vec { - // HBox doesnt' draw anything itself - vec![] - } - +impl Widget for HBox where T: Widget { fn render_header(&self) -> String { self.active_widget().render_header() } fn refresh(&mut self) { - for child in &mut self.children { + self.resize_children(); + for child in &mut self.widgets { child.refresh(); } } fn get_drawlist(&self) -> String { - self.children.iter().map(|child| { + self.widgets.iter().map(|child| { child.get_drawlist() }).collect() } - fn get_size(&self) -> Size { - Size( self.dimensions ) + fn get_size(&self) -> &Size { + &self.coordinates.size } - fn get_position(&self) -> Position { - Position ( self.position ) + fn get_position(&self) -> &Position { + &self.coordinates.position } fn set_size(&mut self, size: Size) { - self.dimensions = size.0; + self.coordinates.size = size; } fn set_position(&mut self, position: Position) { - self.position = position.0; + self.coordinates.position = position; + } + fn get_coordinates(&self) -> &Coordinates { + &self.coordinates + } + fn set_coordinates(&mut self, coordinates: &Coordinates) { + if self.coordinates == *coordinates { + return; + } + self.coordinates = coordinates.clone(); + self.refresh(); } - - fn on_event(&mut self, event: Event) { - self.children[self.active].on_event(event); + self.widgets.last_mut().unwrap().on_event(event); } } diff --git a/src/listview.rs b/src/listview.rs index ad1c148..31104c2 100644 --- a/src/listview.rs +++ b/src/listview.rs @@ -11,6 +11,7 @@ use crate::widget::Widget; // Maybe also buffer drawlist for efficiency when it doesn't change every draw +#[derive(PartialEq)] pub struct ListView where T: Send, diff --git a/src/main.rs b/src/main.rs index 624bad4..a59ad14 100644 --- a/src/main.rs +++ b/src/main.rs @@ -25,6 +25,7 @@ mod textview; mod widget; mod win_main; mod window; +mod hbox; use window::Window; diff --git a/src/miller_columns.rs b/src/miller_columns.rs index 82e15c8..2937ce8 100644 --- a/src/miller_columns.rs +++ b/src/miller_columns.rs @@ -3,9 +3,11 @@ use termion::event::Key; use crate::coordinates::{Coordinates, Position, Size}; use crate::preview::Previewer; use crate::widget::Widget; +use crate::hbox::HBox; -pub struct MillerColumns { - pub widgets: Vec, +#[derive(PartialEq)] +pub struct MillerColumns where T: Widget { + pub widgets: HBox, // pub left: Option, // pub main: Option, pub preview: Previewer, @@ -19,30 +21,26 @@ where { pub fn new() -> Self { Self { - widgets: vec![], + widgets: HBox::new(), coordinates: Coordinates::new(), ratio: (33, 33, 33), preview: Previewer::new(), } } - pub fn push_widget(&mut self, mut widget: T) { - let mcoords = self.calculate_coordinates().1; - widget.set_coordinates(&mcoords); - self.widgets.push(widget); + pub fn push_widget(&mut self, widget: T) { + self.widgets.push_widget(widget); self.refresh(); } pub fn pop_widget(&mut self) -> Option { - let widget = self.widgets.pop(); + let widget = self.widgets.pop_widget(); self.refresh(); widget } - pub fn prepend_widget(&mut self, mut widget: T) { - let lcoords = self.calculate_coordinates().0; - widget.set_coordinates(&lcoords); - self.widgets.insert(0, widget); + pub fn prepend_widget(&mut self, widget: T) { + self.widgets.prepend_widget(widget); } pub fn calculate_coordinates(&self) -> (Coordinates, Coordinates, Coordinates) { @@ -82,25 +80,25 @@ where } pub fn get_left_widget(&self) -> Option<&T> { - let len = self.widgets.len(); + let len = self.widgets.widgets.len(); if len < 2 { return None; } - self.widgets.get(len - 2) + self.widgets.widgets.get(len - 2) } pub fn get_left_widget_mut(&mut self) -> Option<&mut T> { - let len = self.widgets.len(); + let len = self.widgets.widgets.len(); if len < 2 { return None; } - self.widgets.get(len - 2)?.get_position(); - self.widgets.get_mut(len - 2) + self.widgets.widgets.get(len - 2)?.get_position(); + self.widgets.widgets.get_mut(len - 2) } pub fn get_main_widget(&self) -> &T { - self.widgets.last().unwrap() + self.widgets.widgets.last().unwrap() } pub fn get_main_widget_mut(&mut self) -> &mut T { - self.widgets.last_mut().unwrap() + self.widgets.widgets.last_mut().unwrap() } } diff --git a/src/preview.rs b/src/preview.rs index bbada42..8245c34 100644 --- a/src/preview.rs +++ b/src/preview.rs @@ -1,7 +1,4 @@ -use rayon as rayon; - -use std::io::{stdout, Write}; -use std::sync::atomic::AtomicUsize; +use std::io::Write; use std::sync::Mutex; use crate::coordinates::{Coordinates, Position, Size}; @@ -10,11 +7,23 @@ use crate::listview::ListView; use crate::textview::TextView; use crate::widget::Widget; + +pub struct InstanceCounter(Mutex); +impl PartialEq for InstanceCounter { + fn eq(&self, other: &Self) -> bool { + let instance = self.0.lock().unwrap(); + let other = other.0.lock().unwrap(); + *instance == *other + } +} + + +#[derive(PartialEq)] pub struct Previewer { pub file: Option, pub buffer: String, pub coordinates: Coordinates, - pub instances: Mutex + pub instances: InstanceCounter } impl Previewer { @@ -23,17 +32,17 @@ impl Previewer { file: None, buffer: String::new(), coordinates: Coordinates::new(), - instances: From::from(0) + instances: InstanceCounter(Mutex::new(0)) } } pub fn set_file(&mut self, file: &File) { //return; - let mut instance = self.instances.try_lock().unwrap(); + let mut instance = self.instances.0.try_lock().unwrap(); if *instance > 2 { return } *instance = *instance + 1; let coordinates = self.coordinates.clone(); let file = file.clone(); - + let redraw = crate::term::reset() + &self.get_redraw_empty_list(0); //self.threads.install(|| { @@ -66,6 +75,33 @@ impl Previewer { let output = textview.get_drawlist() + &textview.get_redraw_empty_list(len - 1); write!(std::io::stdout(), "{}", output).unwrap(); + } else { + let output = + std::process::Command::new("scope.sh").arg(&file.name) + .arg("10".to_string()) + .arg("10".to_string()) + .arg("".to_string()) + .arg("false".to_string()) + .output().unwrap(); + + + if output.status.code().unwrap() == 5 { + write!(std::io::stdout(), "{}", redraw).unwrap(); + } else { + let output = std::str::from_utf8(&output.stdout) + .unwrap() + .to_string(); + let mut textview = TextView { + lines: output.lines().map(|s| s.to_string()).collect(), + buffer: String::new(), + coordinates: Coordinates::new() }; + textview.set_coordinates(&coordinates); + textview.refresh(); + let len = textview.lines.len(); + let output = textview.get_drawlist() + + &textview.get_redraw_empty_list(len - 1); + write!(std::io::stdout(), "{}", output).unwrap(); + } } } diff --git a/src/textview.rs b/src/textview.rs index f09f368..b3e168b 100644 --- a/src/textview.rs +++ b/src/textview.rs @@ -7,6 +7,7 @@ use crate::files::File; use crate::term::sized_string; use crate::widget::Widget; +#[derive(PartialEq)] pub struct TextView { pub lines: Vec, pub buffer: String, @@ -60,8 +61,9 @@ impl Widget for TextView { .enumerate() .map(|(i, line)| { format!( - "{}{:xsize$}", - crate::term::goto_xy(xpos, i as u16), + "{}{}{:xsize$}", + crate::term::goto_xy(xpos, i as u16 + 2), + crate::term::reset(), sized_string(&line, xsize), xsize = xsize as usize ) diff --git a/src/widget.rs b/src/widget.rs index 528b487..e21cb84 100644 --- a/src/widget.rs +++ b/src/widget.rs @@ -2,7 +2,7 @@ use termion::event::{Event, Key, MouseEvent}; use crate::coordinates::{Coordinates, Position, Size}; -pub trait Widget { +pub trait Widget: PartialEq { //fn render(&self) -> Vec; fn get_size(&self) -> &Size; fn get_position(&self) -> &Position;