mirror of
https://github.com/orhun/systeroid
synced 2024-10-02 21:53:31 +00:00
feat(tui): render the input prompt
This commit is contained in:
parent
54b4c0e61b
commit
cb9d072a3e
|
@ -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()
|
||||
|
|
|
@ -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 => {}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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],
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue