use crate::core::mouse::{MouseClick, MouseScroll};
use std::mem::{size_of, zeroed};
use std::{thread, time, time::Instant};
use winapi::shared::windef::POINT;
use winapi::um::winuser::{
SendInput, SetCursorPos, INPUT, INPUT_MOUSE, MOUSEEVENTF_HWHEEL, MOUSEEVENTF_LEFTDOWN,
MOUSEEVENTF_LEFTUP, MOUSEEVENTF_MIDDLEDOWN, MOUSEEVENTF_MIDDLEUP, MOUSEEVENTF_RIGHTDOWN,
MOUSEEVENTF_RIGHTUP, MOUSEEVENTF_WHEEL,
};
#[derive(Debug)]
pub struct Mouse {}
impl Mouse {
#[allow(unused_variables)]
pub fn new() -> Mouse {
Mouse {}
}
pub fn move_mouse_to_pos(x: i32, y: i32, moving_time: f32) {
unsafe {
if moving_time <= 0.0 {
SetCursorPos(x, y);
return;
}
};
let start = Instant::now();
let start_location = Mouse::get_mouse_position();
let distance_x = x - start_location.0;
let distance_y = y - start_location.1;
loop {
let duration = start.elapsed().as_secs_f32();
let time_passed_percentage = duration / moving_time;
if time_passed_percentage > 10.0 {
continue;
}
let new_x = start_location.0 as f32 + (time_passed_percentage * distance_x as f32);
let new_y = start_location.1 as f32 + (time_passed_percentage * distance_y as f32);
unsafe {
if time_passed_percentage >= 1.0 {
SetCursorPos(x, y);
break;
} else {
SetCursorPos(new_x as i32, new_y as i32);
}
}
}
}
pub fn drag_mouse(x: i32, y: i32, moving_time: f32) {
let (down, up) = (MOUSEEVENTF_LEFTDOWN, MOUSEEVENTF_LEFTUP);
unsafe {
let mut input_down: INPUT = zeroed();
input_down.type_ = INPUT_MOUSE;
input_down.u.mi_mut().dwFlags = down;
SendInput(1, &mut input_down, size_of::<INPUT>() as i32);
thread::sleep(time::Duration::from_millis(80));
Mouse::move_mouse_to_pos(x, y, moving_time);
thread::sleep(time::Duration::from_millis(50));
let mut input_up: INPUT = zeroed();
input_up.type_ = INPUT_MOUSE;
input_up.u.mi_mut().dwFlags = up;
SendInput(2, &mut input_up, size_of::<INPUT>() as i32);
}
}
pub fn get_mouse_position() -> (i32, i32) {
unsafe {
let mut point = POINT { x: 0, y: 0 };
winapi::um::winuser::GetCursorPos(&mut point);
(point.x, point.y)
}
}
pub fn mouse_click(button: MouseClick) {
let (down, up) = match button {
MouseClick::LEFT => (MOUSEEVENTF_LEFTDOWN, MOUSEEVENTF_LEFTUP),
MouseClick::RIGHT => (MOUSEEVENTF_RIGHTDOWN, MOUSEEVENTF_RIGHTUP),
MouseClick::MIDDLE => (MOUSEEVENTF_MIDDLEDOWN, MOUSEEVENTF_MIDDLEUP),
};
unsafe {
let mut inputs: [INPUT; 2] = [zeroed(), zeroed()];
inputs[0].type_ = INPUT_MOUSE;
inputs[0].u.mi_mut().dwFlags = down;
inputs[1].type_ = INPUT_MOUSE;
inputs[1].u.mi_mut().dwFlags = up;
SendInput(2, inputs.as_mut_ptr(), size_of::<INPUT>() as i32);
}
}
pub fn mouse_down(button: MouseClick) {
let down = match button {
MouseClick::LEFT => MOUSEEVENTF_LEFTDOWN,
MouseClick::RIGHT => MOUSEEVENTF_RIGHTDOWN,
MouseClick::MIDDLE => MOUSEEVENTF_MIDDLEDOWN,
};
unsafe {
let mut input: INPUT = zeroed();
input.type_ = INPUT_MOUSE;
input.u.mi_mut().dwFlags = down;
SendInput(1, &mut input, size_of::<INPUT>() as i32);
}
}
pub fn mouse_up(button: MouseClick) {
let up = match button {
MouseClick::LEFT => MOUSEEVENTF_LEFTUP,
MouseClick::RIGHT => MOUSEEVENTF_RIGHTUP,
MouseClick::MIDDLE => MOUSEEVENTF_MIDDLEUP,
};
unsafe {
let mut input: INPUT = zeroed();
input.type_ = INPUT_MOUSE;
input.u.mi_mut().dwFlags = up;
SendInput(1, &mut input, size_of::<INPUT>() as i32);
}
}
pub fn scroll(direction: MouseScroll, intensity: u32) {
let (amount, wheel_direction) = match direction {
MouseScroll::UP => (120, MOUSEEVENTF_WHEEL),
MouseScroll::DOWN => (-120, MOUSEEVENTF_WHEEL),
MouseScroll::LEFT => (-120, MOUSEEVENTF_HWHEEL),
MouseScroll::RIGHT => (120, MOUSEEVENTF_HWHEEL),
};
let amount = amount * intensity as i32;
unsafe {
let mut scroll_input: INPUT = zeroed();
scroll_input.type_ = INPUT_MOUSE;
scroll_input.u.mi_mut().dwFlags = wheel_direction;
scroll_input.u.mi_mut().mouseData = amount as u32;
SendInput(1, &mut scroll_input, size_of::<INPUT>() as i32);
}
}
}