#tui #layout #ui

tuviv

专注于布局的 TUI 库

8 个版本 (5 个重大更新)

0.6.1 2024年1月14日
0.6.0 2024年1月14日
0.5.0 2023年10月4日
0.4.0 2023年5月30日
0.1.0 2022年8月2日

#166命令行界面

Download history 70/week @ 2024-04-16

每月下载 57 次
用于 flashed

LGPL-3.0 或更新版

160KB
4K SLoC

Tuviv

Tuviv 是一个使用 Rust 构建终端用户界面 (TUI) 的库,重点在于布局。Tuviv 不像 tui-rs 那样提供很多小部件,而是包含更多基于布局的小部件:特别是 FlexboxGrid,以及其他一些。

此库的目的是显著简化布局创建,这在 tui-rs 中略显繁琐:例如,无法垂直居中文本 (#396) - 但也包括更广泛的问题 - 例如缺乏弹性框或网格。

功能

  • crosstermtermion - 不同的后端。默认启用 crossterm 并强烈推荐。
  • textwrap - 允许使用 Paragraph 小部件。默认启用。 (请注意,如果您不包含此功能,您将需要重新实现某些内容以渲染文本)

示例

创建一个缓冲区并渲染一个小部件

// 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 使用构建器模式,因此可以轻松创建复杂的小部件

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();

依赖项

~1.7–8MB
~47K SLoC