diff options
author | Jiayi Zhao <jeff.no.zhao@gmail.com> | 2020-12-11 21:07:13 -0500 |
---|---|---|
committer | Jiayi Zhao <jeff.no.zhao@gmail.com> | 2020-12-11 21:07:13 -0500 |
commit | 916d72c42cfc7bcb8fc560e17cb3bd75c00757da (patch) | |
tree | a8024fc9bd9a48065cd6b65375109482ac9b7983 /src/ui/widgets | |
parent | bf9c102a4cfb85a9fd910195e6372dcd1d062c16 (diff) |
add a view for showing worker progress
Diffstat (limited to 'src/ui/widgets')
-rw-r--r-- | src/ui/widgets/mod.rs | 8 | ||||
-rw-r--r-- | src/ui/widgets/tui_dirlist_detailed.rs | 2 | ||||
-rw-r--r-- | src/ui/widgets/tui_folder_view.rs | 133 | ||||
-rw-r--r-- | src/ui/widgets/tui_menu.rs | 4 | ||||
-rw-r--r-- | src/ui/widgets/tui_progress_view.rs | 130 | ||||
-rw-r--r-- | src/ui/widgets/tui_prompt.rs | 5 | ||||
-rw-r--r-- | src/ui/widgets/tui_textfield.rs | 19 | ||||
-rw-r--r-- | src/ui/widgets/tui_view.rs | 28 | ||||
-rw-r--r-- | src/ui/widgets/tui_worker.rs | 94 | ||||
-rw-r--r-- | src/ui/widgets/tui_worker_view.rs | 79 |
10 files changed, 114 insertions, 388 deletions
diff --git a/src/ui/widgets/mod.rs b/src/ui/widgets/mod.rs index fe756a3..b09b4df 100644 --- a/src/ui/widgets/mod.rs +++ b/src/ui/widgets/mod.rs @@ -1,23 +1,19 @@ mod tui_dirlist; mod tui_dirlist_detailed; -mod tui_folder_view; mod tui_footer; mod tui_menu; mod tui_prompt; mod tui_tab; mod tui_textfield; mod tui_topbar; -mod tui_view; -mod tui_worker_view; +mod tui_worker; pub use self::tui_dirlist::TuiDirList; pub use self::tui_dirlist_detailed::TuiDirListDetailed; -pub use self::tui_folder_view::TuiFolderView; pub use self::tui_footer::TuiFooter; pub use self::tui_menu::{TuiCommandMenu, TuiMenu}; pub use self::tui_prompt::TuiPrompt; pub use self::tui_tab::TuiTabBar; pub use self::tui_textfield::TuiTextField; pub use self::tui_topbar::TuiTopBar; -pub use self::tui_view::TuiView; -pub use self::tui_worker_view::TuiWorkerView; +pub use self::tui_worker::TuiWorker; diff --git a/src/ui/widgets/tui_dirlist_detailed.rs b/src/ui/widgets/tui_dirlist_detailed.rs index c76e198..70330c9 100644 --- a/src/ui/widgets/tui_dirlist_detailed.rs +++ b/src/ui/widgets/tui_dirlist_detailed.rs @@ -66,7 +66,7 @@ impl<'a> Widget for TuiDirListDetailed<'a> { buf.set_string(x + area_width as u16 - 1, y + i as u16, "…", style); } } - FileType::Symlink(p) => { + FileType::Symlink(_) => { if name_width < area_width - 4 { buf.set_string(x, y + i as u16, name, style); buf.set_string(x + area_width as u16 - 4, y + i as u16, "->", style); diff --git a/src/ui/widgets/tui_folder_view.rs b/src/ui/widgets/tui_folder_view.rs deleted file mode 100644 index 01dcf2b..0000000 --- a/src/ui/widgets/tui_folder_view.rs +++ /dev/null @@ -1,133 +0,0 @@ -use tui::buffer::Buffer; -use tui::layout::{Direction, Layout, Rect}; -use tui::style::{Color, Style}; -use tui::text::Span; -use tui::widgets::{Paragraph, Widget, Wrap}; - -use super::{TuiDirList, TuiDirListDetailed, TuiFooter, TuiTabBar, TuiTopBar}; -use crate::context::JoshutoContext; - -const TAB_VIEW_WIDTH: u16 = 15; - -pub struct TuiFolderView<'a> { - pub context: &'a JoshutoContext, - pub show_bottom_status: bool, -} - -use super::super::{DEFAULT_LAYOUT, NO_PREVIEW_LAYOUT}; - -impl<'a> TuiFolderView<'a> { - pub fn new(context: &'a JoshutoContext) -> Self { - Self { - context, - show_bottom_status: true, - } - } -} - -impl<'a> Widget for TuiFolderView<'a> { - fn render(self, area: Rect, buf: &mut Buffer) { - let f_size = area; - - let curr_tab = self.context.tab_context_ref().curr_tab_ref(); - - let curr_list = curr_tab.curr_list_ref(); - let parent_list = curr_tab.parent_list_ref(); - let child_list = curr_tab.child_list_ref(); - - let constraints = match child_list { - Some(_) => DEFAULT_LAYOUT, - None => NO_PREVIEW_LAYOUT, - }; - let layout_rect = Layout::default() - .direction(Direction::Horizontal) - .margin(1) - .constraints(constraints.as_ref()) - .split(f_size); - - // render tabs - if self.context.tab_context_ref().len() > 1 { - let topbar_width = if f_size.width > TAB_VIEW_WIDTH { - f_size.width - TAB_VIEW_WIDTH - } else { - 0 - }; - - let rect = Rect { - x: 0, - y: 0, - width: topbar_width, - height: 1, - }; - TuiTopBar::new(curr_tab.pwd()).render(rect, buf); - - let rect = Rect { - x: topbar_width, - y: 0, - width: TAB_VIEW_WIDTH, - height: 1, - }; - let name = if let Some(ostr) = curr_tab.pwd().file_name() { - ostr.to_str().unwrap_or("") - } else { - "" - }; - TuiTabBar::new( - name, - self.context.tab_context_ref().get_index(), - self.context.tab_context_ref().len(), - ) - .render(rect, buf); - } else { - let topbar_width = f_size.width; - - let rect = Rect { - x: 0, - y: 0, - width: topbar_width, - height: 1, - }; - TuiTopBar::new(curr_tab.pwd()).render(rect, buf); - } - - // render parent view - if let Some(list) = parent_list.as_ref() { - TuiDirList::new(&list).render(layout_rect[0], buf); - }; - - // render current view - if let Some(list) = curr_list.as_ref() { - TuiDirListDetailed::new(&list).render(layout_rect[1], buf); - let rect = Rect { - x: 0, - y: f_size.height - 1, - width: f_size.width, - height: 1, - }; - - let message_style = Style::default().fg(Color::Yellow); - - if self.show_bottom_status { - /* draw the bottom status bar */ - if let Some(msg) = self.context.worker_msg() { - let text = Span::styled(msg, message_style); - Paragraph::new(text) - .wrap(Wrap { trim: true }) - .render(rect, buf); - } else if !self.context.message_queue_ref().is_empty() { - let text = Span::styled(&self.context.message_queue_ref()[0], message_style); - Paragraph::new(text) - .wrap(Wrap { trim: true }) - .render(rect, buf); - } else { - TuiFooter::new(list).render(rect, buf); - } - } - }; - - // render preview - if let Some(list) = child_list.as_ref() { - TuiDirList::new(&list).render(layout_rect[2], buf); - }; - } -} diff --git a/src/ui/widgets/tui_menu.rs b/src/ui/widgets/tui_menu.rs index 80a3d3a..f7c9080 100644 --- a/src/ui/widgets/tui_menu.rs +++ b/src/ui/widgets/tui_menu.rs @@ -6,10 +6,10 @@ use tui::layout::Rect; use tui::style::{Color, Style}; use tui::widgets::{Block, Borders, Clear, Widget}; -use super::TuiView; use crate::commands::{CommandKeybind, KeyCommand}; use crate::config::JoshutoCommandMapping; use crate::context::JoshutoContext; +use crate::ui::views::TuiView; use crate::ui::TuiBackend; use crate::util::event::Event; use crate::util::worker; @@ -63,7 +63,7 @@ impl TuiCommandMenu { context.flush_event(); loop { - terminal.draw(|frame| { + let _ = terminal.draw(|frame| { let f_size: Rect = frame.size(); { diff --git a/src/ui/widgets/tui_progress_view.rs b/src/ui/widgets/tui_progress_view.rs deleted file mode 100644 index 9dad78f..0000000 --- a/src/ui/widgets/tui_progress_view.rs +++ /dev/null @@ -1,130 +0,0 @@ -use tui::buffer::Buffer; -use tui::layout::{Direction, Layout, Rect}; -use tui::style::{Color, Style}; -use tui::widgets::{Paragraph, Text, Widget}; - -use super::{TuiDirList, TuiDirListDetailed, TuiFooter, TuiTabBar, TuiTopBar}; -use crate::context::JoshutoContext; - -const TAB_VIEW_WIDTH: u16 = 15; - -pub struct TuiProgressView<'a> { - pub context: &'a JoshutoContext, -} - -impl<'a> TuiProgressView<'a> { - pub fn new(context: &'a JoshutoContext) -> Self { - Self { - context, - show_bottom_status: true, - } - } -} - -impl<'a> Widget for TuiProgressView<'a> { - fn render(self, area: Rect, buf: &mut Buffer) { - let f_size = area; - - let layout_rect = Layout::default() - .direction(Direction::Horizontal) - .margin(1) - .split(f_size); - - let terminal = backend.terminal_mut(); - - loop { - terminal - .draw(|mut frame| { - }) - .unwrap(); - - if let Ok(event) = context.events.next() { - match event { - Event::IOWorkerProgress(_) => { - - } - Event::Input(key) => { - match key { - Key::Backspace => { - if line_buffer.backspace(1) { - completion_tracker.take(); - } - } - Key::Left => { - if line_buffer.move_backward(1) { - completion_tracker.take(); - } - } - Key::Right => { - if line_buffer.move_forward(1) { - completion_tracker.take(); - } - } - Key::Delete => { - if line_buffer.delete(1).is_some() { - completion_tracker.take(); - } - } - Key::Home => { - line_buffer.move_home(); - completion_tracker.take(); - } - Key::End => { - line_buffer.move_end(); - completion_tracker.take(); - } - Key::Up => {} - Key::Down => {} - Key::Esc => { - return None; - } - Key::Char('\t') => { - if completion_tracker.is_none() { - let res = completer - .complete_path(line_buffer.as_str(), line_buffer.pos()); - if let Ok((pos, mut candidates)) = res { - candidates.sort_by(|x, y| { - x.display() - .partial_cmp(y.display()) - .unwrap_or(std::cmp::Ordering::Less) - }); - let ct = CompletionTracker::new( - pos, - candidates, - String::from(line_buffer.as_str()), - ); - completion_tracker = Some(ct); - } - } - - if let Some(ref mut s) = completion_tracker { - if s.index < s.candidates.len() { - let candidate = &s.candidates[s.index]; - completer.update( - &mut line_buffer, - s.pos, - candidate.display(), - ); - s.index += 1; - } - } - } - Key::Char('\n') => { - break; - } - Key::Char(c) => { - if line_buffer.insert(c, 1).is_some() { - completion_tracker.take(); - } - } - _ => {} - } - context.events.flush(); - } - _ => {} - }; - } - } - - } -} diff --git a/src/ui/widgets/tui_prompt.rs b/src/ui/widgets/tui_prompt.rs index ea6aa49..f520de9 100644 --- a/src/ui/widgets/tui_prompt.rs +++ b/src/ui/widgets/tui_prompt.rs @@ -5,12 +5,11 @@ use tui::text::Span; use tui::widgets::{Clear, Paragraph, Wrap}; use crate::context::JoshutoContext; +use crate::ui::views::TuiView; use crate::ui::TuiBackend; use crate::util::event::Event; use crate::util::worker; -use super::TuiView; - pub struct TuiPrompt<'a> { prompt: &'a str, } @@ -25,7 +24,7 @@ impl<'a> TuiPrompt<'a> { context.flush_event(); loop { - terminal.draw(|frame| { + let _ = terminal.draw(|frame| { let f_size: Rect = frame.size(); if f_size.height == 0 { return; diff --git a/src/ui/widgets/tui_textfield.rs b/src/ui/widgets/tui_textfield.rs index 0e413fc..07f38b8 100644 --- a/src/ui/widgets/tui_textfield.rs +++ b/src/ui/widgets/tui_textfield.rs @@ -8,12 +8,12 @@ use tui::text::{Span, Spans}; use tui::widgets::{Clear, Paragraph, Wrap}; use crate::context::JoshutoContext; +use crate::ui::views::TuiView; +use crate::ui::widgets::TuiMenu; use crate::ui::TuiBackend; use crate::util::event::Event; use crate::util::worker; -use super::{TuiMenu, TuiView}; - struct CompletionTracker { pub index: usize, pub pos: usize, @@ -40,6 +40,15 @@ pub struct TuiTextField<'a> { } impl<'a> TuiTextField<'a> { + pub fn new() -> Self { + Self { + _prompt: "", + _prefix: "", + _suffix: "", + _menu_items: None, + } + } + pub fn menu_items<I>(&mut self, items: I) -> &mut Self where I: Iterator<Item = &'a str>, @@ -90,7 +99,6 @@ impl<'a> TuiTextField<'a> { if f_size.height == 0 { return; } - { let mut view = TuiView::new(&context); view.show_bottom_status = false; @@ -98,7 +106,8 @@ impl<'a> TuiTextField<'a> { } if let Some(items) = self._menu_items.as_ref() { - let menu_len = items.len(); + let menu_widget = TuiMenu::new(items); + let menu_len = menu_widget.len(); let menu_y = if menu_len + 2 > f_size.height as usize { 0 } else { @@ -111,13 +120,11 @@ impl<'a> TuiTextField<'a> { width: f_size.width, height: menu_len as u16 + 1, }; - let menu_widget = TuiMenu::new(items); frame.render_widget(Clear, menu_rect); frame.render_widget(menu_widget, menu_rect); } let cursor_xpos = line_buffer.pos(); - let prefix = &line_buffer.as_str()[..cursor_xpos]; let curr = line_buffer.as_str()[cursor_xpos..].chars().next(); diff --git a/src/ui/widgets/tui_view.rs b/src/ui/widgets/tui_view.rs deleted file mode 100644 index f86eaec..0000000 --- a/src/ui/widgets/tui_view.rs +++ /dev/null @@ -1,28 +0,0 @@ -use tui::buffer::Buffer; -use tui::layout::Rect; -use tui::widgets::Widget; - -use super::TuiFolderView; -use crate::context::JoshutoContext; - -const TAB_VIEW_WIDTH: u16 = 15; - -pub struct TuiView<'a> { - pub context: &'a JoshutoContext, - pub show_bottom_status: bool, -} - -impl<'a> TuiView<'a> { - pub fn new(context: &'a JoshutoContext) -> Self { - Self { - context, - show_bottom_status: true, - } - } -} - -impl<'a> Widget for TuiView<'a> { - fn render(self, area: Rect, buf: &mut Buffer) { - TuiFolderView::new(self.context).render(area, buf); - } -} diff --git a/src/ui/widgets/tui_worker.rs b/src/ui/widgets/tui_worker.rs new file mode 100644 index 0000000..8707e5d --- /dev/null +++ b/src/ui/widgets/tui_worker.rs @@ -0,0 +1,94 @@ +use tui::buffer::Buffer; +use tui::layout::Rect; +use tui::style::{Color, Modifier, Style}; +use tui::text::Span; +use tui::widgets::{Paragraph, Widget, Wrap}; + +use crate::context::JoshutoContext; +use crate::io::FileOp; +use crate::ui::widgets::TuiTopBar; + +pub struct TuiWorker<'a> { + pub context: &'a JoshutoContext, +} + +impl<'a> TuiWorker<'a> { + pub fn new(context: &'a JoshutoContext) -> Self { + Self { context } + } +} + +impl<'a> Widget for TuiWorker<'a> { + fn render(self, area: Rect, buf: &mut Buffer) { + let f_size = area; + + let topbar_width = f_size.width; + + let curr_tab = self.context.tab_context_ref().curr_tab_ref(); + let rect = Rect { + x: 0, + y: 0, + width: topbar_width, + height: 1, + }; + TuiTopBar::new(curr_tab.pwd()).render(rect, buf); + + match self.context.worker_ref() { + Some(io_obs) => match io_obs.progress.as_ref() { + Some(progress) => { + let msg = match progress.kind() { + FileOp::Copy => format!( + "Copying ({}/{}) {:?} -> {:?}", + progress.index() + 1, + progress.len(), + io_obs.src_path(), + io_obs.dest_path() + ), + FileOp::Cut => format!( + "Moving ({}/{}) {:?} -> {:?}", + progress.index() + 1, + progress.len(), + io_obs.src_path(), + io_obs.dest_path() + ), + }; + let style = Style::default(); + buf.set_stringn(0, 2, msg, area.width as usize, style); + let style = Style::default() + .fg(Color::Yellow) + .add_modifier(Modifier::BOLD); + buf.set_stringn(0, 4, "Queue:", area.width as usize, style); + let style = Style::default(); + for (i, worker) in self.context.worker_iter().enumerate() { + let msg = match worker.kind() { + FileOp::Copy => format!( + "{:02} Copy {} items {:?} -> {:?}", + i + 1, + worker.paths.len(), + worker.paths[0].parent().unwrap(), + worker.dest + ), + FileOp::Cut => format!( + "{:02} Moving {} items {:?} -> {:?}", + i + 1, + worker.paths.len(), + worker.paths[0].parent().unwrap(), + worker.dest + ), + }; + buf.set_stringn(0, (4 + i + 2) as u16, msg, area.width as usize, style); + } + } + _ => {} + }, + _ => { + let style = Style::default(); + buf.set_stringn(0, 2, "No operations running", area.width as usize, style); + let style = Style::default() + .fg(Color::Yellow) + .add_modifier(Modifier::BOLD); + buf.set_stringn(0, 4, "Queue:", area.width as usize, style); + } + } + } +} diff --git a/src/ui/widgets/tui_worker_view.rs b/src/ui/widgets/tui_worker_view.rs deleted file mode 100644 index d17f7c2..0000000 --- a/src/ui/widgets/tui_worker_view.rs +++ /dev/null @@ -1,79 +0,0 @@ -use tui::buffer::Buffer; -use tui::layout::{Direction, Layout, Rect}; -use tui::style::{Color, Style}; -use tui::text::Span; -use tui::widgets::{Paragraph, Widget, Wrap}; - -use super::{TuiDirList, TuiDirListDetailed, TuiFooter, TuiTabBar, TuiTopBar}; -use crate::context::JoshutoContext; - -const TAB_VIEW_WIDTH: u16 = 15; - -pub struct TuiWorkerView<'a> { - pub context: &'a JoshutoContext, - pub show_bottom_status: bool, -} - -use super::super::{DEFAULT_LAYOUT, NO_PREVIEW_LAYOUT}; - -impl<'a> TuiWorkerView<'a> { - pub fn new(context: &'a JoshutoContext) -> Self { - Self { - context, - show_bottom_status: true, - } - } -} - -impl<'a> Widget for TuiWorkerView<'a> { - fn render(self, area: Rect, buf: &mut Buffer) { - let f_size = area; - - let curr_tab = self.context.tab_context_ref().curr_tab_ref(); - let layout_rect = Layout::default().direction(Direction::Horizontal).margin(1); - - if self.context.tab_context_ref().len() > 1 { - let topbar_width = if f_size.width > TAB_VIEW_WIDTH { - f_size.width - TAB_VIEW_WIDTH - } else { - 0 - }; - - let rect = Rect { - x: 0, - y: 0, - width: topbar_width, - height: 1, - }; - TuiTopBar::new(curr_tab.pwd()).render(rect, buf); - - let rect = Rect { - x: topbar_width, - y: 0, - width: TAB_VIEW_WIDTH, - height: 1, - }; - let name = if let Some(ostr) = curr_tab.pwd().file_name() { - ostr.to_str().unwrap_or("") - } else { - "" - }; - TuiTabBar::new( - name, - self.context.tab_context_ref().get_index(), - self.context.tab_context_ref().len(), - ) - .render(rect, buf); - } else { - let topbar_width = f_size.width; - - let rect = Rect { - x: 0, - y: 0, - width: topbar_width, - height: 1, - }; - TuiTopBar::new(curr_tab.pwd()).render(rect, buf); - } - } -} |