From 3f449c3d85cf33df7af5464dd17678a666f8fcd5 Mon Sep 17 00:00:00 2001 From: Philipp Moers Date: Sat, 26 Oct 2024 22:39:58 +0200 Subject: [PATCH] Add minimal view mode --- config/joshuto.toml | 2 +- src/types/option/display.rs | 2 + src/ui/views/mod.rs | 1 + src/ui/views/tui_minimal_view.rs | 108 +++++++++++++++++++++++++++++++ src/ui/views/tui_view.rs | 5 +- 5 files changed, 116 insertions(+), 2 deletions(-) create mode 100644 src/ui/views/tui_minimal_view.rs diff --git a/config/joshuto.toml b/config/joshuto.toml index 26ecb3df4..f9abde7b1 100644 --- a/config/joshuto.toml +++ b/config/joshuto.toml @@ -12,7 +12,7 @@ zoxide_update = false custom_commands = [] [display] -# default, hsplit +# default, minimal, hsplit mode = "default" automatically_count_files = false diff --git a/src/types/option/display.rs b/src/types/option/display.rs index b05ee61bd..8b8dacadc 100644 --- a/src/types/option/display.rs +++ b/src/types/option/display.rs @@ -11,6 +11,7 @@ use super::line_mode::LineNumberStyle; #[derive(Clone, Copy, Debug)] pub enum DisplayMode { Default, + Minimal, HSplit, } @@ -38,6 +39,7 @@ impl From for DisplayOption { fn from(raw: DisplayOptionRaw) -> Self { let mode = match raw.mode.as_str() { "hsplit" => DisplayMode::HSplit, + "minimal" => DisplayMode::Minimal, _ => DisplayMode::Default, }; diff --git a/src/ui/views/mod.rs b/src/ui/views/mod.rs index 7eac32550..2fab3e9b7 100644 --- a/src/ui/views/mod.rs +++ b/src/ui/views/mod.rs @@ -1,6 +1,7 @@ mod tui_command_menu; mod tui_folder_view; mod tui_hsplit_view; +mod tui_minimal_view; mod tui_textfield; mod tui_view; mod tui_worker_view; diff --git a/src/ui/views/tui_minimal_view.rs b/src/ui/views/tui_minimal_view.rs new file mode 100644 index 000000000..499a24db2 --- /dev/null +++ b/src/ui/views/tui_minimal_view.rs @@ -0,0 +1,108 @@ +use ratatui::buffer::Buffer; +use ratatui::layout::{Constraint, Direction, Layout, Rect}; +use ratatui::style::{Color, Style}; +use ratatui::text::Span; +use ratatui::widgets::{Paragraph, Widget, Wrap}; + +use crate::types::state::AppState; +use crate::ui::widgets::{TuiDirListDetailed, TuiFooter, TuiTopBar}; + +pub struct TuiMinimalView<'a> { + pub app_state: &'a AppState, + pub show_bottom_status: bool, +} + +impl<'a> TuiMinimalView<'a> { + pub fn new(app_state: &'a AppState) -> Self { + Self { + app_state, + show_bottom_status: true, + } + } +} + +impl<'a> Widget for TuiMinimalView<'a> { + fn render(self, area: Rect, buf: &mut Buffer) { + let tab_state = self.app_state.state.tab_state_ref(); + + let display_options = &self.app_state.config.display_options; + let constraints = &[Constraint::Ratio(1, 1)]; + + let layout_rect = { + let area = Rect { + y: area.top() + 1, + height: area.height - 2, + ..area + }; + calculate_layout(area, constraints) + }; + + let tab_id = tab_state.curr_tab_id(); + if let Some(curr_tab) = tab_state.tab_ref(&tab_id) { + let curr_list = curr_tab.curr_list_ref(); + + let layout_rect = layout_rect[0]; + + // render current view + if let Some(list) = curr_list.as_ref() { + TuiDirListDetailed::new( + &self.app_state.config, + list, + display_options, + curr_tab.option_ref(), + true, + ) + .render(layout_rect, buf); + let rect = Rect { + x: 0, + y: area.height - 1, + width: area.width, + height: 1, + }; + + if self.show_bottom_status { + /* draw the bottom status bar */ + if let Some(msg) = self.app_state.state.worker_state_ref().get_msg() { + let message_style = Style::default().fg(Color::Yellow); + let text = Span::styled(msg, message_style); + Paragraph::new(text) + .wrap(Wrap { trim: true }) + .render(rect, buf); + } else if let Some(msg) = + self.app_state.state.message_queue_ref().current_message() + { + let text = Span::styled(msg.content.as_str(), msg.style); + Paragraph::new(text) + .wrap(Wrap { trim: true }) + .render(rect, buf); + } else { + TuiFooter::new(list, curr_tab.option_ref()).render(rect, buf); + } + } + } + + let topbar_width = area.width; + let rect = Rect { + x: 0, + y: 0, + width: topbar_width, + height: 1, + }; + TuiTopBar::new(self.app_state).render(rect, buf); + } + } +} + +fn calculate_layout(area: Rect, constraints: &[Constraint; 1]) -> Vec { + let mut layout_rect = Layout::default() + .direction(Direction::Horizontal) + .constraints(constraints.as_ref()) + .split(area) + .to_vec(); + + layout_rect[0] = Rect { + width: layout_rect[0].width - 1, + ..layout_rect[0] + }; + layout_rect +} diff --git a/src/ui/views/tui_view.rs b/src/ui/views/tui_view.rs index 5e0e91323..52c6a2027 100644 --- a/src/ui/views/tui_view.rs +++ b/src/ui/views/tui_view.rs @@ -4,7 +4,7 @@ use ratatui::widgets::Widget; use crate::types::option::display::DisplayMode; use crate::types::state::AppState; -use crate::ui::views::{TuiFolderView, TuiHSplitView}; +use crate::ui::views::{tui_minimal_view::TuiMinimalView, TuiFolderView, TuiHSplitView}; pub struct TuiView<'a> { pub app_state: &'a AppState, @@ -27,6 +27,9 @@ impl<'a> Widget for TuiView<'a> { DisplayMode::Default => { TuiFolderView::new(self.app_state).render(area, buf); } + DisplayMode::Minimal => { + TuiMinimalView::new(self.app_state).render(area, buf); + } DisplayMode::HSplit => { TuiHSplitView::new(self.app_state).render(area, buf); }