use xkbcommon::xkb;
use std::{cell::RefCell, rc::Rc};
#[derive(Debug, Clone)]
pub struct WindowEventQueue {
inner: Rc<RefCell<Vec<WindowEvent>>>,
}
impl WindowEventQueue {
pub fn new() -> Self {
Self {
inner: Rc::new(RefCell::new(Vec::<WindowEvent>::new())),
}
}
pub fn clone(&self) -> Self {
Self {
inner: self.inner.clone()
}
}
pub fn push(&self, event: WindowEvent) {
self.inner.borrow_mut().push(event);
}
pub fn drain(&self) -> Vec<WindowEvent> {
self.inner.borrow_mut().drain(..).collect()
}
pub fn is_empty(&self) -> bool {
self.inner.borrow().is_empty()
}
}
#[derive(Debug, Clone, PartialEq)]
pub enum WindowEvent {
Keyboard(KeyEvent),
Pointer(MouseEvent),
Resize {
width: u32,
height: u32
},
}
impl WindowEvent {
pub fn new_keyboard_event(keymap_state: &xkb::State, key: u32, value: u32) -> WindowEvent {
let keysym = keymap_state.key_get_one_sym(xkb::Keycode::new(key+8));
let shift = keymap_state.mod_name_is_active(xkb::MOD_NAME_SHIFT, xkb::STATE_MODS_EFFECTIVE);
let ctrl = keymap_state.mod_name_is_active(xkb::MOD_NAME_CTRL, xkb::STATE_MODS_EFFECTIVE);
let alt = keymap_state.mod_name_is_active(xkb::MOD_NAME_ALT, xkb::STATE_MODS_EFFECTIVE);
let keycode = match keysym {
xkb::Keysym::BackSpace => KeyCode::Backspace,
xkb::Keysym::Return => KeyCode::Enter,
xkb::Keysym::Left => KeyCode::Left,
xkb::Keysym::Right => KeyCode::Right,
xkb::Keysym::Up => KeyCode::Up,
xkb::Keysym::Down => KeyCode::Down,
xkb::Keysym::Tab => KeyCode::Tab,
xkb::Keysym::Delete => KeyCode::Delete,
xkb::Keysym::Home => KeyCode::Home,
xkb::Keysym::End => KeyCode::End,
xkb::Keysym::Page_Up => KeyCode::PageUp,
xkb::Keysym::Page_Down => KeyCode::PageDown,
xkb::Keysym::Escape => KeyCode::Esc,
xkb::Keysym::F1 => KeyCode::F(1),
xkb::Keysym::F2 => KeyCode::F(2),
xkb::Keysym::F3 => KeyCode::F(3),
xkb::Keysym::F4 => KeyCode::F(4),
xkb::Keysym::F5 => KeyCode::F(5),
xkb::Keysym::F6 => KeyCode::F(6),
xkb::Keysym::F7 => KeyCode::F(7),
xkb::Keysym::F8 => KeyCode::F(8),
xkb::Keysym::F9 => KeyCode::F(9),
xkb::Keysym::F10 => KeyCode::F(10),
xkb::Keysym::F11 => KeyCode::F(11),
xkb::Keysym::F12 => KeyCode::F(12),
_ => {
let utf32 = xkb::keysym_to_utf32(keysym);
if utf32 != 0 {
let ch = std::char::from_u32(utf32).unwrap();
KeyCode::Char(ch)
} else {
KeyCode::Unidentified
}
}
};
WindowEvent::Keyboard(KeyEvent {
code: keycode,
value,
shift,
alt,
ctrl
})
}
pub fn new_pointer_motion_event(x: f64, y: f64) -> Self {
Self::Pointer(MouseEvent::Motion { x, y })
}
pub fn new_pointer_enter_event(x: f64, y: f64) -> Self {
Self::Pointer(MouseEvent::Enter { x, y })
}
pub fn new_pointer_leave_event() -> Self {
Self::Pointer(MouseEvent::Leave)
}
pub fn new_pointer_axis_event(code: AxisCode, value: f64) -> Self {
Self::Pointer(MouseEvent::Axis { code, value })
}
pub fn new_pointer_button_event(code: u32, value: u32) -> Self {
let button_code = match code {
272 => ButtonCode::Left,
273 => ButtonCode::Right,
274 => ButtonCode::Middle,
_ => ButtonCode::Unknown,
};
Self::Pointer(MouseEvent::Button { code: button_code, value })
}
pub fn new_resize_event(width: u32, height: u32) -> Self {
Self::Resize { width, height }
}
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub struct KeyEvent {
pub code: KeyCode,
pub value: u32,
pub shift: bool,
pub alt: bool,
pub ctrl: bool,
}
#[derive(Debug, Clone, PartialEq)]
pub enum MouseEvent {
Motion { x: f64, y: f64 },
Enter { x: f64, y: f64 },
Leave,
Button { code: ButtonCode, value: u32 },
Axis { code: AxisCode, value: f64 },
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum KeyCode {
Char(char),
F(u8),
Backspace,
Enter,
Left,
Right,
Up,
Down,
Tab,
Delete,
Home,
End,
PageUp,
PageDown,
Esc,
Unidentified,
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum ButtonCode {
Left,
Right,
Middle,
Unknown,
}
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum AxisCode {
VerticalScroll,
HorizontalScroll,
}