Crates.io | tuviv |
lib.rs | tuviv |
version | 0.7.0 |
source | src |
created_at | 2022-08-02 15:55:32.187017 |
updated_at | 2024-09-27 16:16:03.428141 |
description | A TUI library focused on layout |
homepage | |
repository | https://gitlab.com/john_t/tuviv |
max_upload_size | |
id | 637428 |
size | 264,124 |
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.
crossterm
- backend. crossterm
is enabled by default and is recommended.textwrap
- allows for the Paragraph
widget. Is enabled by default.
(please note if you don't include this you will have to reimplement something to render text)// Imports
use std::io;
use std::time::Duration;
use tuviv::{
le::Orientation,
prelude::*,
widgets::{Filler, Flexbox},
};
fn main() -> io::Result<()> {
// Create a flexbox
// With coloured squares
let flexbox = Flexbox::new(Orientation::Horizontal, false)
.child(
Filler::new(" ".styled().bg_red())
.fixed_size(16, 8)
.centered()
.to_flex_child()
.expand(1),
)
.child(
Flexbox::new(Orientation::Vertical, false)
.child(
Filler::new(" ".styled().bg_yellow())
.fixed_size(16, 8)
.centered()
.to_flex_child()
.expand(1),
)
.child(
Filler::new(" ".styled().bg_green())
.fixed_size(16, 8)
.centered()
.to_flex_child()
.expand(1),
)
.to_flex_child()
.expand(1),
);
// Render a single frame.
//
// Look at `tuviv::run_app` for a better way of doing this
// for real applications
tuviv::render_frame(&*flexbox, Duration::from_secs(2))?;
Ok(())
}
Tuviv uses a builder pattern so complicated widgets can be created easily:
use tuviv::prelude::*;
// Create a grid with progressbars:
//
// ╭───────────────╮
// │CPU █▌────────│
// │MEM ███▌──────│
// │GPU ─────CO o │
// ╰───────────────╯
let grid = Grid::new()
.template_rows(vec![Sizing::Auto; 3])
.template_columns(vec![Sizing::Auto, Sizing::AutoFixed(10)])
.column_gap(2)
.auto_child(Paragraph::new("CPU".styled()))
.auto_child(
ProgressBar::new()
.total(100.0)
.value(10.0)
.align_y(Alignment::Center),
)
.auto_child(Paragraph::new("MEM".styled()))
.auto_child(
ProgressBar::new()
.total(8.0)
.value(2.4)
.align_y(Alignment::Center),
)
.auto_child(Paragraph::new("GPU".styled()))
.auto_child(
ProgressBar::new()
.total(15.0)
.value(8.0)
.fg(vec!["─".styled().bold()])
.edge("C".styled().yellow().bold())
.bg(vec!["O o ".styled()])
.align_y(Alignment::Center),
)
.to_box_sizing()
.border(Border::ROUNDED)
.centered();