use std::ffi::CString;
use std::os::raw::c_long;
use wxdragon_sys as ffi;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
#[repr(i32)]
pub enum MouseButton {
Any = ffi::wxd_MouseButton_WXD_MOUSE_BTN_ANY,
None = ffi::wxd_MouseButton_WXD_MOUSE_BTN_NONE,
#[default]
Left = ffi::wxd_MouseButton_WXD_MOUSE_BTN_LEFT,
Middle = ffi::wxd_MouseButton_WXD_MOUSE_BTN_MIDDLE,
Right = ffi::wxd_MouseButton_WXD_MOUSE_BTN_RIGHT,
Aux1 = ffi::wxd_MouseButton_WXD_MOUSE_BTN_AUX1,
Aux2 = ffi::wxd_MouseButton_WXD_MOUSE_BTN_AUX2,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct KeyModifier(i32);
impl KeyModifier {
pub const NONE: KeyModifier = KeyModifier(0x0000);
pub const ALT: KeyModifier = KeyModifier(0x0001);
pub const CONTROL: KeyModifier = KeyModifier(0x0002);
pub const ALTGR: KeyModifier = KeyModifier(0x0003);
pub const SHIFT: KeyModifier = KeyModifier(0x0004);
pub const META: KeyModifier = KeyModifier(0x0008);
pub const WIN: KeyModifier = KeyModifier(0x0008);
pub const ALL: KeyModifier = KeyModifier(0x000f);
pub fn from_raw(value: i32) -> Self {
KeyModifier(value)
}
pub fn to_raw(self) -> i32 {
self.0
}
}
impl Default for KeyModifier {
fn default() -> Self {
KeyModifier::NONE
}
}
impl std::ops::BitOr for KeyModifier {
type Output = Self;
fn bitor(self, rhs: Self) -> Self::Output {
KeyModifier(self.0 | rhs.0)
}
}
impl std::ops::BitOrAssign for KeyModifier {
fn bitor_assign(&mut self, rhs: Self) {
self.0 |= rhs.0;
}
}
pub struct UIActionSimulator {
ptr: *mut ffi::wxd_UIActionSimulator_t,
}
impl UIActionSimulator {
pub fn new() -> Self {
let ptr = unsafe { ffi::wxd_UIActionSimulator_Create() };
Self { ptr }
}
pub fn is_ok(&self) -> bool {
!self.ptr.is_null()
}
pub fn mouse_move(&self, x: i32, y: i32) -> bool {
if self.ptr.is_null() {
return false;
}
unsafe { ffi::wxd_UIActionSimulator_MouseMove(self.ptr, x as c_long, y as c_long) }
}
pub fn mouse_down(&self, button: MouseButton) -> bool {
if self.ptr.is_null() {
return false;
}
unsafe { ffi::wxd_UIActionSimulator_MouseDown(self.ptr, button as i32) }
}
pub fn mouse_up(&self, button: MouseButton) -> bool {
if self.ptr.is_null() {
return false;
}
unsafe { ffi::wxd_UIActionSimulator_MouseUp(self.ptr, button as i32) }
}
pub fn mouse_click(&self, button: MouseButton) -> bool {
if self.ptr.is_null() {
return false;
}
unsafe { ffi::wxd_UIActionSimulator_MouseClick(self.ptr, button as i32) }
}
pub fn mouse_dbl_click(&self, button: MouseButton) -> bool {
if self.ptr.is_null() {
return false;
}
unsafe { ffi::wxd_UIActionSimulator_MouseDblClick(self.ptr, button as i32) }
}
pub fn mouse_drag_drop(&self, x1: i32, y1: i32, x2: i32, y2: i32, button: MouseButton) -> bool {
if self.ptr.is_null() {
return false;
}
unsafe {
ffi::wxd_UIActionSimulator_MouseDragDrop(
self.ptr,
x1 as c_long,
y1 as c_long,
x2 as c_long,
y2 as c_long,
button as i32,
)
}
}
pub fn key_down(&self, keycode: i32, modifiers: KeyModifier) -> bool {
if self.ptr.is_null() {
return false;
}
unsafe { ffi::wxd_UIActionSimulator_KeyDown(self.ptr, keycode, modifiers.to_raw()) }
}
pub fn key_up(&self, keycode: i32, modifiers: KeyModifier) -> bool {
if self.ptr.is_null() {
return false;
}
unsafe { ffi::wxd_UIActionSimulator_KeyUp(self.ptr, keycode, modifiers.to_raw()) }
}
pub fn char_key(&self, keycode: i32) -> bool {
self.char_with_modifiers(keycode, KeyModifier::NONE)
}
pub fn char_with_modifiers(&self, keycode: i32, modifiers: KeyModifier) -> bool {
if self.ptr.is_null() {
return false;
}
unsafe { ffi::wxd_UIActionSimulator_Char(self.ptr, keycode, modifiers.to_raw()) }
}
pub fn text(&self, text: &str) -> bool {
if self.ptr.is_null() {
return false;
}
let c_text = match CString::new(text) {
Ok(s) => s,
Err(_) => return false,
};
unsafe { ffi::wxd_UIActionSimulator_Text(self.ptr, c_text.as_ptr()) }
}
pub fn select(&self, text: &str) -> bool {
if self.ptr.is_null() {
return false;
}
let c_text = match CString::new(text) {
Ok(s) => s,
Err(_) => return false,
};
unsafe { ffi::wxd_UIActionSimulator_Select(self.ptr, c_text.as_ptr()) }
}
}
impl Default for UIActionSimulator {
fn default() -> Self {
Self::new()
}
}
impl Drop for UIActionSimulator {
fn drop(&mut self) {
if !self.ptr.is_null() {
unsafe { ffi::wxd_UIActionSimulator_Destroy(self.ptr) };
}
}
}