mirror of
https://github.com/bobwen-dev/hunter
synced 2025-04-12 00:55:41 +02:00
async stuff much improved
This commit is contained in:
parent
bb917a0dad
commit
fd366a26dc
20
src/fail.rs
20
src/fail.rs
@ -37,6 +37,12 @@ pub enum HError {
|
|||||||
NoneError(Backtrace),
|
NoneError(Backtrace),
|
||||||
#[fail(display = "Not ready yet!")]
|
#[fail(display = "Not ready yet!")]
|
||||||
WillBeNotReady(Backtrace),
|
WillBeNotReady(Backtrace),
|
||||||
|
#[fail(display = "Not ready yet!")]
|
||||||
|
AsyncNotReadyError(Backtrace),
|
||||||
|
#[fail(display = "Value has already been taken!")]
|
||||||
|
AsyncAlreadyTakenError(Backtrace),
|
||||||
|
#[fail(display = "Async Error: {}", _0)]
|
||||||
|
AsyncError(String),
|
||||||
#[fail(display = "No widget found")]
|
#[fail(display = "No widget found")]
|
||||||
NoWidgetError(Backtrace),
|
NoWidgetError(Backtrace),
|
||||||
#[fail(display = "Path: {:?} not in this directory: {:?}", path, dir)]
|
#[fail(display = "Path: {:?} not in this directory: {:?}", path, dir)]
|
||||||
@ -72,7 +78,7 @@ pub enum HError {
|
|||||||
#[fail(display = "Terminal has been resized!")]
|
#[fail(display = "Terminal has been resized!")]
|
||||||
TerminalResizedError,
|
TerminalResizedError,
|
||||||
#[fail(display = "{}", _0)]
|
#[fail(display = "{}", _0)]
|
||||||
Log(String)
|
Log(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl HError {
|
impl HError {
|
||||||
@ -126,6 +132,18 @@ impl HError {
|
|||||||
pub fn stale<T>() -> HResult<T> {
|
pub fn stale<T>() -> HResult<T> {
|
||||||
Err(HError::StaleError(Backtrace::new()))
|
Err(HError::StaleError(Backtrace::new()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn async_not_ready<T>() -> HResult<T> {
|
||||||
|
Err(HError::AsyncNotReadyError(Backtrace::new()))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn async_taken<T>() -> HResult<T> {
|
||||||
|
Err(HError::AsyncAlreadyTakenError(Backtrace::new()))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn async_error<T>(error: &HError) -> HResult<T> {
|
||||||
|
Err(HError::AsyncError(format!("{}", error)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -7,15 +7,14 @@ use std::sync::mpsc::{channel, Receiver, Sender};
|
|||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::ffi::{OsString, OsStr};
|
use std::ffi::OsString;
|
||||||
|
|
||||||
use crate::files::{File, Files, PathBufExt, OsStrTools};
|
use crate::files::{File, Files, PathBufExt};
|
||||||
use crate::listview::ListView;
|
use crate::listview::ListView;
|
||||||
use crate::hbox::HBox;
|
use crate::hbox::HBox;
|
||||||
use crate::widget::Widget;
|
use crate::widget::Widget;
|
||||||
use crate::dirty::Dirtyable;
|
|
||||||
use crate::tabview::{TabView, Tabbable};
|
use crate::tabview::{TabView, Tabbable};
|
||||||
use crate::preview::{Previewer, WillBeWidget};
|
use crate::preview::{Previewer, AsyncWidget};
|
||||||
use crate::fail::{HResult, HError, ErrorLog};
|
use crate::fail::{HResult, HError, ErrorLog};
|
||||||
use crate::widget::{Events, WidgetCore};
|
use crate::widget::{Events, WidgetCore};
|
||||||
use crate::proclist::ProcView;
|
use crate::proclist::ProcView;
|
||||||
@ -27,7 +26,7 @@ use crate::coordinates::Coordinates;
|
|||||||
|
|
||||||
#[derive(PartialEq)]
|
#[derive(PartialEq)]
|
||||||
pub enum FileBrowserWidgets {
|
pub enum FileBrowserWidgets {
|
||||||
FileList(WillBeWidget<ListView<Files>>),
|
FileList(AsyncWidget<ListView<Files>>),
|
||||||
Previewer(Previewer),
|
Previewer(Previewer),
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,7 +190,7 @@ impl FileBrowser {
|
|||||||
}).last()?;
|
}).last()?;
|
||||||
let left_path = main_path.parent().map(|p| p.to_path_buf());
|
let left_path = main_path.parent().map(|p| p.to_path_buf());
|
||||||
|
|
||||||
let main_widget = WillBeWidget::new(&core, Box::new(move |_| {
|
let main_widget = AsyncWidget::new(&core, Box::new(move |_| {
|
||||||
let mut list = ListView::new(&core_m,
|
let mut list = ListView::new(&core_m,
|
||||||
Files::new_from_path(&main_path)?);
|
Files::new_from_path(&main_path)?);
|
||||||
list.animate_slide_up().log();
|
list.animate_slide_up().log();
|
||||||
@ -199,7 +198,7 @@ impl FileBrowser {
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
if let Some(left_path) = left_path {
|
if let Some(left_path) = left_path {
|
||||||
let left_widget = WillBeWidget::new(&core, Box::new(move |_| {
|
let left_widget = AsyncWidget::new(&core, Box::new(move |_| {
|
||||||
let mut list = ListView::new(&core_l,
|
let mut list = ListView::new(&core_l,
|
||||||
Files::new_from_path(&left_path)?);
|
Files::new_from_path(&left_path)?);
|
||||||
list.animate_slide_up().log();
|
list.animate_slide_up().log();
|
||||||
@ -314,8 +313,8 @@ impl FileBrowser {
|
|||||||
self.prev_cwd = Some(self.cwd.clone());
|
self.prev_cwd = Some(self.cwd.clone());
|
||||||
self.cwd = dir.clone();
|
self.cwd = dir.clone();
|
||||||
|
|
||||||
let main_widget = self.main_widget_mut()?;
|
let main_async_widget = self.main_async_widget_mut()?;
|
||||||
main_widget.change_to(Box::new(move |stale, core| {
|
main_async_widget.change_to(Box::new(move |stale, core| {
|
||||||
let path = dir.path();
|
let path = dir.path();
|
||||||
let cached_files = cached_files.clone();
|
let cached_files = cached_files.clone();
|
||||||
|
|
||||||
@ -334,7 +333,7 @@ impl FileBrowser {
|
|||||||
if let Ok(grand_parent) = self.cwd()?.parent_as_file() {
|
if let Ok(grand_parent) = self.cwd()?.parent_as_file() {
|
||||||
self.left_widget_goto(&grand_parent).log();
|
self.left_widget_goto(&grand_parent).log();
|
||||||
} else {
|
} else {
|
||||||
self.left_widget_mut()?.set_stale().log();
|
self.left_async_widget_mut()?.set_stale().log();
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -345,8 +344,8 @@ impl FileBrowser {
|
|||||||
let cached_files = self.get_cached_files(&dir).ok();
|
let cached_files = self.get_cached_files(&dir).ok();
|
||||||
let dir = dir.clone();
|
let dir = dir.clone();
|
||||||
|
|
||||||
let left_widget = self.left_widget_mut()?;
|
let left_async_widget = self.left_async_widget_mut()?;
|
||||||
left_widget.change_to(Box::new(move |stale, core| {
|
left_async_widget.change_to(Box::new(move |stale, core| {
|
||||||
let path = dir.path();
|
let path = dir.path();
|
||||||
let cached_files = cached_files.clone();
|
let cached_files = cached_files.clone();
|
||||||
|
|
||||||
@ -415,34 +414,29 @@ impl FileBrowser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_preview(&mut self) -> HResult<()> {
|
pub fn update_preview(&mut self) -> HResult<()> {
|
||||||
if !self.main_widget()?.ready() { return Ok(()) }
|
if !self.main_async_widget_mut()?.ready() { return Ok(()) }
|
||||||
if self.main_widget()?
|
if self.main_widget()?
|
||||||
.widget()?
|
|
||||||
.lock()?
|
|
||||||
.as_ref()
|
|
||||||
.unwrap()
|
|
||||||
.content
|
.content
|
||||||
.len() == 0 {
|
.len() == 0 {
|
||||||
self.preview_widget_mut()?.set_stale();
|
self.preview_widget_mut()?.set_stale().log();
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
let file = self.selected_file()?.clone();
|
let file = self.selected_file()?.clone();
|
||||||
let selection = self.get_selection(&file).ok().cloned();
|
let selection = self.get_selection(&file).ok().cloned();
|
||||||
let cached_files = self.get_cached_files(&file).ok();
|
let cached_files = self.get_cached_files(&file).ok();
|
||||||
let preview = self.preview_widget_mut()?;
|
let preview = self.preview_widget_mut()?;
|
||||||
preview.set_file(&file, selection, cached_files);
|
preview.set_file(&file, selection, cached_files).log();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_left_selection(&mut self) -> HResult<()> {
|
pub fn set_left_selection(&mut self) -> HResult<()> {
|
||||||
if !self.left_widget()?.ready() { return Ok(()) }
|
if !self.left_async_widget_mut()?.ready() { return Ok(()) }
|
||||||
if self.cwd.parent().is_none() { return Ok(()) }
|
if self.cwd.parent().is_none() { return Ok(()) }
|
||||||
|
|
||||||
let parent = self.cwd()?.parent_as_file();
|
let parent = self.cwd()?.parent_as_file();
|
||||||
|
|
||||||
if let Ok(left_selection) = self.get_selection(&parent?) {
|
let left_selection = self.get_selection(&parent?)?.clone();
|
||||||
self.left_widget()?.widget()?.lock()?.as_mut()?.select_file(&left_selection);
|
self.left_widget_mut()?.select_file(&left_selection);
|
||||||
}
|
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -452,11 +446,11 @@ impl FileBrowser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_files(&mut self) -> HResult<Files> {
|
pub fn get_files(&mut self) -> HResult<Files> {
|
||||||
Ok(self.main_widget()?.widget()?.lock()?.as_ref()?.content.clone())
|
Ok(self.main_widget()?.content.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_left_files(&mut self) -> HResult<Files> {
|
pub fn get_left_files(&mut self) -> HResult<Files> {
|
||||||
Ok(self.left_widget()?.widget()?.lock()?.as_ref()?.content.clone())
|
Ok(self.left_widget()?.content.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cache_files(&mut self, files: Files) -> HResult<()> {
|
pub fn cache_files(&mut self, files: Files) -> HResult<()> {
|
||||||
@ -491,13 +485,14 @@ impl FileBrowser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn left_dir(&self) -> HResult<File> {
|
pub fn left_dir(&self) -> HResult<File> {
|
||||||
let widget = self.left_widget()?.widget()?;
|
let widget = self.left_widget()?;
|
||||||
let dir = widget.lock()?.as_ref()?.content.directory.clone();
|
let dir = widget.content.directory.clone();
|
||||||
Ok(dir)
|
Ok(dir)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_watches(&mut self) -> HResult<()> {
|
fn update_watches(&mut self) -> HResult<()> {
|
||||||
if !self.left_widget()?.ready() || !self.main_widget()?.ready() {
|
if !self.left_async_widget_mut()?.ready() ||
|
||||||
|
!self.main_async_widget_mut()?.ready() {
|
||||||
return Ok(())
|
return Ok(())
|
||||||
}
|
}
|
||||||
let watched_dirs = self.watches.clone();
|
let watched_dirs = self.watches.clone();
|
||||||
@ -539,13 +534,11 @@ impl FileBrowser {
|
|||||||
fn handle_dir_events(&mut self) -> HResult<()> {
|
fn handle_dir_events(&mut self) -> HResult<()> {
|
||||||
let dir_events = self.dir_events.clone();
|
let dir_events = self.dir_events.clone();
|
||||||
for event in dir_events.lock()?.iter() {
|
for event in dir_events.lock()?.iter() {
|
||||||
let main_widget = self.main_widget()?.widget()?;
|
let main_widget = self.main_widget_mut()?;
|
||||||
let mut main_widget = main_widget.lock()?;
|
let main_result = main_widget.content.handle_event(event);
|
||||||
let main_result = main_widget.as_mut()?.content.handle_event(event);
|
|
||||||
|
|
||||||
let left_widget = self.left_widget()?.widget()?;
|
let left_widget = self.left_widget_mut()?;
|
||||||
let mut left_files = left_widget.lock()?;
|
let left_result = left_widget.content.handle_event(event);
|
||||||
let left_result = left_files.as_mut()?.content.handle_event(event);
|
|
||||||
|
|
||||||
match main_result {
|
match main_result {
|
||||||
Err(HError::WrongDirectoryError { .. }) => {
|
Err(HError::WrongDirectoryError { .. }) => {
|
||||||
@ -563,62 +556,80 @@ impl FileBrowser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn selected_file(&self) -> HResult<File> {
|
pub fn selected_file(&self) -> HResult<File> {
|
||||||
let widget = self.main_widget()?.widget()?;
|
let widget = self.main_widget()?;
|
||||||
let file = widget.lock()?.as_ref()?.selected_file().clone();
|
let file = widget.selected_file().clone();
|
||||||
Ok(file)
|
Ok(file)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn selected_files(&self) -> HResult<Vec<File>> {
|
pub fn selected_files(&self) -> HResult<Vec<File>> {
|
||||||
let widget = self.main_widget()?.widget()?;
|
let widget = self.main_widget()?;
|
||||||
let files = widget.lock()?.as_ref()?.content.get_selected().into_iter().map(|f| {
|
let files = widget.content.get_selected().into_iter().map(|f| {
|
||||||
f.clone()
|
f.clone()
|
||||||
}).collect();
|
}).collect();
|
||||||
Ok(files)
|
Ok(files)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn main_widget(&self) -> HResult<&WillBeWidget<ListView<Files>>> {
|
pub fn main_async_widget_mut(&mut self) -> HResult<&mut AsyncWidget<ListView<Files>>> {
|
||||||
let widget = self.columns.active_widget()?;
|
|
||||||
|
|
||||||
let widget = match widget {
|
|
||||||
FileBrowserWidgets::FileList(filelist) => Ok(filelist),
|
|
||||||
_ => { HError::wrong_widget("previewer", "filelist")? }
|
|
||||||
};
|
|
||||||
widget
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn main_widget_mut(&mut self) -> HResult<&mut WillBeWidget<ListView<Files>>> {
|
|
||||||
let widget = self.columns.active_widget_mut()?;
|
let widget = self.columns.active_widget_mut()?;
|
||||||
|
|
||||||
let widget = match widget {
|
let widget = match widget {
|
||||||
FileBrowserWidgets::FileList(filelist) => Ok(filelist),
|
FileBrowserWidgets::FileList(filelist) => filelist,
|
||||||
|
_ => { HError::wrong_widget("previewer", "filelist")? }
|
||||||
|
};
|
||||||
|
Ok(widget)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn main_widget(&self) -> HResult<&ListView<Files>> {
|
||||||
|
let widget = self.columns.active_widget()?;
|
||||||
|
|
||||||
|
let widget = match widget {
|
||||||
|
FileBrowserWidgets::FileList(filelist) => filelist.widget(),
|
||||||
_ => { HError::wrong_widget("previewer", "filelist")? }
|
_ => { HError::wrong_widget("previewer", "filelist")? }
|
||||||
};
|
};
|
||||||
widget
|
widget
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn left_widget(&self) -> HResult<&WillBeWidget<ListView<Files>>> {
|
pub fn main_widget_mut(&mut self) -> HResult<&mut ListView<Files>> {
|
||||||
let widget = match self.columns.widgets.get(0)? {
|
let widget = self.columns.active_widget_mut()?;
|
||||||
FileBrowserWidgets::FileList(filelist) => Ok(filelist),
|
|
||||||
_ => { return HError::wrong_widget("previewer", "filelist"); }
|
let widget = match widget {
|
||||||
|
FileBrowserWidgets::FileList(filelist) => filelist.widget_mut(),
|
||||||
|
_ => { HError::wrong_widget("previewer", "filelist")? }
|
||||||
};
|
};
|
||||||
widget
|
widget
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn left_widget_mut(&mut self) -> HResult<&mut WillBeWidget<ListView<Files>>> {
|
pub fn left_async_widget_mut(&mut self) -> HResult<&mut AsyncWidget<ListView<Files>>> {
|
||||||
let widget = match self.columns.widgets.get_mut(0)? {
|
let widget = match self.columns.widgets.get_mut(0)? {
|
||||||
FileBrowserWidgets::FileList(filelist) => Ok(filelist),
|
FileBrowserWidgets::FileList(filelist) => filelist,
|
||||||
|
_ => { return HError::wrong_widget("previewer", "filelist"); }
|
||||||
|
};
|
||||||
|
Ok(widget)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn left_widget(&self) -> HResult<&ListView<Files>> {
|
||||||
|
let widget = match self.columns.widgets.get(0)? {
|
||||||
|
FileBrowserWidgets::FileList(filelist) => filelist.widget(),
|
||||||
_ => { return HError::wrong_widget("previewer", "filelist"); }
|
_ => { return HError::wrong_widget("previewer", "filelist"); }
|
||||||
};
|
};
|
||||||
widget
|
widget
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn preview_widget(&self) -> HResult<&Previewer> {
|
pub fn left_widget_mut(&mut self) -> HResult<&mut ListView<Files>> {
|
||||||
match self.columns.widgets.get(2)? {
|
let widget = match self.columns.widgets.get_mut(0)? {
|
||||||
FileBrowserWidgets::Previewer(previewer) => Ok(previewer),
|
FileBrowserWidgets::FileList(filelist) => filelist.widget_mut(),
|
||||||
_ => { return HError::wrong_widget("filelist", "previewer"); }
|
_ => { return HError::wrong_widget("previewer", "filelist"); }
|
||||||
}
|
};
|
||||||
|
widget
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// pub fn preview_widget(&self) -> HResult<&Previewer> {
|
||||||
|
// match self.columns.widgets.get(2)? {
|
||||||
|
// FileBrowserWidgets::Previewer(previewer) => Ok(previewer),
|
||||||
|
// _ => { return HError::wrong_widget("filelist", "previewer"); }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
pub fn preview_widget_mut(&mut self) -> HResult<&mut Previewer> {
|
pub fn preview_widget_mut(&mut self) -> HResult<&mut Previewer> {
|
||||||
match self.columns.widgets.get_mut(2)? {
|
match self.columns.widgets.get_mut(2)? {
|
||||||
FileBrowserWidgets::Previewer(previewer) => Ok(previewer),
|
FileBrowserWidgets::Previewer(previewer) => Ok(previewer),
|
||||||
@ -660,14 +671,14 @@ impl FileBrowser {
|
|||||||
let mcore = self.main_widget()?.get_core()?.clone();
|
let mcore = self.main_widget()?.get_core()?.clone();
|
||||||
let lcore = self.left_widget()?.get_core()?.clone();;
|
let lcore = self.left_widget()?.get_core()?.clone();;
|
||||||
|
|
||||||
let middle = WillBeWidget::new(&self.core, Box::new(move |_| {
|
let middle = AsyncWidget::new(&self.core, Box::new(move |_| {
|
||||||
let files = Files::new_from_path(&dir.clone())?;
|
let files = Files::new_from_path(&dir.clone())?;
|
||||||
let listview = ListView::new(&mcore, files);
|
let listview = ListView::new(&mcore, files);
|
||||||
Ok(listview)
|
Ok(listview)
|
||||||
}));
|
}));
|
||||||
let middle = FileBrowserWidgets::FileList(middle);
|
let middle = FileBrowserWidgets::FileList(middle);
|
||||||
|
|
||||||
let left = WillBeWidget::new(&self.core, Box::new(move |_| {
|
let left = AsyncWidget::new(&self.core, Box::new(move |_| {
|
||||||
let files = Files::new_from_path(&left_dir.parent()?)?;
|
let files = Files::new_from_path(&left_dir.parent()?)?;
|
||||||
let listview = ListView::new(&lcore, files);
|
let listview = ListView::new(&lcore, files);
|
||||||
Ok(listview)
|
Ok(listview)
|
||||||
@ -751,9 +762,9 @@ impl FileBrowser {
|
|||||||
"--> ".to_string() + &target.short_string()
|
"--> ".to_string() + &target.short_string()
|
||||||
} else { "".to_string() };
|
} else { "".to_string() };
|
||||||
|
|
||||||
let main_widget = self.main_widget()?.widget()?;
|
let main_widget = self.main_widget()?;
|
||||||
let selection = main_widget.lock()?.as_ref().unwrap().get_selection();
|
let selection = main_widget.get_selection();
|
||||||
let file_count = main_widget.lock()?.as_ref().unwrap().content.len();
|
let file_count = main_widget.content.len();
|
||||||
let file_count = format!("{}", file_count);
|
let file_count = format!("{}", file_count);
|
||||||
let digits = file_count.len();
|
let digits = file_count.len();
|
||||||
let file_count = format!("{:digits$}/{:digits$}",
|
let file_count = format!("{:digits$}/{:digits$}",
|
||||||
|
@ -58,6 +58,7 @@ use term::ScreenExt;
|
|||||||
use fail::{HResult, HError};
|
use fail::{HResult, HError};
|
||||||
use file_browser::FileBrowser;
|
use file_browser::FileBrowser;
|
||||||
use tabview::TabView;
|
use tabview::TabView;
|
||||||
|
use preview::Async;
|
||||||
|
|
||||||
|
|
||||||
fn main() -> HResult<()> {
|
fn main() -> HResult<()> {
|
||||||
|
236
src/preview.rs
236
src/preview.rs
@ -1,7 +1,5 @@
|
|||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
use failure::Backtrace;
|
|
||||||
|
|
||||||
use crate::files::{File, Files, Kind};
|
use crate::files::{File, Files, Kind};
|
||||||
use crate::listview::ListView;
|
use crate::listview::ListView;
|
||||||
use crate::textview::TextView;
|
use crate::textview::TextView;
|
||||||
@ -10,9 +8,14 @@ use crate::coordinates::Coordinates;
|
|||||||
use crate::fail::{HResult, HError, ErrorLog};
|
use crate::fail::{HResult, HError, ErrorLog};
|
||||||
|
|
||||||
|
|
||||||
|
pub type Stale = Arc<Mutex<bool>>;
|
||||||
|
|
||||||
|
pub type AsyncValueFn<T> = Box<Fn(Stale) -> HResult<T> + Send>;
|
||||||
|
pub type AsyncValue<T> = Arc<Mutex<Option<HResult<T>>>>;
|
||||||
|
pub type AsyncReadyFn<T> = Box<Fn(&mut T) -> HResult<()> + Send>;
|
||||||
|
pub type AsyncWidgetFn<W> = Box<Fn(Stale, WidgetCore) -> HResult<W> + Send>;
|
||||||
|
|
||||||
|
|
||||||
type HClosure<T> = Box<Fn(Arc<Mutex<bool>>) -> Result<T, HError> + Send>;
|
|
||||||
type HCClosure<T> = Box<Fn(Arc<Mutex<bool>>, WidgetCore) -> Result<T, HError> + Send>;
|
|
||||||
type WidgetO = Box<dyn Widget + Send>;
|
type WidgetO = Box<dyn Widget + Send>;
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
@ -33,49 +36,49 @@ pub fn is_stale(stale: &Arc<Mutex<bool>>) -> HResult<bool> {
|
|||||||
Ok(stale)
|
Ok(stale)
|
||||||
}
|
}
|
||||||
|
|
||||||
enum State {
|
|
||||||
Is,
|
pub struct Async<T: Send> {
|
||||||
Becoming,
|
pub value: HResult<T>,
|
||||||
Fail(HError)
|
async_value: AsyncValue<T>,
|
||||||
|
async_closure: Option<AsyncValueFn<T>>,
|
||||||
|
on_ready: Arc<Mutex<Option<AsyncReadyFn<T>>>>,
|
||||||
|
stale: Stale
|
||||||
}
|
}
|
||||||
|
|
||||||
struct WillBe<T: Send> {
|
impl<T: Send + 'static> Async<T> {
|
||||||
pub state: Arc<Mutex<State>>,
|
pub fn new(closure: AsyncValueFn<T>)
|
||||||
pub thing: Arc<Mutex<Option<T>>>,
|
-> Async<T> {
|
||||||
on_ready: Arc<Mutex<Option<Box<Fn(Arc<Mutex<Option<T>>>) -> HResult<()> + Send>>>>,
|
let async_value = Async {
|
||||||
stale: Arc<Mutex<bool>>
|
value: HError::async_not_ready(),
|
||||||
}
|
async_value: Arc::new(Mutex::new(None)),
|
||||||
|
async_closure: Some(closure),
|
||||||
impl<T: Send + 'static> WillBe<T> where {
|
|
||||||
pub fn new_become(closure: HClosure<T>)
|
|
||||||
-> WillBe<T> {
|
|
||||||
let mut willbe = WillBe { state: Arc::new(Mutex::new(State::Becoming)),
|
|
||||||
thing: Arc::new(Mutex::new(None)),
|
|
||||||
on_ready: Arc::new(Mutex::new(None)),
|
on_ready: Arc::new(Mutex::new(None)),
|
||||||
stale: Arc::new(Mutex::new(false)) };
|
stale: Arc::new(Mutex::new(false)) };
|
||||||
willbe.run(closure);
|
|
||||||
willbe
|
async_value
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run(&mut self, closure: HClosure<T>) {
|
fn run(&mut self) -> HResult<()> {
|
||||||
let state = self.state.clone();
|
let closure = self.async_closure.take()?;
|
||||||
|
let async_value = self.async_value.clone();
|
||||||
let stale = self.stale.clone();
|
let stale = self.stale.clone();
|
||||||
let thing = self.thing.clone();
|
|
||||||
let on_ready_fn = self.on_ready.clone();
|
let on_ready_fn = self.on_ready.clone();
|
||||||
std::thread::spawn(move|| {
|
|
||||||
let got_thing = closure(stale);
|
std::thread::spawn(move|| -> HResult<()> {
|
||||||
match got_thing {
|
let value = closure(stale);
|
||||||
Ok(got_thing) => {
|
match value {
|
||||||
*thing.lock().unwrap() = Some(got_thing);
|
Ok(mut value) => {
|
||||||
*state.lock().unwrap() = State::Is;
|
match *on_ready_fn.lock()? {
|
||||||
match *on_ready_fn.lock().unwrap() {
|
Some(ref on_ready) => { on_ready(&mut value).log(); },
|
||||||
Some(ref on_ready) => { on_ready(thing.clone()).ok(); },
|
|
||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
|
async_value.lock()?.replace(Ok(value));
|
||||||
},
|
},
|
||||||
Err(err) => *state.lock().unwrap() = State::Fail(err)
|
Err(err) => *async_value.lock()? = Some(Err(err))
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
});
|
});
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_stale(&mut self) -> HResult<()> {
|
pub fn set_stale(&mut self) -> HResult<()> {
|
||||||
@ -87,23 +90,46 @@ impl<T: Send + 'static> WillBe<T> where {
|
|||||||
is_stale(&self.stale)
|
is_stale(&self.stale)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn take(&mut self) -> HResult<T> {
|
pub fn take_async(&mut self) -> HResult<()> {
|
||||||
self.check()?;
|
if self.value.is_ok() { return Ok(()) }
|
||||||
Ok(self.thing.lock()?.take()?)
|
|
||||||
|
let mut async_value = self.async_value.lock()?;
|
||||||
|
match async_value.as_ref() {
|
||||||
|
Some(Ok(_)) => {
|
||||||
|
let value = async_value.take()?;
|
||||||
|
self.value = value;
|
||||||
|
}
|
||||||
|
Some(Err(HError::AsyncAlreadyTakenError(..))) => HError::async_taken()?,
|
||||||
|
Some(Err(_)) => {
|
||||||
|
let value = async_value.take()?;
|
||||||
|
self.value = value;
|
||||||
|
}
|
||||||
|
None => HError::async_not_ready()?,
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn check(&self) -> HResult<()> {
|
pub fn get(&self) -> HResult<&T> {
|
||||||
match *self.state.lock()? {
|
match self.value {
|
||||||
State::Is => Ok(()),
|
Ok(ref value) => Ok(value),
|
||||||
_ => Err(HError::WillBeNotReady(Backtrace::new()))
|
Err(ref err) => HError::async_error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_mut(&mut self) -> HResult<&mut T> {
|
||||||
|
self.take_async().ok();
|
||||||
|
|
||||||
|
match self.value {
|
||||||
|
Ok(ref mut value) => Ok(value),
|
||||||
|
Err(ref err) => HError::async_error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn on_ready(&mut self,
|
pub fn on_ready(&mut self,
|
||||||
fun: Box<Fn(Arc<Mutex<Option<T>>>) -> HResult<()> + Send>)
|
fun: AsyncReadyFn<T>)
|
||||||
-> HResult<()> {
|
-> HResult<()> {
|
||||||
if self.check().is_ok() {
|
if self.value.is_ok() {
|
||||||
fun(self.thing.clone())?;
|
fun(self.value.as_mut().unwrap())?;
|
||||||
} else {
|
} else {
|
||||||
*self.on_ready.lock()? = Some(fun);
|
*self.on_ready.lock()? = Some(fun);
|
||||||
}
|
}
|
||||||
@ -111,8 +137,8 @@ impl<T: Send + 'static> WillBe<T> where {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<W: Widget + Send + 'static> PartialEq for WillBeWidget<W> {
|
impl<W: Widget + Send + 'static> PartialEq for AsyncWidget<W> {
|
||||||
fn eq(&self, other: &WillBeWidget<W>) -> bool {
|
fn eq(&self, other: &AsyncWidget<W>) -> bool {
|
||||||
if self.get_coordinates().unwrap() ==
|
if self.get_coordinates().unwrap() ==
|
||||||
other.get_coordinates().unwrap() {
|
other.get_coordinates().unwrap() {
|
||||||
true
|
true
|
||||||
@ -122,65 +148,66 @@ impl<W: Widget + Send + 'static> PartialEq for WillBeWidget<W> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct WillBeWidget<T: Widget + Send + 'static> {
|
|
||||||
willbe: WillBe<T>,
|
pub struct AsyncWidget<W: Widget + Send + 'static> {
|
||||||
|
widget: Async<W>,
|
||||||
core: WidgetCore
|
core: WidgetCore
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Widget + Send + 'static> WillBeWidget<T> {
|
impl<W: Widget + Send + 'static> AsyncWidget<W> {
|
||||||
pub fn new(core: &WidgetCore, closure: HClosure<T>) -> WillBeWidget<T> {
|
pub fn new(core: &WidgetCore, closure: AsyncValueFn<W>) -> AsyncWidget<W> {
|
||||||
let sender = core.get_sender();
|
let sender = core.get_sender();
|
||||||
let mut willbe = WillBe::new_become(Box::new(move |stale| closure(stale)));
|
let mut widget = Async::new(Box::new(move |stale| closure(stale)));
|
||||||
willbe.on_ready(Box::new(move |_| {
|
widget.on_ready(Box::new(move |_| {
|
||||||
sender.send(crate::widget::Events::WidgetReady)?;
|
sender.send(crate::widget::Events::WidgetReady)?;
|
||||||
Ok(()) })).ok();
|
Ok(())
|
||||||
|
})).log();
|
||||||
|
widget.run().log();
|
||||||
|
|
||||||
WillBeWidget {
|
AsyncWidget {
|
||||||
willbe: willbe,
|
widget: widget,
|
||||||
core: core.clone()
|
core: core.clone()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn change_to(&mut self, closure: HCClosure<T>) -> HResult<()> {
|
pub fn change_to(&mut self, closure: AsyncWidgetFn<W>) -> HResult<()> {
|
||||||
self.set_stale().log();
|
self.set_stale().log();
|
||||||
|
|
||||||
let sender = self.get_core()?.get_sender();
|
let sender = self.get_core()?.get_sender();
|
||||||
let core = self.get_core()?.clone();
|
let core = self.get_core()?.clone();
|
||||||
|
|
||||||
let mut willbe = WillBe::new_become(Box::new(move |stale| {
|
let mut widget = Async::new(Box::new(move |stale| {
|
||||||
let core = core.clone();
|
closure(stale, core.clone())
|
||||||
closure(stale, core)
|
|
||||||
}));
|
}));
|
||||||
willbe.on_ready(Box::new(move |_| {
|
|
||||||
|
widget.on_ready(Box::new(move |_| {
|
||||||
sender.send(crate::widget::Events::WidgetReady)?;
|
sender.send(crate::widget::Events::WidgetReady)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}))?;
|
}))?;
|
||||||
|
|
||||||
self.willbe = willbe;
|
widget.run().log();
|
||||||
|
|
||||||
|
self.widget = widget;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_stale(&mut self) -> HResult<()> {
|
pub fn set_stale(&mut self) -> HResult<()> {
|
||||||
self.willbe.set_stale()
|
self.widget.set_stale()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_stale(&self) -> HResult<bool> {
|
pub fn is_stale(&self) -> HResult<bool> {
|
||||||
self.willbe.is_stale()
|
self.widget.is_stale()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn widget(&self) -> HResult<Arc<Mutex<Option<T>>>> {
|
pub fn widget(&self) -> HResult<&W> {
|
||||||
self.willbe.check()?;
|
self.widget.get()
|
||||||
Ok(self.willbe.thing.clone())
|
}
|
||||||
|
|
||||||
|
pub fn widget_mut(&mut self) -> HResult<&mut W> {
|
||||||
|
self.widget.get_mut()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ready(&self) -> bool {
|
pub fn ready(&self) -> bool {
|
||||||
match self.willbe.check() {
|
self.widget().is_ok()
|
||||||
Ok(_) => true,
|
|
||||||
_ => false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn take(&mut self) -> HResult<T> {
|
|
||||||
self.willbe.take()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,7 +222,7 @@ impl<T: Widget + Send + 'static> WillBeWidget<T> {
|
|||||||
// }
|
// }
|
||||||
//}
|
//}
|
||||||
|
|
||||||
impl<T: Widget + Send + 'static> Widget for WillBeWidget<T> {
|
impl<T: Widget + Send + 'static> Widget for AsyncWidget<T> {
|
||||||
fn get_core(&self) -> HResult<&WidgetCore> {
|
fn get_core(&self) -> HResult<&WidgetCore> {
|
||||||
Ok(&self.core)
|
Ok(&self.core)
|
||||||
}
|
}
|
||||||
@ -205,22 +232,19 @@ impl<T: Widget + Send + 'static> Widget for WillBeWidget<T> {
|
|||||||
|
|
||||||
fn set_coordinates(&mut self, coordinates: &Coordinates) -> HResult<()> {
|
fn set_coordinates(&mut self, coordinates: &Coordinates) -> HResult<()> {
|
||||||
self.core.coordinates = coordinates.clone();
|
self.core.coordinates = coordinates.clone();
|
||||||
if let Ok(widget) = self.widget() {
|
if let Ok(widget) = self.widget_mut() {
|
||||||
let mut widget = widget.lock()?;
|
|
||||||
let widget = widget.as_mut()?;
|
|
||||||
widget.set_coordinates(&coordinates)?;
|
widget.set_coordinates(&coordinates)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn refresh(&mut self) -> HResult<()> {
|
fn refresh(&mut self) -> HResult<()> {
|
||||||
let coords = self.get_coordinates()?;
|
self.widget.take_async().log();
|
||||||
if let Ok(widget) = self.widget() {
|
|
||||||
let mut widget = widget.lock()?;
|
|
||||||
let widget = widget.as_mut()?;
|
|
||||||
|
|
||||||
if widget.get_coordinates()? != coords {
|
let coords = self.get_coordinates()?.clone();
|
||||||
widget.set_coordinates(self.get_coordinates()?)?;
|
if let Ok(widget) = self.widget_mut() {
|
||||||
|
if widget.get_coordinates()? != &coords {
|
||||||
|
widget.set_coordinates(&coords)?;
|
||||||
widget.refresh()?;
|
widget.refresh()?;
|
||||||
} else {
|
} else {
|
||||||
widget.refresh()?;
|
widget.refresh()?;
|
||||||
@ -229,7 +253,7 @@ impl<T: Widget + Send + 'static> Widget for WillBeWidget<T> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
fn get_drawlist(&self) -> HResult<String> {
|
fn get_drawlist(&self) -> HResult<String> {
|
||||||
if self.willbe.check().is_err() {
|
if self.widget().is_err() {
|
||||||
let clear = self.get_clearlist()?;
|
let clear = self.get_clearlist()?;
|
||||||
let (xpos, ypos) = self.get_coordinates()?.u16position();
|
let (xpos, ypos) = self.get_coordinates()?.u16position();
|
||||||
let pos = crate::term::goto_xy(xpos, ypos);
|
let pos = crate::term::goto_xy(xpos, ypos);
|
||||||
@ -240,17 +264,11 @@ impl<T: Widget + Send + 'static> Widget for WillBeWidget<T> {
|
|||||||
return self.get_clearlist()
|
return self.get_clearlist()
|
||||||
}
|
}
|
||||||
|
|
||||||
let widget = self.widget()?;
|
self.widget()?.get_drawlist()
|
||||||
let widget = widget.lock()?;
|
|
||||||
let widget = widget.as_ref()?;
|
|
||||||
widget.get_drawlist()
|
|
||||||
}
|
}
|
||||||
fn on_key(&mut self, key: termion::event::Key) -> HResult<()> {
|
fn on_key(&mut self, key: termion::event::Key) -> HResult<()> {
|
||||||
if self.willbe.check().is_err() { return Ok(()) }
|
if self.widget().is_err() { return Ok(()) }
|
||||||
let widget = self.widget()?;
|
self.widget_mut()?.on_key(key)
|
||||||
let mut widget = widget.lock()?;
|
|
||||||
let widget = widget.as_mut()?;
|
|
||||||
widget.on_key(key)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -267,7 +285,7 @@ impl PartialEq for Previewer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct Previewer {
|
pub struct Previewer {
|
||||||
widget: WillBeWidget<Box<dyn Widget + Send>>,
|
widget: AsyncWidget<Box<dyn Widget + Send>>,
|
||||||
core: WidgetCore,
|
core: WidgetCore,
|
||||||
file: Option<File>,
|
file: Option<File>,
|
||||||
selection: Option<File>,
|
selection: Option<File>,
|
||||||
@ -278,11 +296,10 @@ pub struct Previewer {
|
|||||||
impl Previewer {
|
impl Previewer {
|
||||||
pub fn new(core: &WidgetCore) -> Previewer {
|
pub fn new(core: &WidgetCore) -> Previewer {
|
||||||
let core_ = core.clone();
|
let core_ = core.clone();
|
||||||
let willbe = WillBeWidget::new(&core, Box::new(move |_| {
|
let widget = AsyncWidget::new(&core, Box::new(move |_| {
|
||||||
Ok(Box::new(crate::textview::TextView::new_blank(&core_))
|
Ok(Box::new(TextView::new_blank(&core_)) as Box<dyn Widget + Send>)
|
||||||
as Box<dyn Widget + Send>)
|
|
||||||
}));
|
}));
|
||||||
Previewer { widget: willbe,
|
Previewer { widget: widget,
|
||||||
core: core.clone(),
|
core: core.clone(),
|
||||||
file: None,
|
file: None,
|
||||||
selection: None,
|
selection: None,
|
||||||
@ -290,10 +307,11 @@ impl Previewer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn become_preview(&mut self,
|
fn become_preview(&mut self,
|
||||||
widget: HResult<WillBeWidget<WidgetO>>) {
|
widget: HResult<AsyncWidget<WidgetO>>) -> HResult<()> {
|
||||||
let coordinates = self.get_coordinates().unwrap().clone();
|
let coordinates = self.get_coordinates()?.clone();
|
||||||
self.widget = widget.unwrap();
|
self.widget = widget?;
|
||||||
self.widget.set_coordinates(&coordinates).ok();
|
self.widget.set_coordinates(&coordinates)?;
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_stale(&mut self) -> HResult<()> {
|
pub fn set_stale(&mut self) -> HResult<()> {
|
||||||
@ -315,7 +333,8 @@ impl Previewer {
|
|||||||
|
|
||||||
self.widget.set_stale().ok();
|
self.widget.set_stale().ok();
|
||||||
|
|
||||||
self.become_preview(Ok(WillBeWidget::new(&self.core, Box::new(move |stale| {
|
self.become_preview(Ok(AsyncWidget::new(&self.core,
|
||||||
|
Box::new(move |stale| {
|
||||||
kill_proc().unwrap();
|
kill_proc().unwrap();
|
||||||
|
|
||||||
let file = file.clone();
|
let file = file.clone();
|
||||||
@ -344,15 +363,14 @@ impl Previewer {
|
|||||||
blank.animate_slide_up().log();
|
blank.animate_slide_up().log();
|
||||||
return Ok(blank)
|
return Ok(blank)
|
||||||
}
|
}
|
||||||
}))));
|
}))))
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reload(&mut self) {
|
pub fn reload(&mut self) {
|
||||||
if let Some(file) = self.file.clone() {
|
if let Some(file) = self.file.clone() {
|
||||||
self.file = None;
|
self.file = None;
|
||||||
let cache = self.cached_files.take();
|
let cache = self.cached_files.take();
|
||||||
self.set_file(&file, self.selection.clone(), cache);
|
self.set_file(&file, self.selection.clone(), cache).log();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -403,7 +421,9 @@ impl Previewer {
|
|||||||
Ok(Box::new(textview))
|
Ok(Box::new(textview))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn preview_external(file: &File, core: &WidgetCore, stale: Arc<Mutex<bool>>)
|
fn preview_external(file: &File,
|
||||||
|
core: &WidgetCore,
|
||||||
|
stale: Arc<Mutex<bool>>)
|
||||||
-> Result<Box<dyn Widget + Send>, HError> {
|
-> Result<Box<dyn Widget + Send>, HError> {
|
||||||
let process =
|
let process =
|
||||||
std::process::Command::new("scope.sh")
|
std::process::Command::new("scope.sh")
|
||||||
|
@ -15,7 +15,6 @@ use crate::widget::{Widget, Events, WidgetCore};
|
|||||||
use crate::coordinates::Coordinates;
|
use crate::coordinates::Coordinates;
|
||||||
use crate::dirty::Dirtyable;
|
use crate::dirty::Dirtyable;
|
||||||
use crate::hbox::HBox;
|
use crate::hbox::HBox;
|
||||||
use crate::preview::WillBeWidget;
|
|
||||||
use crate::fail::{HResult, HError, ErrorLog};
|
use crate::fail::{HResult, HError, ErrorLog};
|
||||||
use crate::term;
|
use crate::term;
|
||||||
use crate::files::{File, OsStrTools};
|
use crate::files::{File, OsStrTools};
|
||||||
@ -299,7 +298,7 @@ impl ListView<Vec<Process>> {
|
|||||||
#[derive(PartialEq)]
|
#[derive(PartialEq)]
|
||||||
enum ProcViewWidgets {
|
enum ProcViewWidgets {
|
||||||
List(ListView<Vec<Process>>),
|
List(ListView<Vec<Process>>),
|
||||||
TextView(WillBeWidget<TextView>),
|
TextView(TextView),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Widget for ProcViewWidgets {
|
impl Widget for ProcViewWidgets {
|
||||||
@ -348,7 +347,7 @@ impl HBox<ProcViewWidgets> {
|
|||||||
_ => unreachable!()
|
_ => unreachable!()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn get_textview(&mut self) -> &mut WillBeWidget<TextView> {
|
fn get_textview(&mut self) -> &mut TextView {
|
||||||
match &mut self.widgets[1] {
|
match &mut self.widgets[1] {
|
||||||
ProcViewWidgets::TextView(textview) => textview,
|
ProcViewWidgets::TextView(textview) => textview,
|
||||||
_ => unreachable!()
|
_ => unreachable!()
|
||||||
@ -360,8 +359,7 @@ impl ProcView {
|
|||||||
pub fn new(core: &WidgetCore) -> ProcView {
|
pub fn new(core: &WidgetCore) -> ProcView {
|
||||||
let tcore = core.clone();
|
let tcore = core.clone();
|
||||||
let listview = ListView::new(&core, vec![]);
|
let listview = ListView::new(&core, vec![]);
|
||||||
let textview = Box::new(move |_| Ok(TextView::new_blank(&tcore)));
|
let textview = TextView::new_blank(&tcore);
|
||||||
let textview = WillBeWidget::new(&core, textview);
|
|
||||||
let mut hbox = HBox::new(&core);
|
let mut hbox = HBox::new(&core);
|
||||||
hbox.push_widget(ProcViewWidgets::List(listview));
|
hbox.push_widget(ProcViewWidgets::List(listview));
|
||||||
hbox.push_widget(ProcViewWidgets::TextView(textview));
|
hbox.push_widget(ProcViewWidgets::TextView(textview));
|
||||||
@ -382,7 +380,7 @@ impl ProcView {
|
|||||||
self.hbox.get_listview_mut()
|
self.hbox.get_listview_mut()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_textview(&mut self) -> &mut WillBeWidget<TextView> {
|
fn get_textview(&mut self) -> &mut TextView {
|
||||||
self.hbox.get_textview()
|
self.hbox.get_textview()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -399,13 +397,8 @@ impl ProcView {
|
|||||||
pub fn remove_proc(&mut self) -> HResult<()> {
|
pub fn remove_proc(&mut self) -> HResult<()> {
|
||||||
if self.get_listview_mut().content.len() == 0 { return Ok(()) }
|
if self.get_listview_mut().content.len() == 0 { return Ok(()) }
|
||||||
self.get_listview_mut().remove_proc()?;
|
self.get_listview_mut().remove_proc()?;
|
||||||
self.get_textview().change_to(Box::new(move |_, core| {
|
self.get_textview().clear();
|
||||||
let mut textview = TextView::new_blank(&core);
|
self.get_textview().set_text("")
|
||||||
textview.refresh().log();
|
|
||||||
textview.animate_slide_up().log();
|
|
||||||
Ok(textview)
|
|
||||||
})).log();
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn show_output(&mut self) -> HResult<()> {
|
fn show_output(&mut self) -> HResult<()> {
|
||||||
@ -414,48 +407,45 @@ impl ProcView {
|
|||||||
}
|
}
|
||||||
let output = self.get_listview_mut().selected_proc()?.output.lock()?.clone();
|
let output = self.get_listview_mut().selected_proc()?.output.lock()?.clone();
|
||||||
|
|
||||||
self.get_textview().change_to(Box::new(move |_, core| {
|
self.get_textview().set_text(&output).log();
|
||||||
let mut textview = TextView::new_blank(&core);
|
self.get_textview().animate_slide_up().log();
|
||||||
textview.set_text(&output).log();
|
|
||||||
textview.animate_slide_up().log();
|
|
||||||
Ok(textview)
|
|
||||||
})).log();
|
|
||||||
self.viewing = Some(self.get_listview_mut().get_selection());
|
self.viewing = Some(self.get_listview_mut().get_selection());
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn toggle_follow(&mut self) -> HResult<()> {
|
pub fn toggle_follow(&mut self) -> HResult<()> {
|
||||||
self.get_textview().widget()?.lock()?.as_mut()?.toggle_follow();
|
self.get_textview().toggle_follow();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn scroll_up(&mut self) -> HResult<()> {
|
pub fn scroll_up(&mut self) -> HResult<()> {
|
||||||
self.get_textview().widget()?.lock()?.as_mut()?.scroll_up();
|
self.get_textview().scroll_up();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn scroll_down(&mut self) -> HResult<()> {
|
pub fn scroll_down(&mut self) -> HResult<()> {
|
||||||
self.get_textview().widget()?.lock()?.as_mut()?.scroll_down();
|
self.get_textview().scroll_down();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn page_up(&mut self) -> HResult<()> {
|
pub fn page_up(&mut self) -> HResult<()> {
|
||||||
self.get_textview().widget()?.lock()?.as_mut()?.page_up();
|
self.get_textview().page_up();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn page_down(&mut self) -> HResult<()> {
|
pub fn page_down(&mut self) -> HResult<()> {
|
||||||
self.get_textview().widget()?.lock()?.as_mut()?.page_down();
|
self.get_textview().page_down();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn scroll_top(&mut self) -> HResult<()> {
|
pub fn scroll_top(&mut self) -> HResult<()> {
|
||||||
self.get_textview().widget()?.lock()?.as_mut()?.scroll_top();
|
self.get_textview().scroll_top();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn scroll_bottom(&mut self) -> HResult<()> {
|
pub fn scroll_bottom(&mut self) -> HResult<()> {
|
||||||
self.get_textview().widget()?.lock()?.as_mut()?.scroll_bottom();
|
self.get_textview().scroll_bottom();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user