use std::rc::Rc;
use crate::Position;
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum MouseButton {
Left,
Middle,
Right,
}
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct EventStateFrame {
pub mouse: MouseStateFrame,
pub terminal: TerminalStateFrame,
}
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct EventState {
pub mouse: MouseState,
pub terminal: TerminalState,
}
impl EventState {
pub fn new() -> Self {
Self {
mouse: MouseState::new(),
terminal: TerminalState::new(),
}
}
#[inline(always)]
pub fn calculate_frame(&self, prev: Self) -> EventStateFrame {
return EventStateFrame {
mouse: self.mouse.calculate_frame(prev.mouse),
terminal: self.terminal.calculate_frame(prev.terminal),
};
}
}
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum Focus {
Focused,
Unfocused,
JustNowFocused,
JustNowUnfocused,
}
impl Focus {
#[inline(always)]
pub fn calculate(current: bool, prev: bool) -> Self {
return match (current, prev) {
(true, true) => Focus::Focused,
(false, false) => Focus::Unfocused,
(true, false) => Focus::JustNowFocused,
(false, true) => Focus::JustNowUnfocused,
};
}
}
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct TerminalStateFrame {
pub focused: Focus,
pub paste: Option<Rc<String>>,
}
#[derive(Debug, Clone, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct TerminalState {
pub focused: bool,
pub paste: Option<Rc<String>>,
}
impl TerminalState {
pub fn new() -> Self {
Self {
focused: true,
paste: None,
}
}
#[inline(always)]
pub fn calculate_frame(&self, prev: Self) -> TerminalStateFrame {
return TerminalStateFrame {
focused: Focus::calculate(self.focused, prev.focused),
paste: self.paste.clone(),
};
}
}
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct MouseStateFrame {
pub buttons: MouseButtonsStateFrame,
pub position: Position,
pub scroll: Position,
}
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct MouseState {
pub buttons: MouseButtonsState,
pub position: Position,
pub scroll: MouseScrollState,
}
impl MouseState {
pub fn new() -> Self {
Self {
buttons: MouseButtonsState::new(),
position: Position::zero(),
scroll: MouseScrollState::new(),
}
}
#[inline(always)]
pub fn calculate_frame(&self, prev: Self) -> MouseStateFrame {
return MouseStateFrame {
buttons: self.buttons.calculate_frame(prev.buttons),
position: self.position,
scroll: self.scroll.scroll_diff(prev.scroll),
};
}
}
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct MouseScrollState {
pub cols: i64,
pub rows: i64,
}
impl MouseScrollState {
pub fn new() -> Self {
Self {
cols: 0,
rows: 0,
}
}
#[inline(always)]
pub fn scroll_diff(&self, prev: Self) -> Position {
return Position::new(
(self.cols - prev.cols) as i16,
(self.rows - prev.rows) as i16,
);
}
#[inline(always)]
pub fn go_up(&mut self, amount: i16) {
self.rows -= amount as i64;
}
#[inline(always)]
pub fn go_down(&mut self, amount: i16) {
self.rows += amount as i64;
}
#[inline(always)]
pub fn go_left(&mut self, amount: i16) {
self.cols -= amount as i64;
}
#[inline(always)]
pub fn go_right(&mut self, amount: i16) {
self.cols += amount as i64;
}
}
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct MouseButtonsState {
pub left: bool,
pub middle: bool,
pub right: bool,
}
impl MouseButtonsState {
pub fn new() -> Self {
Self {
left: false,
middle: false,
right: false,
}
}
#[inline(always)]
pub fn is_down(&self, button: MouseButton) -> bool {
return match button {
MouseButton::Left => self.left,
MouseButton::Middle => self.middle,
MouseButton::Right => self.right,
};
}
#[inline(always)]
pub fn calculate_frame(&self, prev: Self) -> MouseButtonsStateFrame {
return MouseButtonsStateFrame {
left: MouseButtonFrame::calculate(self.left, prev.left),
middle: MouseButtonFrame::calculate(self.middle, prev.middle),
right: MouseButtonFrame::calculate(self.right, prev.right),
};
}
}
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum MouseButtonFrame {
Up,
Down,
Pressed,
Released,
}
impl MouseButtonFrame {
#[inline(always)]
pub fn calculate(current: bool, prev: bool) -> Self {
return match (current, prev) {
(false, false) => MouseButtonFrame::Up,
(true, true) => MouseButtonFrame::Down,
(true, false) => MouseButtonFrame::Pressed,
(false, true) => MouseButtonFrame::Released,
};
}
}
#[derive(Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub struct MouseButtonsStateFrame {
pub left: MouseButtonFrame,
pub middle: MouseButtonFrame,
pub right: MouseButtonFrame,
}