parent
c8dc747bcc
commit
638ae4da6e
8 changed files with 217 additions and 105 deletions
@ -1,43 +0,0 @@ |
||||
use super::{ |
||||
state::{State, UiTabs}, |
||||
Frame, |
||||
}; |
||||
use tui::layout::{Constraint, Direction, Layout}; |
||||
use tui::style::{Color, Modifier, Style}; |
||||
use tui::text::Spans; |
||||
use tui::widgets::{Block, Borders, List, ListItem, Tabs}; |
||||
|
||||
pub fn draw(f: &mut Frame, s: &mut State) { |
||||
let size = f.size(); |
||||
let chunks = Layout::default() |
||||
.direction(Direction::Vertical) |
||||
.margin(1) |
||||
.constraints([Constraint::Length(3), Constraint::Min(0)].as_ref()) |
||||
.split(size); |
||||
let titles = UiTabs::variants() |
||||
.iter() |
||||
.cloned() |
||||
.map(Spans::from) |
||||
.collect(); |
||||
let tabs = Tabs::new(titles) |
||||
.block( |
||||
Block::default() |
||||
.title("The whole that you need to know") |
||||
.borders(Borders::ALL), |
||||
) |
||||
.style(Style::default().fg(Color::White)) |
||||
.highlight_style(Style::default().fg(Color::Yellow)) |
||||
.divider("-") |
||||
.select(s.active_tab.index()); |
||||
f.render_widget(tabs, chunks[0]); |
||||
|
||||
let tab_data = s |
||||
.tab_data() |
||||
.into_iter() |
||||
.map(ListItem::new) |
||||
.collect::<Vec<ListItem>>(); |
||||
let list = List::new(tab_data) |
||||
.block(Block::default().borders(Borders::ALL)) |
||||
.highlight_style(Style::default().add_modifier(Modifier::BOLD)); |
||||
f.render_stateful_widget(list, chunks[1], s.tab_list_state()); |
||||
} |
@ -0,0 +1,94 @@ |
||||
mod main_wnd; |
||||
mod processing; |
||||
pub use main_wnd::MainWnd; |
||||
|
||||
use crate::tui::{Backend, Frame}; |
||||
use anyhow::Result as AResult; |
||||
use crossterm::event::KeyCode; |
||||
use std::cell::RefCell; |
||||
use std::process::exit; |
||||
use std::rc::Rc; |
||||
use tui::Terminal; |
||||
|
||||
type Wnd = Rc<RefCell<dyn Window>>; |
||||
|
||||
#[async_trait] |
||||
pub trait Window { |
||||
async fn handle_kbd(&mut self, k: KeyCode) -> AResult<()>; |
||||
async fn update(&mut self) -> AResult<()>; |
||||
async fn close(&mut self); |
||||
fn draw(&mut self, f: &mut Frame); |
||||
} |
||||
|
||||
pub struct WindowsHandler { |
||||
queue: Vec<Wnd>, |
||||
term: Terminal<Backend>, |
||||
redraw_all: bool, |
||||
} |
||||
|
||||
impl WindowsHandler { |
||||
fn get_last_wnd(&self) -> Wnd { |
||||
self.queue.last().expect("No windows found").clone() |
||||
} |
||||
|
||||
pub fn new(term: Terminal<Backend>) -> Self { |
||||
Self { |
||||
term, |
||||
queue: vec![], |
||||
redraw_all: true, |
||||
} |
||||
} |
||||
|
||||
pub fn push<W: Window + Default + 'static>(&mut self) { |
||||
let window = Rc::new(RefCell::new(W::default())); |
||||
self.queue.push(window); |
||||
} |
||||
|
||||
pub fn clear(&mut self) -> AResult<()> { |
||||
self.term.clear()?; |
||||
Ok(()) |
||||
} |
||||
|
||||
pub fn show_cursor(&mut self) -> AResult<()> { |
||||
self.term.show_cursor()?; |
||||
Ok(()) |
||||
} |
||||
|
||||
pub fn draw(&mut self) -> AResult<()> { |
||||
if self.redraw_all { |
||||
for wnd in self.queue.iter() { |
||||
self.term.draw(|f| wnd.borrow_mut().draw(f))?; |
||||
} |
||||
} else { |
||||
let wnd = self.get_last_wnd(); |
||||
self.term.draw(|f| wnd.borrow_mut().draw(f))?; |
||||
} |
||||
Ok(()) |
||||
} |
||||
|
||||
pub async fn close(&mut self) { |
||||
let wnd = self.queue.pop().unwrap(); |
||||
wnd.borrow_mut().close().await; |
||||
self.redraw_all = true; |
||||
if self.queue.is_empty() { |
||||
self.show_cursor().unwrap(); |
||||
exit(0); |
||||
} |
||||
} |
||||
|
||||
pub async fn handle_kbd(&mut self, k: KeyCode) -> AResult<()> { |
||||
if let KeyCode::Esc = k { |
||||
self.close().await; |
||||
} else { |
||||
let current_wnd = self.get_last_wnd(); |
||||
current_wnd.borrow_mut().handle_kbd(k).await?; |
||||
} |
||||
Ok(()) |
||||
} |
||||
|
||||
pub async fn update(&mut self) -> AResult<()> { |
||||
let current_wnd = self.get_last_wnd(); |
||||
current_wnd.borrow_mut().update().await?; |
||||
Ok(()) |
||||
} |
||||
} |
Loading…
Reference in new issue