diff options
author | rabite <rabite@posteo.de> | 2019-01-21 17:47:58 +0100 |
---|---|---|
committer | rabite <rabite@posteo.de> | 2019-01-21 17:47:58 +0100 |
commit | 8ad1b657ec3d20bab2199b33a22ff9a191dfe58d (patch) | |
tree | 9cf9d11a7f40060c0a5ceb8b72c9577f443b5614 /src | |
parent | 724cc61680e14d45fb7c0e5ebac525b71e7a1381 (diff) |
got file sizes working in listview
Diffstat (limited to 'src')
-rw-r--r-- | src/files.rs | 17 | ||||
-rw-r--r-- | src/hbox.rs | 20 | ||||
-rw-r--r-- | src/listview.rs | 51 | ||||
-rw-r--r-- | src/term.rs | 19 | ||||
-rw-r--r-- | src/widget.rs | 46 | ||||
-rw-r--r-- | src/window.rs | 3 |
6 files changed, 96 insertions, 60 deletions
diff --git a/src/files.rs b/src/files.rs index a35a4b1..2d83bd9 100644 --- a/src/files.rs +++ b/src/files.rs @@ -45,6 +45,23 @@ impl File { // mtime: None } } + pub fn calculate_size(&self) -> (usize, String) { + let mut unit = 0; + let mut size = self.size.unwrap(); + while size > 1024 { + size /= 1024; + unit += 1; + } + let unit = match unit { + 0 => "", + 1 => " KB", + 2 => " GB", + 3 => " TB", + 4 => "wtf are you doing", + _ => "" + }.to_string(); + (size, unit) + } } pub fn get_files(dir: &str) -> Result<Files, std::io::Error> { diff --git a/src/hbox.rs b/src/hbox.rs index 7013b2b..9c9c900 100644 --- a/src/hbox.rs +++ b/src/hbox.rs @@ -17,12 +17,15 @@ pub struct HBox { } impl HBox { - pub fn new(widgets: Vec<Box<Widget>>) -> HBox { + pub fn new(widgets: Vec<Box<Widget>>, + dimensions: (u16, u16), + position: (u16, u16), + main: usize) -> HBox { HBox { - dimensions: (100, 100), - position: (1, 1), + dimensions: dimensions, + position: position, children: widgets, - main: 0 + main: main } } } @@ -30,7 +33,7 @@ impl HBox { impl Widget for HBox { fn render(&self) -> Vec<String> { // HBox doesnt' draw anything itself - vec![] + vec![] } fn render_header(&self) -> String { @@ -55,6 +58,13 @@ impl Widget for HBox { fn get_position(&self) -> (u16, u16) { self.position } + fn set_dimensions(&mut self, size: (u16, u16)) { + self.dimensions = size; + } + fn set_position(&mut self, position: (u16, u16)) { + self.position = position; + } + fn on_event(&mut self, event: Event) { self.children[self.main].on_event(event); diff --git a/src/listview.rs b/src/listview.rs index 2e26ace..e5f7c77 100644 --- a/src/listview.rs +++ b/src/listview.rs @@ -1,9 +1,11 @@ +use unicode_width::{UnicodeWidthStr}; use termion::event::{Key,Event}; use crate::term; use crate::files::Files; use crate::widget::Widget; -use crate::window::{STATUS_BAR_MARGIN, HEADER_MARGIN}; + +// Maybe also buffer drawlist for efficiency when it doesn't change every draw pub struct ListView<T> { pub content: T, @@ -29,7 +31,7 @@ impl<T: 'static> ListView<T> where ListView<T>: Widget { pub fn to_trait(self) -> Box<Widget> { Box::new(self) } - + fn move_up(&mut self) { if self.selection == 0 { return; @@ -57,6 +59,26 @@ impl<T: 'static> ListView<T> where ListView<T>: Widget { self.selection += 1; } + fn render_line(&self, name: &str, size: usize, unit: &str) -> String { + let (xsize, _) = self.get_dimensions(); + let sized_string = term::sized_string(name, xsize); + let padding = xsize - sized_string.width() as u16; + + + + format!( + "{}{}{:padding$}{}{}{}{}", + term::normal_color(), + sized_string, + " ", + term::highlight_color(), + term::cursor_left(size.to_string().width() + unit.width()), + size, + unit, + padding = padding as usize + ) + } + } impl Widget for ListView<Files> { @@ -66,25 +88,32 @@ impl Widget for ListView<Files> { fn get_position(&self) -> (u16, u16) { self.position } + fn set_dimensions(&mut self, size: (u16, u16)) { + self.dimensions = size; + } + fn set_position(&mut self, position: (u16, u16)) { + self.position = position; + } fn refresh(&mut self) { self.buffer = self.render(); } - + + + fn render(&self) -> Vec<String> { self.content.iter().map(|file| { - self.render_line(&file.name, - &format!("{:?}", file.size), - false) + let (size, unit) = file.calculate_size(); + self.render_line(&file.name, size, &unit) }).collect() } - + fn get_drawlist(&mut self) -> String { let mut output = term::reset(); let (xsize, ysize) = self.dimensions; let (xpos, ypos) = self.position; output += &term::reset(); - + for (i, item) in self.buffer .iter() .skip(self.offset) @@ -102,10 +131,10 @@ impl Widget for ListView<Files> { term::reset()); } - + if ysize as usize > self.buffer.len() { let start_y = self.buffer.len() + 1 + ypos as usize; - for i in start_y..ysize as usize { + for i in start_y..ysize as usize { output += &format!("{}{:xsize$}{}", term::gotoy(i), " ", xsize = xsize as usize); } } @@ -115,7 +144,7 @@ impl Widget for ListView<Files> { fn render_header(&self) -> String { format!("{} files", self.content.len()) } - + fn on_key(&mut self, key: Key) { match key { Key::Up => { self.move_up(); self.refresh() }, diff --git a/src/term.rs b/src/term.rs index c559ad8..022f16b 100644 --- a/src/term.rs +++ b/src/term.rs @@ -1,3 +1,5 @@ +use unicode_width::UnicodeWidthStr; + use std::io::{Stdout, Write}; use termion; use termion::screen::AlternateScreen; @@ -16,6 +18,10 @@ pub trait ScreenExt: Write { impl ScreenExt for AlternateScreen<Box<Stdout>> {} +pub fn size() -> (u16, u16) { + termion::terminal_size().unwrap() +} + pub fn xsize() -> usize { let (xsize, _) = termion::terminal_size().unwrap(); xsize as usize @@ -26,6 +32,17 @@ pub fn ysize() -> usize { ysize as usize } +pub fn sized_string(string: &str, xsize: u16) -> String { + let lenstr: String = string.chars().fold("".into(), |acc,ch| { + if acc.width() + 1 >= xsize as usize { acc } + else { acc + &ch.to_string() } + }); + lenstr +} + +// Do these as constants + + pub fn highlight_color() -> String { format!( "{}{}", @@ -42,6 +59,7 @@ pub fn normal_color() -> String { ) } + pub fn cursor_left(n: usize) -> String { format!("{}", termion::cursor::Left(n as u16)) } @@ -81,4 +99,3 @@ pub fn header_color() -> String { pub fn status_bg() -> String { format!("{}", termion::color::Bg(termion::color::LightBlue)) } - diff --git a/src/widget.rs b/src/widget.rs index 72ca00b..4e173ed 100644 --- a/src/widget.rs +++ b/src/widget.rs @@ -1,45 +1,13 @@ use termion::event::{Key, MouseEvent, Event}; -use unicode_width::{UnicodeWidthStr}; - -use crate::term; - pub trait Widget { fn render(&self) -> Vec<String>; fn get_dimensions(&self) -> (u16, u16); fn get_position(&self) -> (u16, u16); - fn render_line(&self, left: &str, right: &str, highlight: bool) -> String { - let (xsize, _) = self.get_dimensions(); - let text_color = match highlight { - true => term::highlight_color(), - false => term::normal_color(), - }; - let sized_string = self.sized_string(left); - let padding = xsize - sized_string.width() as u16; - - format!( - "{}{}{:padding$}{}{}{}", - text_color, - sized_string, - " ", - term::highlight_color(), - term::cursor_left(right.width()), - right, - padding = padding as usize - ) - } - // fn add_highlight(&self, line: &str) -> String { - // line.to_string() - // } + fn set_dimensions(&mut self, size: (u16, u16)); + fn set_position(&mut self, position: (u16, u16)); fn render_header(&self) -> String; - fn sized_string(&self, string: &str) -> String { - let (xsize, _) = self.get_dimensions(); - let lenstr: String = string.chars().fold("".into(), |acc,ch| { - if acc.width() + 1 >= xsize as usize { acc } - else { acc + &ch.to_string() } - }); - lenstr - } + fn on_event(&mut self, event: Event) { match event { @@ -49,7 +17,7 @@ pub trait Widget { Event::Unsupported(wtf) => self.on_wtf(wtf), } } - + fn on_key(&mut self, key: Key) { match key { _ => { @@ -57,7 +25,7 @@ pub trait Widget { } } } - + fn on_mouse(&mut self, event: MouseEvent) { match event { _ => { @@ -73,13 +41,11 @@ pub trait Widget { } } } - - fn show_status(&mut self, status: &str) { crate::window::show_status(status); } - + fn bad(&mut self, event: Event) { self.show_status(&format!("Stop the nasty stuff!! {:?} does nothing!", event)); } diff --git a/src/window.rs b/src/window.rs index d8deb40..2d7ef6c 100644 --- a/src/window.rs +++ b/src/window.rs @@ -1,6 +1,5 @@ use std::cell::RefCell; use std::io::{stdin, stdout, Stdout, Write}; -use std::process::exit; use std::rc::*; use std::sync::{Arc, Mutex}; @@ -23,8 +22,6 @@ where T: Widget pub dimensions: (u16, u16), } -pub const HEADER_MARGIN: usize = 1; -pub const STATUS_BAR_MARGIN: usize = 2; impl<T> Window<T> where |