diff --git a/Cargo.toml b/Cargo.toml index 299363a8..78d72164 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -85,3 +85,7 @@ path = "examples/tabs.rs" [[example]] name = "user_input" path = "examples/user_input.rs" + +[[example]] +name = "layout" +path = "examples/layout.rs" diff --git a/examples/layout.rs b/examples/layout.rs new file mode 100644 index 00000000..71ce68b5 --- /dev/null +++ b/examples/layout.rs @@ -0,0 +1,104 @@ +extern crate log; +extern crate stderrlog; +extern crate termion; +extern crate tui; + +use std::io; +use std::thread; +use std::sync::mpsc; + +use termion::event; +use termion::input::TermRead; + +use tui::Terminal; +use tui::backend::MouseBackend; +use tui::widgets::{Block, Borders, Widget}; +use tui::layout::{Direction, Group, Rect, Size}; + +struct App { + size: Rect, +} + +impl App { + fn new() -> App { + App { + size: Rect::default(), + } + } +} + +enum Event { + Input(event::Key), +} + +fn main() { + stderrlog::new().verbosity(4).init().unwrap(); + + // Terminal initialization + let backend = MouseBackend::new().unwrap(); + let mut terminal = Terminal::new(backend).unwrap(); + + // Channels + let (tx, rx) = mpsc::channel(); + let input_tx = tx.clone(); + + // Input + thread::spawn(move || { + let stdin = io::stdin(); + for c in stdin.keys() { + let evt = c.unwrap(); + input_tx.send(Event::Input(evt)).unwrap(); + if evt == event::Key::Char('q') { + break; + } + } + }); + + // App + let mut app = App::new(); + + // First draw call + terminal.clear().unwrap(); + terminal.hide_cursor().unwrap(); + app.size = terminal.size().unwrap(); + draw(&mut terminal, &app); + + loop { + let size = terminal.size().unwrap(); + if size != app.size { + terminal.resize(size).unwrap(); + app.size = size; + } + + let evt = rx.recv().unwrap(); + match evt { + Event::Input(input) => match input { + event::Key::Char('q') => { + break; + } + _ => {} + }, + } + draw(&mut terminal, &app); + } + + terminal.show_cursor().unwrap(); +} + +fn draw(t: &mut Terminal, app: &App) { + Group::default() + .direction(Direction::Vertical) + .sizes(&[Size::Percent(10), Size::Percent(80), Size::Percent(10)]) + .render(t, &app.size, |t, chunks| { + Block::default() + .title("Block") + .borders(Borders::ALL) + .render(t, &chunks[0]); + Block::default() + .title("Block 2") + .borders(Borders::ALL) + .render(t, &chunks[2]); + }); + + t.draw().unwrap(); +}