summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorrabite <rabite@posteo.de>2019-01-22 21:05:06 +0100
committerrabite <rabite@posteo.de>2019-01-22 21:05:06 +0100
commitab9baf17f110622391d143122195e2b82acc7d10 (patch)
treecb3fc15e8a51b78b012bb78f9bd9693b1618abc9 /src
parent00c2eb8e461d135b33756da79009df3d7c1bc8ff (diff)
basic browsing working
Diffstat (limited to 'src')
-rw-r--r--src/files.rs42
-rw-r--r--src/hbox.rs22
-rw-r--r--src/listview.rs61
-rw-r--r--src/widget.rs1
4 files changed, 93 insertions, 33 deletions
diff --git a/src/files.rs b/src/files.rs
index 2d83bd9..dd86304 100644
--- a/src/files.rs
+++ b/src/files.rs
@@ -1,4 +1,7 @@
use std::ops::Index;
+use std::error::Error;
+use std::path::PathBuf;
+use std::ffi::OsStr;
pub struct Files(Vec<File>);
@@ -10,6 +13,22 @@ impl Index<usize> for 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> {
self.0.iter()
}
@@ -22,7 +41,7 @@ impl Files {
#[derive(Debug)]
pub struct File {
pub name: String,
- pub path: String,
+ pub path: PathBuf,
pub size: Option<usize>,
// owner: Option<String>,
// group: Option<String>,
@@ -33,10 +52,10 @@ pub struct File {
impl File {
- pub fn new(name: &str, path: &str, size: usize) -> File {
+ pub fn new(name: &str, path: PathBuf, size: usize) -> File {
File {
name: name.to_string(),
- path: path.to_string(),
+ path: path,
size: Some(size),
// owner: None,
// group: None,
@@ -62,18 +81,13 @@ impl File {
}.to_string();
(size, unit)
}
-}
-pub fn get_files(dir: &str) -> Result<Files, std::io::Error> {
- let mut files = Vec::new();
- 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();
- let path = file.as_ref().unwrap().path().into_os_string().into_string().unwrap();
- let size = file.unwrap().metadata()?.len() / 1024;
- files.push(File::new(&name, &path, size as usize));
+ pub fn grand_parent(&self) -> Option<PathBuf> {
+ Some(self.path.parent()?.parent()?.to_path_buf())
}
- Ok(Files(files))
-}
+ pub fn path(&self) -> PathBuf {
+ self.path.clone()
+ }
+}
diff --git a/src/hbox.rs b/src/hbox.rs
index 4719544..3cd8f53 100644
--- a/src/hbox.rs
+++ b/src/hbox.rs
@@ -9,7 +9,6 @@ use crate::widget::Widget;
// active: bool
// }
-
pub struct HBox {
dimensions: (u16, u16),
position: (u16, u16),
@@ -39,27 +38,20 @@ impl HBox {
let hbox_position = dbg!(self.position);
let cell_size = dbg!(hbox_size.0 / self.children.len() as u16);
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_position(dbg!((current_pos, hbox_position.1)));
widget.refresh();
dbg!(current_pos += cell_size);
- dbg!(current_edge += cell_size);
}
}
- pub fn resize_child(&mut self, index: usize, size: (u16, u16)) {
- self.children[index].set_dimensions(size);
- }
-
-
- pub fn widget(&self, index: usize) -> &Box<Widget> {
- &self.children[index]
- }
+ // pub fn widget(&self, index: usize) -> &Box<Widget> {
+ // &self.children[index]
+ // }
- pub fn active_widget(&self, index: usize) -> &Box<Widget> {
+ pub fn active_widget(&self) -> &Box<Widget> {
&self.children[self.active]
}
@@ -75,7 +67,7 @@ impl Widget for HBox {
}
fn render_header(&self) -> String {
- self.children[self.active].render_header()
+ self.active_widget().render_header()
}
fn refresh(&mut self) {
diff --git a/src/listview.rs b/src/listview.rs
index 8098564..1ec0dfb 100644
--- a/src/listview.rs
+++ b/src/listview.rs
@@ -1,8 +1,10 @@
use unicode_width::{UnicodeWidthStr};
use termion::event::{Key,Event};
+use std::path::{Path, PathBuf};
+
use crate::term;
-use crate::files::Files;
+use crate::files::{File, Files};
use crate::widget::Widget;
// 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> {
fn get_dimensions(&self) -> (u16, u16) {
self.dimensions
@@ -147,9 +195,14 @@ impl Widget for ListView<Files> {
fn on_key(&mut self, key: Key) {
match key {
- Key::Up => { self.move_up(); self.refresh() },
- Key::Down => { self.move_down(); self.refresh() },
- //Key::Right => self.go(),
+ Key::Up => { self.move_up(); self.refresh(); },
+ Key::Down => { self.move_down(); self.refresh(); },
+ Key::Left => {
+ self.goto_grand_parent()
+ },
+ Key::Right => {
+ self.goto_selected()
+ },
_ => { self.bad(Event::Key(key)); }
}
}
diff --git a/src/widget.rs b/src/widget.rs
index c9012c9..da98f60 100644
--- a/src/widget.rs
+++ b/src/widget.rs
@@ -1,5 +1,6 @@
use termion::event::{Key, MouseEvent, Event};
+
pub trait Widget {
fn render(&self) -> Vec<String>;
fn get_dimensions(&self) -> (u16, u16);