don't animate over other widgets

This commit is contained in:
rabite 2019-04-03 11:28:30 +02:00
parent 000bd4ab9e
commit 8bfc707a59
4 changed files with 100 additions and 35 deletions

View File

@ -244,7 +244,7 @@ impl FileBrowser {
list.refresh().log(); list.refresh().log();
if startup { if startup {
list.animate_slide_up().log(); list.animate_slide_up(None).log();
} }
list.content.meta_all(); list.content.meta_all();
@ -275,7 +275,7 @@ impl FileBrowser {
list.refresh().log(); list.refresh().log();
if startup { if startup {
list.animate_slide_up().log(); list.animate_slide_up(None).log();
} }
Ok(list) Ok(list)
@ -787,6 +787,7 @@ impl FileBrowser {
} }
pub fn toggle_colums(&mut self) { pub fn toggle_colums(&mut self) {
self.preview_widget().map(|preview| preview.cancel_animation()).log();
self.columns.toggle_zoom().log(); self.columns.toggle_zoom().log();
} }
@ -849,6 +850,7 @@ impl FileBrowser {
pub fn run_subshell(&mut self) -> HResult<()> { pub fn run_subshell(&mut self) -> HResult<()> {
self.core.get_sender().send(Events::InputEnabled(false))?; self.core.get_sender().send(Events::InputEnabled(false))?;
self.preview_widget().map(|preview| preview.cancel_animation()).log();
self.core.screen.cursor_show().log(); self.core.screen.cursor_show().log();
self.core.screen.drop_screen(); self.core.screen.drop_screen();
@ -874,6 +876,18 @@ impl FileBrowser {
Ok(()) Ok(())
} }
pub fn show_procview(&mut self) -> HResult<()> {
self.preview_widget().map(|preview| preview.cancel_animation()).log();
self.proc_view.lock()?.popup()?;
Ok(())
}
pub fn show_log(&mut self) -> HResult<()> {
self.preview_widget().map(|preview| preview.cancel_animation()).log();
self.log_view.lock()?.popup()?;
Ok(())
}
pub fn get_footer(&self) -> HResult<String> { pub fn get_footer(&self) -> HResult<String> {
let xsize = self.get_coordinates()?.xsize(); let xsize = self.get_coordinates()?.xsize();
let ypos = self.get_coordinates()?.position().y(); let ypos = self.get_coordinates()?.position().y();
@ -991,8 +1005,8 @@ impl Widget for FileBrowser {
Key::Char('-') => { self.goto_prev_cwd()?; }, Key::Char('-') => { self.goto_prev_cwd()?; },
Key::Char('`') => { self.goto_bookmark()?; }, Key::Char('`') => { self.goto_bookmark()?; },
Key::Char('m') => { self.add_bookmark()?; }, Key::Char('m') => { self.add_bookmark()?; },
Key::Char('w') => { self.proc_view.lock()?.popup()?; }, Key::Char('w') => { self.show_procview()?; },
Key::Char('l') => self.log_view.lock()?.popup()?, Key::Char('l') => self.show_log()?,
Key::Char('z') => self.run_subshell()?, Key::Char('z') => self.run_subshell()?,
Key::Char('c') => self.toggle_colums(), Key::Char('c') => self.toggle_colums(),
_ => { self.main_widget_mut()?.on_key(key)?; }, _ => { self.main_widget_mut()?.on_key(key)?; },

View File

@ -420,6 +420,7 @@ pub struct Previewer {
core: WidgetCore, core: WidgetCore,
file: Option<File>, file: Option<File>,
pub cache: FsCache, pub cache: FsCache,
animator: Stale
} }
@ -434,7 +435,8 @@ impl Previewer {
Previewer { widget: widget, Previewer { widget: widget,
core: core.clone(), core: core.clone(),
file: None, file: None,
cache: cache } cache: cache,
animator: Stale::new()}
} }
fn become_preview(&mut self, fn become_preview(&mut self,
@ -453,6 +455,10 @@ impl Previewer {
self.file.as_ref() self.file.as_ref()
} }
pub fn cancel_animation(&self) -> HResult<()> {
self.animator.set_stale()
}
pub fn take_files(&mut self) -> HResult<Files> { pub fn take_files(&mut self) -> HResult<Files> {
let core = self.core.clone(); let core = self.core.clone();
let mut widget = AsyncWidget::new(&core.clone(), Box::new(move |_| { let mut widget = AsyncWidget::new(&core.clone(), Box::new(move |_| {
@ -513,8 +519,10 @@ impl Previewer {
let file = file.clone(); let file = file.clone();
let core = self.core.clone(); let core = self.core.clone();
let cache = self.cache.clone(); let cache = self.cache.clone();
let animator = self.animator.clone();
self.widget.set_stale().ok(); self.widget.set_stale().ok();
self.animator.set_fresh().log();
self.become_preview(Ok(AsyncWidget::new(&self.core, self.become_preview(Ok(AsyncWidget::new(&self.core,
Box::new(move |stale: Stale| { Box::new(move |stale: Stale| {
@ -524,21 +532,28 @@ impl Previewer {
let preview = Previewer::preview_dir(&file, let preview = Previewer::preview_dir(&file,
cache, cache,
&core, &core,
stale); stale,
animator);
return preview; return preview;
} }
if file.is_text() { if file.is_text() {
return Previewer::preview_text(&file, &core, stale) return Previewer::preview_text(&file,
&core,
stale,
animator);
} }
let preview = Previewer::preview_external(&file, &core, stale); let preview = Previewer::preview_external(&file,
&core,
stale,
animator.clone());
if preview.is_ok() { return preview; } if preview.is_ok() { return preview; }
else { else {
let mut blank = TextView::new_blank(&core); let mut blank = TextView::new_blank(&core);
blank.set_coordinates(&coordinates).log(); blank.set_coordinates(&coordinates).log();
blank.refresh().log(); blank.refresh().log();
blank.animate_slide_up().log(); blank.animate_slide_up(Some(animator)).log();
return Ok(PreviewWidget::TextView(blank)) return Ok(PreviewWidget::TextView(blank))
} }
})))) }))))
@ -560,7 +575,8 @@ impl Previewer {
fn preview_dir(file: &File, fn preview_dir(file: &File,
cache: FsCache, cache: FsCache,
core: &WidgetCore, core: &WidgetCore,
stale: Stale) stale: Stale,
animator: Stale)
-> HResult<PreviewWidget> { -> HResult<PreviewWidget> {
let (selection, cached_files) = cache.get_files(&file, stale.clone())?; let (selection, cached_files) = cache.get_files(&file, stale.clone())?;
@ -577,11 +593,14 @@ impl Previewer {
file_list.set_coordinates(&core.coordinates)?; file_list.set_coordinates(&core.coordinates)?;
file_list.refresh()?; file_list.refresh()?;
if is_stale(&stale)? { return Previewer::preview_failed(&file) } if is_stale(&stale)? { return Previewer::preview_failed(&file) }
file_list.animate_slide_up()?; file_list.animate_slide_up(Some(animator))?;
Ok(PreviewWidget::FileList(file_list)) Ok(PreviewWidget::FileList(file_list))
} }
fn preview_text(file: &File, core: &WidgetCore, stale: Stale) fn preview_text(file: &File,
core: &WidgetCore,
stale: Stale,
animator: Stale)
-> HResult<PreviewWidget> { -> HResult<PreviewWidget> {
let lines = core.coordinates.ysize() as usize; let lines = core.coordinates.ysize() as usize;
let mut textview let mut textview
@ -595,13 +614,14 @@ impl Previewer {
if is_stale(&stale)? { return Previewer::preview_failed(&file) } if is_stale(&stale)? { return Previewer::preview_failed(&file) }
textview.animate_slide_up()?; textview.animate_slide_up(Some(animator))?;
Ok(PreviewWidget::TextView(textview)) Ok(PreviewWidget::TextView(textview))
} }
fn preview_external(file: &File, fn preview_external(file: &File,
core: &WidgetCore, core: &WidgetCore,
stale: Stale) stale: Stale,
animator: Stale)
-> HResult<PreviewWidget> { -> HResult<PreviewWidget> {
let process = let process =
std::process::Command::new("scope.sh") std::process::Command::new("scope.sh")
@ -644,7 +664,7 @@ impl Previewer {
offset: 0}; offset: 0};
textview.set_coordinates(&core.coordinates).log(); textview.set_coordinates(&core.coordinates).log();
textview.refresh().log(); textview.refresh().log();
textview.animate_slide_up().log(); textview.animate_slide_up(Some(animator)).log();
return Ok(PreviewWidget::TextView(textview)) return Ok(PreviewWidget::TextView(textview))
} }
HError::preview_failed(file) HError::preview_failed(file)

View File

@ -13,6 +13,7 @@ use crate::listview::{Listable, ListView};
use crate::textview::TextView; use crate::textview::TextView;
use crate::widget::{Widget, Events, WidgetCore}; use crate::widget::{Widget, Events, WidgetCore};
use crate::coordinates::Coordinates; use crate::coordinates::Coordinates;
use crate::preview::{AsyncWidget, Stale};
use crate::dirty::Dirtyable; use crate::dirty::Dirtyable;
use crate::hbox::HBox; use crate::hbox::HBox;
use crate::fail::{HResult, HError, ErrorLog}; use crate::fail::{HResult, HError, ErrorLog};
@ -298,7 +299,7 @@ impl ListView<Vec<Process>> {
#[derive(PartialEq)] #[derive(PartialEq)]
enum ProcViewWidgets { enum ProcViewWidgets {
List(ListView<Vec<Process>>), List(ListView<Vec<Process>>),
TextView(TextView), TextView(AsyncWidget<TextView>),
} }
impl Widget for ProcViewWidgets { impl Widget for ProcViewWidgets {
@ -331,7 +332,8 @@ impl Widget for ProcViewWidgets {
pub struct ProcView { pub struct ProcView {
core: WidgetCore, core: WidgetCore,
hbox: HBox<ProcViewWidgets>, hbox: HBox<ProcViewWidgets>,
viewing: Option<usize> viewing: Option<usize>,
animator: Stale
} }
impl HBox<ProcViewWidgets> { impl HBox<ProcViewWidgets> {
@ -347,7 +349,7 @@ impl HBox<ProcViewWidgets> {
_ => unreachable!() _ => unreachable!()
} }
} }
fn get_textview(&mut self) -> &mut TextView { fn get_textview(&mut self) -> &mut AsyncWidget<TextView> {
match &mut self.widgets[1] { match &mut self.widgets[1] {
ProcViewWidgets::TextView(textview) => textview, ProcViewWidgets::TextView(textview) => textview,
_ => unreachable!() _ => unreachable!()
@ -359,7 +361,10 @@ 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 = TextView::new_blank(&tcore); let textview = AsyncWidget::new(&core, Box::new(move |_| {
let textview = TextView::new_blank(&tcore);
Ok(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));
@ -368,7 +373,8 @@ impl ProcView {
ProcView { ProcView {
core: core.clone(), core: core.clone(),
hbox: hbox, hbox: hbox,
viewing: None viewing: None,
animator: Stale::new()
} }
} }
@ -380,7 +386,7 @@ impl ProcView {
self.hbox.get_listview_mut() self.hbox.get_listview_mut()
} }
fn get_textview(&mut self) -> &mut TextView { fn get_textview(&mut self) -> &mut AsyncWidget<TextView> {
self.hbox.get_textview() self.hbox.get_textview()
} }
@ -398,7 +404,7 @@ impl ProcView {
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().clear(); self.get_textview().clear();
self.get_textview().set_text("") self.get_textview().widget_mut()?.set_text("")
} }
fn show_output(&mut self) -> HResult<()> { fn show_output(&mut self) -> HResult<()> {
@ -407,45 +413,52 @@ 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().set_text(&output).log(); let animator = self.animator.clone();
self.get_textview().animate_slide_up().log(); animator.set_fresh();
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(Some(animator));
Ok(textview)
}));
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().toggle_follow(); self.get_textview().widget_mut()?.toggle_follow();
Ok(()) Ok(())
} }
pub fn scroll_up(&mut self) -> HResult<()> { pub fn scroll_up(&mut self) -> HResult<()> {
self.get_textview().scroll_up(); self.get_textview().widget_mut()?.scroll_up();
Ok(()) Ok(())
} }
pub fn scroll_down(&mut self) -> HResult<()> { pub fn scroll_down(&mut self) -> HResult<()> {
self.get_textview().scroll_down(); self.get_textview().widget_mut()?.scroll_down();
Ok(()) Ok(())
} }
pub fn page_up(&mut self) -> HResult<()> { pub fn page_up(&mut self) -> HResult<()> {
self.get_textview().page_up(); self.get_textview().widget_mut()?.page_up();
Ok(()) Ok(())
} }
pub fn page_down(&mut self) -> HResult<()> { pub fn page_down(&mut self) -> HResult<()> {
self.get_textview().page_down(); self.get_textview().widget_mut()?.page_down();
Ok(()) Ok(())
} }
pub fn scroll_top(&mut self) -> HResult<()> { pub fn scroll_top(&mut self) -> HResult<()> {
self.get_textview().scroll_top(); self.get_textview().widget_mut()?.scroll_top();
Ok(()) Ok(())
} }
pub fn scroll_bottom(&mut self) -> HResult<()> { pub fn scroll_bottom(&mut self) -> HResult<()> {
self.get_textview().scroll_bottom(); self.get_textview().widget_mut()?.scroll_bottom();
Ok(()) Ok(())
} }
} }
@ -536,7 +549,10 @@ impl Widget for ProcView {
} }
fn on_key(&mut self, key: Key) -> HResult<()> { fn on_key(&mut self, key: Key) -> HResult<()> {
match key { match key {
Key::Char('w') => { return Err(HError::PopupFinnished) } Key::Char('w') => {
self.animator.set_stale();
self.clear();
return Err(HError::PopupFinnished) }
Key::Char('d') => { self.remove_proc()? } Key::Char('d') => { self.remove_proc()? }
Key::Char('k') => { self.get_listview_mut().kill_proc()? } Key::Char('k') => { self.get_listview_mut().kill_proc()? }
Key::Up | Key::Char('p') => { Key::Up | Key::Char('p') => {

View File

@ -11,6 +11,7 @@ use crate::minibuffer::MiniBuffer;
use crate::term; use crate::term;
use crate::term::{Screen, ScreenExt}; use crate::term::{Screen, ScreenExt};
use crate::dirty::{Dirtyable, DirtyBit}; use crate::dirty::{Dirtyable, DirtyBit};
use crate::preview::Stale;
use crate::signal_notify::{notify, Signal}; use crate::signal_notify::{notify, Signal};
@ -264,6 +265,7 @@ pub trait Widget {
} }
Events::WidgetReady => { Events::WidgetReady => {
self.refresh().log(); self.refresh().log();
self.draw().log();
} }
Events::Status(status) => { Events::Status(status) => {
self.show_status(&status).log(); self.show_status(&status).log();
@ -289,7 +291,7 @@ pub trait Widget {
self.write_to_screen(&clearlist) self.write_to_screen(&clearlist)
} }
fn animate_slide_up(&mut self) -> HResult<()> { fn animate_slide_up(&mut self, animator: Option<Stale>) -> HResult<()> {
let coords = self.get_coordinates()?.clone(); let coords = self.get_coordinates()?.clone();
let xpos = coords.position().x(); let xpos = coords.position().x();
let ypos = coords.position().y(); let ypos = coords.position().y();
@ -298,20 +300,33 @@ pub trait Widget {
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);
if let Some(ref animator) = animator {
if animator.is_stale()? {
return Ok(())
}
}
self.write_to_screen(&clear).log(); self.write_to_screen(&clear).log();
for i in (0..10).rev() { for i in (0..10).rev() {
let coords = Coordinates { size: Size((xsize,ysize-i)), if let Some(ref animator) = animator {
if animator.is_stale()? {
self.set_coordinates(&coords).log();
return Ok(())
}
}
let ani_coords = Coordinates { size: Size((xsize,ysize-i)),
position: Position position: Position
((xpos, ((xpos,
ypos+i)) ypos+i))
}; };
self.set_coordinates(&coords).log(); self.set_coordinates(&ani_coords).log();
let buffer = self.get_drawlist()?; let buffer = self.get_drawlist()?;
self.write_to_screen(&buffer).log(); self.write_to_screen(&buffer).log();
std::thread::sleep(pause); std::thread::sleep(pause);
} }
Ok(()) Ok(())
} }