use std::{io::Result, time::Duration};
use nu_utils::time::Instant;
use crossterm::event::{Event, KeyEvent, KeyEventKind, poll, read};
pub struct UIEvents {
tick_rate: Duration,
}
pub struct Cfg {
pub tick_rate: Duration,
}
impl Default for Cfg {
fn default() -> Cfg {
Cfg {
tick_rate: Duration::from_millis(250),
}
}
}
impl UIEvents {
pub fn new() -> UIEvents {
UIEvents::with_config(Cfg::default())
}
pub fn with_config(config: Cfg) -> UIEvents {
UIEvents {
tick_rate: config.tick_rate,
}
}
pub fn next_key_press(&self) -> Result<Option<KeyEvent>> {
let deadline = Instant::now() + self.tick_rate;
loop {
let timeout = deadline.saturating_duration_since(Instant::now());
if !poll(timeout)? {
return Ok(None);
}
if let Event::Key(event) = read()?
&& event.kind == KeyEventKind::Press
{
return Ok(Some(event));
}
}
}
pub fn try_next_key_press(&self) -> Result<Option<KeyEvent>> {
loop {
if !poll(Duration::ZERO)? {
return Ok(None);
}
if let Event::Key(event) = read()?
&& event.kind == KeyEventKind::Press
{
return Ok(Some(event));
}
}
}
}