use std::cell::{Cell, RefCell};
use std::collections::VecDeque;
use std::rc::Rc;
use thiserror::Error;
#[cfg(target_os = "windows")]
pub mod win32;
#[cfg(target_os = "windows")]
use win32::TabletData;
#[cfg(target_os = "windows")]
pub use win32::WindowsError;
#[cfg(not(any(target_os = "windows")))]
compile_error!("easytab is not yet implemented for this platform");
#[derive(Error, Clone, Debug)]
pub enum EasyTabError {
#[cfg(target_os = "windows")]
#[error("windows error: {0}")]
WindowsError(#[from] WindowsError),
#[cfg(feature = "raw-window-handle")]
#[error("{0}")]
HandleError(#[from] raw_window_handle::HandleError),
#[cfg(feature = "raw-window-handle")]
#[error("unsupported platform")]
UnsupportedPlatform,
}
pub type EasyTabResult<T> = std::result::Result<T, EasyTabError>;
#[derive(Clone)]
pub struct EasyTabOptions {
pub pressure_normalization: f32,
}
impl Default for EasyTabOptions {
fn default() -> Self {
Self {
pressure_normalization: 1024.0,
}
}
}
#[non_exhaustive]
#[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
pub enum TabletEvent {
StylusEnter,
StylusLeave,
StylusDown {
x: i32,
y: i32,
pressure: f32,
raw_pressure: f32,
},
StylusUp { x: i32, y: i32 },
StylusMove {
x: i32,
y: i32,
pressure: f32,
raw_pressure: f32,
},
}
#[doc(hidden)]
pub(crate) struct TabletInner {
pub(crate) enabled: Cell<bool>,
pub(crate) events: RefCell<VecDeque<TabletEvent>>,
pub(crate) options: EasyTabOptions,
}
pub struct EasyTablet {
pub(crate) inner: Rc<TabletInner>,
pub(crate) data: TabletData,
}
#[cfg(feature = "raw-window-handle")]
impl EasyTablet {
pub fn from_window<W: raw_window_handle::HasWindowHandle>(window: &W) -> EasyTabResult<Self> {
use raw_window_handle::RawWindowHandle;
let raw = window
.window_handle()
.map_err(EasyTabError::HandleError)?
.as_raw();
match raw {
#[cfg(target_os = "windows")]
RawWindowHandle::Win32(h) => Self::init(h.hwnd.get() as usize),
_ => Err(EasyTabError::UnsupportedPlatform),
}
}
}