mirror of https://github.com/bobwen-dev/hunter
async widget
This commit is contained in:
parent
1c500d91cf
commit
56d9c35215
|
@ -16,4 +16,8 @@ rayon = "1.0.3"
|
||||||
dirs-2 = "1.1.0"
|
dirs-2 = "1.1.0"
|
||||||
users = "0.8"
|
users = "0.8"
|
||||||
chrono = "0.4"
|
chrono = "0.4"
|
||||||
libc = "*"
|
libc = "*"
|
||||||
|
|
||||||
|
#[profile.release]
|
||||||
|
#debug = true
|
||||||
|
#lto = false
|
||||||
|
|
|
@ -40,6 +40,18 @@ impl Coordinates {
|
||||||
&self.position
|
&self.position
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn u16position(&self) -> (u16, u16) {
|
||||||
|
self.position.position()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn size(&self) -> &Size {
|
||||||
|
&self.size
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn u16size(&self) -> (u16, u16) {
|
||||||
|
self.size.size()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn top(&self) -> Position {
|
pub fn top(&self) -> Position {
|
||||||
self.position().clone()
|
self.position().clone()
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ pub struct FileBrowser {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Tabbable<FileBrowser> for FileBrowser {
|
impl Tabbable<FileBrowser> for FileBrowser {
|
||||||
fn new_tab(&self) -> Self {
|
fn new_tab(&self) -> FileBrowser {
|
||||||
FileBrowser::new().unwrap()
|
FileBrowser::new().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,8 +115,12 @@ impl FileBrowser {
|
||||||
pub fn update_preview(&mut self) {
|
pub fn update_preview(&mut self) {
|
||||||
if self.columns.get_main_widget().content.len() == 0 { return }
|
if self.columns.get_main_widget().content.len() == 0 { return }
|
||||||
let file = self.columns.get_main_widget().selected_file().clone();
|
let file = self.columns.get_main_widget().selected_file().clone();
|
||||||
let preview = &mut self.columns.preview;
|
//let preview = &mut self.columns.preview;
|
||||||
|
let coords = self.columns.preview.get_coordinates();
|
||||||
|
let mut preview = crate::preview::AsyncPreviewer::new();
|
||||||
|
preview.set_coordinates(&coords);
|
||||||
preview.set_file(&file);
|
preview.set_file(&file);
|
||||||
|
self.columns.preview = preview;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fix_selection(&mut self) {
|
pub fn fix_selection(&mut self) {
|
||||||
|
@ -188,18 +192,6 @@ impl FileBrowser {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Widget for FileBrowser {
|
impl Widget for FileBrowser {
|
||||||
fn get_size(&self) -> &Size {
|
|
||||||
&self.columns.get_size()
|
|
||||||
}
|
|
||||||
fn get_position(&self) -> &Position {
|
|
||||||
&self.columns.get_position()
|
|
||||||
}
|
|
||||||
fn set_size(&mut self, size: Size) {
|
|
||||||
self.columns.set_size(size);
|
|
||||||
}
|
|
||||||
fn set_position(&mut self, position: Position) {
|
|
||||||
self.columns.set_position(position);
|
|
||||||
}
|
|
||||||
fn get_coordinates(&self) -> &Coordinates {
|
fn get_coordinates(&self) -> &Coordinates {
|
||||||
&self.columns.coordinates
|
&self.columns.coordinates
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,7 +26,7 @@ pub struct Files {
|
||||||
|
|
||||||
impl Index<usize> for Files {
|
impl Index<usize> for Files {
|
||||||
type Output = File;
|
type Output = File;
|
||||||
fn index(&self, pos: usize) -> &Self::Output {
|
fn index(&self, pos: usize) -> &File {
|
||||||
&self.files[pos]
|
&self.files[pos]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
16
src/hbox.rs
16
src/hbox.rs
|
@ -11,7 +11,7 @@ pub struct HBox<T: Widget> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl<T> HBox<T> where T: Widget {
|
impl<T> HBox<T> where T: Widget + PartialEq {
|
||||||
pub fn new() -> HBox<T> {
|
pub fn new() -> HBox<T> {
|
||||||
HBox { coordinates: Coordinates::new(),
|
HBox { coordinates: Coordinates::new(),
|
||||||
widgets: vec![],
|
widgets: vec![],
|
||||||
|
@ -78,7 +78,7 @@ impl<T> HBox<T> where T: Widget {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
impl<T> Widget for HBox<T> where T: Widget {
|
impl<T> Widget for HBox<T> where T: Widget + PartialEq {
|
||||||
fn render_header(&self) -> String {
|
fn render_header(&self) -> String {
|
||||||
self.active_widget().render_header()
|
self.active_widget().render_header()
|
||||||
}
|
}
|
||||||
|
@ -96,18 +96,6 @@ impl<T> Widget for HBox<T> where T: Widget {
|
||||||
}).collect()
|
}).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_size(&self) -> &Size {
|
|
||||||
&self.coordinates.size
|
|
||||||
}
|
|
||||||
fn get_position(&self) -> &Position {
|
|
||||||
&self.coordinates.position
|
|
||||||
}
|
|
||||||
fn set_size(&mut self, size: Size) {
|
|
||||||
self.coordinates.size = size;
|
|
||||||
}
|
|
||||||
fn set_position(&mut self, position: Position) {
|
|
||||||
self.coordinates.position = position;
|
|
||||||
}
|
|
||||||
fn get_coordinates(&self) -> &Coordinates {
|
fn get_coordinates(&self) -> &Coordinates {
|
||||||
&self.coordinates
|
&self.coordinates
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,11 +4,12 @@ use unicode_width::UnicodeWidthStr;
|
||||||
|
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
|
//use std::sync::mpsc::{channel, Sender, Receiver};
|
||||||
|
|
||||||
use crate::coordinates::{Coordinates, Position, Size};
|
use crate::coordinates::{Coordinates, Position, Size};
|
||||||
use crate::files::{File, Files};
|
use crate::files::{File, Files};
|
||||||
use crate::term;
|
use crate::term;
|
||||||
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
|
||||||
|
|
||||||
|
@ -30,7 +31,7 @@ where
|
||||||
ListView<T>: Widget,
|
ListView<T>: Widget,
|
||||||
T: Send,
|
T: Send,
|
||||||
{
|
{
|
||||||
pub fn new(content: T) -> Self {
|
pub fn new(content: T) -> ListView<T> {
|
||||||
let view = ListView::<T> {
|
let view = ListView::<T> {
|
||||||
content: content,
|
content: content,
|
||||||
selection: 0,
|
selection: 0,
|
||||||
|
@ -81,7 +82,8 @@ where
|
||||||
let ysize = self.coordinates.ysize() as usize;
|
let ysize = self.coordinates.ysize() as usize;
|
||||||
let mut offset = 0;
|
let mut offset = 0;
|
||||||
|
|
||||||
while position + 2 >= ysize + offset {
|
while position + 2
|
||||||
|
>= ysize + offset {
|
||||||
offset += 1
|
offset += 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,7 +101,7 @@ where
|
||||||
} else { (name.clone(), "".to_string()) };
|
} else { (name.clone(), "".to_string()) };
|
||||||
|
|
||||||
|
|
||||||
let xsize = self.get_size().xsize();
|
let xsize = self.get_coordinates().xsize();
|
||||||
let sized_string = term::sized_string(&name, xsize);
|
let sized_string = term::sized_string(&name, xsize);
|
||||||
let size_pos = xsize - (size.to_string().len() as u16
|
let size_pos = xsize - (size.to_string().len() as u16
|
||||||
+ unit.to_string().len() as u16);
|
+ unit.to_string().len() as u16);
|
||||||
|
@ -321,8 +323,8 @@ where
|
||||||
.arg("-c")
|
.arg("-c")
|
||||||
.arg(&cmd)
|
.arg(&cmd)
|
||||||
.status();
|
.status();
|
||||||
|
let mut bufout = std::io::BufWriter::new(std::io::stdout());
|
||||||
write!(std::io::stdout(), "{}{}",
|
write!(bufout, "{}{}",
|
||||||
termion::style::Reset,
|
termion::style::Reset,
|
||||||
termion::clear::All).unwrap();
|
termion::clear::All).unwrap();
|
||||||
|
|
||||||
|
@ -347,18 +349,6 @@ where
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Widget for ListView<Files> {
|
impl Widget for ListView<Files> {
|
||||||
fn get_size(&self) -> &Size {
|
|
||||||
&self.coordinates.size
|
|
||||||
}
|
|
||||||
fn get_position(&self) -> &Position {
|
|
||||||
&self.coordinates.position
|
|
||||||
}
|
|
||||||
fn set_size(&mut self, size: Size) {
|
|
||||||
self.coordinates.size = size;
|
|
||||||
}
|
|
||||||
fn set_position(&mut self, position: Position) {
|
|
||||||
self.coordinates.position = position;
|
|
||||||
}
|
|
||||||
fn get_coordinates(&self) -> &Coordinates {
|
fn get_coordinates(&self) -> &Coordinates {
|
||||||
&self.coordinates
|
&self.coordinates
|
||||||
}
|
}
|
||||||
|
@ -376,7 +366,7 @@ impl Widget for ListView<Files> {
|
||||||
|
|
||||||
fn get_drawlist(&self) -> String {
|
fn get_drawlist(&self) -> String {
|
||||||
let mut output = term::reset();
|
let mut output = term::reset();
|
||||||
let (_, ysize) = self.get_size().size();
|
let ysize = self.get_coordinates().ysize();
|
||||||
let (xpos, ypos) = self.coordinates.position().position();
|
let (xpos, ypos) = self.coordinates.position().position();
|
||||||
|
|
||||||
output += &self
|
output += &self
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#![feature(vec_remove_item)]
|
#![feature(vec_remove_item)]
|
||||||
|
#![feature(trivial_bounds)]
|
||||||
|
|
||||||
extern crate termion;
|
extern crate termion;
|
||||||
extern crate unicode_width;
|
extern crate unicode_width;
|
||||||
|
@ -18,6 +19,7 @@ use termion::raw::IntoRawMode;
|
||||||
use termion::screen::AlternateScreen;
|
use termion::screen::AlternateScreen;
|
||||||
|
|
||||||
use std::io::{stdout, Write};
|
use std::io::{stdout, Write};
|
||||||
|
use std::marker::Send;
|
||||||
|
|
||||||
mod coordinates;
|
mod coordinates;
|
||||||
mod file_browser;
|
mod file_browser;
|
||||||
|
@ -32,12 +34,16 @@ mod win_main;
|
||||||
mod window;
|
mod window;
|
||||||
mod hbox;
|
mod hbox;
|
||||||
mod tabview;
|
mod tabview;
|
||||||
|
mod async_widget;
|
||||||
|
|
||||||
use window::Window;
|
use window::Window;
|
||||||
|
use async_widget::AsyncPlug;
|
||||||
|
use widget::Widget;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
let mut bufout = std::io::BufWriter::new(std::io::stdout());
|
||||||
// Need to do this here to actually turn terminal into raw mode...
|
// Need to do this here to actually turn terminal into raw mode...
|
||||||
let mut _screen = AlternateScreen::from(Box::new(stdout()));
|
let mut _screen = AlternateScreen::from(Box::new(bufout));
|
||||||
let mut _stdout = MouseTerminal::from(stdout().into_raw_mode().unwrap());
|
let mut _stdout = MouseTerminal::from(stdout().into_raw_mode().unwrap());
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use termion::event::Key;
|
use termion::event::Key;
|
||||||
|
|
||||||
use crate::coordinates::{Coordinates, Position, Size};
|
use crate::coordinates::{Coordinates, Position, Size};
|
||||||
use crate::preview::Previewer;
|
use crate::preview::AsyncPreviewer;
|
||||||
use crate::widget::Widget;
|
use crate::widget::Widget;
|
||||||
use crate::hbox::HBox;
|
use crate::hbox::HBox;
|
||||||
|
|
||||||
|
@ -10,21 +10,21 @@ pub struct MillerColumns<T> where T: Widget {
|
||||||
pub widgets: HBox<T>,
|
pub widgets: HBox<T>,
|
||||||
// pub left: Option<T>,
|
// pub left: Option<T>,
|
||||||
// pub main: Option<T>,
|
// pub main: Option<T>,
|
||||||
pub preview: Previewer,
|
pub preview: AsyncPreviewer,
|
||||||
pub ratio: (u16, u16, u16),
|
pub ratio: (u16, u16, u16),
|
||||||
pub coordinates: Coordinates,
|
pub coordinates: Coordinates,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> MillerColumns<T>
|
impl<T> MillerColumns<T>
|
||||||
where
|
where
|
||||||
T: Widget,
|
T: Widget + PartialEq,
|
||||||
{
|
{
|
||||||
pub fn new() -> Self {
|
pub fn new() -> MillerColumns<T> {
|
||||||
Self {
|
MillerColumns {
|
||||||
widgets: HBox::new(),
|
widgets: HBox::new(),
|
||||||
coordinates: Coordinates::new(),
|
coordinates: Coordinates::new(),
|
||||||
ratio: (20, 30, 50),
|
ratio: (20, 30, 50),
|
||||||
preview: Previewer::new(),
|
preview: AsyncPreviewer::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,7 +91,6 @@ where
|
||||||
if len < 2 {
|
if len < 2 {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
self.widgets.widgets.get(len - 2)?.get_position();
|
|
||||||
self.widgets.widgets.get_mut(len - 2)
|
self.widgets.widgets.get_mut(len - 2)
|
||||||
}
|
}
|
||||||
pub fn get_main_widget(&self) -> &T {
|
pub fn get_main_widget(&self) -> &T {
|
||||||
|
@ -105,19 +104,8 @@ where
|
||||||
impl<T> Widget for MillerColumns<T>
|
impl<T> Widget for MillerColumns<T>
|
||||||
where
|
where
|
||||||
T: Widget,
|
T: Widget,
|
||||||
|
T: PartialEq
|
||||||
{
|
{
|
||||||
fn get_size(&self) -> &Size {
|
|
||||||
&self.coordinates.size
|
|
||||||
}
|
|
||||||
fn get_position(&self) -> &Position {
|
|
||||||
&self.coordinates.position
|
|
||||||
}
|
|
||||||
fn set_size(&mut self, size: Size) {
|
|
||||||
self.coordinates.size = size;
|
|
||||||
}
|
|
||||||
fn set_position(&mut self, position: Position) {
|
|
||||||
self.coordinates.position = position;
|
|
||||||
}
|
|
||||||
fn get_coordinates(&self) -> &Coordinates {
|
fn get_coordinates(&self) -> &Coordinates {
|
||||||
&self.coordinates
|
&self.coordinates
|
||||||
}
|
}
|
||||||
|
|
163
src/preview.rs
163
src/preview.rs
|
@ -7,6 +7,7 @@ use crate::files::{File, Files, Kind};
|
||||||
use crate::listview::ListView;
|
use crate::listview::ListView;
|
||||||
use crate::textview::TextView;
|
use crate::textview::TextView;
|
||||||
use crate::widget::Widget;
|
use crate::widget::Widget;
|
||||||
|
use crate::async_widget::AsyncPlug;
|
||||||
|
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
|
@ -23,10 +24,130 @@ fn kill_procs() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_current(file: &File) -> bool {
|
fn is_current(file: &File) -> bool {
|
||||||
CURFILE.lock().unwrap().as_ref().unwrap() == file
|
true
|
||||||
|
//CURFILE.lock().unwrap().as_ref().unwrap() == file
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(PartialEq)]
|
||||||
|
pub struct AsyncPreviewer {
|
||||||
|
pub file: Option<File>,
|
||||||
|
pub buffer: String,
|
||||||
|
pub coordinates: Coordinates,
|
||||||
|
pub async_plug: AsyncPlug
|
||||||
|
}
|
||||||
|
|
||||||
|
impl AsyncPreviewer {
|
||||||
|
pub fn new() -> AsyncPreviewer {
|
||||||
|
let textview = crate::textview::TextView {
|
||||||
|
lines: vec![],
|
||||||
|
buffer: "".to_string(),
|
||||||
|
coordinates: Coordinates::new(),
|
||||||
|
};
|
||||||
|
let textview = Box::new(textview);
|
||||||
|
|
||||||
|
AsyncPreviewer {
|
||||||
|
file: None,
|
||||||
|
buffer: String::new(),
|
||||||
|
coordinates: Coordinates::new(),
|
||||||
|
async_plug: AsyncPlug::new(textview)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn set_file(&mut self, file: &File) {
|
||||||
|
let coordinates = self.coordinates.clone();
|
||||||
|
let file = file.clone();
|
||||||
|
let redraw = crate::term::reset() + &self.get_redraw_empty_list(0);
|
||||||
|
|
||||||
|
self.async_plug.replace_widget(Box::new(move || {
|
||||||
|
kill_procs();
|
||||||
|
let mut bufout = std::io::BufWriter::new(std::io::stdout());
|
||||||
|
match &file.kind {
|
||||||
|
Kind::Directory => match Files::new_from_path(&file.path) {
|
||||||
|
Ok(files) => {
|
||||||
|
//if !is_current(&file) { return }
|
||||||
|
let len = files.len();
|
||||||
|
//if len == 0 { return };
|
||||||
|
let mut file_list = ListView::new(files);
|
||||||
|
file_list.set_coordinates(&coordinates);
|
||||||
|
file_list.refresh();
|
||||||
|
//if !is_current(&file) { return }
|
||||||
|
file_list.animate_slide_up();
|
||||||
|
return Box::new(file_list) as Box<dyn Widget + Send>;
|
||||||
|
|
||||||
|
}
|
||||||
|
Err(err) => {
|
||||||
|
write!(bufout, "{}", redraw).unwrap();
|
||||||
|
let textview = crate::textview::TextView {
|
||||||
|
lines: vec![],
|
||||||
|
buffer: "".to_string(),
|
||||||
|
coordinates: Coordinates::new(),
|
||||||
|
};
|
||||||
|
return Box::new(textview) as Box<dyn Widget + Send>;
|
||||||
|
},
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
if file.get_mime() == Some("text".to_string()) {
|
||||||
|
let mut textview = TextView::new_from_file(&file);
|
||||||
|
//if !is_current(&file) { return }
|
||||||
|
textview.set_coordinates(&coordinates);
|
||||||
|
textview.refresh();
|
||||||
|
//if !is_current(&file) { return }
|
||||||
|
textview.animate_slide_up();
|
||||||
|
return Box::new(textview);
|
||||||
|
} else {
|
||||||
|
let process =
|
||||||
|
std::process::Command::new("scope.sh")
|
||||||
|
.arg(&file.name)
|
||||||
|
.arg("10".to_string())
|
||||||
|
.arg("10".to_string())
|
||||||
|
.arg("".to_string())
|
||||||
|
.arg("false".to_string())
|
||||||
|
.stdin(std::process::Stdio::null())
|
||||||
|
.stdout(std::process::Stdio::piped())
|
||||||
|
.stderr(std::process::Stdio::null())
|
||||||
|
.spawn().unwrap();
|
||||||
|
|
||||||
|
// let pid = process.id();
|
||||||
|
// PIDS.lock().unwrap().push(pid);
|
||||||
|
|
||||||
|
//if !is_current(&file) { return }
|
||||||
|
|
||||||
|
let output = process.wait_with_output();
|
||||||
|
//if output.is_err() { return }
|
||||||
|
let output = output.unwrap();
|
||||||
|
|
||||||
|
let status = output.status.code();
|
||||||
|
//if status.is_none() { return }
|
||||||
|
let status = status.unwrap();
|
||||||
|
|
||||||
|
if status == 0 || status == 5 && is_current(&file) {
|
||||||
|
let output = std::str::from_utf8(&output.stdout)
|
||||||
|
.unwrap()
|
||||||
|
.to_string();
|
||||||
|
let mut textview = TextView {
|
||||||
|
lines: output.lines().map(|s| s.to_string()).collect(),
|
||||||
|
buffer: String::new(),
|
||||||
|
coordinates: Coordinates::new() };
|
||||||
|
textview.set_coordinates(&coordinates);
|
||||||
|
textview.refresh();
|
||||||
|
textview.animate_slide_up();
|
||||||
|
return Box::new(textview);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
write!(bufout, "{}", redraw).unwrap();
|
||||||
|
//std::io::stdout().flush().unwrap();
|
||||||
|
let textview = crate::textview::TextView {
|
||||||
|
lines: vec![],
|
||||||
|
buffer: "".to_string(),
|
||||||
|
coordinates: Coordinates::new(),
|
||||||
|
};
|
||||||
|
return Box::new(textview);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(PartialEq)]
|
#[derive(PartialEq)]
|
||||||
pub struct Previewer {
|
pub struct Previewer {
|
||||||
|
@ -129,18 +250,6 @@ impl Previewer {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Widget for Previewer {
|
impl Widget for Previewer {
|
||||||
fn get_size(&self) -> &Size {
|
|
||||||
&self.coordinates.size
|
|
||||||
}
|
|
||||||
fn set_size(&mut self, size: Size) {
|
|
||||||
self.coordinates.size = size;
|
|
||||||
}
|
|
||||||
fn get_position(&self) -> &Position {
|
|
||||||
&self.coordinates.position
|
|
||||||
}
|
|
||||||
fn set_position(&mut self, pos: Position) {
|
|
||||||
self.coordinates.position = pos;
|
|
||||||
}
|
|
||||||
fn get_coordinates(&self) -> &Coordinates {
|
fn get_coordinates(&self) -> &Coordinates {
|
||||||
&self.coordinates
|
&self.coordinates
|
||||||
}
|
}
|
||||||
|
@ -164,3 +273,31 @@ impl Widget for Previewer {
|
||||||
self.buffer.clone()
|
self.buffer.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl Widget for AsyncPreviewer {
|
||||||
|
fn get_coordinates(&self) -> &Coordinates {
|
||||||
|
&self.coordinates
|
||||||
|
}
|
||||||
|
fn set_coordinates(&mut self, coordinates: &Coordinates) {
|
||||||
|
if self.coordinates == *coordinates {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self.coordinates = coordinates.clone();
|
||||||
|
self.async_plug.set_coordinates(&coordinates.clone());
|
||||||
|
self.async_plug.refresh();
|
||||||
|
}
|
||||||
|
fn render_header(&self) -> String {
|
||||||
|
"".to_string()
|
||||||
|
}
|
||||||
|
fn refresh(&mut self) {
|
||||||
|
let file = self.file.clone();
|
||||||
|
if let Some(file) = file {
|
||||||
|
self.set_file(&file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn get_drawlist(&self) -> String {
|
||||||
|
self.async_plug.get_drawlist();
|
||||||
|
"".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -10,15 +10,15 @@ pub trait Tabbable<T: Widget> {
|
||||||
|
|
||||||
|
|
||||||
#[derive(PartialEq)]
|
#[derive(PartialEq)]
|
||||||
pub struct TabView<T> where T: Widget {
|
pub struct TabView<T> where T: Widget, T: Tabbable<T> {
|
||||||
widgets: Vec<T>,
|
widgets: Vec<T>,
|
||||||
active: usize,
|
active: usize,
|
||||||
coordinates: Coordinates
|
coordinates: Coordinates
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> TabView<T> where T: Widget + Tabbable<T> {
|
impl<T> TabView<T> where T: Widget, T: Tabbable<T> {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> TabView<T> {
|
||||||
Self {
|
TabView {
|
||||||
widgets: vec![],
|
widgets: vec![],
|
||||||
active: 0,
|
active: 0,
|
||||||
coordinates: Coordinates::new()
|
coordinates: Coordinates::new()
|
||||||
|
@ -67,7 +67,7 @@ impl<T> TabView<T> where T: Widget + Tabbable<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Widget for TabView<T> where T: Widget + Tabbable<T> + PartialEq {
|
impl<T> Widget for TabView<T> where T: Widget + Tabbable<T> {
|
||||||
fn render_header(&self) -> String {
|
fn render_header(&self) -> String {
|
||||||
let xsize = self.get_coordinates().xsize();
|
let xsize = self.get_coordinates().xsize();
|
||||||
let header = self.active_widget().render_header();
|
let header = self.active_widget().render_header();
|
||||||
|
@ -106,18 +106,6 @@ impl<T> Widget for TabView<T> where T: Widget + Tabbable<T> + PartialEq {
|
||||||
self.active_widget().get_drawlist()
|
self.active_widget().get_drawlist()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_size(&self) -> &Size {
|
|
||||||
&self.coordinates.size
|
|
||||||
}
|
|
||||||
fn get_position(&self) -> &Position {
|
|
||||||
&self.coordinates.position
|
|
||||||
}
|
|
||||||
fn set_size(&mut self, size: Size) {
|
|
||||||
self.coordinates.size = size;
|
|
||||||
}
|
|
||||||
fn set_position(&mut self, position: Position) {
|
|
||||||
self.coordinates.position = position;
|
|
||||||
}
|
|
||||||
fn get_coordinates(&self) -> &Coordinates {
|
fn get_coordinates(&self) -> &Coordinates {
|
||||||
&self.coordinates
|
&self.coordinates
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,18 +31,6 @@ impl TextView {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Widget for TextView {
|
impl Widget for TextView {
|
||||||
fn get_size(&self) -> &Size {
|
|
||||||
&self.coordinates.size
|
|
||||||
}
|
|
||||||
fn set_size(&mut self, size: Size) {
|
|
||||||
self.coordinates.size = size;
|
|
||||||
}
|
|
||||||
fn get_position(&self) -> &Position {
|
|
||||||
&self.coordinates.position
|
|
||||||
}
|
|
||||||
fn set_position(&mut self, pos: Position) {
|
|
||||||
self.coordinates.position = pos;
|
|
||||||
}
|
|
||||||
fn get_coordinates(&self) -> &Coordinates {
|
fn get_coordinates(&self) -> &Coordinates {
|
||||||
&self.coordinates
|
&self.coordinates
|
||||||
}
|
}
|
||||||
|
@ -54,7 +42,7 @@ impl Widget for TextView {
|
||||||
"".to_string()
|
"".to_string()
|
||||||
}
|
}
|
||||||
fn refresh(&mut self) {
|
fn refresh(&mut self) {
|
||||||
let (xsize, ysize) = self.get_size().size();
|
let (xsize, ysize) = self.get_coordinates().size().size();
|
||||||
let (xpos, ypos) = self.get_coordinates().position().position();
|
let (xpos, ypos) = self.get_coordinates().position().position();
|
||||||
|
|
||||||
self.buffer = self.get_clearlist() +
|
self.buffer = self.get_clearlist() +
|
||||||
|
|
|
@ -2,18 +2,17 @@ use termion::event::{Event, Key, MouseEvent};
|
||||||
|
|
||||||
use crate::coordinates::{Coordinates, Position, Size};
|
use crate::coordinates::{Coordinates, Position, Size};
|
||||||
|
|
||||||
use std::io::Write;
|
use std::io::{BufWriter, Write};
|
||||||
|
|
||||||
pub trait Widget: PartialEq {
|
|
||||||
//fn render(&self) -> Vec<String>;
|
pub trait Widget {
|
||||||
fn get_size(&self) -> &Size;
|
|
||||||
fn get_position(&self) -> &Position;
|
|
||||||
fn set_size(&mut self, size: Size);
|
|
||||||
fn set_position(&mut self, position: Position);
|
|
||||||
fn get_coordinates(&self) -> &Coordinates;
|
fn get_coordinates(&self) -> &Coordinates;
|
||||||
fn set_coordinates(&mut self, coordinates: &Coordinates);
|
fn set_coordinates(&mut self, coordinates: &Coordinates);
|
||||||
fn render_header(&self) -> String;
|
fn render_header(&self) -> String;
|
||||||
fn render_footer(&self) -> String { "".into() }
|
fn render_footer(&self) -> String { "".into() }
|
||||||
|
fn refresh(&mut self);
|
||||||
|
fn get_drawlist(&self) -> String;
|
||||||
|
|
||||||
|
|
||||||
fn on_event(&mut self, event: Event) {
|
fn on_event(&mut self, event: Event) {
|
||||||
match event {
|
match event {
|
||||||
|
@ -62,7 +61,7 @@ pub trait Widget: PartialEq {
|
||||||
" ",
|
" ",
|
||||||
crate::term::goto_xy(1, 1),
|
crate::term::goto_xy(1, 1),
|
||||||
self.render_header(),
|
self.render_header(),
|
||||||
xsize = self.get_size().xsize() as usize
|
xsize = self.get_coordinates().xsize() as usize
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,8 +79,8 @@ pub trait Widget: PartialEq {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_clearlist(&self) -> String {
|
fn get_clearlist(&self) -> String {
|
||||||
let (xpos, ypos) = self.get_position().position();
|
let (xpos, ypos) = self.get_coordinates().u16position();
|
||||||
let (xsize, ysize) = self.get_size().size();
|
let (xsize, ysize) = self.get_coordinates().u16size();
|
||||||
|
|
||||||
(ypos..ysize + 2)
|
(ypos..ysize + 2)
|
||||||
.map(|line| {
|
.map(|line| {
|
||||||
|
@ -97,8 +96,8 @@ pub trait Widget: PartialEq {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_redraw_empty_list(&self, lines: usize) -> String {
|
fn get_redraw_empty_list(&self, lines: usize) -> String {
|
||||||
let (xpos, ypos) = self.get_position().position();
|
let (xpos, ypos) = self.get_coordinates().u16position();
|
||||||
let (xsize, ysize) = self.get_size().size();
|
let (xsize, ysize) = self.get_coordinates().u16size();
|
||||||
|
|
||||||
let start_y = lines + ypos as usize;
|
let start_y = lines + ypos as usize;
|
||||||
(start_y..(ysize + 2) as usize)
|
(start_y..(ysize + 2) as usize)
|
||||||
|
@ -121,6 +120,7 @@ pub trait Widget: PartialEq {
|
||||||
let ysize = coords.ysize();
|
let ysize = coords.ysize();
|
||||||
let clear = self.get_clearlist();
|
let clear = self.get_clearlist();
|
||||||
let pause = std::time::Duration::from_millis(5);
|
let pause = std::time::Duration::from_millis(5);
|
||||||
|
let mut bufout = std::io::BufWriter::new(std::io::stdout());
|
||||||
|
|
||||||
for i in (0..10).rev() {
|
for i in (0..10).rev() {
|
||||||
let coords = Coordinates { size: Size((xsize,ysize-i)),
|
let coords = Coordinates { size: Size((xsize,ysize-i)),
|
||||||
|
@ -130,13 +130,11 @@ pub trait Widget: PartialEq {
|
||||||
};
|
};
|
||||||
self.set_coordinates(&coords);
|
self.set_coordinates(&coords);
|
||||||
let buffer = self.get_drawlist();
|
let buffer = self.get_drawlist();
|
||||||
write!(std::io::stdout(), "{}{}",
|
write!(bufout, "{}{}",
|
||||||
clear, buffer).unwrap();
|
clear, buffer).unwrap();
|
||||||
|
|
||||||
|
|
||||||
std::thread::sleep(pause);
|
std::thread::sleep(pause);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn refresh(&mut self);
|
|
||||||
fn get_drawlist(&self) -> String;
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue