From 84cd7ae0f4598d13807819817c4339821eaa7228 Mon Sep 17 00:00:00 2001 From: Michael Zhang Date: Mon, 1 Mar 2021 03:35:14 -0600 Subject: [PATCH] playing around with ui --- src/ui/events.rs | 95 ------------------------------------------------ src/ui/mod.rs | 51 +++++++++++++++++++------- 2 files changed, 38 insertions(+), 108 deletions(-) delete mode 100644 src/ui/events.rs diff --git a/src/ui/events.rs b/src/ui/events.rs deleted file mode 100644 index 333096a..0000000 --- a/src/ui/events.rs +++ /dev/null @@ -1,95 +0,0 @@ -use std::io; -use std::sync::mpsc; -use std::sync::{ - atomic::{AtomicBool, Ordering}, - Arc, -}; -use std::thread; -use std::time::Duration; - -use termion::event::Key; -use termion::input::TermRead; - -pub enum Event { - Input(I), - Tick, -} - -/// A small event handler that wrap termion input and tick events. Each event -/// type is handled in its own thread and returned to a common `Receiver` -pub struct Events { - rx: mpsc::Receiver>, - input_handle: thread::JoinHandle<()>, - ignore_exit_key: Arc, - tick_handle: thread::JoinHandle<()>, -} - -#[derive(Debug, Clone, Copy)] -pub struct Config { - pub exit_key: Key, - pub tick_rate: Duration, -} - -impl Default for Config { - fn default() -> Config { - Config { - exit_key: Key::Char('q'), - tick_rate: Duration::from_millis(250), - } - } -} - -impl Events { - pub fn new() -> Events { - Events::with_config(Config::default()) - } - - pub fn with_config(config: Config) -> Events { - let (tx, rx) = mpsc::channel(); - let ignore_exit_key = Arc::new(AtomicBool::new(false)); - let input_handle = { - let tx = tx.clone(); - let ignore_exit_key = ignore_exit_key.clone(); - thread::spawn(move || { - let stdin = io::stdin(); - for evt in stdin.keys() { - if let Ok(key) = evt { - if let Err(err) = tx.send(Event::Input(key)) { - eprintln!("{}", err); - return; - } - if !ignore_exit_key.load(Ordering::Relaxed) && key == config.exit_key { - return; - } - } - } - }) - }; - let tick_handle = { - thread::spawn(move || loop { - if tx.send(Event::Tick).is_err() { - break; - } - thread::sleep(config.tick_rate); - }) - }; - Events { - rx, - ignore_exit_key, - input_handle, - tick_handle, - } - } - - pub fn next(&self) -> Result, mpsc::RecvError> { - self.rx.recv() - } - - pub fn disable_exit_key(&mut self) { - self.ignore_exit_key.store(true, Ordering::Relaxed); - } - - pub fn enable_exit_key(&mut self) { - self.ignore_exit_key.store(false, Ordering::Relaxed); - } -} diff --git a/src/ui/mod.rs b/src/ui/mod.rs index f9701d2..c04a358 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -14,6 +14,7 @@ use tokio::{sync::mpsc, time}; use tui::{ backend::CrosstermBackend, layout::{Constraint, Direction, Layout}, + style::{Color, Modifier, Style}, text::Spans, widgets::*, Terminal, @@ -34,23 +35,47 @@ pub async fn run_ui(mut stdout: Stdout, exit_tx: mpsc::Sender<()>) -> Result<()> let chunks = Layout::default() .direction(Direction::Vertical) .margin(0) - .constraints( - [ - Constraint::Percentage(10), - Constraint::Percentage(80), - Constraint::Percentage(10), - ] - .as_ref(), - ) + .constraints([ + Constraint::Length(1), + Constraint::Max(5000), + // Constraint::Percentage(10), + // Constraint::Percentage(80), + // Constraint::Percentage(10), + ]) .split(f.size()); - let block = Block::default().title("Block").borders(Borders::NONE); - f.render_widget(block, chunks[0]); - let block = Block::default().title("Block 2").borders(Borders::ALL); - f.render_widget(block, chunks[1]); + let chunks2 = Layout::default() + .direction(Direction::Horizontal) + .margin(0) + .constraints([ + Constraint::Length(20), + Constraint::Max(5000), + // + ]) + .split(chunks[1]); + + // this is the title bar let titles = vec!["hellosu"].into_iter().map(Spans::from).collect(); let tabs = Tabs::new(titles); - f.render_widget(tabs, chunks[2]); + f.render_widget(tabs, chunks[0]); + + // TODO: check active tab + let items = [ + ListItem::new("Osu"), + ListItem::new("Game").style(Style::default().add_modifier(Modifier::BOLD)), + ]; + let dirlist = List::new(items) + .block(Block::default().title("List").borders(Borders::ALL)) + .style(Style::default().fg(Color::White)) + .highlight_style(Style::default().add_modifier(Modifier::ITALIC)) + .highlight_symbol(">>"); + f.render_widget(dirlist, chunks2[0]); + + let block = Block::default().title("Block").borders(Borders::ALL); + f.render_widget(block, chunks2[1]); + + // let block = Block::default().title("Block 2").borders(Borders::ALL); + // f.render_widget(block, chunks[1]); })?; let event = if event::poll(FRAME_DURATION)? {