summaryrefslogtreecommitdiffstats
path: root/src/ui
diff options
context:
space:
mode:
authorJiayi Zhao <jeff.no.zhao@gmail.com>2020-02-22 12:59:13 -0500
committerJiayi Zhao <jeff.no.zhao@gmail.com>2020-02-22 13:32:02 -0500
commit03594099dafb4cda04e50f087df61cf76e2034d0 (patch)
tree724d31c9b1d31d122d1862141fdc9391891821e4 /src/ui
parentb3ed647b033c079a614e7a9ff5bb88da14dd99b4 (diff)
move the majority of rendering into its own widget: TuiView
- textfield is now a widget as well - reduced code duplication with TuiView - add backtab support - add a message queue for notifications
Diffstat (limited to 'src/ui')
-rw-r--r--src/ui/tui_backend.rs79
-rw-r--r--src/ui/widgets/mod.rs6
-rw-r--r--src/ui/widgets/tui_dirlist.rs36
-rw-r--r--src/ui/widgets/tui_dirlist_detailed.rs48
-rw-r--r--src/ui/widgets/tui_footer.rs10
-rw-r--r--src/ui/widgets/tui_menu.rs146
-rw-r--r--src/ui/widgets/tui_textfield.rs86
-rw-r--r--src/ui/widgets/tui_topbar.rs4
-rw-r--r--src/ui/widgets/tui_view.rs74
9 files changed, 266 insertions, 223 deletions
diff --git a/src/ui/tui_backend.rs b/src/ui/tui_backend.rs
index 4c64497..446d1c0 100644
--- a/src/ui/tui_backend.rs
+++ b/src/ui/tui_backend.rs
@@ -1,22 +1,12 @@
-use std::io::Write;
-
-use tui::buffer::Buffer;
use termion::raw::{IntoRawMode, RawTerminal};
use termion::screen::AlternateScreen;
use tui::backend::TermionBackend;
-use tui::layout::{Constraint, Direction, Layout, Rect};
use tui::widgets::Widget;
-use unicode_width::UnicodeWidthStr;
-
-use super::widgets::{TuiDirList, TuiDirListDetailed, TuiFooter, TuiTopBar};
-use crate::context::JoshutoContext;
pub struct TuiBackend {
pub terminal: tui::Terminal<TermionBackend<AlternateScreen<RawTerminal<std::io::Stdout>>>>,
}
-use super::{DEFAULT_LAYOUT, NO_PREVIEW_LAYOUT};
-
impl TuiBackend {
pub fn new() -> std::io::Result<Self> {
let stdout = std::io::stdout().into_raw_mode()?;
@@ -27,70 +17,13 @@ impl TuiBackend {
Ok(Self { terminal })
}
- pub fn render(&mut self, context: &JoshutoContext) {
- let curr_tab = context.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 f_size = {
- let frame = self.terminal.get_frame();
- frame.size()
- };
-
+ pub fn render<W>(&mut self, widget: &mut W)
+ where
+ W: Widget,
+ {
self.terminal.draw(|mut frame| {
- let f_size = frame.size();
-
- {
- let top_rect = Rect {
- x: 0,
- y: 0,
- width: f_size.width,
- height: 1,
- };
-
- TuiTopBar::new(curr_tab.curr_path.as_path())
- .render(&mut frame, top_rect);
- }
-
- 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);
-
- if let Some(curr_list) = parent_list.as_ref() {
- TuiDirList::new(&curr_list).render(&mut frame, layout_rect[0]);
- };
-
- if let Some(curr_list) = curr_list.as_ref() {
- TuiDirListDetailed::new(&curr_list).render(&mut frame, layout_rect[1]);
- if let Some(entry) = curr_list.get_curr_ref() {
- let top_rect = Rect {
- x: 0,
- y: f_size.height - 1,
- width: f_size.width,
- height: 1,
- };
- TuiFooter::new(entry)
- .render(&mut frame, top_rect);
- }
- };
-
- if let Some(curr_list) = child_list.as_ref() {
- TuiDirList::new(&curr_list).render(&mut frame, layout_rect[2]);
- };
+ let rect = frame.size();
+ widget.render(&mut frame, rect);
});
}
}
-
-impl Widget for TuiBackend {
- fn draw(&mut self, area: Rect, buf: &mut Buffer) {
-
- }
-}
diff --git a/src/ui/widgets/mod.rs b/src/ui/widgets/mod.rs
index d80d4ca..e36c904 100644
--- a/src/ui/widgets/mod.rs
+++ b/src/ui/widgets/mod.rs
@@ -2,10 +2,14 @@ pub mod tui_dirlist;
pub mod tui_dirlist_detailed;
pub mod tui_footer;
pub mod tui_menu;
+pub mod tui_textfield;
pub mod tui_topbar;
+pub mod tui_view;
pub use self::tui_dirlist::TuiDirList;
pub use self::tui_dirlist_detailed::TuiDirListDetailed;
pub use self::tui_footer::TuiFooter;
-pub use self::tui_menu::TuiCommandMenu;
+pub use self::tui_menu::{TuiCommandMenu, TuiMenu};
+pub use self::tui_textfield::TuiTextField;
pub use self::tui_topbar::TuiTopBar;
+pub use self::tui_view::TuiView;
diff --git a/src/ui/widgets/tui_dirlist.rs b/src/ui/widgets/tui_dirlist.rs
index 77684c7..4992fab 100644
--- a/src/ui/widgets/tui_dirlist.rs
+++ b/src/ui/widgets/tui_dirlist.rs
@@ -3,10 +3,8 @@ use tui::layout::Rect;
use tui::style::{Color, Modifier, Style};
use tui::widgets::Widget;
use unicode_width::UnicodeWidthStr;
-use unicode_width::UnicodeWidthChar;
use crate::fs::JoshutoDirList;
-use crate::util::format;
pub struct TuiDirList<'a> {
dirlist: &'a JoshutoDirList,
@@ -67,40 +65,32 @@ impl<'a> Widget for TuiDirList<'a> {
let file_type = entry.metadata.file_type;
if file_type.is_dir() {
if name_width <= area_width {
- buf.set_stringn(x, y + i as u16,
- name,
- area_width, style);
+ buf.set_stringn(x, y + i as u16, name, area_width, style);
} else {
- buf.set_stringn(x, y + i as u16,
- name,
- area_width - 1, style);
- buf.set_string(x + area_width as u16 - 1, y + i as u16,
- "…", style);
+ buf.set_stringn(x, y + i as u16, name, area_width - 1, style);
+ buf.set_string(x + area_width as u16 - 1, y + i as u16, "…", style);
}
continue;
}
if name_width < area_width {
- buf.set_stringn(x, y + i as u16,
- name,
- area_width, style);
+ buf.set_stringn(x, y + i as u16, name, area_width, style);
} else {
match name.rfind('.') {
None => {
- buf.set_stringn(x, y + i as u16,
- name,
- area_width, style);
+ buf.set_stringn(x, y + i as u16, name, area_width, style);
}
Some(p_ind) => {
let ext_width = name[p_ind..].width();
let file_name_width = area_width - ext_width - 1;
- buf.set_stringn(x, y + i as u16,
- &name[..p_ind],
- file_name_width, style);
- buf.set_string(x + file_name_width as u16, y + i as u16,
- "…", style);
- buf.set_string(x + file_name_width as u16 + 1, y + i as u16,
- &name[p_ind..], style);
+ buf.set_stringn(x, y + i as u16, &name[..p_ind], file_name_width, style);
+ buf.set_string(x + file_name_width as u16, y + i as u16, "…", style);
+ buf.set_string(
+ x + file_name_width as u16 + 1,
+ y + i as u16,
+ &name[p_ind..],
+ style,
+ );
}
}
}
diff --git a/src/ui/widgets/tui_dirlist_detailed.rs b/src/ui/widgets/tui_dirlist_detailed.rs
index 2e01a26..d0f9c12 100644
--- a/src/ui/widgets/tui_dirlist_detailed.rs
+++ b/src/ui/widgets/tui_dirlist_detailed.rs
@@ -2,8 +2,8 @@ use tui::buffer::Buffer;
use tui::layout::Rect;
use tui::style::{Color, Modifier, Style};
use tui::widgets::Widget;
-use unicode_width::UnicodeWidthStr;
use unicode_width::UnicodeWidthChar;
+use unicode_width::UnicodeWidthStr;
use crate::fs::JoshutoDirList;
use crate::util::format;
@@ -35,9 +35,7 @@ impl<'a> Widget for TuiDirListDetailed<'a> {
let dir_len = self.dirlist.contents.len();
if dir_len == 0 {
- let style = Style::default()
- .bg(Color::Red)
- .fg(Color::White);
+ let style = Style::default().bg(Color::Red).fg(Color::White);
buf.set_stringn(x, y, "empty", area.width as usize, style);
return;
}
@@ -71,47 +69,43 @@ impl<'a> Widget for TuiDirListDetailed<'a> {
let file_type = entry.metadata.file_type;
if file_type.is_dir() {
if name_width <= area_width {
- buf.set_stringn(x, y + i as u16,
- name,
- area_width, style);
+ buf.set_stringn(x, y + i as u16, name, area_width, style);
} else {
- buf.set_stringn(x, y + i as u16,
- name,
- area_width - 1, style);
- buf.set_string(x + area_width as u16 - 1, y + i as u16,
- "…", style);
+ buf.set_stringn(x, y + i as u16, name, area_width - 1, style);
+ buf.set_string(x + area_width as u16 - 1, y + i as u16, "…", style);
}
continue;
}
if name_width < area_width - FILE_SIZE_WIDTH {
- buf.set_stringn(x, y + i as u16,
- name,
- area_width - FILE_SIZE_WIDTH, style);
+ buf.set_stringn(x, y + i as u16, name, area_width - FILE_SIZE_WIDTH, style);
} else {
match name.rfind('.') {
None => {
- buf.set_stringn(x, y + i as u16,
- name,
- area_width - FILE_SIZE_WIDTH, style);
+ buf.set_stringn(x, y + i as u16, name, area_width - FILE_SIZE_WIDTH, style);
}
Some(p_ind) => {
let ext_width = name[p_ind..].width();
let file_name_width = area_width - FILE_SIZE_WIDTH - ext_width - 2;
- buf.set_stringn(x, y + i as u16,
- &name[..p_ind],
- file_name_width, style);
- buf.set_string(x + file_name_width as u16, y + i as u16,
- "…", style);
- buf.set_string(x + file_name_width as u16 + 1, y + i as u16,
- &name[p_ind..], style);
+ buf.set_stringn(x, y + i as u16, &name[..p_ind], file_name_width, style);
+ buf.set_string(x + file_name_width as u16, y + i as u16, "…", style);
+ buf.set_string(
+ x + file_name_width as u16 + 1,
+ y + i as u16,
+ &name[p_ind..],
+ style,
+ );
}
}
}
let file_size_string = format::file_size_to_string(entry.metadata.len as f64);
- buf.set_string(x + (area_width - FILE_SIZE_WIDTH) as u16, y + i as u16,
- file_size_string, style);
+ buf.set_string(
+ x + (area_width - FILE_SIZE_WIDTH) as u16,
+ y + i as u16,
+ file_size_string,
+ style,
+ );
}
}
}
diff --git a/src/ui/widgets/tui_footer.rs b/src/ui/widgets/tui_footer.rs
index ac34b98..8bc1b49 100644
--- a/src/ui/widgets/tui_footer.rs
+++ b/src/ui/widgets/tui_footer.rs
@@ -1,5 +1,4 @@
use std::fs;
-use std::path::Path;
use tui::buffer::Buffer;
use tui::layout::Rect;
@@ -9,8 +8,6 @@ use tui::widgets::{Paragraph, Text, Widget};
use crate::fs::JoshutoDirEntry;
use crate::util::format;
-use crate::{HOSTNAME, USERNAME};
-
pub struct TuiFooter<'a> {
entry: &'a JoshutoDirEntry,
}
@@ -28,8 +25,7 @@ impl<'a> Widget for TuiFooter<'a> {
let mode = self.entry.metadata.permissions.mode();
let mode = format::mode_to_string(mode);
- let mode_style = Style::default()
- .fg(Color::Cyan);
+ let mode_style = Style::default().fg(Color::Cyan);
let mtime = self.entry.metadata.modified;
let mtime = format::mtime_to_string(mtime);
@@ -54,8 +50,6 @@ impl<'a> Widget for TuiFooter<'a> {
}
}
- Paragraph::new(text.iter())
- .wrap(true)
- .draw(area, buf);
+ Paragraph::new(text.iter()).wrap(true).draw(area, buf);
}
}
diff --git a/src/ui/widgets/tui_menu.rs b/src/ui/widgets/tui_menu.rs
index 64100f4..9dde1fe 100644
--- a/src/ui/widgets/tui_menu.rs
+++ b/src/ui/widgets/tui_menu.rs
@@ -1,28 +1,18 @@
-use std::io::{self, Write};
use std::iter::Iterator;
-use tui::buffer::Buffer;
-use termion::clear;
-use termion::cursor::Goto;
use termion::event::Key;
-use termion::raw::IntoRawMode;
-use termion::screen::AlternateScreen;
-use tui::backend::TermionBackend;
-use tui::layout::{Constraint, Direction, Layout, Rect};
+use tui::buffer::Buffer;
+use tui::layout::Rect;
use tui::style::{Color, Style};
-use tui::widgets::{Block, Borders, List, Paragraph, Text, Widget};
-use tui::Terminal;
+use tui::widgets::{Block, Borders, Widget};
use unicode_width::UnicodeWidthStr;
-use crate::commands::{CommandKeybind, CursorMoveUp, JoshutoCommand, JoshutoRunnable};
+use super::TuiView;
+use crate::commands::{CommandKeybind, JoshutoCommand};
use crate::config::JoshutoCommandMapping;
use crate::context::JoshutoContext;
use crate::ui::TuiBackend;
-use crate::util::event::{Event, Events};
-use super::{TuiDirList, TuiDirListDetailed, TuiTopBar};
-
-use crate::{HOSTNAME, USERNAME};
-use super::super::{DEFAULT_LAYOUT, NO_PREVIEW_LAYOUT};
+use crate::util::event::Event;
const BORDER_HEIGHT: usize = 1;
const BOTTOM_MARGIN: usize = 1;
@@ -34,76 +24,43 @@ impl TuiCommandMenu {
Self {}
}
- pub fn get_input<'a>(&mut self, backend: &mut TuiBackend,
- context: &JoshutoContext, m: &'a JoshutoCommandMapping) ->
- Option<&'a Box<JoshutoCommand>> {
+ pub fn get_input<'a>(
+ &mut self,
+ backend: &mut TuiBackend,
+ context: &JoshutoContext,
+ m: &'a JoshutoCommandMapping,
+ ) -> Option<&'a Box<dyn JoshutoCommand>> {
let mut map: &JoshutoCommandMapping = &m;
- let events = &context.events;
-
- let curr_tab = context.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();
loop {
backend.terminal.draw(|mut frame| {
let f_size = frame.size();
{
- let top_rect = Rect {
- x: 0,
- y: 0,
- width: f_size.width,
- height: 1,
- };
-
- TuiTopBar::new(curr_tab.curr_path.as_path())
- .render(&mut frame, top_rect);
+ let mut view = TuiView::new(&context);
+ view.render(&mut frame, f_size);
}
- 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);
-
- if let Some(curr_list) = parent_list.as_ref() {
- TuiDirList::new(&curr_list).render(&mut frame, layout_rect[0]);
- };
-
- if let Some(curr_list) = curr_list.as_ref() {
- TuiDirListDetailed::new(&curr_list).render(&mut frame, layout_rect[1]);
- };
-
- if let Some(curr_list) = child_list.as_ref() {
- TuiDirList::new(&curr_list).render(&mut frame, layout_rect[2]);
- };
-
{
// draw menu
let mut display_vec: Vec<String> = map
.iter()
- .map(|(k, v)| {
- format!(" {:?} {}", k, v)
- })
+ .map(|(k, v)| format!(" {:?} {}", k, v))
.collect();
display_vec.sort();
- let display_str: Vec<&str> =
- display_vec.iter().map(|v| v.as_str()).collect();
+ let display_str: Vec<&str> = display_vec.iter().map(|v| v.as_str()).collect();
let display_str_len = display_str.len();
- let y = if (f_size.height as usize) < display_str_len + BORDER_HEIGHT + BOTTOM_MARGIN {
- 0
- } else {
- f_size.height - (BORDER_HEIGHT + BOTTOM_MARGIN) as u16
- - display_str_len as u16
- };
+ let y = if (f_size.height as usize)
+ < display_str_len + BORDER_HEIGHT + BOTTOM_MARGIN
+ {
+ 0
+ } else {
+ f_size.height
+ - (BORDER_HEIGHT + BOTTOM_MARGIN) as u16
+ - display_str_len as u16
+ };
let menu_rect = Rect {
x: 0,
@@ -115,27 +72,24 @@ impl TuiCommandMenu {
TuiMenu::new(&display_str).render(&mut frame, menu_rect);
}
});
- if let Ok(event) = events.next() {
+ if let Ok(event) = context.events.next() {
match event {
Event::Input(Key::Esc) => {
return None;
}
- Event::Input(key) => {
- match map.get(&key) {
- Some(CommandKeybind::SimpleKeybind(s)) => {
- return Some(s);
- }
- Some(CommandKeybind::CompositeKeybind(m)) => {
- map = m;
- }
- None => return None,
+ Event::Input(key) => match map.get(&key) {
+ Some(CommandKeybind::SimpleKeybind(s)) => {
+ return Some(s);
}
- }
- _ => {},
+ Some(CommandKeybind::CompositeKeybind(m)) => {
+ map = m;
+ }
+ None => return None,
+ },
+ _ => {}
}
}
}
-
}
}
@@ -149,14 +103,30 @@ impl<'a> TuiMenu<'a> {
}
}
+const LONG_SPACE: &str = " ";
+
impl<'a> Widget for TuiMenu<'a> {
fn draw(&mut self, area: Rect, buf: &mut Buffer) {
- let text_iter = self.options.iter().map(|s| Text::raw(*s));
- let block = Block::default()
- .borders(Borders::TOP);
-
- List::new(text_iter)
- .block(block)
- .draw(area, buf);
+ let text_iter = self.options.iter();
+ let mut block = Block::default().borders(Borders::TOP);
+
+ block.draw(area, buf);
+
+ let style = Style::default();
+
+ let area_x = area.x + 1;
+ let area_y = area.y + 1;
+
+ for (i, text) in text_iter.enumerate() {
+ let width = text.width();
+ buf.set_stringn(area_x, area_y + i as u16, text, width, style);
+ buf.set_stringn(
+ area_x + width as u16,
+ area_y + i as u16,
+ LONG_SPACE,
+ area.width as usize,
+ style,
+ );
+ }
}
}
diff --git a/src/ui/widgets/tui_textfield.rs b/src/ui/widgets/tui_textfield.rs
new file mode 100644
index 0000000..c0f54a8
--- /dev/null
+++ b/src/ui/widgets/tui_textfield.rs
@@ -0,0 +1,86 @@
+use rustyline::completion::{Candidate, Completer, FilenameCompleter, Pair};
+use rustyline::line_buffer;
+
+use termion::clear;
+use termion::cursor::Goto;
+use termion::event::Key;
+use tui::layout::Rect;
+use tui::style::{Color, Style};
+use tui::widgets::{Block, Borders, List, Paragraph, Text, Widget};
+use unicode_width::UnicodeWidthStr;
+
+use crate::context::JoshutoContext;
+use crate::ui::TuiBackend;
+use crate::util::event::{Event, Events};
+
+use super::TuiMenu;
+
+struct CompletionTracker {
+ pub index: usize,
+ pub pos: usize,
+ pub original: String,
+ pub candidates: Vec<Pair>,
+}
+
+impl CompletionTracker {
+ pub fn new(pos: usize, candidates: Vec<Pair>, original: String) -> Self {
+ CompletionTracker {
+ index: 0,
+ pos,
+ original,
+ candidates,
+ }
+ }
+}
+
+pub struct TuiTextField<'a> {
+ menu: Option<&'a mut TuiMenu<'a>>,
+}
+
+impl<'a> TuiTextField<'a> {
+ pub fn new(menu: &'a mut TuiMenu<'a>) -> Self {
+ Self { menu: Some(menu) }
+ }
+
+ pub fn get_input(
+ &mut self,
+ backend: &mut TuiBackend,
+ context: &JoshutoContext,
+ ) -> Option<String> {
+ let mut input_string = String::with_capacity(64);
+
+ loop {
+ backend.terminal.draw(|mut frame| {
+ let f_size = frame.size();
+
+ let top_rect = Rect {
+ x: 0,
+ y: 0,
+ width: f_size.width,
+ height: 1,
+ };
+
+ if let Some(menu) = self.menu.as_mut() {
+ menu.render(&mut frame, top_rect);
+ }
+ });
+
+ if let Ok(event) = context.events.next() {
+ match event {
+ Event::Input(Key::Esc) => {
+ return None;
+ }
+ Event::Input(Key::Char('\n')) => {
+ break;
+ }
+ Event::Input(Key::Char(c)) => {
+ input_string.push(c);
+ }
+ _ => {}
+ };
+ }
+ }
+ eprintln!("You typed: {}", input_string);
+ Some(input_string)
+ }
+}
diff --git a/src/ui/widgets/tui_topbar.rs b/src/ui/widgets/tui_topbar.rs
index 6ff46b7..e87a3e5 100644
--- a/src/ui/widgets/tui_topbar.rs
+++ b/src/ui/widgets/tui_topbar.rs
@@ -34,8 +34,6 @@ impl<'a> Widget for TuiTopBar<'a> {
Text::styled(curr_path_str, path_style),
];
- Paragraph::new(text.iter())
- .wrap(true)
- .draw(area, buf);
+ Paragraph::new(text.iter()).wrap(true).draw(area, buf);
}
}
diff --git a/src/ui/widgets/tui_view.rs b/src/ui/widgets/tui_view.rs
new file mode 100644
index 0000000..57f644c
--- /dev/null
+++ b/src/ui/widgets/tui_view.rs
@@ -0,0 +1,74 @@
+use tui::buffer::Buffer;
+use tui::layout::{Direction, Layout, Rect};
+use tui::widgets::Widget;
+use unicode_width::UnicodeWidthStr;
+
+use super::{TuiDirList, TuiDirListDetailed, TuiFooter, TuiTopBar};
+use crate::context::JoshutoContext;
+
+pub struct TuiView<'a> {
+ pub context: &'a JoshutoContext,
+}
+
+use super::super::{DEFAULT_LAYOUT, NO_PREVIEW_LAYOUT};
+
+impl<'a> TuiView<'a> {
+ pub fn new(context: &'a JoshutoContext) -> Self {
+ Self { context }
+ }
+}
+
+impl<'a> Widget for TuiView<'a> {
+ fn draw(&mut self, area: Rect, buf: &mut Buffer) {
+ let curr_tab = self.context.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 f_size = area;
+
+ 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);
+
+ {
+ let rect = Rect {
+ x: 0,
+ y: 0,
+ width: f_size.width,
+ height: 1,
+ };
+
+ TuiTopBar::new(curr_tab.curr_path.as_path()).draw(rect, buf);
+ }
+
+ if let Some(curr_list) = parent_list.as_ref() {
+ TuiDirList::new(&curr_list).draw(layout_rect[0], buf);
+ };
+
+ if let Some(curr_list) = curr_list.as_ref() {
+ TuiDirListDetailed::new(&curr_list).draw(layout_rect[1], buf);
+
+ if let Some(entry) = curr_list.get_curr_ref() {
+ let rect = Rect {
+ x: 0,
+ y: f_size.height - 1,
+ width: f_size.width,
+ height: 1,
+ };
+ TuiFooter::new(entry).draw(rect, buf);
+ }
+ };
+
+ if let Some(curr_list) = child_list.as_ref() {
+ TuiDirList::new(&curr_list).draw(layout_rect[2], buf);
+ };
+ }
+}