diff options
author | Jiayi Zhao <jeff.no.zhao@gmail.com> | 2020-02-16 11:59:33 -0500 |
---|---|---|
committer | Jiayi Zhao <jeff.no.zhao@gmail.com> | 2020-02-16 12:01:23 -0500 |
commit | d788f8d740be85bb014ddfa005156723f0a31e99 (patch) | |
tree | 1cd74c86358b70f78dffe25da5e0bfe4bd9b1abf /src/ui | |
parent | 726a7a424f7ddec97478490a0f3a25005dde45ac (diff) |
rework rendering system to use tui-rs widgets
- move files around
- delete some old ncurses code
- integrate tui-rs styles and colors
Diffstat (limited to 'src/ui')
-rw-r--r-- | src/ui/mod.rs | 1 | ||||
-rw-r--r-- | src/ui/tui_backend.rs | 63 | ||||
-rw-r--r-- | src/ui/widgets/mod.rs | 3 | ||||
-rw-r--r-- | src/ui/widgets/tui_dirlist.rs | 124 |
4 files changed, 147 insertions, 44 deletions
diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 574bc46..e250d20 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -1,5 +1,6 @@ mod ncurses_backend; mod tui_backend; +pub mod widgets; pub use ncurses_backend::*; pub use tui_backend::*; diff --git a/src/ui/tui_backend.rs b/src/ui/tui_backend.rs index d59c619..b5afced 100644 --- a/src/ui/tui_backend.rs +++ b/src/ui/tui_backend.rs @@ -1,3 +1,6 @@ +use std::io::{self, Write}; + +use termion::clear; use termion::cursor::Goto; use termion::event::Key; use termion::input::TermRead; @@ -9,6 +12,7 @@ use tui::style::{Color, Style}; use tui::widgets::{Block, Borders, List, Paragraph, SelectableList, Text, Widget}; use unicode_width::UnicodeWidthStr; +use super::widgets::TuiDirList; use crate::context::JoshutoContext; // use crate::fs::JoshutoDirList; @@ -22,6 +26,7 @@ impl TuiBackend { let stdout = AlternateScreen::from(stdout); let backend = TermionBackend::new(stdout); let mut terminal = tui::Terminal::new(backend)?; + terminal.hide_cursor()?; Ok(Self { terminal }) } @@ -32,8 +37,13 @@ impl TuiBackend { let parent_list = curr_tab.parent_list_ref(); let child_list = curr_tab.child_list_ref(); - self.terminal.draw(|mut f| { - let f_size = f.size(); + let f_size = { + let frame = self.terminal.get_frame(); + frame.size() + }; + + self.terminal.draw(|mut frame| { + let f_size = frame.size(); let constraints = match child_list { Some(_) => [ @@ -49,56 +59,21 @@ impl TuiBackend { }; 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() { - let list_name = "parent_list"; - let list_style = Style::default().fg(tui::style::Color::LightBlue); - let selected_style = Style::default() - .fg(tui::style::Color::LightBlue) - .modifier(tui::style::Modifier::REVERSED); - - SelectableList::default() - .block(Block::default().borders(Borders::ALL).title(list_name)) - .items(&curr_list.contents) - .style(list_style) - .highlight_style(selected_style) - .select(curr_list.index) - .render(&mut f, layout_rect[0]); - } + TuiDirList::new(&curr_list).render(&mut frame, layout_rect[0]); + }; if let Some(curr_list) = curr_list.as_ref() { - let list_name = "curr_list"; - let list_style = Style::default().fg(tui::style::Color::LightBlue); - let selected_style = Style::default() - .fg(tui::style::Color::LightBlue) - .modifier(tui::style::Modifier::REVERSED); - - SelectableList::default() - .block(Block::default().borders(Borders::ALL).title(list_name)) - .items(&curr_list.contents) - .style(list_style) - .highlight_style(selected_style) - .select(curr_list.index) - .render(&mut f, layout_rect[1]); - } + TuiDirList::new(&curr_list).render(&mut frame, layout_rect[1]); + }; if let Some(curr_list) = child_list.as_ref() { - let list_name = "child_list"; - let list_style = Style::default().fg(tui::style::Color::LightBlue); - let selected_style = Style::default() - .fg(tui::style::Color::LightBlue) - .modifier(tui::style::Modifier::REVERSED); - - SelectableList::default() - .block(Block::default().borders(Borders::ALL).title(list_name)) - .items(&curr_list.contents) - .style(list_style) - .highlight_style(selected_style) - .select(curr_list.index) - .render(&mut f, layout_rect[2]); - } + TuiDirList::new(&curr_list).render(&mut frame, layout_rect[2]); + }; }); } } diff --git a/src/ui/widgets/mod.rs b/src/ui/widgets/mod.rs new file mode 100644 index 0000000..9ace2b7 --- /dev/null +++ b/src/ui/widgets/mod.rs @@ -0,0 +1,3 @@ +pub mod tui_dirlist; + +pub use self::tui_dirlist::TuiDirList; diff --git a/src/ui/widgets/tui_dirlist.rs b/src/ui/widgets/tui_dirlist.rs new file mode 100644 index 0000000..e2ba9a6 --- /dev/null +++ b/src/ui/widgets/tui_dirlist.rs @@ -0,0 +1,124 @@ +use std::io::{self, Write}; + +use tui::buffer::Buffer; +use tui::layout::Rect; +use tui::style::{Modifier, Style}; +use tui::widgets::{Block, Text, Widget}; + +use crate::fs::JoshutoDirList; +/* +pub struct TermionWindow<'a> { + rect: Rect, + dirlist: &'a JoshutoDirList, +} + +impl<'a> TermionWindow<'a> { + pub fn new(rect: &Rect, dirlist: &'a JoshutoDirList) -> Self { + Self { + rect: rect.clone(), + dirlist + } + } + + pub fn update_rect(&mut self, rect: &Rect) { + self.rect = rect.clone(); + } + + pub fn clear<W: Write>(&self, terminal: &mut W) { + for i in 1..self.rect.height + 1 { + write!(terminal, "{}{}", Goto(self.rect.width, i as u16), clear::BeforeCursor); + } + } + + pub fn draw<W: Write>(&self, terminal: &mut W) { + if self.rect.height < 4 { + return; + } + let dir_len = self.dirlist.contents.len(); + if dir_len == 0 { + write!(terminal, "{}EMPTY", Goto(self.rect.x, self.rect.y)); + return; + } + + let curr_index = self.dirlist.index.unwrap(); + + let height = self.rect.height as usize; + + for (i, entry) in self.dirlist.contents.iter().enumerate() { + let goto_i = i + 1; + if goto_i > height { + break; + } + let fg = entry.get_fg_color(); + let bg = entry.get_bg_color(); + let file_ansi_text = entry.as_ansi_text(); + + if i == curr_index { + write!(terminal, "{}{}{}{}{}", + Goto(self.rect.x, goto_i as u16), + style::Invert, + bg.bg_str(), + fg.fg_str(), + file_ansi_text); + } else { + write!(terminal, "{}{}{}{}{}", + Goto(self.rect.x, goto_i as u16), + style::Reset, + bg.bg_str(), + fg.fg_str(), + file_ansi_text); + } + } + } +} +*/ +pub struct TuiDirList<'a> { + dirlist: &'a JoshutoDirList, +} + +impl<'a> TuiDirList<'a> { + pub fn new(dirlist: &'a JoshutoDirList) -> Self { + Self { dirlist } + } +} + +impl<'a> Widget for TuiDirList<'a> { + fn draw(&mut self, area: Rect, buf: &mut Buffer) { + if area.width < 1 || area.height < 1 { + return; + } + + if area.width < 4 { + return; + } + + let x = area.left(); + let y = area.top(); + + let dir_len = self.dirlist.contents.len(); + if dir_len == 0 { + buf.set_stringn(x, y, "empty", area.width as usize, Style::default()); + return; + } + + let curr_index = self.dirlist.index.unwrap(); + for (i, entry) in self + .dirlist + .contents + .iter() + .enumerate() + .take(area.height as usize) + { + let fg = entry.get_fg_color(); + let bg = entry.get_bg_color(); + let name = entry.file_name(); + + let mut style = Style::default().fg(fg).bg(bg); + + if i == curr_index { + style = style.modifier(Modifier::REVERSED); + } + buf.set_stringn(x, y + i as u16, name, area.width as usize, style); + } + } +} |