use std::rc::Rc;
use crate::{JsJson, dev::JsJsonListDecoder, struct_mut::ValueMut};
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub enum PointerType {
#[default]
Mouse,
Pen,
Touch,
}
#[derive(Clone, Debug, Default)]
pub struct PointerEvent {
pub pointer_id: i32,
pub pointer_type: PointerType,
pub is_primary: bool,
pub button: i16,
pub buttons: u16,
pub pointer_x: f64,
pub pointer_y: f64,
pub element_width: f64,
pub element_height: f64,
pub alt_key: bool,
pub ctrl_key: bool,
pub shift_key: bool,
pub meta_key: bool,
flags: Rc<ValueMut<PointerEventFlags>>,
}
#[derive(Clone, Copy, Debug, Default)]
struct PointerEventFlags {
stop_propagation: bool,
prevent_default: bool,
capture_pointer: bool,
}
impl PointerEvent {
pub fn stop_propagation(&self) {
self.flags.change(|flags| flags.stop_propagation = true);
}
pub fn prevent_default(&self) {
self.flags.change(|flags| flags.prevent_default = true);
}
pub fn capture_pointer(&self) {
self.flags.change(|flags| flags.capture_pointer = true);
}
pub(crate) fn from_driver(data: JsJson) -> Result<Self, String> {
data.map_list(|mut params: JsJsonListDecoder| {
let pointer_id = params.get_f64("pointerId")? as i32;
let pointer_type = match params.get_string("pointerType")?.as_str() {
"pen" => PointerType::Pen,
"touch" => PointerType::Touch,
_ => PointerType::Mouse,
};
let is_primary = params.get_bool("isPrimary")?;
let button = params.get_f64("button")? as i16;
let buttons = params.get_f64("buttons")? as u16;
let pointer_x = params.get_f64("pointerX")?;
let pointer_y = params.get_f64("pointerY")?;
let element_width = params.get_f64("elementWidth")?;
let element_height = params.get_f64("elementHeight")?;
let alt_key = params.get_bool("altKey")?;
let ctrl_key = params.get_bool("ctrlKey")?;
let shift_key = params.get_bool("shiftKey")?;
let meta_key = params.get_bool("metaKey")?;
params.expect_no_more()?;
Ok(Self {
pointer_id,
pointer_type,
is_primary,
button,
buttons,
pointer_x,
pointer_y,
element_width,
element_height,
alt_key,
ctrl_key,
shift_key,
meta_key,
flags: Rc::default(),
})
})
}
}
impl From<PointerEvent> for JsJson {
fn from(val: PointerEvent) -> JsJson {
let flags = val.flags.get();
JsJson::Object(
[
(
"stop_propagation".to_string(),
JsJson::from(flags.stop_propagation),
),
(
"prevent_default".to_string(),
JsJson::from(flags.prevent_default),
),
(
"capture_pointer".to_string(),
JsJson::from(flags.capture_pointer),
),
]
.into_iter()
.collect(),
)
}
}