Creare una TUI in Rust
La costruzione di TUI (text user interface) non è per nulla facile neanche se usiamo librerie apposite.
In questo articolo vediamo come usare il modulo tui in Rust!
Ovviamente il mio è un esempio abbastanza banale, non come quello che vedete nella pagina di documentazione.
Ma può essere un inizio se avete bisogno di qualcosa del genere; prima di tutto aggiungiamo queste dipendenze al Cargo.toml:
[dependencies]
tui = "0.19"
crossterm = "0.25"
Qui sotto il mio codice di esempio:
use crossterm::{
event::{self, DisableMouseCapture, EnableMouseCapture, Event, KeyCode},
execute,
terminal::{disable_raw_mode, enable_raw_mode, EnterAlternateScreen, LeaveAlternateScreen},
};
use std::{error::Error, io};
use tui::{
backend::{Backend, CrosstermBackend},
layout::{Alignment, Constraint, Direction, Layout},
style::{Color, Modifier, Style},
text::Span,
widgets::{Block, BorderType, Borders},
Frame, Terminal,
};
fn main() -> Result<(), Box<dyn Error>> {
enable_raw_mode()?;
let mut stdout = io::stdout();
execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?;
let backend = CrosstermBackend::new(stdout);
let mut terminal = Terminal::new(backend)?;
let res = start_app(&mut terminal);
disable_raw_mode()?;
execute!(
terminal.backend_mut(),
LeaveAlternateScreen,
DisableMouseCapture
)?;
terminal.show_cursor()?;
if let Err(err) = res {
println!("{:?}", err)
}
Ok(())
}
fn start_app<B: Backend>(terminal: &mut Terminal<B>) -> io::Result<()> {
loop {
terminal.draw(my_ui)?;
if let Event::Key(key) = event::read()? {
if let KeyCode::Char('q') = key.code {
return Ok(());
}
}
}
}
fn my_ui<B: Backend>(f: &mut Frame<B>) {
let size = f.size();
let block = Block::default()
.borders(Borders::ALL)
.title("Blocco principale")
.title_alignment(Alignment::Center)
.border_type(BorderType::Rounded);
f.render_widget(block, size);
let chunks = Layout::default()
.direction(Direction::Vertical)
.margin(4)
.constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref())
.split(f.size());
let top_chunks = Layout::default()
.direction(Direction::Horizontal)
.constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref())
.split(chunks[0]);
let block = Block::default()
.title(vec![
Span::styled("Scritta verde su sfondo rosso", Style::default().fg(Color::Green)),
])
.style(Style::default().bg(Color::Red));
f.render_widget(block, top_chunks[0]);
let block = Block::default()
.title(Span::styled(
"Testo con stile",
Style::default()
.fg(Color::White)
.bg(Color::Red)
.add_modifier(Modifier::BOLD),
))
.title_alignment(Alignment::Right);
f.render_widget(block, top_chunks[1]);
let bottom_chunks = Layout::default()
.direction(Direction::Horizontal)
.constraints([Constraint::Percentage(50), Constraint::Percentage(50)].as_ref())
.split(chunks[1]);
let block = Block::default()
.title("Sotto blocco con bordo blu")
.borders(Borders::ALL)
.border_style(Style::default().fg(Color::LightBlue));
f.render_widget(block, bottom_chunks[0]);
}
Enjoy!
rust cargo tui
Commentami!