1use crate::{Error, EzCptId, EzCptIds, Matcher};
2use crossterm::event::{Event as CrosstermEvent, KeyEventKind};
3use crossterm::event::{KeyEvent, MouseEvent};
4use std::fmt::Debug;
5use std::hash::Hash;
6use tracing::trace;
7pub trait EzMsg: PartialEq + Debug + Clone + Send + 'static {}
9
10#[derive(PartialEq, Eq, Clone, Debug, Hash)]
12pub struct NoClientMsg;
13impl EzMsg for NoClientMsg {}
14
15#[derive(Debug, Eq, PartialEq, Clone)]
18pub enum EzEvent<CID, CM>
19where
20 CID: EzCptIds,
21 CM: EzMsg,
22{
23 Keyboard(KeyEvent),
25 Mouse(MouseEvent),
27 WindowResize(u16, u16),
29
30 ForceFocus(EzCptId<CID>),
32 ForceBlur(),
34 FocusGained,
36 FocusLost,
38 Paste(String),
40
41 Init,
43 Tick,
45 Render,
47 Quit,
49
50 None,
52
53 Error(Error),
55
56 UpdateLegend(String, Vec<Matcher>),
58
59 Client(CM),
61}
62impl<CID, CM> EzEvent<CID, CM>
63where
64 CID: EzCptIds,
65 CM: EzMsg,
66{
67 pub fn as_kb(&self) -> Option<&KeyEvent> {
69 if let EzEvent::Keyboard(k) = self {
70 Some(k)
71 } else {
72 None
73 }
74 }
75
76 pub fn as_mouse(&self) -> Option<&MouseEvent> {
78 if let EzEvent::Mouse(m) = self {
79 Some(m)
80 } else {
81 None
82 }
83 }
84 pub fn as_resize(&self) -> Option<(&u16, &u16)> {
86 if let EzEvent::WindowResize(x, y) = self {
87 Some((x, y))
88 } else {
89 None
90 }
91 }
92
93 pub fn as_client(&self) -> Option<&CM> {
95 if let EzEvent::Client(msg) = self {
96 Some(msg)
97 } else {
98 None
99 }
100 }
101}
102
103impl<CID, CM> EzEvent<CID, CM>
104where
105 CID: EzCptIds,
106 CM: EzMsg,
107{
108 pub fn try_original(&self) -> Option<CrosstermEvent> {
110 match self {
111 EzEvent::Keyboard(key) => Some(CrosstermEvent::Key(*key)),
112 EzEvent::Mouse(mouse) => Some(CrosstermEvent::Mouse(*mouse)),
113 EzEvent::WindowResize(x, y) => Some(CrosstermEvent::Resize(*x, *y)),
114 EzEvent::FocusLost => Some(CrosstermEvent::FocusLost),
115 EzEvent::FocusGained => Some(CrosstermEvent::FocusGained),
116 EzEvent::Paste(s) => Some(CrosstermEvent::Paste(s.to_string())),
117 _ => None,
118 }
119 }
120}
121
122impl<CID, CM> From<CrosstermEvent> for EzEvent<CID, CM>
126where
127 CID: EzCptIds,
128 CM: EzMsg,
129{
130 fn from(event: CrosstermEvent) -> Self {
131 trace!("{event:?}");
132 match event {
133 CrosstermEvent::Key(key) => match key.kind {
134 KeyEventKind::Press | KeyEventKind::Repeat | KeyEventKind::Release => {
136 EzEvent::Keyboard(key)
137 }
138 },
139 CrosstermEvent::Mouse(mouse) => EzEvent::Mouse(mouse),
140 CrosstermEvent::Resize(x, y) => EzEvent::WindowResize(x, y),
141 CrosstermEvent::FocusLost => EzEvent::FocusLost,
142 CrosstermEvent::FocusGained => EzEvent::FocusGained,
143 CrosstermEvent::Paste(s) => EzEvent::Paste(s),
144 }
145 }
146}