Tuviv is a library for building terminal user interfaces (TUIs) with
rust with a heavy focus on layout. Tuviv does not come with as many
widgets as, say, tui-rs, but rather
contains many more widgets based on layout: specifically a
Flexbox
,
and a Grid
,
along with others.
The purpose of this library is to significantly ease creating layouts, which is mildly clunky with tui-rs: such as the fact that you cannot center text vertically (#396) - but also wider-scale things - such as the lack of a flexbox or a grid.
```rust use std::io::{self, stdout, Write}; use crossterm::{cursor, event::DisableMouseCapture, execute, terminal::{ self, disablerawmode, enablerawmode, EnterAlternateScreen, LeaveAlternateScreen, }, }; use tuviv::{layout::{Rect, Vec2}, CrosstermBackend, Widget};
fn main() -> io::Result<()> {
// Prepare the stdout for printing a tui
let mut stdout = stdout();
execute!(stdout, EnterAlternateScreen, cursor::Hide)?;
enable_raw_mode()?;
let p = Paragraph::new("HI");
loop {
// Get the size of the terminal
let size = terminal::size()?;
// Create the buffer to write to
let backend = CrosstermBackend;
let mut buffer =
tuviv::Buffer::new(Vec2::new(size.0.into(), size.1.into()));
// Render the widget onto the buffer.
p.render(Rect::new(0, 0, size.0.into(), size.1.into()), &mut buffer);
// Render the buffer to the terminal
backend.finish(&buffer, &mut stdout)?;
}
// Restore terminal
disable_raw_mode()?;
execute!(stdout, LeaveAlternateScreen, DisableMouseCapture, cursor::Show)?;
Ok(())
}
```
Tuviv uses a builder pattern so more complicated widgets can be created easily:
```rust use tuviv::prelude::*;
// Create a grid with progressbars: // // ╭───────────────╮ // │CPU █▌────────│ // │MEM ███▌──────│ // │GPU ─────CO o │ // ╰───────────────╯ let grid = Grid::new() .templaterows(vec![Sizing::Auto; 3]) .templatecolumns(vec![Sizing::Auto, Sizing::AutoFixed(10)]) .columngap(2) .autochild(Paragraph::new("CPU".styled())) .autochild( ProgressBar::new() .total(100.0) .value(10.0) .aligny(Alignment::Center), ) .autochild(Paragraph::new("MEM".styled())) .autochild( ProgressBar::new() .total(8.0) .value(2.4) .aligny(Alignment::Center), ) .autochild(Paragraph::new("GPU".styled())) .autochild( ProgressBar::new() .total(15.0) .value(8.0) .fg(vec!["─".styled().bold()]) .edge("C".styled().yellow().bold()) .bg(vec!["O o ".styled()]) .aligny(Alignment::Center), ) .toboxsizing() .border(Border::ROUNDED) .centered(); ```