mirror of
https://github.com/bobwen-dev/hunter
synced 2025-04-12 00:55:41 +02:00
got file sizes working in listview
This commit is contained in:
parent
724cc61680
commit
8ad1b657ec
17
src/files.rs
17
src/files.rs
@ -45,6 +45,23 @@ impl File {
|
|||||||
// mtime: None
|
// 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> {
|
pub fn get_files(dir: &str) -> Result<Files, std::io::Error> {
|
||||||
|
20
src/hbox.rs
20
src/hbox.rs
@ -17,12 +17,15 @@ pub struct HBox {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl 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 {
|
HBox {
|
||||||
dimensions: (100, 100),
|
dimensions: dimensions,
|
||||||
position: (1, 1),
|
position: position,
|
||||||
children: widgets,
|
children: widgets,
|
||||||
main: 0
|
main: main
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -30,7 +33,7 @@ impl HBox {
|
|||||||
impl Widget for HBox {
|
impl Widget for HBox {
|
||||||
fn render(&self) -> Vec<String> {
|
fn render(&self) -> Vec<String> {
|
||||||
// HBox doesnt' draw anything itself
|
// HBox doesnt' draw anything itself
|
||||||
vec![]
|
vec![]
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_header(&self) -> String {
|
fn render_header(&self) -> String {
|
||||||
@ -55,6 +58,13 @@ impl Widget for HBox {
|
|||||||
fn get_position(&self) -> (u16, u16) {
|
fn get_position(&self) -> (u16, u16) {
|
||||||
self.position
|
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) {
|
fn on_event(&mut self, event: Event) {
|
||||||
self.children[self.main].on_event(event);
|
self.children[self.main].on_event(event);
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
|
use unicode_width::{UnicodeWidthStr};
|
||||||
use termion::event::{Key,Event};
|
use termion::event::{Key,Event};
|
||||||
|
|
||||||
use crate::term;
|
use crate::term;
|
||||||
use crate::files::Files;
|
use crate::files::Files;
|
||||||
use crate::widget::Widget;
|
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 struct ListView<T> {
|
||||||
pub content: T,
|
pub content: T,
|
||||||
@ -29,7 +31,7 @@ impl<T: 'static> ListView<T> where ListView<T>: Widget {
|
|||||||
pub fn to_trait(self) -> Box<Widget> {
|
pub fn to_trait(self) -> Box<Widget> {
|
||||||
Box::new(self)
|
Box::new(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn move_up(&mut self) {
|
fn move_up(&mut self) {
|
||||||
if self.selection == 0 {
|
if self.selection == 0 {
|
||||||
return;
|
return;
|
||||||
@ -57,6 +59,26 @@ impl<T: 'static> ListView<T> where ListView<T>: Widget {
|
|||||||
self.selection += 1;
|
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> {
|
impl Widget for ListView<Files> {
|
||||||
@ -66,25 +88,32 @@ impl Widget for ListView<Files> {
|
|||||||
fn get_position(&self) -> (u16, u16) {
|
fn get_position(&self) -> (u16, u16) {
|
||||||
self.position
|
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) {
|
fn refresh(&mut self) {
|
||||||
self.buffer = self.render();
|
self.buffer = self.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fn render(&self) -> Vec<String> {
|
fn render(&self) -> Vec<String> {
|
||||||
self.content.iter().map(|file| {
|
self.content.iter().map(|file| {
|
||||||
self.render_line(&file.name,
|
let (size, unit) = file.calculate_size();
|
||||||
&format!("{:?}", file.size),
|
self.render_line(&file.name, size, &unit)
|
||||||
false)
|
|
||||||
}).collect()
|
}).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_drawlist(&mut self) -> String {
|
fn get_drawlist(&mut self) -> String {
|
||||||
let mut output = term::reset();
|
let mut output = term::reset();
|
||||||
let (xsize, ysize) = self.dimensions;
|
let (xsize, ysize) = self.dimensions;
|
||||||
let (xpos, ypos) = self.position;
|
let (xpos, ypos) = self.position;
|
||||||
output += &term::reset();
|
output += &term::reset();
|
||||||
|
|
||||||
|
|
||||||
for (i, item) in self.buffer
|
for (i, item) in self.buffer
|
||||||
.iter()
|
.iter()
|
||||||
.skip(self.offset)
|
.skip(self.offset)
|
||||||
@ -102,10 +131,10 @@ impl Widget for ListView<Files> {
|
|||||||
term::reset());
|
term::reset());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if ysize as usize > self.buffer.len() {
|
if ysize as usize > self.buffer.len() {
|
||||||
let start_y = self.buffer.len() + 1 + ypos as usize;
|
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);
|
output += &format!("{}{:xsize$}{}", term::gotoy(i), " ", xsize = xsize as usize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -115,7 +144,7 @@ impl Widget for ListView<Files> {
|
|||||||
fn render_header(&self) -> String {
|
fn render_header(&self) -> String {
|
||||||
format!("{} files", self.content.len())
|
format!("{} files", self.content.len())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_key(&mut self, key: Key) {
|
fn on_key(&mut self, key: Key) {
|
||||||
match key {
|
match key {
|
||||||
Key::Up => { self.move_up(); self.refresh() },
|
Key::Up => { self.move_up(); self.refresh() },
|
||||||
|
19
src/term.rs
19
src/term.rs
@ -1,3 +1,5 @@
|
|||||||
|
use unicode_width::UnicodeWidthStr;
|
||||||
|
|
||||||
use std::io::{Stdout, Write};
|
use std::io::{Stdout, Write};
|
||||||
use termion;
|
use termion;
|
||||||
use termion::screen::AlternateScreen;
|
use termion::screen::AlternateScreen;
|
||||||
@ -16,6 +18,10 @@ pub trait ScreenExt: Write {
|
|||||||
|
|
||||||
impl ScreenExt for AlternateScreen<Box<Stdout>> {}
|
impl ScreenExt for AlternateScreen<Box<Stdout>> {}
|
||||||
|
|
||||||
|
pub fn size() -> (u16, u16) {
|
||||||
|
termion::terminal_size().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn xsize() -> usize {
|
pub fn xsize() -> usize {
|
||||||
let (xsize, _) = termion::terminal_size().unwrap();
|
let (xsize, _) = termion::terminal_size().unwrap();
|
||||||
xsize as usize
|
xsize as usize
|
||||||
@ -26,6 +32,17 @@ pub fn ysize() -> usize {
|
|||||||
ysize as 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 {
|
pub fn highlight_color() -> String {
|
||||||
format!(
|
format!(
|
||||||
"{}{}",
|
"{}{}",
|
||||||
@ -42,6 +59,7 @@ pub fn normal_color() -> String {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn cursor_left(n: usize) -> String {
|
pub fn cursor_left(n: usize) -> String {
|
||||||
format!("{}", termion::cursor::Left(n as u16))
|
format!("{}", termion::cursor::Left(n as u16))
|
||||||
}
|
}
|
||||||
@ -81,4 +99,3 @@ pub fn header_color() -> String {
|
|||||||
pub fn status_bg() -> String {
|
pub fn status_bg() -> String {
|
||||||
format!("{}", termion::color::Bg(termion::color::LightBlue))
|
format!("{}", termion::color::Bg(termion::color::LightBlue))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,45 +1,13 @@
|
|||||||
use termion::event::{Key, MouseEvent, Event};
|
use termion::event::{Key, MouseEvent, Event};
|
||||||
use unicode_width::{UnicodeWidthStr};
|
|
||||||
|
|
||||||
use crate::term;
|
|
||||||
|
|
||||||
|
|
||||||
pub trait Widget {
|
pub trait Widget {
|
||||||
fn render(&self) -> Vec<String>;
|
fn render(&self) -> Vec<String>;
|
||||||
fn get_dimensions(&self) -> (u16, u16);
|
fn get_dimensions(&self) -> (u16, u16);
|
||||||
fn get_position(&self) -> (u16, u16);
|
fn get_position(&self) -> (u16, u16);
|
||||||
fn render_line(&self, left: &str, right: &str, highlight: bool) -> String {
|
fn set_dimensions(&mut self, size: (u16, u16));
|
||||||
let (xsize, _) = self.get_dimensions();
|
fn set_position(&mut self, position: (u16, u16));
|
||||||
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 render_header(&self) -> String;
|
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) {
|
fn on_event(&mut self, event: Event) {
|
||||||
match event {
|
match event {
|
||||||
@ -49,7 +17,7 @@ pub trait Widget {
|
|||||||
Event::Unsupported(wtf) => self.on_wtf(wtf),
|
Event::Unsupported(wtf) => self.on_wtf(wtf),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_key(&mut self, key: Key) {
|
fn on_key(&mut self, key: Key) {
|
||||||
match key {
|
match key {
|
||||||
_ => {
|
_ => {
|
||||||
@ -57,7 +25,7 @@ pub trait Widget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_mouse(&mut self, event: MouseEvent) {
|
fn on_mouse(&mut self, event: MouseEvent) {
|
||||||
match event {
|
match event {
|
||||||
_ => {
|
_ => {
|
||||||
@ -73,13 +41,11 @@ pub trait Widget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
fn show_status(&mut self, status: &str) {
|
fn show_status(&mut self, status: &str) {
|
||||||
crate::window::show_status(status);
|
crate::window::show_status(status);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn bad(&mut self, event: Event) {
|
fn bad(&mut self, event: Event) {
|
||||||
self.show_status(&format!("Stop the nasty stuff!! {:?} does nothing!", event));
|
self.show_status(&format!("Stop the nasty stuff!! {:?} does nothing!", event));
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
use std::cell::RefCell;
|
use std::cell::RefCell;
|
||||||
use std::io::{stdin, stdout, Stdout, Write};
|
use std::io::{stdin, stdout, Stdout, Write};
|
||||||
use std::process::exit;
|
|
||||||
use std::rc::*;
|
use std::rc::*;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
@ -23,8 +22,6 @@ where T: Widget
|
|||||||
pub dimensions: (u16, u16),
|
pub dimensions: (u16, u16),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const HEADER_MARGIN: usize = 1;
|
|
||||||
pub const STATUS_BAR_MARGIN: usize = 2;
|
|
||||||
|
|
||||||
impl<T> Window<T>
|
impl<T> Window<T>
|
||||||
where
|
where
|
||||||
|
Loading…
x
Reference in New Issue
Block a user