2023-04-13 14:09:59 +02:00
|
|
|
use crossterm::event::{self, Event as CrosstermEvent};
|
|
|
|
use std::thread;
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
use mockall::automock;
|
|
|
|
|
|
|
|
use super::event::{Event, EventError, EventSender};
|
|
|
|
|
|
|
|
#[cfg_attr(test, automock)]
|
2023-05-10 22:52:03 +02:00
|
|
|
pub trait IEventListener {
|
2023-04-13 14:09:59 +02:00
|
|
|
fn spawn(self) -> thread::JoinHandle<EventError>;
|
|
|
|
}
|
|
|
|
|
2023-05-10 22:52:03 +02:00
|
|
|
pub struct EventListener {
|
2023-04-13 14:09:59 +02:00
|
|
|
events: EventSender,
|
|
|
|
}
|
|
|
|
|
|
|
|
// GRCOV_EXCL_START
|
2023-05-10 22:52:03 +02:00
|
|
|
impl EventListener {
|
2023-04-13 14:09:59 +02:00
|
|
|
pub fn new(events: EventSender) -> Self {
|
2023-05-10 22:52:03 +02:00
|
|
|
EventListener { events }
|
2023-04-13 14:09:59 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-05-10 22:52:03 +02:00
|
|
|
impl IEventListener for EventListener {
|
2023-04-13 14:09:59 +02:00
|
|
|
fn spawn(self) -> thread::JoinHandle<EventError> {
|
|
|
|
thread::spawn(move || {
|
|
|
|
loop {
|
|
|
|
// Put this inside an if event::poll {...} if the display needs to be refreshed on a
|
|
|
|
// periodic basis. See
|
|
|
|
// https://github.com/tui-rs-revival/rust-tui-template/blob/master/src/event.rs.
|
|
|
|
match event::read() {
|
|
|
|
Ok(event) => {
|
|
|
|
if let Err(err) = match event {
|
|
|
|
CrosstermEvent::Key(e) => self.events.send(Event::Key(e)),
|
|
|
|
CrosstermEvent::Mouse(e) => self.events.send(Event::Mouse(e)),
|
|
|
|
CrosstermEvent::Resize(w, h) => self.events.send(Event::Resize(w, h)),
|
|
|
|
_ => unimplemented!(),
|
|
|
|
} {
|
|
|
|
return err;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
Err(err) => return EventError::Io(err),
|
|
|
|
};
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// GRCOV_EXCL_STOP
|