Crates.io | tuikit |
lib.rs | tuikit |
version | 0.5.0 |
source | src |
created_at | 2019-01-13 12:26:30.652814 |
updated_at | 2022-10-28 17:22:25.446317 |
description | Toolkit for writing TUI applications |
homepage | https://github.com/lotabout/tuikit |
repository | https://github.com/lotabout/tuikit |
max_upload_size | |
id | 108328 |
size | 229,828 |
Tuikit is a TUI library for writing terminal UI applications. Highlights:
Alt
keys, mouse events, etc.Tuikit is modeld after termbox which views the terminal as a table of fixed-size cells and input being a stream of structured messages.
WARNING: The library is not stable yet, the API might change.
In your Cargo.toml
add the following:
[dependencies]
tuikit = "*"
And if you'd like to use the latest snapshot version:
[dependencies]
tuikit = { git = "https://github.com/lotabout/tuikit.git" }
Here is an example (could also be run by cargo run --example hello-world
):
use tuikit::prelude::*;
use std::cmp::{min, max};
fn main() {
let term: Term<()> = Term::with_height(TermHeight::Percent(30)).unwrap();
let mut row = 1;
let mut col = 0;
let _ = term.print(0, 0, "press arrow key to move the text, (q) to quit");
let _ = term.present();
while let Ok(ev) = term.poll_event() {
let _ = term.clear();
let _ = term.print(0, 0, "press arrow key to move the text, (q) to quit");
let (width, height) = term.term_size().unwrap();
match ev {
Event::Key(Key::ESC) | Event::Key(Key::Char('q')) => break,
Event::Key(Key::Up) => row = max(row-1, 1),
Event::Key(Key::Down) => row = min(row+1, height-1),
Event::Key(Key::Left) => col = max(col, 1)-1,
Event::Key(Key::Right) => col = min(col+1, width-1),
_ => {}
}
let attr = Attr{ fg: Color::RED, ..Attr::default() };
let _ = term.print_with_attr(row, col, "Hello World! 你好!今日は。", attr);
let _ = term.set_cursor(row, col);
let _ = term.present();
}
}
tuikit
provides HSplit
, VSplit
and Win
for managing layouts:
HSplit
allow you to split area horizontally into pieces.VSplit
works just like HSplit
but splits vertically.Win
do not split, it could have margin, padding and border.For example:
use tuikit::prelude::*;
struct Model(String);
impl Draw for Model {
fn draw(&self, canvas: &mut dyn Canvas) -> DrawResult<()> {
let (width, height) = canvas.size()?;
let message_width = self.0.len();
let left = (width - message_width) / 2;
let top = height / 2;
let _ = canvas.print(top, left, &self.0);
Ok(())
}
}
impl Widget for Model{}
fn main() {
let term: Term<()> = Term::with_height(TermHeight::Percent(50)).unwrap();
let model = Model("middle!".to_string());
while let Ok(ev) = term.poll_event() {
if let Event::Key(Key::Char('q')) = ev {
break;
}
let _ = term.print(0, 0, "press 'q' to exit");
let hsplit = HSplit::default()
.split(
VSplit::default()
.basis(Size::Percent(30))
.split(Win::new(&model).border(true).basis(Size::Percent(30)))
.split(Win::new(&model).border(true).basis(Size::Percent(30)))
)
.split(Win::new(&model).border(true));
let _ = term.draw(&hsplit);
let _ = term.present();
}
}
The split algorithm is simple:
HSplit
and VSplit
will take several Split
where a Split
would
contains:
HSplit/VSplit
will count the total width/height(basis) of the split itemsfactor / sum(factors)
Tuikit
borrows ideas from lots of other projects: