mirror of
https://github.com/ratatui/ratatui.git
synced 2025-10-01 15:02:21 +00:00

Consensus is that explicit imports make it easier to understand the example code. This commit removes the prelude import from all examples and replaces it with the necessary imports, and expands other glob imports (widget::*, Constraint::*, KeyCode::*, etc.) everywhere else. Prelude glob imports not in examples are not covered by this PR. See https://github.com/ratatui-org/ratatui/issues/1150 for more details.
86 lines
2.2 KiB
Rust
86 lines
2.2 KiB
Rust
use std::{error::Error, io, sync::mpsc, thread, time::Duration};
|
|
|
|
use ratatui::{
|
|
backend::{Backend, TermionBackend},
|
|
terminal::Terminal,
|
|
termion::{
|
|
event::Key,
|
|
input::{MouseTerminal, TermRead},
|
|
raw::IntoRawMode,
|
|
screen::IntoAlternateScreen,
|
|
},
|
|
};
|
|
|
|
use crate::{app::App, ui};
|
|
|
|
pub fn run(tick_rate: Duration, enhanced_graphics: bool) -> Result<(), Box<dyn Error>> {
|
|
// setup terminal
|
|
let stdout = io::stdout()
|
|
.into_raw_mode()
|
|
.unwrap()
|
|
.into_alternate_screen()
|
|
.unwrap();
|
|
let stdout = MouseTerminal::from(stdout);
|
|
let backend = TermionBackend::new(stdout);
|
|
let mut terminal = Terminal::new(backend)?;
|
|
|
|
// create app and run it
|
|
let app = App::new("Termion demo", enhanced_graphics);
|
|
run_app(&mut terminal, app, tick_rate)?;
|
|
|
|
Ok(())
|
|
}
|
|
|
|
fn run_app<B: Backend>(
|
|
terminal: &mut Terminal<B>,
|
|
mut app: App,
|
|
tick_rate: Duration,
|
|
) -> Result<(), Box<dyn Error>> {
|
|
let events = events(tick_rate);
|
|
loop {
|
|
terminal.draw(|f| ui::draw(f, &mut app))?;
|
|
|
|
match events.recv()? {
|
|
Event::Input(key) => match key {
|
|
Key::Up | Key::Char('k') => app.on_up(),
|
|
Key::Down | Key::Char('j') => app.on_down(),
|
|
Key::Left | Key::Char('h') => app.on_left(),
|
|
Key::Right | Key::Char('l') => app.on_right(),
|
|
Key::Char(c) => app.on_key(c),
|
|
_ => {}
|
|
},
|
|
Event::Tick => app.on_tick(),
|
|
}
|
|
if app.should_quit {
|
|
return Ok(());
|
|
}
|
|
}
|
|
}
|
|
|
|
enum Event {
|
|
Input(Key),
|
|
Tick,
|
|
}
|
|
|
|
fn events(tick_rate: Duration) -> mpsc::Receiver<Event> {
|
|
let (tx, rx) = mpsc::channel();
|
|
let keys_tx = tx.clone();
|
|
thread::spawn(move || {
|
|
let stdin = io::stdin();
|
|
for key in stdin.keys().flatten() {
|
|
if let Err(err) = keys_tx.send(Event::Input(key)) {
|
|
eprintln!("{err}");
|
|
return;
|
|
}
|
|
}
|
|
});
|
|
thread::spawn(move || loop {
|
|
if let Err(err) = tx.send(Event::Tick) {
|
|
eprintln!("{err}");
|
|
break;
|
|
}
|
|
thread::sleep(tick_rate);
|
|
});
|
|
rx
|
|
}
|