use parking_lot::RwLock;
use std::sync::Arc;
use windows::Win32::Foundation::*;
#[derive(Clone, Debug)]
pub struct UIElement {
inner: Arc<UIElementInner>,
}
#[derive(Debug)]
struct UIElementInner {
hwnd: RwLock<isize>,
width: RwLock<i32>,
height: RwLock<i32>,
x: RwLock<i32>,
y: RwLock<i32>,
visible: RwLock<bool>,
enabled: RwLock<bool>,
tag: RwLock<Option<String>>,
}
impl UIElement {
pub fn new(hwnd: HWND) -> Self {
Self {
inner: Arc::new(UIElementInner {
hwnd: RwLock::new(hwnd.0 as isize),
width: RwLock::new(0),
height: RwLock::new(0),
x: RwLock::new(0),
y: RwLock::new(0),
visible: RwLock::new(true),
enabled: RwLock::new(true),
tag: RwLock::new(None),
}),
}
}
pub fn empty() -> Self {
Self::new(HWND(std::ptr::null_mut()))
}
pub fn hwnd(&self) -> HWND {
HWND(*self.inner.hwnd.read() as *mut core::ffi::c_void)
}
pub fn set_hwnd(&self, hwnd: HWND) {
*self.inner.hwnd.write() = hwnd.0 as isize;
}
pub fn position(&self) -> (i32, i32) {
(*self.inner.x.read(), *self.inner.y.read())
}
pub fn size(&self) -> (i32, i32) {
(*self.inner.width.read(), *self.inner.height.read())
}
pub fn width(&self) -> i32 {
*self.inner.width.read()
}
pub fn set_width(&self, width: i32) {
*self.inner.width.write() = width;
}
pub fn height(&self) -> i32 {
*self.inner.height.read()
}
pub fn set_height(&self, height: i32) {
*self.inner.height.write() = height;
}
pub fn x(&self) -> i32 {
*self.inner.x.read()
}
pub fn set_x(&self, x: i32) {
*self.inner.x.write() = x;
}
pub fn y(&self) -> i32 {
*self.inner.y.read()
}
pub fn set_y(&self, y: i32) {
*self.inner.y.write() = y;
}
pub fn is_visible(&self) -> bool {
*self.inner.visible.read()
}
pub fn set_visible(&self, visible: bool) {
*self.inner.visible.write() = visible;
}
pub fn is_enabled(&self) -> bool {
*self.inner.enabled.read()
}
pub fn set_enabled(&self, enabled: bool) {
*self.inner.enabled.write() = enabled;
}
pub fn tag(&self) -> Option<String> {
self.inner.tag.read().clone()
}
pub fn set_tag(&self, tag: Option<String>) {
*self.inner.tag.write() = tag;
}
pub fn is_empty(&self) -> bool {
self.hwnd().0.is_null()
}
}
impl Default for UIElement {
fn default() -> Self {
Self::empty()
}
}
impl From<HWND> for UIElement {
fn from(hwnd: HWND) -> Self {
UIElement::new(hwnd)
}
}