use std::sync::Arc;
use crate::{Key, Keymap};
use super::handlers::{FocusHandler, MouseHandler, ResizeHandler};
pub struct CrosstermHandlers<S, A> {
pub mouse: Option<MouseHandler<S, A>>,
pub resize: Option<ResizeHandler<S, A>>,
pub focus_gained: Option<FocusHandler<S, A>>,
pub focus_lost: Option<FocusHandler<S, A>>,
}
impl<S, A> Default for CrosstermHandlers<S, A> {
fn default() -> Self {
Self {
mouse: None,
resize: None,
focus_gained: None,
focus_lost: None,
}
}
}
impl<S, A> Clone for CrosstermHandlers<S, A> {
fn clone(&self) -> Self {
Self {
mouse: self.mouse.clone(),
resize: self.resize.clone(),
focus_gained: self.focus_gained.clone(),
focus_lost: self.focus_lost.clone(),
}
}
}
pub trait CrosstermKeymapExt<K, S, A, C>: Sized
where
K: Key,
{
#[must_use]
fn on_mouse<F>(self, handler: F) -> Self
where
F: Fn(crossterm::event::MouseEvent, &S) -> Option<A> + Send + Sync + 'static;
#[must_use]
fn on_resize<F>(self, handler: F) -> Self
where
F: Fn(u16, u16, &S) -> Option<A> + Send + Sync + 'static;
#[must_use]
fn on_focus_gained<F>(self, handler: F) -> Self
where
F: Fn(&S) -> Option<A> + Send + Sync + 'static;
#[must_use]
fn on_focus_lost<F>(self, handler: F) -> Self
where
F: Fn(&S) -> Option<A> + Send + Sync + 'static;
fn mouse_handler(&self) -> Option<&MouseHandler<S, A>>;
fn resize_handler(&self) -> Option<&ResizeHandler<S, A>>;
fn focus_gained_handler(&self) -> Option<&FocusHandler<S, A>>;
fn focus_lost_handler(&self) -> Option<&FocusHandler<S, A>>;
}
impl<K, S, A, C> CrosstermKeymapExt<K, S, A, C> for Keymap<K, S, A, C>
where
K: Key,
S: 'static,
A: 'static,
C: Clone,
{
fn on_mouse<F>(mut self, handler: F) -> Self
where
F: Fn(crossterm::event::MouseEvent, &S) -> Option<A> + Send + Sync + 'static,
{
let mut handlers = self
.backend_handlers::<CrosstermHandlers<S, A>>()
.cloned()
.unwrap_or_default();
handlers.mouse = Some(Arc::new(handler));
self.set_backend_handlers(handlers);
self
}
fn on_resize<F>(mut self, handler: F) -> Self
where
F: Fn(u16, u16, &S) -> Option<A> + Send + Sync + 'static,
{
let mut handlers = self
.backend_handlers::<CrosstermHandlers<S, A>>()
.cloned()
.unwrap_or_default();
handlers.resize = Some(Arc::new(handler));
self.set_backend_handlers(handlers);
self
}
fn on_focus_gained<F>(mut self, handler: F) -> Self
where
F: Fn(&S) -> Option<A> + Send + Sync + 'static,
{
let mut handlers = self
.backend_handlers::<CrosstermHandlers<S, A>>()
.cloned()
.unwrap_or_default();
handlers.focus_gained = Some(Arc::new(handler));
self.set_backend_handlers(handlers);
self
}
fn on_focus_lost<F>(mut self, handler: F) -> Self
where
F: Fn(&S) -> Option<A> + Send + Sync + 'static,
{
let mut handlers = self
.backend_handlers::<CrosstermHandlers<S, A>>()
.cloned()
.unwrap_or_default();
handlers.focus_lost = Some(Arc::new(handler));
self.set_backend_handlers(handlers);
self
}
fn mouse_handler(&self) -> Option<&MouseHandler<S, A>> {
self.backend_handlers::<CrosstermHandlers<S, A>>()
.and_then(|h| h.mouse.as_ref())
}
fn resize_handler(&self) -> Option<&ResizeHandler<S, A>> {
self.backend_handlers::<CrosstermHandlers<S, A>>()
.and_then(|h| h.resize.as_ref())
}
fn focus_gained_handler(&self) -> Option<&FocusHandler<S, A>> {
self.backend_handlers::<CrosstermHandlers<S, A>>()
.and_then(|h| h.focus_gained.as_ref())
}
fn focus_lost_handler(&self) -> Option<&FocusHandler<S, A>> {
self.backend_handlers::<CrosstermHandlers<S, A>>()
.and_then(|h| h.focus_lost.as_ref())
}
}