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