bitbucket_cli/tui/
event.rs

1use anyhow::Result;
2use crossterm::event::{self, KeyEvent, MouseEvent};
3use std::sync::mpsc;
4use std::thread;
5use std::time::Duration;
6
7/// Terminal events
8#[derive(Debug)]
9pub enum Event {
10    /// Key press
11    Key(KeyEvent),
12    /// Mouse event
13    Mouse(MouseEvent),
14    /// Terminal resize
15    Resize(u16, u16),
16    /// Tick (for animations/updates)
17    Tick,
18}
19
20/// Event handler
21pub struct EventHandler {
22    rx: mpsc::Receiver<Event>,
23    _tx: mpsc::Sender<Event>,
24}
25
26impl EventHandler {
27    /// Create a new event handler with the given tick rate in milliseconds
28    pub fn new(tick_rate: u64) -> Self {
29        let tick_rate = Duration::from_millis(tick_rate);
30        let (tx, rx) = mpsc::channel();
31        let _tx = tx.clone();
32
33        thread::spawn(move || {
34            loop {
35                // Poll for events with timeout
36                if event::poll(tick_rate).unwrap_or(false) {
37                    match event::read() {
38                        Ok(event::Event::Key(key)) => {
39                            if tx.send(Event::Key(key)).is_err() {
40                                break;
41                            }
42                        }
43                        Ok(event::Event::Mouse(mouse)) => {
44                            if tx.send(Event::Mouse(mouse)).is_err() {
45                                break;
46                            }
47                        }
48                        Ok(event::Event::Resize(w, h)) => {
49                            if tx.send(Event::Resize(w, h)).is_err() {
50                                break;
51                            }
52                        }
53                        _ => {}
54                    }
55                } else {
56                    // Send tick event
57                    if tx.send(Event::Tick).is_err() {
58                        break;
59                    }
60                }
61            }
62        });
63
64        Self { rx, _tx }
65    }
66
67    /// Get the next event
68    pub fn next(&self) -> Result<Event> {
69        Ok(self.rx.recv()?)
70    }
71}