feat(tui): render the input prompt

This commit is contained in:
Orhun Parmaksız 2022-01-02 00:07:06 +03:00
parent 54b4c0e61b
commit cb9d072a3e
No known key found for this signature in database
GPG key ID: F83424824B3E4B90
3 changed files with 39 additions and 12 deletions

View file

@ -1,6 +1,7 @@
use std::io;
use std::sync::mpsc::{self, Receiver, RecvError};
use std::thread;
use std::time::Duration;
use termion::event::Key;
use termion::input::TermRead;
@ -9,6 +10,8 @@ use termion::input::TermRead;
pub enum Event {
/// A key press event.
KeyPress(Key),
/// A terminal refresh event.
Tick,
}
/// [`Event`] handler.
@ -18,21 +21,28 @@ pub struct EventHandler {
receiver: Receiver<Event>,
}
impl Default for EventHandler {
fn default() -> Self {
impl EventHandler {
/// Constructs a new event handler with the given refresh rate.
pub fn new(tick_rate: u64) -> Self {
let tick_rate = Duration::from_millis(tick_rate);
let (sender, receiver) = mpsc::channel();
{
let sender = sender.clone();
thread::spawn(move || loop {
io::stdin()
.keys()
.flatten()
.try_for_each(|key| sender.send(Event::KeyPress(key)))
.expect("failed to send key input event");
});
}
thread::spawn(move || loop {
io::stdin()
.keys()
.flatten()
.try_for_each(|key| sender.send(Event::KeyPress(key)))
.expect("failed to send key input event");
sender.send(Event::Tick).expect("failed to send tick event");
thread::sleep(tick_rate);
});
Self { receiver }
}
}
impl EventHandler {
/// Receives the next event from the channel.
pub fn next(&self) -> Result<Event, RecvError> {
self.receiver.recv()

View file

@ -34,7 +34,7 @@ pub fn run<Output: Write>(output: Output) -> Result<()> {
terminal.hide_cursor()?;
terminal.clear()?;
let event_handler = EventHandler::default();
let event_handler = EventHandler::new(250);
let mut app = App::default();
while app.running {
terminal.draw(|frame| ui::render(frame))?;
@ -43,6 +43,7 @@ pub fn run<Output: Write>(output: Output) -> Result<()> {
let command = Command::from(key);
app.run_command(command);
}
Event::Tick => {}
}
}

View file

@ -1,8 +1,24 @@
use tui::backend::Backend;
use tui::widgets::Paragraph;
use tui::layout::{Constraint, Direction, Layout};
use tui::style::{Color, Style};
use tui::widgets::{Block, BorderType, Borders, Paragraph};
use tui::Frame;
/// Renders the user interface.
pub fn render<B: Backend>(frame: &mut Frame<'_, B>) {
frame.render_widget(Paragraph::new(env!("CARGO_PKG_NAME")), frame.size());
let rect = frame.size();
let chunks = Layout::default()
.direction(Direction::Vertical)
.constraints([Constraint::Min(rect.height - 3), Constraint::Min(3)].as_ref())
.split(rect);
frame.render_widget(
Paragraph::new(env!("CARGO_PKG_NAME")).block(
Block::default()
.borders(Borders::all())
.border_style(Style::default().fg(Color::White))
.border_type(BorderType::Rounded)
.style(Style::default().bg(Color::Black)),
),
chunks[1],
);
}