Skip to main content

dwipe/events/
mod.rs

1mod handler;
2
3pub use handler::handle_key_events;
4
5use crossterm::event::{Event as CrosstermEvent, KeyEvent, MouseEvent};
6use std::sync::mpsc::{self, Receiver};
7use std::thread;
8use std::time::{Duration, Instant};
9
10/// Terminal events.
11#[derive(Clone, Copy, Debug)]
12pub enum Event {
13    /// Terminal tick.
14    Tick,
15    /// Key press.
16    Key(KeyEvent),
17    /// Mouse click/scroll.
18    Mouse(MouseEvent),
19    /// Terminal resize.
20    Resize(u16, u16),
21}
22
23#[derive(Debug)]
24pub struct EventHandler {
25    receiver: Receiver<Event>,
26}
27
28impl EventHandler {
29    pub fn new(tick_rate: u64) -> Self {
30        let tick_rate = Duration::from_millis(tick_rate);
31        let (sender, receiver) = mpsc::channel();
32        let sender_clone = sender.clone();
33
34        thread::spawn(move || {
35            let mut last_tick = Instant::now();
36            loop {
37                if last_tick.elapsed() >= tick_rate {
38                    if sender_clone.send(Event::Tick).is_err() {
39                        break; // Exit if the receiver has dropped
40                    }
41                    last_tick = Instant::now();
42                }
43                if crossterm::event::poll(Duration::from_millis(1)).unwrap() {
44                    if let Ok(crossterm_event) = crossterm::event::read() {
45                        match crossterm_event {
46                            CrosstermEvent::Key(key) => {
47                                let _ = sender_clone.send(Event::Key(key));
48                            }
49                            CrosstermEvent::Mouse(mouse) => {
50                                let _ = sender_clone.send(Event::Mouse(mouse));
51                            }
52                            CrosstermEvent::Resize(x, y) => {
53                                let _ = sender_clone.send(Event::Resize(x, y));
54                            }
55                            _ => {}
56                        }
57                    }
58                }
59                thread::sleep(Duration::from_millis(10));
60            }
61        });
62
63        Self { receiver }
64    }
65
66    pub fn next(&self) -> Result<Event, mpsc::RecvError> {
67        self.receiver.recv()
68    }
69}