#[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum MouseButton { Left, Right, Middle, } #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub enum MouseEventType { Down(MouseButton), Up(MouseButton), Move, } #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct MouseEvent { pub etype: MouseEventType, pub pos: (u32, u32), } #[derive(Copy, Clone, Default, PartialEq, Eq)] pub struct MouseState { pub buttons: [bool; 3], pub pos: (u32, u32), } impl MouseEvent { pub fn new(etype: MouseEventType, pos: (u32, u32)) -> Self { Self { etype, pos, } } } impl From for MouseButton { fn from(index: usize) -> MouseButton { match index { 0 => MouseButton::Left, 1 => MouseButton::Right, 2 => MouseButton::Middle, _ => panic!("unexpected mouse button index: {:?}", index), } } } impl From for usize { fn from(button: MouseButton) -> usize { match button { MouseButton::Left => 0, MouseButton::Right => 1, MouseButton::Middle => 2, } } } impl MouseState { pub fn with(left: bool, right: bool, middle: bool, x: u32, y: u32) -> Self { Self { buttons: [left, right, middle], pos: (x, y), } } pub fn to_events(&mut self, next_state: MouseState) -> Vec { if *self != next_state { self.pos = next_state.pos; let events: Vec = self .buttons .into_iter() .zip(next_state.buttons) .enumerate() .filter_map(|(i, (prev, next))| { if prev != next { self.buttons[i] = next; let button = MouseButton::from(i); let etype = if next { MouseEventType::Down(button) } else { MouseEventType::Up(button) }; Some(MouseEvent::new(etype, next_state.pos)) } else { None } }) .collect(); if !events.is_empty() { events } else { vec![MouseEvent::new(MouseEventType::Move, next_state.pos)] } } else { vec![] } } pub fn update_with(&mut self, event: MouseEvent) { self.pos = event.pos; match event.etype { MouseEventType::Up(button) => self.buttons[usize::from(button)] = false, MouseEventType::Down(button) => self.buttons[usize::from(button)] = true, MouseEventType::Move => {}, } } }