diff options
author | Jeff Zhao <jeff.no.zhao@gmail.com> | 2022-09-05 17:00:01 -0400 |
---|---|---|
committer | Jeff Zhao <jeff.no.zhao@gmail.com> | 2022-09-05 17:00:01 -0400 |
commit | 35b36cfe5e2053a53656d3e1b4ba54a10d1a1618 (patch) | |
tree | 0a17e8f1960522c0cbb9e2c87b2a5009f1ef307e /src/ui | |
parent | e8a812d73cfb0c3e9a171dc9de3b43acc2f3a2f3 (diff) |
move border rendering out of folder view
Diffstat (limited to 'src/ui')
-rw-r--r-- | src/ui/views/tui_folder_view.rs | 200 |
1 files changed, 115 insertions, 85 deletions
diff --git a/src/ui/views/tui_folder_view.rs b/src/ui/views/tui_folder_view.rs index 10f16c7..260c8fa 100644 --- a/src/ui/views/tui_folder_view.rs +++ b/src/ui/views/tui_folder_view.rs @@ -15,6 +15,62 @@ use crate::ui::widgets::{ }; use crate::ui::PreviewArea; +struct TuiFolderViewBorders<'a> { + pub constraints: &'a [Constraint; 3], +} + +impl<'a> TuiFolderViewBorders<'a> { + pub fn new(constraints: &'a [Constraint; 3]) -> Self { + Self { constraints } + } +} + +impl<'a> Widget for TuiFolderViewBorders<'a> { + fn render(self, area: Rect, buf: &mut Buffer) { + let block = Block::default().borders(Borders::ALL); + let inner = block.inner(area); + block.render(area, buf); + + let layout_rect = Layout::default() + .direction(Direction::Horizontal) + .constraints(self.constraints.as_ref()) + .split(inner); + + // Won't render intersections if parent view is turned off + match self.constraints[0] { + Constraint::Ratio(0, _) => {} + _ => { + let block = Block::default().borders(Borders::RIGHT); + block.render(layout_rect[0], buf); + } + } + let block = Block::default().borders(Borders::LEFT); + block.render(layout_rect[2], buf); + + let top = area.top(); + let bottom = area.bottom() - 1; + let left = layout_rect[1].left() - 1; + let right = layout_rect[2].left(); + let intersections = Intersections { + top, + bottom, + left, + right, + }; + + // Won't render intersections if parent view is turned off + match self.constraints[0] { + Constraint::Ratio(0, _) => (), + _ => intersections.render_left(buf), + } + // Won't render intersections if child preview is unavailable + match self.constraints[2] { + Constraint::Ratio(0, _) => (), + _ => intersections.render_right(buf), + } + } +} + pub struct TuiFolderView<'a> { pub context: &'a AppContext, pub show_bottom_status: bool, @@ -27,10 +83,57 @@ impl<'a> TuiFolderView<'a> { show_bottom_status: true, } } + + pub fn folder_area(area: &Rect) -> Rect { + Rect { + y: area.top() + 1, + height: area.bottom() - 2, + ..area.clone() + } + } + + pub fn header_area(area: &Rect) -> Rect { + Rect { + x: area.left(), + y: area.top(), + width: area.width, + height: 1, + } + } + + pub fn footer_area(area: &Rect) -> Rect { + Rect { + x: area.x, + y: area.bottom() - 1, + width: area.width, + height: 1, + } + } + + pub fn tab_area(&self, area: &Rect, num_tabs: usize) -> Rect { + // render tabs + let tab_width = (num_tabs * 5) as u16; + let tab_width = if tab_width > area.width { + area.width + } else { + tab_width + }; + let topbar_x = area.width.saturating_sub(tab_width); + + Rect { + x: topbar_x, + y: area.top(), + width: tab_width, + height: 1, + } + } } impl<'a> Widget for TuiFolderView<'a> { fn render(self, area: Rect, buf: &mut Buffer) { + let config = self.context.config_ref(); + let display_options = config.display_options_ref(); + let preview_context = self.context.preview_context_ref(); let curr_tab = self.context.tab_context_ref().curr_tab_ref(); let curr_tab_cwd = curr_tab.cwd(); @@ -40,71 +143,22 @@ impl<'a> Widget for TuiFolderView<'a> { let curr_entry = curr_list.and_then(|c| c.curr_entry_ref()); - let config = self.context.config_ref(); - let display_options = config.display_options_ref(); - let constraints = get_constraints(self.context); - let is_default_layout = constraints == &display_options.default_layout; let layout_rect = if display_options.show_borders() { - let area = Rect { - y: area.top() + 1, - height: area.height - 2, - ..area - }; + let area = Self::folder_area(&area); + TuiFolderViewBorders::new(constraints).render(area, buf); let layout = calculate_layout_with_borders(area, constraints); - - let block = Block::default().borders(Borders::ALL); - let inner = block.inner(area); - block.render(area, buf); - - let layout_rect = Layout::default() - .direction(Direction::Horizontal) - .constraints(constraints.as_ref()) - .split(inner); - - let block = Block::default().borders(Borders::RIGHT); - block.render(layout_rect[0], buf); - - let block = Block::default().borders(Borders::LEFT); - block.render(layout_rect[2], buf); - - // Render inner borders properly. - { - let top = area.top(); - let bottom = area.bottom() - 1; - let left = layout_rect[1].left() - 1; - let right = layout_rect[2].left(); - let intersections = Intersections { - top, - bottom, - left, - right, - }; - - // Won't render intersections if parent view is turned off - match constraints[0] { - Constraint::Ratio(0, _) => (), - _ => intersections.render_left(buf), - } - if is_default_layout { - intersections.render_right(buf); - } - } layout } else { - let area = Rect { - y: area.top() + 1, - height: area.height - 2, - ..area - }; + let area = Self::folder_area(&area); calculate_layout(area, constraints) }; // render parent view match constraints[0] { - Constraint::Ratio(0, _) => (), + Constraint::Ratio(0, _) => {} _ => { if let Some(list) = curr_tab.parent_list_ref().as_ref() { TuiDirList::new(list, true).render(layout_rect[0], buf); @@ -115,13 +169,8 @@ impl<'a> Widget for TuiFolderView<'a> { // render current view if let Some(list) = curr_list.as_ref() { TuiDirListDetailed::new(list, display_options, true).render(layout_rect[1], buf); - let rect = Rect { - x: 0, - y: area.height - 1, - width: area.width, - height: 1, - }; + let footer_area = Self::footer_area(&area); if self.show_bottom_status { /* draw the bottom status bar */ if let Some(msg) = self.context.worker_context_ref().get_msg() { @@ -129,14 +178,14 @@ impl<'a> Widget for TuiFolderView<'a> { let text = Span::styled(msg, message_style); Paragraph::new(text) .wrap(Wrap { trim: true }) - .render(rect, buf); + .render(footer_area, buf); } else if let Some(msg) = self.context.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); + .render(footer_area, buf); } else { - TuiFooter::new(list).render(rect, buf); + TuiFooter::new(list).render(footer_area, buf); } } } else { @@ -186,35 +235,16 @@ impl<'a> Widget for TuiFolderView<'a> { .render(layout_rect[2], buf); } - let topbar_width = area.width; - let rect = Rect { - x: 0, - y: 0, - width: topbar_width, - height: 1, - }; - TuiTopBar::new(self.context, curr_tab_cwd).render(rect, buf); + let topbar_area = Self::header_area(&area); + TuiTopBar::new(self.context, curr_tab_cwd).render(topbar_area, buf); // render tabs - let topbar_width = (self.context.tab_context_ref().len() * 5) as u16; - let topbar_width = if topbar_width > area.width { - area.width - } else { - topbar_width - }; - let topbar_x = area.width.saturating_sub(topbar_width); - - let rect = Rect { - x: topbar_x, - y: 0, - width: topbar_width, - height: 1, - }; + let tab_area = self.tab_area(&area, self.context.tab_context_ref().len()); TuiTabBar::new( self.context.tab_context_ref().tab_order.as_slice(), self.context.tab_context_ref().index, ) - .render(rect, buf); + .render(tab_area, buf); } } |