use super::raw::RawPointerPoint;
use super::{IPointer, MouseButton, RawInputModifiers};
use crate::{Point, Rect};
use std::rc::Rc;
#[derive(Clone)]
pub struct PointerPoint {
pub pointer: Rc<dyn IPointer>,
pub properties: PointerPointProperties,
pub position: Point,
}
impl PointerPoint {
pub fn new(pointer: Rc<dyn IPointer>, position: Point, properties: PointerPointProperties) -> Self {
Self { pointer, properties, position }
}
}
impl PartialEq for PointerPoint {
fn eq(&self, other: &Self) -> bool {
std::ptr::addr_eq(Rc::as_ptr(&self.pointer), Rc::as_ptr(&other.pointer))
&& self.properties == other.properties
&& self.position == other.position
}
}
#[derive(Clone, Copy, Debug, PartialEq)]
pub struct PointerPointProperties {
pub contact_rect: Rect,
pub is_left_button_pressed: bool,
pub is_middle_button_pressed: bool,
pub is_right_button_pressed: bool,
pub is_x_button_1_pressed: bool,
pub is_x_button_2_pressed: bool,
pub is_barrel_button_pressed: bool,
pub is_eraser: bool,
pub is_inverted: bool,
pub twist: f32,
pub pressure: f32,
pub x_tilt: f32,
pub y_tilt: f32,
pub pointer_update_kind: PointerUpdateKind,
}
impl Default for PointerPointProperties {
fn default() -> Self {
Self::NONE
}
}
impl PointerPointProperties {
pub const NONE: PointerPointProperties = PointerPointProperties {
contact_rect: Rect::new(0.0, 0.0, 0.0, 0.0),
is_left_button_pressed: false,
is_middle_button_pressed: false,
is_right_button_pressed: false,
is_x_button_1_pressed: false,
is_x_button_2_pressed: false,
is_barrel_button_pressed: false,
is_eraser: false,
is_inverted: false,
twist: 0.0,
pressure: 0.5,
x_tilt: 0.0,
y_tilt: 0.0,
pointer_update_kind: PointerUpdateKind::LeftButtonPressed,
};
pub fn new(modifiers: RawInputModifiers, kind: PointerUpdateKind) -> Self {
let mut result = Self {
pointer_update_kind: kind,
is_left_button_pressed: modifiers.contains(RawInputModifiers::LEFT_MOUSE_BUTTON),
is_middle_button_pressed: modifiers.contains(RawInputModifiers::MIDDLE_MOUSE_BUTTON),
is_right_button_pressed: modifiers.contains(RawInputModifiers::RIGHT_MOUSE_BUTTON),
is_x_button_1_pressed: modifiers.contains(RawInputModifiers::X_BUTTON_1_MOUSE_BUTTON),
is_x_button_2_pressed: modifiers.contains(RawInputModifiers::X_BUTTON_2_MOUSE_BUTTON),
is_inverted: modifiers.contains(RawInputModifiers::PEN_INVERTED),
is_eraser: modifiers.contains(RawInputModifiers::PEN_ERASER),
is_barrel_button_pressed: modifiers.contains(RawInputModifiers::PEN_BARREL_BUTTON),
..Self::NONE
};
match kind {
PointerUpdateKind::LeftButtonPressed => result.is_left_button_pressed = true,
PointerUpdateKind::LeftButtonReleased => result.is_left_button_pressed = false,
PointerUpdateKind::MiddleButtonPressed => result.is_middle_button_pressed = true,
PointerUpdateKind::MiddleButtonReleased => result.is_middle_button_pressed = false,
PointerUpdateKind::RightButtonPressed => result.is_right_button_pressed = true,
PointerUpdateKind::RightButtonReleased => result.is_right_button_pressed = false,
PointerUpdateKind::XButton1Pressed => result.is_x_button_1_pressed = true,
PointerUpdateKind::XButton1Released => result.is_x_button_1_pressed = false,
PointerUpdateKind::XButton2Pressed => result.is_x_button_2_pressed = true,
PointerUpdateKind::XButton2Released => result.is_x_button_2_pressed = false,
PointerUpdateKind::Other => {}
}
result
}
pub fn with_pen_state(
modifiers: RawInputModifiers,
kind: PointerUpdateKind,
twist: f32,
pressure: f32,
x_tilt: f32,
y_tilt: f32,
) -> Self {
Self::with_pen_state_and_contact_rect(modifiers, kind, twist, pressure, x_tilt, y_tilt, Rect::default())
}
pub fn with_pen_state_and_contact_rect(
modifiers: RawInputModifiers,
kind: PointerUpdateKind,
twist: f32,
pressure: f32,
x_tilt: f32,
y_tilt: f32,
contact_rect: Rect,
) -> Self {
Self { twist, pressure, x_tilt, y_tilt, contact_rect, ..Self::new(modifiers, kind) }
}
pub fn from_raw_point(modifiers: RawInputModifiers, kind: PointerUpdateKind, raw_point: RawPointerPoint) -> Self {
Self::with_pen_state_and_contact_rect(
modifiers,
kind,
raw_point.twist,
raw_point.pressure,
raw_point.x_tilt,
raw_point.y_tilt,
raw_point.contact_rect(),
)
}
pub fn based_on(based_on: PointerPointProperties, raw_point: RawPointerPoint) -> Self {
Self {
is_left_button_pressed: based_on.is_left_button_pressed,
is_middle_button_pressed: based_on.is_middle_button_pressed,
is_right_button_pressed: based_on.is_right_button_pressed,
is_x_button_1_pressed: based_on.is_x_button_1_pressed,
is_x_button_2_pressed: based_on.is_x_button_2_pressed,
is_inverted: based_on.is_inverted,
is_eraser: based_on.is_eraser,
is_barrel_button_pressed: based_on.is_barrel_button_pressed,
twist: raw_point.twist,
pressure: raw_point.pressure,
x_tilt: raw_point.x_tilt,
y_tilt: raw_point.y_tilt,
..Self::NONE
}
}
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)]
pub enum PointerUpdateKind {
#[default]
LeftButtonPressed,
MiddleButtonPressed,
RightButtonPressed,
XButton1Pressed,
XButton2Pressed,
LeftButtonReleased,
MiddleButtonReleased,
RightButtonReleased,
XButton1Released,
XButton2Released,
Other,
}
impl PointerUpdateKind {
pub fn get_mouse_button(self) -> MouseButton {
match self {
PointerUpdateKind::LeftButtonPressed | PointerUpdateKind::LeftButtonReleased => MouseButton::Left,
PointerUpdateKind::MiddleButtonPressed | PointerUpdateKind::MiddleButtonReleased => MouseButton::Middle,
PointerUpdateKind::RightButtonPressed | PointerUpdateKind::RightButtonReleased => MouseButton::Right,
PointerUpdateKind::XButton1Pressed | PointerUpdateKind::XButton1Released => MouseButton::XButton1,
PointerUpdateKind::XButton2Pressed | PointerUpdateKind::XButton2Released => MouseButton::XButton2,
PointerUpdateKind::Other => MouseButton::None,
}
}
}