1
0
mirror of https://github.com/bobwen-dev/hunter synced 2025-04-12 00:55:41 +02:00

basic browsing working

This commit is contained in:
rabite 2019-01-22 21:05:06 +01:00
parent 00c2eb8e46
commit ab9baf17f1
4 changed files with 93 additions and 33 deletions

View File

@ -1,4 +1,7 @@
use std::ops::Index; use std::ops::Index;
use std::error::Error;
use std::path::PathBuf;
use std::ffi::OsStr;
pub struct Files(Vec<File>); pub struct Files(Vec<File>);
@ -10,6 +13,22 @@ impl Index<usize> for Files {
} }
impl Files { impl Files {
pub fn new_from_path<S: AsRef<OsStr> + Sized>(path: S)
-> Result<Files, Box<dyn Error>>
where S: std::convert::AsRef<std::path::Path> {
let mut files = Vec::new();
for file in std::fs::read_dir(path)? {
let file = file?;
let name = file.file_name();
let name = name.to_string_lossy();
let path = file.path();
let size = file.metadata()?.len() / 1024;
files.push(File::new(&name, path, size as usize));
}
Ok(Files(files))
}
pub fn iter(&self) -> std::slice::Iter<File> { pub fn iter(&self) -> std::slice::Iter<File> {
self.0.iter() self.0.iter()
} }
@ -22,7 +41,7 @@ impl Files {
#[derive(Debug)] #[derive(Debug)]
pub struct File { pub struct File {
pub name: String, pub name: String,
pub path: String, pub path: PathBuf,
pub size: Option<usize>, pub size: Option<usize>,
// owner: Option<String>, // owner: Option<String>,
// group: Option<String>, // group: Option<String>,
@ -33,10 +52,10 @@ pub struct File {
impl File { impl File {
pub fn new(name: &str, path: &str, size: usize) -> File { pub fn new(name: &str, path: PathBuf, size: usize) -> File {
File { File {
name: name.to_string(), name: name.to_string(),
path: path.to_string(), path: path,
size: Some(size), size: Some(size),
// owner: None, // owner: None,
// group: None, // group: None,
@ -62,18 +81,13 @@ impl File {
}.to_string(); }.to_string();
(size, unit) (size, unit)
} }
}
pub fn get_files(dir: &str) -> Result<Files, std::io::Error> { pub fn grand_parent(&self) -> Option<PathBuf> {
let mut files = Vec::new(); Some(self.path.parent()?.parent()?.to_path_buf())
for file in std::fs::read_dir(dir)? { }
let name = file.as_ref().unwrap().file_name().into_string().unwrap();
file.as_ref().unwrap().path().pop(); pub fn path(&self) -> PathBuf {
let path = file.as_ref().unwrap().path().into_os_string().into_string().unwrap(); self.path.clone()
let size = file.unwrap().metadata()?.len() / 1024;
files.push(File::new(&name, &path, size as usize));
} }
Ok(Files(files))
} }

View File

@ -9,7 +9,6 @@ use crate::widget::Widget;
// active: bool // active: bool
// } // }
pub struct HBox { pub struct HBox {
dimensions: (u16, u16), dimensions: (u16, u16),
position: (u16, u16), position: (u16, u16),
@ -39,27 +38,20 @@ impl HBox {
let hbox_position = dbg!(self.position); let hbox_position = dbg!(self.position);
let cell_size = dbg!(hbox_size.0 / self.children.len() as u16); let cell_size = dbg!(hbox_size.0 / self.children.len() as u16);
let mut current_pos = dbg!(hbox_position.1); let mut current_pos = dbg!(hbox_position.1);
let mut current_edge = dbg!(cell_size);
for mut widget in &mut self.children { for widget in &mut self.children {
widget.set_dimensions(dbg!((cell_size, hbox_size.1))); widget.set_dimensions(dbg!((cell_size, hbox_size.1)));
widget.set_position(dbg!((current_pos, hbox_position.1))); widget.set_position(dbg!((current_pos, hbox_position.1)));
widget.refresh(); widget.refresh();
dbg!(current_pos += cell_size); dbg!(current_pos += cell_size);
dbg!(current_edge += cell_size);
} }
} }
pub fn resize_child(&mut self, index: usize, size: (u16, u16)) { // pub fn widget(&self, index: usize) -> &Box<Widget> {
self.children[index].set_dimensions(size); // &self.children[index]
} // }
pub fn active_widget(&self) -> &Box<Widget> {
pub fn widget(&self, index: usize) -> &Box<Widget> {
&self.children[index]
}
pub fn active_widget(&self, index: usize) -> &Box<Widget> {
&self.children[self.active] &self.children[self.active]
} }
@ -75,7 +67,7 @@ impl Widget for HBox {
} }
fn render_header(&self) -> String { fn render_header(&self) -> String {
self.children[self.active].render_header() self.active_widget().render_header()
} }
fn refresh(&mut self) { fn refresh(&mut self) {

View File

@ -1,8 +1,10 @@
use unicode_width::{UnicodeWidthStr}; use unicode_width::{UnicodeWidthStr};
use termion::event::{Key,Event}; use termion::event::{Key,Event};
use std::path::{Path, PathBuf};
use crate::term; use crate::term;
use crate::files::Files; use crate::files::{File, Files};
use crate::widget::Widget; use crate::widget::Widget;
// Maybe also buffer drawlist for efficiency when it doesn't change every draw // Maybe also buffer drawlist for efficiency when it doesn't change every draw
@ -79,8 +81,54 @@ impl<T: 'static> ListView<T> where ListView<T>: Widget {
} }
} }
impl ListView<Files> where
ListView<Files>: Widget,
Files: std::ops::Index<usize, Output=File>,
Files: std::marker::Sized
{
fn selected_file(&self) -> &File {
let selection = self.selection;
let file = &self.content[selection];
file
}
fn grand_parent(&self) -> Option<PathBuf> {
self.selected_file().grand_parent()
}
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!")
}
}
fn goto_selected(&mut self) {
let path = self.selected_file().path();
self.goto_path(&path);
}
fn goto_path(&mut self, path: &Path) {
match crate::files::Files::new_from_path(path){
Ok(files) => {
self.content = files;
self.selection = 0;
self.offset = 0;
self.refresh();
},
Err(err) => {
self.show_status(&format!("Can't open this path: {}", err));
return;
}
}
}
}
impl Widget for ListView<Files> { impl Widget for ListView<Files> {
fn get_dimensions(&self) -> (u16, u16) { fn get_dimensions(&self) -> (u16, u16) {
self.dimensions self.dimensions
@ -147,9 +195,14 @@ impl Widget for ListView<Files> {
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(); },
Key::Down => { self.move_down(); self.refresh() }, Key::Down => { self.move_down(); self.refresh(); },
//Key::Right => self.go(), Key::Left => {
self.goto_grand_parent()
},
Key::Right => {
self.goto_selected()
},
_ => { self.bad(Event::Key(key)); } _ => { self.bad(Event::Key(key)); }
} }
} }

View File

@ -1,5 +1,6 @@
use termion::event::{Key, MouseEvent, Event}; use termion::event::{Key, MouseEvent, Event};
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);