async stuff much improved

This commit is contained in:
rabite 2019-03-22 22:49:34 +01:00
parent bb917a0dad
commit fd366a26dc
5 changed files with 242 additions and 202 deletions

View File

@ -37,6 +37,12 @@ pub enum HError {
NoneError(Backtrace),
#[fail(display = "Not ready yet!")]
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")]
NoWidgetError(Backtrace),
#[fail(display = "Path: {:?} not in this directory: {:?}", path, dir)]
@ -72,7 +78,7 @@ pub enum HError {
#[fail(display = "Terminal has been resized!")]
TerminalResizedError,
#[fail(display = "{}", _0)]
Log(String)
Log(String),
}
impl HError {
@ -126,6 +132,18 @@ impl HError {
pub fn stale<T>() -> HResult<T> {
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)))
}
}

View File

@ -7,15 +7,14 @@ use std::sync::mpsc::{channel, Receiver, Sender};
use std::time::Duration;
use std::path::PathBuf;
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::hbox::HBox;
use crate::widget::Widget;
use crate::dirty::Dirtyable;
use crate::tabview::{TabView, Tabbable};
use crate::preview::{Previewer, WillBeWidget};
use crate::preview::{Previewer, AsyncWidget};
use crate::fail::{HResult, HError, ErrorLog};
use crate::widget::{Events, WidgetCore};
use crate::proclist::ProcView;
@ -27,7 +26,7 @@ use crate::coordinates::Coordinates;
#[derive(PartialEq)]
pub enum FileBrowserWidgets {
FileList(WillBeWidget<ListView<Files>>),
FileList(AsyncWidget<ListView<Files>>),
Previewer(Previewer),
}
@ -191,7 +190,7 @@ impl FileBrowser {
}).last()?;
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,
Files::new_from_path(&main_path)?);
list.animate_slide_up().log();
@ -199,7 +198,7 @@ impl FileBrowser {
}));
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,
Files::new_from_path(&left_path)?);
list.animate_slide_up().log();
@ -314,8 +313,8 @@ impl FileBrowser {
self.prev_cwd = Some(self.cwd.clone());
self.cwd = dir.clone();
let main_widget = self.main_widget_mut()?;
main_widget.change_to(Box::new(move |stale, core| {
let main_async_widget = self.main_async_widget_mut()?;
main_async_widget.change_to(Box::new(move |stale, core| {
let path = dir.path();
let cached_files = cached_files.clone();
@ -334,7 +333,7 @@ impl FileBrowser {
if let Ok(grand_parent) = self.cwd()?.parent_as_file() {
self.left_widget_goto(&grand_parent).log();
} else {
self.left_widget_mut()?.set_stale().log();
self.left_async_widget_mut()?.set_stale().log();
}
Ok(())
@ -345,8 +344,8 @@ impl FileBrowser {
let cached_files = self.get_cached_files(&dir).ok();
let dir = dir.clone();
let left_widget = self.left_widget_mut()?;
left_widget.change_to(Box::new(move |stale, core| {
let left_async_widget = self.left_async_widget_mut()?;
left_async_widget.change_to(Box::new(move |stale, core| {
let path = dir.path();
let cached_files = cached_files.clone();
@ -415,34 +414,29 @@ impl FileBrowser {
}
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()?
.widget()?
.lock()?
.as_ref()
.unwrap()
.content
.len() == 0 {
self.preview_widget_mut()?.set_stale();
self.preview_widget_mut()?.set_stale().log();
return Ok(());
}
let file = self.selected_file()?.clone();
let selection = self.get_selection(&file).ok().cloned();
let cached_files = self.get_cached_files(&file).ok();
let preview = self.preview_widget_mut()?;
preview.set_file(&file, selection, cached_files);
preview.set_file(&file, selection, cached_files).log();
Ok(())
}
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(()) }
let parent = self.cwd()?.parent_as_file();
if let Ok(left_selection) = self.get_selection(&parent?) {
self.left_widget()?.widget()?.lock()?.as_mut()?.select_file(&left_selection);
}
let left_selection = self.get_selection(&parent?)?.clone();
self.left_widget_mut()?.select_file(&left_selection);
Ok(())
}
@ -452,11 +446,11 @@ impl FileBrowser {
}
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> {
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<()> {
@ -491,13 +485,14 @@ impl FileBrowser {
}
pub fn left_dir(&self) -> HResult<File> {
let widget = self.left_widget()?.widget()?;
let dir = widget.lock()?.as_ref()?.content.directory.clone();
let widget = self.left_widget()?;
let dir = widget.content.directory.clone();
Ok(dir)
}
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(())
}
let watched_dirs = self.watches.clone();
@ -539,13 +534,11 @@ impl FileBrowser {
fn handle_dir_events(&mut self) -> HResult<()> {
let dir_events = self.dir_events.clone();
for event in dir_events.lock()?.iter() {
let main_widget = self.main_widget()?.widget()?;
let mut main_widget = main_widget.lock()?;
let main_result = main_widget.as_mut()?.content.handle_event(event);
let main_widget = self.main_widget_mut()?;
let main_result = main_widget.content.handle_event(event);
let left_widget = self.left_widget()?.widget()?;
let mut left_files = left_widget.lock()?;
let left_result = left_files.as_mut()?.content.handle_event(event);
let left_widget = self.left_widget_mut()?;
let left_result = left_widget.content.handle_event(event);
match main_result {
Err(HError::WrongDirectoryError { .. }) => {
@ -563,62 +556,80 @@ impl FileBrowser {
}
pub fn selected_file(&self) -> HResult<File> {
let widget = self.main_widget()?.widget()?;
let file = widget.lock()?.as_ref()?.selected_file().clone();
let widget = self.main_widget()?;
let file = widget.selected_file().clone();
Ok(file)
}
pub fn selected_files(&self) -> HResult<Vec<File>> {
let widget = self.main_widget()?.widget()?;
let files = widget.lock()?.as_ref()?.content.get_selected().into_iter().map(|f| {
let widget = self.main_widget()?;
let files = widget.content.get_selected().into_iter().map(|f| {
f.clone()
}).collect();
Ok(files)
}
pub fn main_widget(&self) -> HResult<&WillBeWidget<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>>> {
pub fn main_async_widget_mut(&mut self) -> HResult<&mut AsyncWidget<ListView<Files>>> {
let widget = self.columns.active_widget_mut()?;
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")? }
};
widget
}
pub fn left_widget(&self) -> HResult<&WillBeWidget<ListView<Files>>> {
let widget = match self.columns.widgets.get(0)? {
FileBrowserWidgets::FileList(filelist) => Ok(filelist),
_ => { return HError::wrong_widget("previewer", "filelist"); }
pub fn main_widget_mut(&mut self) -> HResult<&mut ListView<Files>> {
let widget = self.columns.active_widget_mut()?;
let widget = match widget {
FileBrowserWidgets::FileList(filelist) => filelist.widget_mut(),
_ => { HError::wrong_widget("previewer", "filelist")? }
};
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)? {
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"); }
};
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 left_widget_mut(&mut self) -> HResult<&mut ListView<Files>> {
let widget = match self.columns.widgets.get_mut(0)? {
FileBrowserWidgets::FileList(filelist) => filelist.widget_mut(),
_ => { 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> {
match self.columns.widgets.get_mut(2)? {
FileBrowserWidgets::Previewer(previewer) => Ok(previewer),
@ -660,14 +671,14 @@ impl FileBrowser {
let mcore = self.main_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 listview = ListView::new(&mcore, files);
Ok(listview)
}));
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 listview = ListView::new(&lcore, files);
Ok(listview)
@ -751,9 +762,9 @@ impl FileBrowser {
"--> ".to_string() + &target.short_string()
} else { "".to_string() };
let main_widget = self.main_widget()?.widget()?;
let selection = main_widget.lock()?.as_ref().unwrap().get_selection();
let file_count = main_widget.lock()?.as_ref().unwrap().content.len();
let main_widget = self.main_widget()?;
let selection = main_widget.get_selection();
let file_count = main_widget.content.len();
let file_count = format!("{}", file_count);
let digits = file_count.len();
let file_count = format!("{:digits$}/{:digits$}",

View File

@ -58,6 +58,7 @@ use term::ScreenExt;
use fail::{HResult, HError};
use file_browser::FileBrowser;
use tabview::TabView;
use preview::Async;
fn main() -> HResult<()> {

View File

@ -1,7 +1,5 @@
use std::sync::{Arc, Mutex};
use failure::Backtrace;
use crate::files::{File, Files, Kind};
use crate::listview::ListView;
use crate::textview::TextView;
@ -10,9 +8,14 @@ use crate::coordinates::Coordinates;
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>;
lazy_static! {
@ -33,49 +36,49 @@ pub fn is_stale(stale: &Arc<Mutex<bool>>) -> HResult<bool> {
Ok(stale)
}
enum State {
Is,
Becoming,
Fail(HError)
pub struct Async<T: Send> {
pub value: HResult<T>,
async_value: AsyncValue<T>,
async_closure: Option<AsyncValueFn<T>>,
on_ready: Arc<Mutex<Option<AsyncReadyFn<T>>>>,
stale: Stale
}
struct WillBe<T: Send> {
pub state: Arc<Mutex<State>>,
pub thing: Arc<Mutex<Option<T>>>,
on_ready: Arc<Mutex<Option<Box<Fn(Arc<Mutex<Option<T>>>) -> HResult<()> + Send>>>>,
stale: Arc<Mutex<bool>>
}
impl<T: Send + 'static> Async<T> {
pub fn new(closure: AsyncValueFn<T>)
-> Async<T> {
let async_value = Async {
value: HError::async_not_ready(),
async_value: Arc::new(Mutex::new(None)),
async_closure: Some(closure),
on_ready: Arc::new(Mutex::new(None)),
stale: Arc::new(Mutex::new(false)) };
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)),
stale: Arc::new(Mutex::new(false)) };
willbe.run(closure);
willbe
async_value
}
fn run(&mut self, closure: HClosure<T>) {
let state = self.state.clone();
fn run(&mut self) -> HResult<()> {
let closure = self.async_closure.take()?;
let async_value = self.async_value.clone();
let stale = self.stale.clone();
let thing = self.thing.clone();
let on_ready_fn = self.on_ready.clone();
std::thread::spawn(move|| {
let got_thing = closure(stale);
match got_thing {
Ok(got_thing) => {
*thing.lock().unwrap() = Some(got_thing);
*state.lock().unwrap() = State::Is;
match *on_ready_fn.lock().unwrap() {
Some(ref on_ready) => { on_ready(thing.clone()).ok(); },
std::thread::spawn(move|| -> HResult<()> {
let value = closure(stale);
match value {
Ok(mut value) => {
match *on_ready_fn.lock()? {
Some(ref on_ready) => { on_ready(&mut value).log(); },
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<()> {
@ -87,23 +90,46 @@ impl<T: Send + 'static> WillBe<T> where {
is_stale(&self.stale)
}
pub fn take(&mut self) -> HResult<T> {
self.check()?;
Ok(self.thing.lock()?.take()?)
pub fn take_async(&mut self) -> HResult<()> {
if self.value.is_ok() { return Ok(()) }
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<()> {
match *self.state.lock()? {
State::Is => Ok(()),
_ => Err(HError::WillBeNotReady(Backtrace::new()))
pub fn get(&self) -> HResult<&T> {
match self.value {
Ok(ref value) => Ok(value),
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,
fun: Box<Fn(Arc<Mutex<Option<T>>>) -> HResult<()> + Send>)
fun: AsyncReadyFn<T>)
-> HResult<()> {
if self.check().is_ok() {
fun(self.thing.clone())?;
if self.value.is_ok() {
fun(self.value.as_mut().unwrap())?;
} else {
*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> {
fn eq(&self, other: &WillBeWidget<W>) -> bool {
impl<W: Widget + Send + 'static> PartialEq for AsyncWidget<W> {
fn eq(&self, other: &AsyncWidget<W>) -> bool {
if self.get_coordinates().unwrap() ==
other.get_coordinates().unwrap() {
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
}
impl<T: Widget + Send + 'static> WillBeWidget<T> {
pub fn new(core: &WidgetCore, closure: HClosure<T>) -> WillBeWidget<T> {
impl<W: Widget + Send + 'static> AsyncWidget<W> {
pub fn new(core: &WidgetCore, closure: AsyncValueFn<W>) -> AsyncWidget<W> {
let sender = core.get_sender();
let mut willbe = WillBe::new_become(Box::new(move |stale| closure(stale)));
willbe.on_ready(Box::new(move |_| {
let mut widget = Async::new(Box::new(move |stale| closure(stale)));
widget.on_ready(Box::new(move |_| {
sender.send(crate::widget::Events::WidgetReady)?;
Ok(()) })).ok();
Ok(())
})).log();
widget.run().log();
WillBeWidget {
willbe: willbe,
AsyncWidget {
widget: widget,
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();
let sender = self.get_core()?.get_sender();
let core = self.get_core()?.clone();
let mut willbe = WillBe::new_become(Box::new(move |stale| {
let core = core.clone();
closure(stale, core)
let mut widget = Async::new(Box::new(move |stale| {
closure(stale, core.clone())
}));
willbe.on_ready(Box::new(move |_| {
widget.on_ready(Box::new(move |_| {
sender.send(crate::widget::Events::WidgetReady)?;
Ok(())
}))?;
self.willbe = willbe;
widget.run().log();
self.widget = widget;
Ok(())
}
pub fn set_stale(&mut self) -> HResult<()> {
self.willbe.set_stale()
self.widget.set_stale()
}
pub fn is_stale(&self) -> HResult<bool> {
self.willbe.is_stale()
self.widget.is_stale()
}
pub fn widget(&self) -> HResult<Arc<Mutex<Option<T>>>> {
self.willbe.check()?;
Ok(self.willbe.thing.clone())
pub fn widget(&self) -> HResult<&W> {
self.widget.get()
}
pub fn widget_mut(&mut self) -> HResult<&mut W> {
self.widget.get_mut()
}
pub fn ready(&self) -> bool {
match self.willbe.check() {
Ok(_) => true,
_ => false
}
}
pub fn take(&mut self) -> HResult<T> {
self.willbe.take()
self.widget().is_ok()
}
}
@ -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> {
Ok(&self.core)
}
@ -205,22 +232,19 @@ impl<T: Widget + Send + 'static> Widget for WillBeWidget<T> {
fn set_coordinates(&mut self, coordinates: &Coordinates) -> HResult<()> {
self.core.coordinates = coordinates.clone();
if let Ok(widget) = self.widget() {
let mut widget = widget.lock()?;
let widget = widget.as_mut()?;
if let Ok(widget) = self.widget_mut() {
widget.set_coordinates(&coordinates)?;
}
Ok(())
}
fn refresh(&mut self) -> HResult<()> {
let coords = self.get_coordinates()?;
if let Ok(widget) = self.widget() {
let mut widget = widget.lock()?;
let widget = widget.as_mut()?;
self.widget.take_async().log();
if widget.get_coordinates()? != coords {
widget.set_coordinates(self.get_coordinates()?)?;
let coords = self.get_coordinates()?.clone();
if let Ok(widget) = self.widget_mut() {
if widget.get_coordinates()? != &coords {
widget.set_coordinates(&coords)?;
widget.refresh()?;
} else {
widget.refresh()?;
@ -229,7 +253,7 @@ impl<T: Widget + Send + 'static> Widget for WillBeWidget<T> {
Ok(())
}
fn get_drawlist(&self) -> HResult<String> {
if self.willbe.check().is_err() {
if self.widget().is_err() {
let clear = self.get_clearlist()?;
let (xpos, ypos) = self.get_coordinates()?.u16position();
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()
}
let widget = self.widget()?;
let widget = widget.lock()?;
let widget = widget.as_ref()?;
widget.get_drawlist()
self.widget()?.get_drawlist()
}
fn on_key(&mut self, key: termion::event::Key) -> HResult<()> {
if self.willbe.check().is_err() { return Ok(()) }
let widget = self.widget()?;
let mut widget = widget.lock()?;
let widget = widget.as_mut()?;
widget.on_key(key)
if self.widget().is_err() { return Ok(()) }
self.widget_mut()?.on_key(key)
}
}
@ -267,7 +285,7 @@ impl PartialEq for Previewer {
}
pub struct Previewer {
widget: WillBeWidget<Box<dyn Widget + Send>>,
widget: AsyncWidget<Box<dyn Widget + Send>>,
core: WidgetCore,
file: Option<File>,
selection: Option<File>,
@ -278,11 +296,10 @@ pub struct Previewer {
impl Previewer {
pub fn new(core: &WidgetCore) -> Previewer {
let core_ = core.clone();
let willbe = WillBeWidget::new(&core, Box::new(move |_| {
Ok(Box::new(crate::textview::TextView::new_blank(&core_))
as Box<dyn Widget + Send>)
let widget = AsyncWidget::new(&core, Box::new(move |_| {
Ok(Box::new(TextView::new_blank(&core_)) as Box<dyn Widget + Send>)
}));
Previewer { widget: willbe,
Previewer { widget: widget,
core: core.clone(),
file: None,
selection: None,
@ -290,10 +307,11 @@ impl Previewer {
}
fn become_preview(&mut self,
widget: HResult<WillBeWidget<WidgetO>>) {
let coordinates = self.get_coordinates().unwrap().clone();
self.widget = widget.unwrap();
self.widget.set_coordinates(&coordinates).ok();
widget: HResult<AsyncWidget<WidgetO>>) -> HResult<()> {
let coordinates = self.get_coordinates()?.clone();
self.widget = widget?;
self.widget.set_coordinates(&coordinates)?;
Ok(())
}
pub fn set_stale(&mut self) -> HResult<()> {
@ -315,7 +333,8 @@ impl Previewer {
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();
let file = file.clone();
@ -344,15 +363,14 @@ impl Previewer {
blank.animate_slide_up().log();
return Ok(blank)
}
}))));
Ok(())
}))))
}
pub fn reload(&mut self) {
if let Some(file) = self.file.clone() {
self.file = None;
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))
}
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> {
let process =
std::process::Command::new("scope.sh")

View File

@ -15,7 +15,6 @@ use crate::widget::{Widget, Events, WidgetCore};
use crate::coordinates::Coordinates;
use crate::dirty::Dirtyable;
use crate::hbox::HBox;
use crate::preview::WillBeWidget;
use crate::fail::{HResult, HError, ErrorLog};
use crate::term;
use crate::files::{File, OsStrTools};
@ -299,7 +298,7 @@ impl ListView<Vec<Process>> {
#[derive(PartialEq)]
enum ProcViewWidgets {
List(ListView<Vec<Process>>),
TextView(WillBeWidget<TextView>),
TextView(TextView),
}
impl Widget for ProcViewWidgets {
@ -348,7 +347,7 @@ impl HBox<ProcViewWidgets> {
_ => unreachable!()
}
}
fn get_textview(&mut self) -> &mut WillBeWidget<TextView> {
fn get_textview(&mut self) -> &mut TextView {
match &mut self.widgets[1] {
ProcViewWidgets::TextView(textview) => textview,
_ => unreachable!()
@ -360,8 +359,7 @@ impl ProcView {
pub fn new(core: &WidgetCore) -> ProcView {
let tcore = core.clone();
let listview = ListView::new(&core, vec![]);
let textview = Box::new(move |_| Ok(TextView::new_blank(&tcore)));
let textview = WillBeWidget::new(&core, textview);
let textview = TextView::new_blank(&tcore);
let mut hbox = HBox::new(&core);
hbox.push_widget(ProcViewWidgets::List(listview));
hbox.push_widget(ProcViewWidgets::TextView(textview));
@ -382,7 +380,7 @@ impl ProcView {
self.hbox.get_listview_mut()
}
fn get_textview(&mut self) -> &mut WillBeWidget<TextView> {
fn get_textview(&mut self) -> &mut TextView {
self.hbox.get_textview()
}
@ -399,13 +397,8 @@ impl ProcView {
pub fn remove_proc(&mut self) -> HResult<()> {
if self.get_listview_mut().content.len() == 0 { return Ok(()) }
self.get_listview_mut().remove_proc()?;
self.get_textview().change_to(Box::new(move |_, core| {
let mut textview = TextView::new_blank(&core);
textview.refresh().log();
textview.animate_slide_up().log();
Ok(textview)
})).log();
Ok(())
self.get_textview().clear();
self.get_textview().set_text("")
}
fn show_output(&mut self) -> HResult<()> {
@ -414,48 +407,45 @@ impl ProcView {
}
let output = self.get_listview_mut().selected_proc()?.output.lock()?.clone();
self.get_textview().change_to(Box::new(move |_, core| {
let mut textview = TextView::new_blank(&core);
textview.set_text(&output).log();
textview.animate_slide_up().log();
Ok(textview)
})).log();
self.get_textview().set_text(&output).log();
self.get_textview().animate_slide_up().log();
self.viewing = Some(self.get_listview_mut().get_selection());
Ok(())
}
pub fn toggle_follow(&mut self) -> HResult<()> {
self.get_textview().widget()?.lock()?.as_mut()?.toggle_follow();
self.get_textview().toggle_follow();
Ok(())
}
pub fn scroll_up(&mut self) -> HResult<()> {
self.get_textview().widget()?.lock()?.as_mut()?.scroll_up();
self.get_textview().scroll_up();
Ok(())
}
pub fn scroll_down(&mut self) -> HResult<()> {
self.get_textview().widget()?.lock()?.as_mut()?.scroll_down();
self.get_textview().scroll_down();
Ok(())
}
pub fn page_up(&mut self) -> HResult<()> {
self.get_textview().widget()?.lock()?.as_mut()?.page_up();
self.get_textview().page_up();
Ok(())
}
pub fn page_down(&mut self) -> HResult<()> {
self.get_textview().widget()?.lock()?.as_mut()?.page_down();
self.get_textview().page_down();
Ok(())
}
pub fn scroll_top(&mut self) -> HResult<()> {
self.get_textview().widget()?.lock()?.as_mut()?.scroll_top();
self.get_textview().scroll_top();
Ok(())
}
pub fn scroll_bottom(&mut self) -> HResult<()> {
self.get_textview().widget()?.lock()?.as_mut()?.scroll_bottom();
self.get_textview().scroll_bottom();
Ok(())
}
}