summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/coordinates.rs59
-rw-r--r--src/file_browser.rs99
-rw-r--r--src/hbox.rs28
-rw-r--r--src/listview.rs50
-rw-r--r--src/main.rs74
-rw-r--r--src/miller_columns.rs195
-rw-r--r--src/widget.rs12
-rw-r--r--src/window.rs1
8 files changed, 468 insertions, 50 deletions
diff --git a/src/coordinates.rs b/src/coordinates.rs
new file mode 100644
index 0000000..5506b4d
--- /dev/null
+++ b/src/coordinates.rs
@@ -0,0 +1,59 @@
+#[derive(Debug,Clone)]
+pub struct Size(pub (u16,u16));
+#[derive(Debug,Clone)]
+pub struct Position(pub (u16,u16));
+
+
+#[derive(Debug,Clone)]
+pub struct Coordinates {
+ pub size: Size,
+ pub position: Position,
+}
+
+impl Coordinates {
+ pub fn size(&self) -> &Size {
+ &self.size
+ }
+
+ pub fn xsize(&self) -> u16 {
+ self.size.xsize()
+ }
+
+ pub fn ysize(&self) -> u16 {
+ self.size.ysize()
+ }
+
+ pub fn position(&self) -> &Position {
+ &self.position
+ }
+
+ pub fn top(&self) -> Position {
+ self.position().clone()
+ }
+
+// pub fn left(&self) -> /
+}
+
+impl Size {
+ pub fn size(&self) -> (u16,u16) {
+ self.0
+ }
+ pub fn xsize(&self) -> u16 {
+ (self.0).0
+ }
+ pub fn ysize(&self) -> u16 {
+ (self.0).1
+ }
+}
+
+impl Position {
+ pub fn position(&self) -> (u16,u16) {
+ self.0
+ }
+ pub fn x(&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
new file mode 100644
index 0000000..e021dd9
--- /dev/null
+++ b/src/file_browser.rs
@@ -0,0 +1,99 @@
+use termion::event::{Key,Event};
+
+
+use crate::widget::Widget;
+use crate::files::Files;
+//use crate::hbox::HBox;
+use crate::listview::ListView;
+use crate::coordinates::{Coordinates, Size,Position};
+use crate::files::File;
+use crate::miller_columns::MillerColumns;
+
+pub struct FileBrowser {
+ pub columns: MillerColumns<ListView<Files>>,
+}
+
+impl FileBrowser {
+ pub fn set_left_directory(&mut self) {
+
+ }
+}
+
+
+impl Widget for FileBrowser {
+ fn render(&self) -> Vec<String> {
+ vec![]
+ }
+ fn get_size(&self) -> &Size {
+ &self.columns.get_size()
+ }
+ fn get_position(&self) -> &Position {
+ &self.columns.get_position()
+ }
+ fn set_size(&mut self, size: Size) {
+ self.columns.set_size(size);
+ }
+ fn set_position(&mut self, position: Position) {
+ self.columns.set_position(position);
+ }
+ fn render_header(&self) -> String {
+ "".to_string()
+ }
+ fn refresh(&mut self) {
+ self.columns.refresh();
+ }
+
+ fn get_drawlist(&self) -> String {
+ self.columns.get_drawlist()
+ // let view_count = self.columns.widgets.len();
+
+ // if view_count < 2 {
+ // // TODO: Special handling
+ // } else if view_count < 1 {
+ // // etc.
+ // }
+
+ // self.views
+ // .iter()
+ // .skip(view_count - 2)
+ // .map(|view| {
+ // eprintln!("{}", view.get_drawlist());
+ // view.get_drawlist()
+ // }).collect()
+ }
+
+
+ fn on_key(&mut self, key: Key) {
+ match key {
+ Key::Right => {
+ match self.columns.get_main_widget() {
+ Some(widget) => {
+ let path = widget.selected_file().path();
+ let files = Files::new_from_path(&path).unwrap();
+ let view = ListView::new(files);
+ self.columns.widgets.push(view);
+ self.refresh();
+ }, None => { }
+ }
+ },
+ Key::Left => {
+ if self.columns.get_left_widget().is_some() {
+ self.columns.widgets.pop();
+ }
+ }
+
+ _ => {
+ match self.columns.get_main_widget_mut() {
+ Some(widget) => {
+ widget.on_key(key);
+ self.set_left_directory();
+ self.refresh();
+ }, None => { self.refresh(); }
+
+ }
+ //_ => { self.bad(Event::Key(key)); }
+ }
+ }
+ }
+}
+
diff --git a/src/hbox.rs b/src/hbox.rs
index 3cd8f53..330bb0e 100644
--- a/src/hbox.rs
+++ b/src/hbox.rs
@@ -1,6 +1,7 @@
use termion::event::{Event};
use crate::widget::Widget;
+use crate::coordinates::{Coordinates, Size, Position};
// pub struct Child<T> {
// widget: T,
@@ -12,6 +13,7 @@ use crate::widget::Widget;
pub struct HBox {
dimensions: (u16, u16),
position: (u16, u16),
+ coordinates: Coordinates,
children: Vec<Box<Widget>>,
active: usize
}
@@ -20,10 +22,14 @@ pub struct HBox {
impl HBox {
pub fn new(widgets: Vec<Box<Widget>>,
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
@@ -40,7 +46,7 @@ impl HBox {
let mut current_pos = dbg!(hbox_position.1);
for widget in &mut self.children {
- widget.set_dimensions(dbg!((cell_size, hbox_size.1)));
+ 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);
@@ -76,23 +82,23 @@ impl Widget for HBox {
}
}
- fn get_drawlist(&mut self) -> String {
- self.children.iter_mut().map(|child| {
+ fn get_drawlist(&self) -> String {
+ self.children.iter().map(|child| {
child.get_drawlist()
}).collect()
}
- fn get_dimensions(&self) -> (u16, u16) {
- self.dimensions
+ fn get_size(&self) -> Size {
+ Size( self.dimensions )
}
- fn get_position(&self) -> (u16, u16) {
- self.position
+ fn get_position(&self) -> Position {
+ Position ( self.position )
}
- fn set_dimensions(&mut self, size: (u16, u16)) {
- self.dimensions = size;
+ fn set_size(&mut self, size: Size) {
+ self.dimensions = size.0;
}
- fn set_position(&mut self, position: (u16, u16)) {
- self.position = position;
+ fn set_position(&mut self, position: Position) {
+ self.position = position.0;
}
diff --git a/src/listview.rs b/src/listview.rs
index bd8f3a3..c6d200a 100644
--- a/src/listview.rs
+++ b/src/listview.rs
@@ -6,6 +6,7 @@ use std::path::{Path, PathBuf};
use crate::term;
use crate::files::{File, Files};
use crate::widget::Widget;
+use crate::coordinates::{Coordinates,Size,Position};
// Maybe also buffer drawlist for efficiency when it doesn't change every draw
@@ -14,8 +15,9 @@ pub struct ListView<T> {
selection: usize,
offset: usize,
buffer: Vec<String>,
- dimensions: (u16, u16),
- position: (u16, u16),
+ // dimensions: (u16, u16),
+ // position: (u16, u16),
+ coordinates: Coordinates,
}
impl<T: 'static> ListView<T> where ListView<T>: Widget {
@@ -25,8 +27,10 @@ impl<T: 'static> ListView<T> where ListView<T>: Widget {
selection: 0,
offset: 0,
buffer: Vec::new(),
- dimensions: (1,1),
- position: (1,1)
+ coordinates: Coordinates { size: Size ((1,1)),
+ position: Position((1,1)) }
+ // dimensions: (1,1),
+ // position: (1,1)
};
view
}
@@ -48,7 +52,7 @@ impl<T: 'static> ListView<T> where ListView<T>: Widget {
}
fn move_down(&mut self) {
let lines = self.buffer.len();
- let y_size = self.dimensions.1 as usize;
+ let y_size = self.coordinates.ysize() as usize;
if self.selection == lines - 1 {
return;
@@ -63,7 +67,7 @@ impl<T: 'static> ListView<T> where ListView<T>: Widget {
}
fn set_selection(&mut self, position: usize) {
- let ysize = self.dimensions.1 as usize;
+ let ysize = self.coordinates.ysize() as usize;
let mut offset = 0;
while position + 1 > ysize + offset { offset += 1 }
@@ -76,7 +80,7 @@ impl<T: 'static> ListView<T> where ListView<T>: Widget {
let name = &file.name;
let (size, unit) = file.calculate_size();
- let (xsize, _) = self.get_dimensions();
+ let xsize = self.get_size().xsize();
let sized_string = term::sized_string(&name, xsize);
let padding = xsize - sized_string.width() as u16;
let styled_string = match &file.style {
@@ -105,23 +109,23 @@ impl ListView<Files> where
Files: std::ops::Index<usize, Output=File>,
Files: std::marker::Sized
{
- fn selected_file(&self) -> &File {
+ pub fn selected_file(&self) -> &File {
let selection = self.selection;
let file = &self.content[selection];
file
}
- fn clone_selected_file(&self) -> File {
+ pub fn clone_selected_file(&self) -> File {
let selection = self.selection;
let file = self.content[selection].clone();
file
}
- fn grand_parent(&self) -> Option<PathBuf> {
+ pub fn grand_parent(&self) -> Option<PathBuf> {
self.selected_file().grand_parent()
}
- fn goto_grand_parent(&mut self) {
+ pub fn goto_grand_parent(&mut self) {
match self.grand_parent() {
Some(grand_parent) => self.goto_path(&grand_parent),
None => self.show_status("Can't go further!")
@@ -134,7 +138,7 @@ impl ListView<Files> where
self.goto_path(&path);
}
- fn goto_path(&mut self, path: &Path) {
+ pub fn goto_path(&mut self, path: &Path) {
match crate::files::Files::new_from_path(path){
Ok(files) => {
self.content = files;
@@ -198,17 +202,17 @@ impl ListView<Files> where
impl Widget for ListView<Files> {
- fn get_dimensions(&self) -> (u16, u16) {
- self.dimensions
+ fn get_size(&self) -> &Size {
+ &self.coordinates.size
}
- fn get_position(&self) -> (u16, u16) {
- self.position
+ fn get_position(&self) -> &Position {
+ &self.coordinates.position
}
- fn set_dimensions(&mut self, size: (u16, u16)) {
- self.dimensions = size;
+ fn set_size(&mut self, size: Size) {
+ self.coordinates.size = size;
}
- fn set_position(&mut self, position: (u16, u16)) {
- self.position = position;
+ fn set_position(&mut self, position: Position) {
+ self.coordinates.position = position;
}
fn refresh(&mut self) {
self.buffer = self.render();
@@ -222,10 +226,10 @@ impl Widget for ListView<Files> {
}).collect()
}
- fn get_drawlist(&mut self) -> String {
+ fn get_drawlist(&self) -> String {
let mut output = term::reset();
- let (xsize, ysize) = self.dimensions;
- let (xpos, ypos) = self.position;
+ let (xsize, ysize) = self.coordinates.size().size();
+ let (xpos, ypos) = self.coordinates.position().position();
output += &term::reset();
diff --git a/src/main.rs b/src/main.rs
index 4a79322..b6a2321 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -19,30 +19,82 @@ mod listview;
mod files;
mod win_main;
mod widget;
-mod hbox;
+//mod hbox;
+mod miller_columns;
+mod coordinates;
use listview::ListView;
use window::Window;
-use hbox::HBox;
-
+//use hbox::HBox;
+use miller_columns::MillerColumns;
+use widget::Widget;
+use coordinates::{Coordinates,Size,Position};
+mod file_browser;
+use file_browser::FileBrowser;
fn main() {
// Need to do this here to actually turn terminal into raw mode...
let mut _screen = AlternateScreen::from(Box::new(stdout()));
let mut _stdout = MouseTerminal::from(stdout().into_raw_mode().unwrap());
- let files = files::get_files("/home/project/code").unwrap();
- let listview = ListView::new(files, (50,50), (10,10));
+ let (xsize, ysize) = term::size();
+ let ysize = ysize - 1;
+
+ let coordinates = Coordinates { size: Size ((xsize, ysize - 1)) ,
+ position: Position( (1, 2 )) };
+
+
+ let files = files::Files::new_from_path("/home/project/").unwrap();
+ let mut listview = ListView::new(files);
+
+ let files = files::Files::new_from_path("/home/project/Downloads/").unwrap();
+ let mut listview2 = ListView::new(files);
+
+ let files = files::Files::new_from_path("/home/").unwrap();
+ let mut listview3 = ListView::new(files);
+
+ // let files = files::Files::new_from_path("/").unwrap();
+ // let mut listview4 = ListView::new(files);
+
+ // listview.set_size( Size ((20,30)));
+ // listview.set_position(Position((160,1)));
+
+ // listview2.set_size( Size ((20,30)));
+ // listview2.set_position(Position((160,1)));
+
+ // listview3.set_size( Size ((20,30)));
+ // listview3.set_position(Position((160,1)));
+
+ // listview4.set_size( Size ((20,30)));
+ // listview4.set_position(Position((160,1)));
+
+
+ // listview2.set_dimensions((95,53));
+ // listview2.set_position((95,1));
+
+ // let boxed = vec![listview.to_trait(), listview2.to_trait()];
+
+ // let hbox = HBox::new(boxed, (xsize, ysize-1), (1,2) , 0);
+
+
+
+ let mut miller
+ = MillerColumns::new(vec![listview3,listview,listview2],
+ coordinates,
+ (33, 33, 33));
- let files = files::get_files("/home/project/code").unwrap();
- let listview2 = ListView::new(files, (50,50), (80,10));
+ // miller.main = Some(listview2);
+ // miller.left = Some(listview3);
+ // miller.preview = Some(listview4);
- let boxed = vec![listview.to_trait(), listview2.to_trait()];
+ let coords = dbg!(miller.calculate_coordinates());
- let hbox = HBox::new(boxed);
- let mut win = Window::new(hbox);
+ miller.refresh();
+ let filebrowser = crate::file_browser::FileBrowser { columns: miller };
+
+ let mut win = Window::new(filebrowser);
win.handle_input();
write!(_stdout, "{}", termion::cursor::Show).unwrap();
-}
+ }
diff --git a/src/miller_columns.rs b/src/miller_columns.rs
new file mode 100644
index 0000000..fce25ac
--- /dev/null
+++ b/src/miller_columns.rs
@@ -0,0 +1,195 @@
+use termion::event::{Key,Event};
+
+
+use crate::widget::Widget;
+use crate::files::Files;
+//use crate::hbox::HBox;
+use crate::listview::ListView;
+use crate::coordinates::{Coordinates, Size,Position};
+use crate::files::File;
+
+pub struct MillerColumns<T> {
+ pub widgets: Vec<T>,
+ // pub left: Option<T>,
+ // pub main: Option<T>,
+ // pub preview: Option<T>,
+ ratio: (u16,u16,u16),
+ coordinates: Coordinates,
+}
+
+
+
+
+
+impl<T> MillerColumns<T> where T: Widget {
+ pub fn new(widgets: Vec<T>,
+ coordinates: Coordinates,
+ ratio: (u16, u16, u16))
+ -> Self { Self { widgets: widgets,
+ coordinates: coordinates,
+ ratio: ratio } }
+
+
+ pub fn push_widget(&mut self, widget: T) {
+
+ }
+
+ pub fn calculate_coordinates(&self) -> (Coordinates, Coordinates, Coordinates) {
+ let xsize = self.coordinates.xsize();
+ let ysize = self.coordinates.ysize();
+ let top = self.coordinates.top().x();
+ let ratio = self.ratio;
+
+ let left_xsize = xsize * ratio.0 / 100;
+ let left_size = Size ((left_xsize, ysize));
+ let left_pos = self.coordinates.top();
+
+
+ let main_xsize = xsize * ratio.1 / 100;
+ let main_size = Size ( (main_xsize, ysize) );
+ let main_pos = Position ( (left_xsize + 2, top ));
+
+ let preview_xsize = xsize * ratio.2 / 100;
+ let preview_size = Size ( (preview_xsize, ysize) );
+ let preview_pos = Position ( (left_xsize + main_xsize + 2, top) );
+
+ let left_coords = Coordinates { size: left_size,
+ position: left_pos };
+
+
+ let main_coords = Coordinates { size: main_size,
+ position: main_pos };
+
+
+ let preview_coords = Coordinates { size: preview_size,
+ position: preview_pos };
+
+
+ (left_coords, main_coords, preview_coords)
+ }
+
+ pub fn get_left_widget(&self) -> Option<&T> {
+ let len = self.widgets.len();
+ self.widgets.get(len-2)
+ }
+ pub fn get_left_widget_mut(&mut self) -> Option<&mut T> {
+ let len = self.widgets.len();
+ dbg!((self.widgets[len-2]).get_position());
+ Some(&mut self.widgets[len-2])
+ }
+ pub fn get_main_widget(&self) -> Option<&T> {
+ self.widgets.last()
+ }
+ pub fn get_main_widget_mut(&mut self) -> Option<&mut T> {
+ self.widgets.last_mut()
+ }
+
+
+}
+
+impl<T> Widget for MillerColumns<T> where T: Widget {
+ fn render(&self) -> Vec<String> {
+ vec![]
+ }
+ fn get_size(&self) -> &Size {
+ &self.coordinates.size
+ }
+ fn get_position(&self) -> &Position {
+ &self.coordinates.position
+ }
+ fn set_size(&mut self, size: Size) {
+ self.coordinates.size = size;
+ }
+ fn set_position(&mut self, position: Position) {
+ self.coordinates.position = position;
+ }
+ fn render_header(&self) -> String {
+ "".to_string()
+ }
+ fn refresh(&mut self) {
+ let (left_coords, main_coords, preview_coords) = self.calculate_coordinates();
+
+ // self.left.as_mut().unwrap().set_size(left_coords.size);
+ // self.left.as_mut().unwrap().set_position(left_coords.position);
+
+ // self.get_main_widget_mut().map(|widget| {
+ // widget.set_size(main_coords.size);
+ // widget.set_position(main_coords.position);
+ // });
+
+
+ let (left_coords, main_coords, preview_coords) = self.calculate_coordinates();
+
+ let widget2 = self.get_left_widget_mut().unwrap();
+ widget2.set_size( left_coords.size );
+ widget2.set_position( left_coords.position );
+ widget2.refresh();
+
+
+ let widget = self.get_main_widget_mut().unwrap();
+ widget.set_size(main_coords.size);
+ widget.set_position(main_coords.position);
+ widget.refresh();
+
+
+ // self.main.as_mut().unwrap().set_size(main_coords.size);
+ // self.main.as_mut().unwrap().set_position(main_coords.position);
+
+ // self.preview.as_mut().unwrap().set_size(preview_coords.size);
+ // self.preview.as_mut().unwrap().set_position(preview_coords.position);
+
+ // self.left.as_mut().unwrap().refresh();
+ // self.main.as_mut().unwrap().refresh();
+ // self.preview.as_mut().unwrap().refresh()
+ }
+
+ fn get_drawlist(&self) -> String {
+ let left_widget = self.get_left_widget().unwrap().get_drawlist();
+ let main_widget = self.get_main_widget().unwrap().get_drawlist();
+ format!("{}{}", main_widget, left_widget)
+ // let left_drawlist = &self.left.as_ref().unwrap().get_drawlist();
+ // let main_drawlist = &self.main.as_ref().unwrap().get_drawlist();
+ // let preview_drawlist = &self.preview.as_ref().unwrap().get_drawlist();
+
+ // format!("{}{}{}", left_drawlist, &main_drawlist, &preview_drawlist)
+ // let main_widget_drawlist = self.get_main_widget().map(|widget| {
+
+ // widget.get_drawlist()
+ // });
+
+
+ // match main_widget_drawlist {
+ // Some(drawlist) => { drawlist },
+ // None => "Can't draw this".to_string()
+ // }
+
+ }
+
+ fn on_key(&mut self, key: Key) {
+ match key {
+ _ => {
+ self.refresh();
+ self.get_main_widget_mut().unwrap().on_key(key);
+ //self.set_left_directory();
+ self.refresh();
+ },
+ //_ => { self.bad(Event::Key(key)); }
+ }
+ }
+// }
+
+// impl MillerColumns<ListView<Files>>
+// {
+ // pub fn godir(&mut self) -> Result<(),Box<dyn std::error::Error>> {
+ // let current_dir = self.widgets.iter().last().unwrap();
+ // let selected_path = &current_dir.selected_file().path;
+ // let files = Files::new_from_path(selected_path)?;
+ // let dir_list = ListView::new(files);
+ // Ok(())
+ // }
+ // fn set_left_directory(&mut self, dir: File) {
+ // let parent_dir = self.main.as_ref().unwrap().grand_parent().unwrap();
+ // self.left.as_mut().unwrap().goto_path(&parent_dir);
+ // }
+}
+
diff --git a/src/widget.rs b/src/widget.rs
index 2cbdbaf..7fc319c 100644
--- a/src/widget.rs
+++ b/src/widget.rs
@@ -1,12 +1,14 @@
use termion::event::{Key, MouseEvent, Event};
+use crate::coordinates::{Coordinates, Size, Position};
+
pub trait Widget {
fn render(&self) -> Vec<String>;
- fn get_dimensions(&self) -> (u16, u16);
- fn get_position(&self) -> (u16, u16);
- fn set_dimensions(&mut self, size: (u16, u16));
- fn set_position(&mut self, position: (u16, u16));
+ fn get_size(&self) -> &Size;
+ fn get_position(&self) -> &Position;
+ fn set_size(&mut self, size: Size);
+ fn set_position(&mut self, position: Position);
fn render_header(&self) -> String;
@@ -77,5 +79,5 @@ pub trait Widget {
//fn get_buffer(&self) -> &Vec<String>;
fn refresh(&mut self);
- fn get_drawlist(&mut self) -> String;
+ fn get_drawlist(&self) -> String;
}
diff --git a/src/window.rs b/src/window.rs
index b0a1974..8c21b7e 100644
--- a/src/window.rs
+++ b/src/window.rs
@@ -68,6 +68,7 @@ where
self.draw();
let event = event.unwrap();
self.widget.on_event(event);
+ self.widget.refresh();
self.draw();
}
}