summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorrabite <rabite@posteo.de>2019-04-02 22:17:07 +0200
committerrabite <rabite@posteo.de>2019-04-02 22:17:07 +0200
commite99a3d993cc401720dc5f1c649cd3436fb47d3b3 (patch)
tree13b6f35b90dbc0616869581408336934de7c563c
parented32c83aca9acf40b09c5fb4e7a24cbc2d76d7c9 (diff)
move widgets/files around instead of caching
-rw-r--r--src/fail.rs8
-rw-r--r--src/file_browser.rs212
-rw-r--r--src/files.rs1
-rw-r--r--src/fscache.rs98
-rw-r--r--src/hbox.rs5
-rw-r--r--src/preview.rs131
-rw-r--r--src/term.rs11
-rw-r--r--src/widget.rs7
8 files changed, 401 insertions, 72 deletions
diff --git a/src/fail.rs b/src/fail.rs
index ea5a4a7..1d5736d 100644
--- a/src/fail.rs
+++ b/src/fail.rs
@@ -84,7 +84,9 @@ pub enum HError {
#[fail(display = "{}", _0)]
Log(String),
#[fail(display = "Metadata already processed")]
- MetadataProcessedError
+ MetadataProcessedError,
+ #[fail(display = "No files to take from widget")]
+ WidgetNoFilesError,
}
impl HError {
@@ -158,6 +160,10 @@ impl HError {
pub fn metadata_processed<T>() -> HResult<T> {
Err(HError::MetadataProcessedError)
}
+
+ pub fn no_files<T>() -> HResult<T> {
+ Err(HError::WidgetNoFilesError)
+ }
}
diff --git a/src/file_browser.rs b/src/file_browser.rs
index 941901c..2c94219 100644
--- a/src/file_browser.rs
+++ b/src/file_browser.rs
@@ -4,6 +4,7 @@ use std::io::Write;
use std::sync::{Arc, Mutex};
use std::path::PathBuf;
use std::ffi::OsString;
+use std::collections::HashSet;
use crate::files::{File, Files, PathBufExt};
use crate::fscache::FsCache;
@@ -12,6 +13,7 @@ use crate::hbox::HBox;
use crate::widget::Widget;
use crate::tabview::{TabView, Tabbable};
use crate::preview::{Previewer, AsyncWidget};
+use crate::textview::TextView;
use crate::fail::{HResult, HError, ErrorLog};
use crate::widget::{Events, WidgetCore};
use crate::proclist::ProcView;
@@ -25,37 +27,43 @@ use crate::coordinates::Coordinates;
pub enum FileBrowserWidgets {
FileList(AsyncWidget<ListView<Files>>),
Previewer(Previewer),
+ Blank(AsyncWidget<TextView>),
}
impl Widget for FileBrowserWidgets {
fn get_core(&self) -> HResult<&WidgetCore> {
match self {
FileBrowserWidgets::FileList(widget) => widget.get_core(),
- FileBrowserWidgets::Previewer(widget) => widget.get_core()
+ FileBrowserWidgets::Previewer(widget) => widget.get_core(),
+ FileBrowserWidgets::Blank(widget) => widget.get_core(),
}
}
fn get_core_mut(&mut self) -> HResult<&mut WidgetCore> {
match self {
FileBrowserWidgets::FileList(widget) => widget.get_core_mut(),
- FileBrowserWidgets::Previewer(widget) => widget.get_core_mut()
+ FileBrowserWidgets::Previewer(widget) => widget.get_core_mut(),
+ FileBrowserWidgets::Blank(widget) => widget.get_core_mut(),
}
}
fn set_coordinates(&mut self, coordinates: &Coordinates) -> HResult<()> {
match self {
FileBrowserWidgets::FileList(widget) => widget.set_coordinates(coordinates),
FileBrowserWidgets::Previewer(widget) => widget.set_coordinates(coordinates),
+ FileBrowserWidgets::Blank(widget) => widget.set_coordinates(coordinates),
}
}
fn refresh(&mut self) -> HResult<()> {
match self {
FileBrowserWidgets::FileList(widget) => widget.refresh(),
- FileBrowserWidgets::Previewer(widget) => widget.refresh()
+ FileBrowserWidgets::Previewer(widget) => widget.refresh(),
+ FileBrowserWidgets::Blank(widget) => widget.refresh(),
}
}
fn get_drawlist(&self) -> HResult<String> {
match self {
FileBrowserWidgets::FileList(widget) => widget.get_drawlist(),
- FileBrowserWidgets::Previewer(widget) => widget.get_drawlist()
+ FileBrowserWidgets::Previewer(widget) => widget.get_drawlist(),
+ FileBrowserWidgets::Blank(widget) => widget.get_drawlist(),
}
}
}
@@ -162,6 +170,22 @@ impl Tabbable for TabView<FileBrowser> {
new_file.as_ref()).log()
}
}
+
+ let open_dirs = self.widgets
+ .iter()
+ .fold(HashSet::new(), |mut dirs, tab| {
+ tab.left_dir().map(|dir| dirs.insert(dir.clone())).ok();
+ dirs.insert(tab.cwd.clone());
+ tab.preview_widget()
+ .map(|preview| preview.get_file().map(|file| {
+ if file.is_dir() {
+ dirs.insert(file.clone());
+ }
+ })).ok();
+ dirs
+ });
+
+ self.active_tab_mut_().fs_cache.watch_only(open_dirs).log();
Ok(())
}
}
@@ -199,9 +223,14 @@ impl FileBrowser {
let cache = fs_cache.clone();
let main_widget = AsyncWidget::new(&core, Box::new(move |_| {
- let main_dir = File::new(&main_path.file_name()?
- .to_string_lossy()
- .to_string(),
+ let name = if main_path.parent().is_none() {
+ "root".to_string()
+ } else {
+ main_path.file_name()?
+ .to_string_lossy()
+ .to_string()
+ };
+ let main_dir = File::new(&name,
main_path.clone(),
None);
let files = cache.get_files_sync(&main_dir)?;
@@ -225,9 +254,14 @@ impl FileBrowser {
let cache = fs_cache.clone();
if let Some(left_path) = left_path {
let left_widget = AsyncWidget::new(&core, Box::new(move |_| {
- let left_dir = File::new(&left_path.file_name()?
- .to_string_lossy()
- .to_string(),
+ let name = if left_path.parent().is_none() {
+ "root".to_string()
+ } else {
+ left_path.file_name()?
+ .to_string_lossy()
+ .to_string()
+ };
+ let left_dir = File::new(&name,
left_path.clone(),
None);
let files = cache.get_files_sync(&left_dir)?;
@@ -248,6 +282,14 @@ impl FileBrowser {
}));
let left_widget = FileBrowserWidgets::FileList(left_widget);
columns.push_widget(left_widget);
+ } else {
+ let left_widget = AsyncWidget::new(&core, Box::new(move |_| {
+ let blank = TextView::new_blank(&core_l);
+ Ok(blank)
+ }));
+
+ let left_widget = FileBrowserWidgets::Blank(left_widget);
+ columns.push_widget(left_widget);
}
let previewer = Previewer::new(&core_p, fs_cache.clone());
@@ -281,7 +323,8 @@ impl FileBrowser {
let file = self.selected_file()?;
if file.is_dir() {
- match file.is_readable() {
+ let dir = file;
+ match dir.is_readable() {
Ok(true) => {},
Ok(false) => {
let status =
@@ -293,7 +336,38 @@ impl FileBrowser {
err @ Err(_) => err.log()
}
- self.main_widget_goto(&file).log();
+ let previewer_files = self.preview_widget_mut()?.take_files().ok();
+
+ self.columns.remove_widget(0);
+
+ self.prev_cwd = Some(self.cwd.clone());
+ self.cwd = dir.clone();
+
+ let core = self.core.clone();
+ let cache = self.fs_cache.clone();
+
+ let main_widget = AsyncWidget::new(&core.clone(), Box::new(move |_| {
+ let files = match previewer_files {
+ Some(files) => files,
+ None => cache.get_files_sync(&dir)?
+ };
+
+ let selection = cache.get_selection(&dir).ok();
+
+ let mut list = ListView::new(&core, files);
+
+ if let Some(file) = selection {
+ list.select_file(&file);
+ }
+
+ list.content.meta_all();
+
+ Ok(list)
+ }));
+
+ let main_widget = FileBrowserWidgets::FileList(main_widget);
+ self.columns.insert_widget(1, main_widget);
+
} else {
self.core.get_sender().send(Events::InputEnabled(false))?;
@@ -392,9 +466,42 @@ impl FileBrowser {
pub fn go_back(&mut self) -> HResult<()> {
if let Ok(new_cwd) = self.cwd.parent_as_file() {
- self.main_widget_goto(&new_cwd).log();
+ let core = self.core.clone();
+ let preview_files = self.take_main_files();
+ let old_left = self.columns.remove_widget(0);
+ self.prev_cwd = Some(self.cwd.clone());
+ self.cwd = new_cwd.clone();
+
+ if let Ok(left_dir) = new_cwd.parent_as_file() {
+ let cache = self.fs_cache.clone();
+ let left_widget = AsyncWidget::new(&core.clone(), Box::new(move |_| {
+ let files = cache.get_files_sync(&left_dir)?;
+ let list = ListView::new(&core, files);
+ Ok(list)
+ }));
+
+ let left_widget = FileBrowserWidgets::FileList(left_widget);
+ self.columns.prepend_widget(left_widget);
+ } else {
+ let left_widget = AsyncWidget::new(&core.clone(), Box::new(move |_| {
+ let blank = TextView::new_blank(&core);
+ Ok(blank)
+ }));
+
+ let left_widget = FileBrowserWidgets::Blank(left_widget);
+ self.columns.prepend_widget(left_widget);
+ }
+ self.columns.replace_widget(1, old_left);
+ self.main_widget_mut()?.content.meta_all();
+
+ if let Ok(preview_files) = preview_files {
+ self.preview_widget_mut().map(|preview| {
+ preview.put_preview_files(preview_files)
+ }).ok();
+ }
}
+ self.columns.resize_children();
self.refresh()
}
@@ -459,8 +566,8 @@ impl FileBrowser {
}
pub fn set_left_selection(&mut self) -> HResult<()> {
- if !self.left_async_widget_mut()?.ready() { return Ok(()) }
if self.cwd.parent().is_none() { return Ok(()) }
+ if !self.left_async_widget_mut()?.ready() { return Ok(()) }
let selection = self.cwd()?.clone();
@@ -469,6 +576,63 @@ impl FileBrowser {
Ok(())
}
+ pub fn take_main_files(&mut self) -> HResult<Files> {
+ let core = self.core.clone();
+ let blank = AsyncWidget::new(&core.clone(), Box::new(move |_| {
+ HError::no_files()
+ }));
+ let blank = FileBrowserWidgets::Blank(blank);
+
+ let old_widget = self.columns.replace_widget(1, blank);
+
+ if let FileBrowserWidgets::FileList(main_widget) = old_widget {
+ let files = main_widget.take_widget()?.content;
+ return Ok(files)
+ }
+ HError::no_files()
+ }
+
+ pub fn take_left_files(&mut self) -> HResult<Files> {
+ let core = self.core.clone();
+ let blank = AsyncWidget::new(&core.clone(), Box::new(move |_| {
+ HError::no_files()
+ }));
+ let blank = FileBrowserWidgets::FileList(blank);
+
+ let old_widget = self.columns.replace_widget(0, blank);
+
+ if let FileBrowserWidgets::FileList(left_widget) = old_widget {
+ let files = left_widget.take_widget()?.content;
+ return Ok(files)
+ }
+ HError::no_files()
+ }
+
+ // pub fn take_preview_files(&mut self) -> HResult<Files> {
+ // let widget = self.columns.remove_widget(2);
+ // if let Filxx
+ // }
+
+ // pub fn take_files_from_widget(&self,
+ // widget: FileBrowserWidgets) -> HResult<Files> {
+ // match widget {
+ // FileBrowserWidgets::FileList(file_list) => {
+ // match file_list.take_widget() {
+ // Ok(widget) => {
+ // let files = widget.content;
+ // Ok(files)
+ // }
+ // _ => HError::no_files()
+ // }
+ // }
+ // FileBrowserWidgets::Previewer(previewer) => {
+ // let files = previewer.take_files()?;
+ // Ok(files)
+ // }
+ // _ => HError::no_files()
+ // }
+ // }
+
pub fn get_files(&self) -> HResult<&Files> {
Ok(&self.main_widget()?.content)
}
@@ -484,10 +648,12 @@ impl FileBrowser {
self.main_widget_mut()?.content.meta_updated = false;
- let left_selection = self.left_widget()?.clone_selected_file();
- let left_files = self.get_left_files()?;
- self.fs_cache.put_files(left_files, Some(left_selection)).log();
- self.left_widget_mut()?.content.meta_updated = false;
+ if self.cwd.parent().is_some() {
+ let left_selection = self.left_widget()?.clone_selected_file();
+ let left_files = self.get_left_files()?;
+ self.fs_cache.put_files(left_files, Some(left_selection)).log();
+ self.left_widget_mut()?.content.meta_updated = false;
+ }
Ok(())
}
@@ -516,6 +682,9 @@ impl FileBrowser {
if &self.cwd == dir {
self.main_widget_mut()?.content.replace_file(old, new.cloned()).log();
}
+
+ self.preview_widget_mut()?.replace_file(dir, old, new).ok();
+
if &self.left_dir()? == &dir {
self.left_widget_mut()?.content.replace_file(old, new.cloned()).log();
}
@@ -590,6 +759,13 @@ impl FileBrowser {
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),
diff --git a/src/files.rs b/src/files.rs
index a1c5592..01620bd 100644
--- a/src/files.rs
+++ b/src/files.rs
@@ -464,7 +464,6 @@ impl Hash for File {
fn hash<H: Hasher>(&self, state: &mut H) {
self.name.hash(state);
self.path.hash(state);
- self.selected.hash(state);
}
}
diff --git a/src/fscache.rs b/src/fscache.rs
index 8e33d44..ba0212f 100644
--- a/src/fscache.rs
+++ b/src/fscache.rs
@@ -114,15 +114,17 @@ impl FsCache {
} else {
self.add_watch(&dir).log();
let dir = dir.clone();
+ let selection = self.get_selection(&dir).ok();
let files = Async::new(Box::new(move |_| {
let files = Files::new_from_path_cancellable(&dir.path, stale)?;
Ok(files)
}));
- Ok((None, files))
+ Ok((selection, files))
}
}
pub fn get_files_sync(&self, dir: &File) -> HResult<Files> {
+ self.add_watch(&dir).log();
let files = self.get_files(&dir, Stale::new())?.1;
files.wait()
}
@@ -145,17 +147,17 @@ impl FsCache {
self.tab_settings.write()?.insert(dir.clone(), tab_settings);
- let mut file_cache = self.files.write()?;
+ // let mut file_cache = self.files.write()?;
- if file_cache.contains_key(&files.directory) {
- if files.meta_updated {
- let mut files = files.clone();
- files.meta_updated = false;
- file_cache.insert(dir, files);
- }
- } else {
- file_cache.insert(dir, files.clone());
- }
+ // if file_cache.contains_key(&files.directory) {
+ // if files.meta_updated {
+ // let mut files = files.clone();
+ // files.meta_updated = false;
+ // file_cache.insert(dir, files);
+ // }
+ // } else {
+ // file_cache.insert(dir, files.clone());
+ // }
Ok(())
}
@@ -164,8 +166,23 @@ impl FsCache {
Ok(self.files.read()?.contains_key(dir))
}
+ pub fn watch_only(&self, open_dirs: HashSet<File>) -> HResult<()> {
+ let removable = self.watched_dirs
+ .read()?
+ .difference(&open_dirs)
+ .map(|dir| dir.clone())
+ .collect::<Vec<File>>();
+
+ for watch in removable {
+ self.remove_watch(&watch).log();
+ }
+
+ Ok(())
+ }
+
fn add_watch(&self, dir: &File) -> HResult<()> {
if !self.watched_dirs.read()?.contains(&dir) {
+ self.watched_dirs.write()?.insert(dir.clone());
self.watcher.write()?.watch(&dir.path, RecursiveMode::NonRecursive)?
}
Ok(())
@@ -245,32 +262,49 @@ fn watch_fs(rx_fs_events: Receiver<DebouncedEvent>,
});
}
-fn apply_event(fs_cache: &Arc<RwLock<HashMap<File, Files>>>,
+fn apply_event(_fs_cache: &Arc<RwLock<HashMap<File, Files>>>,
fs_changes: &Arc<RwLock<Vec<(File, Option<File>, Option<File>)>>>,
event: DebouncedEvent)
-> HResult<()> {
let path = &event.get_source_path()?;
- for dir in fs_cache.write()?.values_mut() {
- if dir.path_in_here(&path).unwrap_or(false) {
- let old_file = dir.find_file_with_path(&path).cloned();
- let dirty_meta = old_file
- .as_ref()
- .map(|f| f.dirty_meta.clone())
- .unwrap_or(None);
- let mut new_file = match event {
- DebouncedEvent::Remove(_) => None,
- _ => Some(File::new_from_path(&path, dirty_meta)?)
- };
-
- new_file.as_mut().map(|file| file.meta_sync());
- dir.replace_file(old_file.as_ref(), new_file.clone()).log();
-
- fs_changes.write()?.push((dir.directory.clone(),
- old_file,
- new_file));
- }
- }
+ let dirpath = path.parent()
+ .map(|path| path.to_path_buf())
+ .unwrap_or_else(|| PathBuf::from("/"));
+ let dir = File::new_from_path(&dirpath, None)?;
+
+ let old_file = File::new_from_path(&path, None)?;
+ let mut new_file = match event {
+ DebouncedEvent::Remove(_) => None,
+ _ => Some(File::new_from_path(&path, None)?)
+ };
+
+ new_file.as_mut().map(|file| file.meta_sync());
+
+ fs_changes.write()?.push((dir,
+ Some(old_file),
+ new_file));
+
+ // for dir in fs_cache.write()?.values_mut() {
+ // if dir.path_in_here(&path).unwrap_or(false) {
+ // let old_file = dir.find_file_with_path(&path).cloned();
+ // let dirty_meta = old_file
+ // .as_ref()
+ // .map(|f| f.dirty_meta.clone())
+ // .unwrap_or(None);
+ // let mut new_file = match event {
+ // DebouncedEvent::Remove(_) => None,
+ // _ => Some(File::new_from_path(&path, dirty_meta)?)
+ // };
+
+ // new_file.as_mut().map(|file| file.meta_sync());
+ // dir.replace_file(old_file.as_ref(), new_file.clone()).log();
+
+ // fs_changes.write()?.push((dir.directory.clone(),
+ // old_file,
+ // new_file));
+ // }
+ // }
Ok(())
}
diff --git a/src/hbox.rs b/src/hbox.rs
index 0be0408..4537961 100644
--- a/src/hbox.rs
+++ b/src/hbox.rs
@@ -66,6 +66,11 @@ impl<T> HBox<T> where T: Widget + PartialEq {
self.widgets.insert(index, widget);
}
+ pub fn replace_widget(&mut self, index: usize, mut widget: T) -> T {
+ std::mem::swap(&mut self.widgets[index], &mut widget);
+ widget
+ }
+
pub fn toggle_zoom(&mut self) -> HResult<()> {
self.clear().log();
self.zoom_active = !self.zoom_active;
diff --git a/src/preview.rs b/src/preview.rs
index 013b2d6..4607fa4 100644
--- a/src/preview.rs
+++ b/src/preview.rs
@@ -3,7 +3,8 @@ use std::boxed::FnBox;
use rayon::ThreadPool;
-use crate::files::{File, Kind};
+use crate::files::{File, Files, Kind};
+use crate::fscache::FsCache;
use crate::listview::ListView;
use crate::textview::TextView;
use crate::widget::{Widget, WidgetCore};
@@ -131,7 +132,9 @@ impl<T: Send + 'static> Async<T> {
let value_fn = async_fn.lock()?.take()?;
let value = value_fn.call_box((stale.clone(),));
async_value.lock()?.replace(value);
- on_ready_fn.lock()?.take()?.call_box(()).log();
+ on_ready_fn.lock()?
+ .take()
+ .map(|on_ready| on_ready.call_box(()).log());
Ok(())
}
@@ -331,6 +334,10 @@ impl<W: Widget + Send + 'static> AsyncWidget<W> {
self.widget.get_mut()
}
+ pub fn take_widget(self) -> HResult<W> {
+ Ok(self.widget.value?)
+ }
+
pub fn ready(&self) -> bool {
self.widget().is_ok()
}
@@ -400,10 +407,16 @@ impl PartialEq for Previewer {
}
}
-use crate::fscache::FsCache;
+#[derive(PartialEq)]
+enum PreviewWidget {
+ FileList(ListView<Files>),
+ TextView(TextView)
+}
+
+
pub struct Previewer {
- widget: AsyncWidget<Box<dyn Widget + Send>>,
+ widget: AsyncWidget<PreviewWidget>,
core: WidgetCore,
file: Option<File>,
pub cache: FsCache,
@@ -414,7 +427,9 @@ impl Previewer {
pub fn new(core: &WidgetCore, cache: FsCache) -> Previewer {
let core_ = core.clone();
let widget = AsyncWidget::new(&core, Box::new(move |_| {
- Ok(Box::new(TextView::new_blank(&core_)) as Box<dyn Widget + Send>)
+ let blank = TextView::new_blank(&core_);
+ let blank = PreviewWidget::TextView(blank);
+ Ok(blank)
}));
Previewer { widget: widget,
core: core.clone(),
@@ -423,7 +438,7 @@ impl Previewer {
}
fn become_preview(&mut self,
- widget: HResult<AsyncWidget<WidgetO>>) -> HResult<()> {
+ widget: HResult<AsyncWidget<PreviewWidget>>) -> HResult<()> {
let coordinates = self.get_coordinates()?.clone();
self.widget = widget?;
self.widget.set_coordinates(&coordinates)?;
@@ -438,6 +453,57 @@ impl Previewer {
self.file.as_ref()
}
+ pub fn take_files(&mut self) -> HResult<Files> {
+ let core = self.core.clone();
+ let mut widget = AsyncWidget::new(&core.clone(), Box::new(move |_| {
+ let widget = TextView::new_blank(&core);
+ let widget = PreviewWidget::TextView(widget);
+ Ok(widget)
+ }));
+ std::mem::swap(&mut self.widget, &mut widget);
+
+ match widget.take_widget() {
+ Ok(PreviewWidget::FileList(file_list)) => {
+ let files = file_list.content;
+ Ok(files)
+ }
+ _ => HError::no_files()?
+ }
+ }
+
+ pub fn replace_file(&mut self, dir: &File,
+ old: Option<&File>,
+ new: Option<&File>) -> HResult<()> {
+ if self.file.as_ref() != Some(dir) { return Ok(()) }
+ self.widget.widget_mut().map(|widget| {
+ match widget {
+ PreviewWidget::FileList(filelist) => {
+ filelist.content.replace_file(old, new.cloned()).map(|_| {
+ filelist.refresh().ok();
+ }).ok();
+
+ }
+ _ => {}
+ }
+ })
+ }
+
+ pub fn put_preview_files(&mut self, files: Files) {
+ let core = self.core.clone();
+ let dir = files.directory.clone();
+ let cache = self.cache.clone();
+ self.file = Some(dir);
+
+ self.widget = AsyncWidget::new(&self.core, Box::new(move |_| {
+ let selected_file = cache.get_selection(&files.directory);
+ let mut filelist = ListView::new(&core, files);
+
+ selected_file.map(|file| filelist.select_file(&file));
+
+ Ok(PreviewWidget::FileList(filelist))
+ }));
+ }
+
pub fn set_file(&mut self,
file: &File) -> HResult<()> {
if Some(file) == self.file.as_ref() && !self.widget.is_stale()? { return Ok(()) }
@@ -469,11 +535,11 @@ impl Previewer {
let preview = Previewer::preview_external(&file, &core, stale);
if preview.is_ok() { return preview; }
else {
- let mut blank = Box::new(TextView::new_blank(&core));
+ let mut blank = TextView::new_blank(&core);
blank.set_coordinates(&coordinates).log();
blank.refresh().log();
blank.animate_slide_up().log();
- return Ok(blank)
+ return Ok(PreviewWidget::TextView(blank))
}
}))))
}
@@ -485,7 +551,9 @@ impl Previewer {
}
}
- fn preview_failed(file: &File) -> HResult<WidgetO> {
+
+
+ fn preview_failed(file: &File) -> HResult<PreviewWidget> {
HError::preview_failed(file)
}
@@ -493,7 +561,7 @@ impl Previewer {
cache: FsCache,
core: &WidgetCore,
stale: Stale)
- -> Result<WidgetO, HError> {
+ -> HResult<PreviewWidget> {
let (selection, cached_files) = cache.get_files(&file, stale.clone())?;
let files = cached_files.wait()?;
@@ -510,11 +578,11 @@ impl Previewer {
file_list.refresh()?;
if is_stale(&stale)? { return Previewer::preview_failed(&file) }
file_list.animate_slide_up()?;
- Ok(Box::new(file_list) as Box<dyn Widget + Send>)
+ Ok(PreviewWidget::FileList(file_list))
}
fn preview_text(file: &File, core: &WidgetCore, stale: Stale)
- -> HResult<WidgetO> {
+ -> HResult<PreviewWidget> {
let lines = core.coordinates.ysize() as usize;
let mut textview
= TextView::new_from_file_limit_lines(&core,
@@ -528,13 +596,13 @@ impl Previewer {
if is_stale(&stale)? { return Previewer::preview_failed(&file) }
textview.animate_slide_up()?;
- Ok(Box::new(textview))
+ Ok(PreviewWidget::TextView(textview))
}
fn preview_external(file: &File,
core: &WidgetCore,
stale: Stale)
- -> Result<Box<dyn Widget + Send>, HError> {
+ -> HResult<PreviewWidget> {
let process =
std::process::Command::new("scope.sh")
.arg(&file.path)
@@ -577,7 +645,7 @@ impl Previewer {
textview.set_coordinates(&core.coordinates).log();
textview.refresh().log();
textview.animate_slide_up().log();
- return Ok(Box::new(textview))
+ return Ok(PreviewWidget::TextView(textview))
}
HError::preview_failed(file)
}
@@ -607,7 +675,38 @@ impl Widget for Previewer {
}
}
-
+impl Widget for PreviewWidget {
+ fn get_core(&self) -> HResult<&WidgetCore> {
+ match self {
+ PreviewWidget::FileList(widget) => widget.get_core(),
+ PreviewWidget::TextView(widget) => widget.get_core()
+ }
+ }
+ fn get_core_mut(&mut self) -> HResult<&mut WidgetCore> {
+ match self {
+ PreviewWidget::FileList(widget) => widget.get_core_mut(),
+ PreviewWidget::TextView(widget) => widget.get_core_mut()
+ }
+ }
+ fn set_coordinates(&mut self, coordinates: &Coordinates) -> HResult<()> {
+ match self {
+ PreviewWidget::FileList(widget) => widget.set_coordinates(coordinates),
+ PreviewWidget::TextView(widget) => widget.set_coordinates(coordinates),
+ }
+ }
+ fn refresh(&mut self) -> HResult<()> {
+ match self {
+ PreviewWidget::FileList(widget) => widget.refresh(),
+ PreviewWidget::TextView(widget) => widget.refresh()
+ }
+ }
+ fn get_drawlist(&self) -> HResult<String> {
+ match self {
+ PreviewWidget::FileList(widget) => widget.get_drawlist(),
+ PreviewWidget::TextView(widget) => widget.get_drawlist()
+ }
+ }
+}
impl<T> Widget for Box<T> where T: Widget + ?Sized {
diff --git a/src/term.rs b/src/term.rs
index 7c63066..bc99c36 100644
--- a/src/term.rs
+++ b/src/term.rs
@@ -54,8 +54,15 @@ impl Screen {
Ok(())
}
- pub fn is_resized(&self) -> HResult<(usize, usize)> {
- Ok(self.size.read()?.clone()?)
+ pub fn is_resized(&self) -> HResult<bool> {
+ Ok(self.size.read()?.is_some())
+ }
+
+ pub fn get_size(&self) -> HResult<(usize, usize)> {
+ match self.size.read()?.clone() {
+ Some((xsize, ysize)) => Ok((xsize, ysize)),
+ None => Ok((self.xsize()?, self.ysize()?))
+ }
}
pub fn take_size(&self) -> HResult<(usize, usize)> {
diff --git a/src/widget.rs b/src/widget.rs
index 4f400c6..46eb340 100644
--- a/src/widget.rs
+++ b/src/widget.rs
@@ -348,7 +348,9 @@ pub trait Widget {
_ => {}
}
self.resize().log();
- self.screen()?.take_size().ok();
+ if self.screen()?.is_resized()? {
+ self.screen()?.take_size().ok();
+ }
self.refresh().ok();
self.draw().ok();
}
@@ -408,7 +410,8 @@ pub trait Widget {
}
fn resize(&mut self) -> HResult<()> {
- if let Ok((xsize, ysize)) = self.screen()?.is_resized() {
+ if let Ok(true) = self.screen()?.is_resized() {
+ let (xsize, ysize) = self.screen()?.get_size()?;
let mut coords = self.get_core()?.coordinates.clone();
coords.set_size_u(xsize, ysize-2);
self.set_coordinates(&coords)?;