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:
parent
00c2eb8e46
commit
ab9baf17f1
42
src/files.rs
42
src/files.rs
@ -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))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
20
src/hbox.rs
20
src/hbox.rs
@ -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) {
|
||||||
|
@ -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)); }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user