use std::fmt::Debug;
use winapi::um::winuser::*;
use winapi::shared::minwindef::DWORD;
use crate::sender::{Event, EventQueue};
use crate::util::{i32_to_u32};
#[derive(Debug)]
pub enum MouseEvent {
SetCursor(i16, i16),
MoveCursor(i32, i32),
ButtonDown(MouseButton),
ButtonUp(MouseButton),
ButtonDoubleClick(MouseButton),
ScrollHorizontal(i32),
ScrollVertical(i32)
}
impl Event for MouseEvent {
fn into_event_queue(self) -> EventQueue {
match self {
MouseEvent::SetCursor(x, y) => _move(x as i32, y as i32, false),
MouseEvent::MoveCursor(x, y) => _move(x, y, true),
MouseEvent::ButtonDown(b) => _button(b, false),
MouseEvent::ButtonUp(b) => _button(b, true),
MouseEvent::ScrollHorizontal(a) => _scroll(a, MOUSEEVENTF_HWHEEL),
MouseEvent::ScrollVertical(a) => _scroll(a, MOUSEEVENTF_WHEEL),
e => panic!("Cannot convert {:?} to EventQueue.", e)
}.into()
}
}
#[derive(Debug)]
pub enum MouseButton {
Left,
Middle,
Right
}
impl MouseButton {
fn get_down_flag(&self) -> DWORD {
match self {
MouseButton::Left => MOUSEEVENTF_LEFTDOWN,
MouseButton::Right => MOUSEEVENTF_RIGHTDOWN,
MouseButton::Middle => MOUSEEVENTF_MIDDLEDOWN
}
}
fn get_up_flag(&self) -> DWORD {
match self {
MouseButton::Left => MOUSEEVENTF_LEFTUP,
MouseButton::Right => MOUSEEVENTF_RIGHTUP,
MouseButton::Middle => MOUSEEVENTF_MIDDLEUP
}
}
}
fn _scroll(amount: i32, flags: DWORD) -> INPUT {
_get_by_data_and_flag(i32_to_u32(amount * WHEEL_DELTA as i32), flags)
}
fn _get_by_data_and_flag(data: u32, flags: DWORD) -> INPUT {
get_mouse_input(0, 0, data, flags)
}
fn _button(b: MouseButton, up: bool) -> INPUT {
_get_by_data_and_flag(0, if up { b.get_up_flag() } else { b.get_down_flag() })
}
fn _move(x: i32, y: i32, rel: bool) -> INPUT {
get_mouse_input(x, y, 0, MOUSEEVENTF_MOVE | if rel { 0 } else { MOUSEEVENTF_ABSOLUTE })
}
pub fn get_mouse_input(dx: i32, dy: i32, mouse_data: DWORD, dw_flags: DWORD) -> INPUT {
let mut union: INPUT_u = unsafe { std::mem::zeroed() };
let inner_union = unsafe { union.mi_mut() };
*inner_union = MOUSEINPUT {
dx,
dy,
mouseData: mouse_data,
dwFlags: dw_flags,
time: 0,
dwExtraInfo: 0
};
INPUT {
type_: INPUT_MOUSE,
u: union,
}
}