add touch data to touch events

This commit is contained in:
Evan Almloff committed 2023-09-12 17:28:55 -05:00
1 parent b47064165e
commit c10700c962
8 files changed
+339 -160

No files matched your search

+163 -56
View File
@@ -1,4 +1,8 @@
use dioxus_core::Event;
use keyboard_types::Modifiers;
use crate::geometry::*;
use crate::prelude::{InteractionLocation, ModifiersInteraction};
pub type TouchEvent = Event<TouchData>;
pub struct TouchData {
@@ -14,20 +18,14 @@ impl<E: HasTouchData> From<E> for TouchData {
impl std::fmt::Debug for TouchData {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("TouchData")
.field("alt_key", &self.alt_key())
.field("ctrl_key", &self.ctrl_key())
.field("meta_key", &self.meta_key())
.field("shift_key", &self.shift_key())
.field("modifiers", &self.modifiers())
.finish()
}
}
impl PartialEq for TouchData {
fn eq(&self, other: &Self) -> bool {
self.alt_key() == other.alt_key()
&& self.ctrl_key() == other.ctrl_key()
&& self.meta_key() == other.meta_key()
&& self.shift_key() == other.shift_key()
self.modifiers() == other.modifiers()
}
}
@@ -39,24 +37,9 @@ impl TouchData {
}
}
/// Returns true if the "ALT" key was down when the touch event was fired.
pub fn alt_key(&self) -> bool {
self.inner.alt_key()
}
/// Returns true if the "CTRL" key was down when the touch event was fired.
pub fn ctrl_key(&self) -> bool {
self.inner.ctrl_key()
}
/// Returns true if the "META" key was down when the touch event was fired.
pub fn meta_key(&self) -> bool {
self.inner.meta_key()
}
/// Returns true if the "SHIFT" key was down when the touch event was fired.
pub fn shift_key(&self) -> bool {
self.inner.shift_key()
/// Get the pointers that are currently down
pub fn touches(&self) -> Vec<TouchPoint> {
self.inner.touches()
}
/// Downcast this event to a concrete event type
@@ -65,6 +48,12 @@ impl TouchData {
}
}
impl ModifiersInteraction for TouchData {
fn modifiers(&self) -> Modifiers {
self.inner.modifiers()
}
}
#[cfg(feature = "serialize")]
/// A serialized version of TouchData
#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Clone)]
@@ -73,36 +62,47 @@ pub struct SerializedTouchData {
ctrl_key: bool,
meta_key: bool,
shift_key: bool,
touches: Vec<SerializedTouchPoint>,
}
#[cfg(feature = "serialize")]
impl From<&TouchData> for SerializedTouchData {
fn from(data: &TouchData) -> Self {
let modifiers = data.modifiers();
Self {
alt_key: data.alt_key(),
ctrl_key: data.ctrl_key(),
meta_key: data.meta_key(),
shift_key: data.shift_key(),
alt_key: modifiers.contains(Modifiers::ALT),
ctrl_key: modifiers.contains(Modifiers::CONTROL),
meta_key: modifiers.contains(Modifiers::META),
shift_key: modifiers.contains(Modifiers::SHIFT),
touches: data.touches().iter().map(|t| t.into()).collect(),
}
}
}
#[cfg(feature = "serialize")]
impl ModifiersInteraction for SerializedTouchData {
fn modifiers(&self) -> Modifiers {
let mut modifiers = Modifiers::default();
if self.alt_key {
modifiers.insert(Modifiers::ALT);
}
if self.ctrl_key {
modifiers.insert(Modifiers::CONTROL);
}
if self.meta_key {
modifiers.insert(Modifiers::META);
}
if self.shift_key {
modifiers.insert(Modifiers::SHIFT);
}
modifiers
}
}
#[cfg(feature = "serialize")]
impl HasTouchData for SerializedTouchData {
fn alt_key(&self) -> bool {
self.alt_key
}
fn ctrl_key(&self) -> bool {
self.ctrl_key
}
fn meta_key(&self) -> bool {
self.meta_key
}
fn shift_key(&self) -> bool {
self.shift_key
fn touches(&self) -> Vec<TouchPoint> {
Vec::new()
}
fn as_any(&self) -> &dyn std::any::Any {
@@ -127,23 +127,130 @@ impl<'de> serde::Deserialize<'de> for TouchData {
}
}
pub trait HasTouchData: std::any::Any {
/// Returns true if the "ALT" key was down when the touch event was fired.
fn alt_key(&self) -> bool;
/// Returns true if the "CTRL" key was down when the touch event was fired.
fn ctrl_key(&self) -> bool;
/// Returns true if the "META" key was down when the touch event was fired.
fn meta_key(&self) -> bool;
/// Returns true if the "SHIFT" key was down when the touch event was fired.
fn shift_key(&self) -> bool;
pub trait HasTouchData: ModifiersInteraction + std::any::Any {
/// Get the pointers that are currently down
fn touches(&self) -> Vec<TouchPoint>;
/// return self as Any
fn as_any(&self) -> &dyn std::any::Any;
}
pub struct TouchPoint {
inner: Box<dyn HasTouchPointData>,
}
impl<E: HasTouchPointData> From<E> for TouchPoint {
fn from(e: E) -> Self {
Self { inner: Box::new(e) }
}
}
impl TouchPoint {
/// Create a new TouchPoint
pub fn new(inner: impl HasTouchPointData + 'static) -> Self {
Self {
inner: Box::new(inner),
}
}
/// A unique identifier for this touch point that will be the same for the duration of the touch
fn identifier(&self) -> i32 {
self.inner.identifier()
}
/// the pressure of the touch
fn force(&self) -> f64 {
self.inner.force()
}
/// the radius of the touch
fn radius(&self) -> ScreenPoint {
self.inner.radius()
}
/// the rotation of the touch in degrees between 0 and 90
fn rotation(&self) -> f64 {
self.inner.rotation()
}
/// Downcast this event to a concrete event type
pub fn downcast<T: 'static>(&self) -> Option<&T> {
self.inner.as_any().downcast_ref::<T>()
}
}
impl InteractionLocation for TouchPoint {
fn client_coordinates(&self) -> ClientPoint {
self.inner.client_coordinates()
}
fn page_coordinates(&self) -> PagePoint {
self.inner.page_coordinates()
}
fn screen_coordinates(&self) -> ScreenPoint {
self.inner.screen_coordinates()
}
}
/// A trait for touch point data
pub trait HasTouchPointData: InteractionLocation + std::any::Any {
/// A unique identifier for this touch point that will be the same for the duration of the touch
fn identifier(&self) -> i32;
/// the pressure of the touch
fn force(&self) -> f64;
/// the radius of the touch
fn radius(&self) -> ScreenPoint;
/// the rotation of the touch in degrees between 0 and 90
fn rotation(&self) -> f64;
/// return self as Any
fn as_any(&self) -> &dyn std::any::Any;
}
#[cfg(feature = "serialize")]
/// A serialized version of TouchPoint
#[derive(serde::Serialize, serde::Deserialize, Debug, PartialEq, Clone)]
struct SerializedTouchPoint {
identifier: i32,
client_x: f64,
client_y: f64,
page_x: f64,
page_y: f64,
screen_x: f64,
screen_y: f64,
force: f64,
radius_x: f64,
radius_y: f64,
rotation_angle: f64,
}
#[cfg(feature = "serialize")]
impl From<&TouchPoint> for SerializedTouchPoint {
fn from(point: &TouchPoint) -> Self {
let client_coordinates = point.client_coordinates();
let page_coordinates = point.page_coordinates();
let screen_coordinates = point.screen_coordinates();
Self {
identifier: point.identifier(),
client_x: client_coordinates.x,
client_y: client_coordinates.y,
page_x: page_coordinates.x,
page_y: page_coordinates.y,
screen_x: screen_coordinates.x,
screen_y: screen_coordinates.y,
force: point.force(),
radius_x: point.radius().x,
radius_y: point.radius().y,
rotation_angle: point.rotation(),
}
}
}
impl_event! {
TouchData;
/// touchstart