123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366 |
- use dioxus_core::Event;
- use keyboard_types::Modifiers;
- use crate::geometry::*;
- use crate::prelude::{InteractionLocation, ModifiersInteraction};
- pub type TouchEvent = Event<TouchData>;
- pub struct TouchData {
- inner: Box<dyn HasTouchData>,
- }
- impl<E: HasTouchData> From<E> for TouchData {
- fn from(e: E) -> Self {
- Self { inner: Box::new(e) }
- }
- }
- impl std::fmt::Debug for TouchData {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- f.debug_struct("TouchData")
- .field("modifiers", &self.modifiers())
- .field("touches", &self.touches())
- .field("touches_changed", &self.touches_changed())
- .field("target_touches", &self.target_touches())
- .finish()
- }
- }
- impl PartialEq for TouchData {
- fn eq(&self, other: &Self) -> bool {
- self.modifiers() == other.modifiers()
- }
- }
- impl TouchData {
- /// Create a new TouchData
- pub fn new(inner: impl HasTouchData + 'static) -> Self {
- Self {
- inner: Box::new(inner),
- }
- }
- /// Get the pointers that are currently down
- pub fn touches(&self) -> Vec<TouchPoint> {
- self.inner.touches()
- }
- /// Get the touches that have changed since the last event
- pub fn touches_changed(&self) -> Vec<TouchPoint> {
- self.inner.touches_changed()
- }
- /// Get the touches that started and stayed on the element that triggered this event
- pub fn target_touches(&self) -> Vec<TouchPoint> {
- self.inner.target_touches()
- }
- /// Downcast this event to a concrete event type
- pub fn downcast<T: 'static>(&self) -> Option<&T> {
- self.inner.as_any().downcast_ref::<T>()
- }
- }
- 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)]
- pub struct SerializedTouchData {
- alt_key: bool,
- ctrl_key: bool,
- meta_key: bool,
- shift_key: bool,
- touches: Vec<SerializedTouchPoint>,
- changed_touches: Vec<SerializedTouchPoint>,
- target_touches: Vec<SerializedTouchPoint>,
- }
- #[cfg(feature = "serialize")]
- impl From<&TouchData> for SerializedTouchData {
- fn from(data: &TouchData) -> Self {
- let modifiers = data.modifiers();
- Self {
- 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(),
- changed_touches: data.touches_changed().iter().map(|t| t.into()).collect(),
- target_touches: data.target_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 touches(&self) -> Vec<TouchPoint> {
- self.touches.clone().into_iter().map(Into::into).collect()
- }
- fn touches_changed(&self) -> Vec<TouchPoint> {
- self.changed_touches
- .clone()
- .into_iter()
- .map(Into::into)
- .collect()
- }
- fn target_touches(&self) -> Vec<TouchPoint> {
- self.target_touches
- .clone()
- .into_iter()
- .map(Into::into)
- .collect()
- }
- fn as_any(&self) -> &dyn std::any::Any {
- self
- }
- }
- #[cfg(feature = "serialize")]
- impl serde::Serialize for TouchData {
- fn serialize<S: serde::Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
- SerializedTouchData::from(self).serialize(serializer)
- }
- }
- #[cfg(feature = "serialize")]
- impl<'de> serde::Deserialize<'de> for TouchData {
- fn deserialize<D: serde::Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
- let data = SerializedTouchData::deserialize(deserializer)?;
- Ok(Self {
- inner: Box::new(data),
- })
- }
- }
- pub trait HasTouchData: ModifiersInteraction + std::any::Any {
- /// Get the touches that are currently down
- fn touches(&self) -> Vec<TouchPoint>;
- /// Get the touches that have changed since the last event
- fn touches_changed(&self) -> Vec<TouchPoint>;
- /// Get the touches that started and stayed on the element that triggered this event
- fn target_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 std::fmt::Debug for TouchPoint {
- fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
- f.debug_struct("TouchPoint")
- .field("client_coordinates", &self.client_coordinates())
- .field("page_coordinates", &self.page_coordinates())
- .field("screen_coordinates", &self.screen_coordinates())
- .field("identifier", &self.identifier())
- .field("force", &self.force())
- .field("radius", &self.radius())
- .field("rotation", &self.rotation())
- .finish()
- }
- }
- 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(),
- }
- }
- }
- #[cfg(feature = "serialize")]
- impl HasTouchPointData for SerializedTouchPoint {
- /// A unique identifier for this touch point that will be the same for the duration of the touch
- fn identifier(&self) -> i32 {
- self.identifier
- }
- /// the pressure of the touch
- fn force(&self) -> f64 {
- self.force
- }
- /// the radius of the touch
- fn radius(&self) -> ScreenPoint {
- ScreenPoint::new(self.radius_x, self.radius_y)
- }
- /// the rotation of the touch in degrees between 0 and 90
- fn rotation(&self) -> f64 {
- self.rotation_angle
- }
- /// return self as Any
- fn as_any(&self) -> &dyn std::any::Any {
- self
- }
- }
- #[cfg(feature = "serialize")]
- impl InteractionLocation for SerializedTouchPoint {
- /// Gets the coordinates of the event relative to the browser viewport.
- fn client_coordinates(&self) -> ClientPoint {
- ClientPoint::new(self.client_x, self.client_y)
- }
- /// Gets the coordinates of the event relative to the screen.
- fn screen_coordinates(&self) -> ScreenPoint {
- ScreenPoint::new(self.screen_x, self.screen_y)
- }
- /// Gets the coordinates of the event relative to the page.
- fn page_coordinates(&self) -> PagePoint {
- PagePoint::new(self.page_x, self.page_y)
- }
- }
- impl_event! {
- TouchData;
- /// touchstart
- ontouchstart
- /// touchmove
- ontouchmove
- /// touchend
- ontouchend
- /// touchcancel
- ontouchcancel
- }
|