use crate::{Result, Yarr, Yogurt};
use crossterm::event::read;
use crossterm::event::DisableMouseCapture;
use crossterm::event::EnableMouseCapture;
pub use crossterm::event::KeyEventKind;
pub use crossterm::event::KeyModifiers;
use crossterm::event::{self, poll};
use crossterm::execute;
pub use event::MouseEvent;
use std::time::Duration;
pub use crossterm::event::MouseEventKind;
pub use crossterm::event::MouseButton;
impl Yogurt {
pub fn read_event(&mut self, dur: Duration) -> Result<Option<Event>> {
if self.size.is_none() {
return Err(Yarr::NotInAltMode);
}
if poll(dur)? {
let read = read()?;
let event = read.try_into()?;
Ok(Some(event))
} else {
Ok(None)
}
}
pub fn block_event(&mut self) -> Result<Event> {
if self.size.is_none() {
return Err(Yarr::NotInAltMode);
}
let read = read()?;
let event = read.try_into()?;
Ok(event)
}
pub fn enable_mouse_capture(&mut self) -> Result<()> {
execute! {
self.stdout,
EnableMouseCapture,
}?;
Ok(())
}
pub fn disable_mouse_capture(&mut self) -> Result<()> {
execute! {
self.stdout,
DisableMouseCapture,
}?;
Ok(())
}
}
pub enum Event {
FocusGained,
FocusLost,
Key(KeyEvent),
Mouse(MouseEvent),
Paste(String),
Resize(u16, u16),
}
impl TryFrom<event::Event> for Event {
type Error = Yarr;
fn try_from(value: event::Event) -> Result<Self> {
match value {
event::Event::FocusGained => Ok(Event::FocusGained),
event::Event::FocusLost => Ok(Event::FocusLost),
event::Event::Key(ke) => Ok(Event::Key(ke.try_into()?)),
event::Event::Mouse(me) => Ok(Event::Mouse(me)),
event::Event::Paste(ps) => Ok(Event::Paste(ps)),
event::Event::Resize(x, y) => Ok(Event::Resize(x, y)),
}
}
}
pub struct KeyEvent {
pub code: KeyCode,
pub kind: KeyEventKind,
pub mods: KeyModifiers,
}
impl From<KeyEvent> for event::KeyEvent {
fn from(ke: KeyEvent) -> Self {
event::KeyEvent {
code: ke.code.into(),
modifiers: ke.mods,
kind: ke.kind,
state: event::KeyEventState::NONE,
}
}
}
impl TryFrom<event::KeyEvent> for KeyEvent {
type Error = Yarr;
fn try_from(ke: event::KeyEvent) -> Result<Self> {
let code = ke.code.try_into()?;
Ok(KeyEvent {
code,
kind: ke.kind,
mods: ke.modifiers,
})
}
}
pub enum KeyCode {
Backspace,
Enter,
Left,
Right,
Up,
Down,
Home,
End,
PageUp,
PageDown,
Tab,
Backtab,
Delete,
Insert,
F(u8),
Char(char),
Null,
Esc,
}
impl From<KeyCode> for event::KeyCode {
fn from(kc: KeyCode) -> Self {
use KeyCode::*;
match kc {
Backspace => event::KeyCode::Backspace,
Enter => event::KeyCode::Enter,
Left => event::KeyCode::Left,
Right => event::KeyCode::Right,
Up => event::KeyCode::Up,
Down => event::KeyCode::Down,
Home => event::KeyCode::Home,
End => event::KeyCode::End,
PageUp => event::KeyCode::PageUp,
PageDown => event::KeyCode::PageDown,
Tab => event::KeyCode::Tab,
Backtab => event::KeyCode::BackTab,
Delete => event::KeyCode::Delete,
Insert => event::KeyCode::Insert,
F(f) => event::KeyCode::F(f),
Char(ch) => event::KeyCode::Char(ch),
Null => event::KeyCode::Null,
Esc => event::KeyCode::Esc,
}
}
}
impl TryFrom<event::KeyCode> for KeyCode {
type Error = Yarr;
fn try_from(kc: event::KeyCode) -> Result<KeyCode> {
use KeyCode::*;
match kc {
event::KeyCode::Backspace => Ok(Backspace),
event::KeyCode::Enter => Ok(Enter),
event::KeyCode::Left => Ok(Left),
event::KeyCode::Right => Ok(Right),
event::KeyCode::Up => Ok(Up),
event::KeyCode::Down => Ok(Down),
event::KeyCode::Home => Ok(Home),
event::KeyCode::End => Ok(End),
event::KeyCode::PageUp => Ok(PageUp),
event::KeyCode::PageDown => Ok(PageDown),
event::KeyCode::Tab => Ok(Tab),
event::KeyCode::BackTab => Ok(Backtab),
event::KeyCode::Delete => Ok(Delete),
event::KeyCode::Insert => Ok(Insert),
event::KeyCode::F(f) => Ok(F(f)),
event::KeyCode::Char(ch) => Ok(Char(ch)),
event::KeyCode::Null => Ok(Null),
event::KeyCode::Esc => Ok(Esc),
_ => Err(Yarr::FromCrossKeyCodeError),
}
}
}