diff options
author | DLFW <daniel@llin.info> | 2021-12-21 01:44:29 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-12-20 19:44:29 -0500 |
commit | 1d9986a2b3d3f849ac0288fb7135d3e938d72cf5 (patch) | |
tree | eacbeda78933f31cc3401c87d491b0751e0cc6c6 /src/ui | |
parent | 51c567a620e64ed1876df87d7837ba66a4c3e27f (diff) |
Add script hooks for image previews (#113)
This adds two configuration options, `preview_shown_hook_script`
and `preview_removed_hook_script` in the preview-section where the
user can configure external scripts which are called when a file preview
is shown or when the file preview widget disappears, respectively.
The `preview_shown_hook_script` gets the path of the file being previwed
as first argument and then the x and y coordinate and the width an
height of the preview area as second to fifth parameters.
To get the geometry information back from the UI rendering process, a
new struct `RenderResult` has been introduced which is given as mutable
reference to the rendering function.
The main-loop then checks for a changed preview and calls the hook
scripts.
Additionally, documentation has been added how these hooks can be used
to implement image previews.
Diffstat (limited to 'src/ui')
-rw-r--r-- | src/ui/mod.rs | 24 | ||||
-rw-r--r-- | src/ui/views/tui_command_menu.rs | 4 | ||||
-rw-r--r-- | src/ui/views/tui_folder_view.rs | 22 | ||||
-rw-r--r-- | src/ui/views/tui_textfield.rs | 4 | ||||
-rw-r--r-- | src/ui/views/tui_view.rs | 7 | ||||
-rw-r--r-- | src/ui/widgets/tui_prompt.rs | 4 |
6 files changed, 58 insertions, 7 deletions
diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 16ebd19..b782b1f 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -1,5 +1,29 @@ +use std::path; + mod tui_backend; pub mod views; pub mod widgets; pub use tui_backend::*; + +#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)] +pub struct Rect { + pub x: u16, + pub y: u16, + pub width: u16, + pub height: u16, +} + +pub struct RenderResult { + pub file_preview_path: Option<path::PathBuf>, + pub preview_area: Option<Rect>, +} + +impl RenderResult { + pub fn new() -> RenderResult { + RenderResult { + file_preview_path: None, + preview_area: None, + } + } +} diff --git a/src/ui/views/tui_command_menu.rs b/src/ui/views/tui_command_menu.rs index bc94752..d62fa09 100644 --- a/src/ui/views/tui_command_menu.rs +++ b/src/ui/views/tui_command_menu.rs @@ -8,6 +8,7 @@ use crate::config::AppKeyMapping; use crate::context::AppContext; use crate::ui::views::TuiView; use crate::ui::widgets::TuiMenu; +use crate::ui::RenderResult; use crate::util::to_string::ToString; const BORDER_HEIGHT: usize = 1; @@ -26,7 +27,8 @@ impl<'a> TuiCommandMenu<'a> { impl<'a> Widget for TuiCommandMenu<'a> { fn render(self, area: Rect, buf: &mut Buffer) { - TuiView::new(self.context).render(area, buf); + let mut render_result = RenderResult::new(); + TuiView::new(self.context, &mut render_result).render(area, buf); // draw menu let mut display_vec: Vec<String> = self diff --git a/src/ui/views/tui_folder_view.rs b/src/ui/views/tui_folder_view.rs index de3c8a0..1a07ce0 100644 --- a/src/ui/views/tui_folder_view.rs +++ b/src/ui/views/tui_folder_view.rs @@ -1,3 +1,5 @@ +use std::path; + use tui::buffer::Buffer; use tui::layout::{Constraint, Direction, Layout, Rect}; use tui::style::{Color, Style}; @@ -6,22 +8,26 @@ use tui::text::Span; use tui::widgets::{Block, Borders, Paragraph, Widget, Wrap}; use crate::context::AppContext; +use crate::ui; use crate::ui::widgets::{ TuiDirList, TuiDirListDetailed, TuiFilePreview, TuiFooter, TuiTabBar, TuiTopBar, }; +use crate::ui::RenderResult; const TAB_VIEW_WIDTH: u16 = 15; pub struct TuiFolderView<'a> { pub context: &'a AppContext, pub show_bottom_status: bool, + pub render_result: &'a mut RenderResult, } impl<'a> TuiFolderView<'a> { - pub fn new(context: &'a AppContext) -> Self { + pub fn new(context: &'a AppContext, render_result: &'a mut RenderResult) -> Self { Self { context, show_bottom_status: true, + render_result, } } } @@ -163,6 +169,8 @@ impl<'a> Widget for TuiFolderView<'a> { } // render preview + let mut file_preview_path: Option<path::PathBuf> = None; + let mut preview_area: Option<ui::Rect> = None; if let Some(list) = child_list.as_ref() { TuiDirList::new(list).render(layout_rect[2], buf); } else if let Some(entry) = curr_entry { @@ -170,11 +178,21 @@ impl<'a> Widget for TuiFolderView<'a> { match preview.status.code() { Some(1) | None => {} _ => { - TuiFilePreview::new(entry, preview).render(layout_rect[2], buf); + let rect = layout_rect[2]; + TuiFilePreview::new(entry, preview).render(rect, buf); + file_preview_path = Some(entry.file_path_buf()); + preview_area = Some(ui::Rect { + x: rect.x, + y: rect.y, + width: rect.width, + height: rect.height, + }) } } } } + self.render_result.file_preview_path = file_preview_path; + self.render_result.preview_area = preview_area; let topbar_width = area.width; let rect = Rect { diff --git a/src/ui/views/tui_textfield.rs b/src/ui/views/tui_textfield.rs index d829852..b9426db 100644 --- a/src/ui/views/tui_textfield.rs +++ b/src/ui/views/tui_textfield.rs @@ -10,6 +10,7 @@ use crate::context::AppContext; use crate::event::AppEvent; use crate::ui::views::TuiView; use crate::ui::widgets::{TuiMenu, TuiMultilineText}; +use crate::ui::RenderResult; use crate::ui::TuiBackend; use crate::util::input; @@ -96,7 +97,8 @@ impl<'a> TuiTextField<'a> { return; } { - let mut view = TuiView::new(context); + let mut render_result = RenderResult::new(); + let mut view = TuiView::new(context, &mut render_result); view.show_bottom_status = false; frame.render_widget(view, area); } diff --git a/src/ui/views/tui_view.rs b/src/ui/views/tui_view.rs index 2178475..a5f093c 100644 --- a/src/ui/views/tui_view.rs +++ b/src/ui/views/tui_view.rs @@ -4,23 +4,26 @@ use tui::widgets::Widget; use super::TuiFolderView; use crate::context::AppContext; +use crate::ui::RenderResult; pub struct TuiView<'a> { pub context: &'a AppContext, pub show_bottom_status: bool, + pub render_result: &'a mut RenderResult, } impl<'a> TuiView<'a> { - pub fn new(context: &'a AppContext) -> Self { + pub fn new(context: &'a AppContext, render_result: &'a mut RenderResult) -> Self { Self { context, show_bottom_status: true, + render_result, } } } impl<'a> Widget for TuiView<'a> { fn render(self, area: Rect, buf: &mut Buffer) { - TuiFolderView::new(self.context).render(area, buf); + TuiFolderView::new(self.context, self.render_result).render(area, buf); } } diff --git a/src/ui/widgets/tui_prompt.rs b/src/ui/widgets/tui_prompt.rs index bc1b210..f1bd0d4 100644 --- a/src/ui/widgets/tui_prompt.rs +++ b/src/ui/widgets/tui_prompt.rs @@ -7,6 +7,7 @@ use tui::widgets::{Clear, Paragraph, Wrap}; use crate::context::AppContext; use crate::event::AppEvent; use crate::ui::views::TuiView; +use crate::ui::RenderResult; use crate::ui::TuiBackend; use crate::util::input; @@ -31,7 +32,8 @@ impl<'a> TuiPrompt<'a> { } { - let mut view = TuiView::new(context); + let mut render_result = RenderResult::new(); + let mut view = TuiView::new(context, &mut render_result); view.show_bottom_status = false; frame.render_widget(view, f_size); } |