1use std::f64::consts::PI;
6
7use dom_struct::dom_struct;
8use euclid::Point2D;
9use script_bindings::inheritance::Castable;
10
11use crate::dom::bindings::codegen::Bindings::TouchBinding::TouchMethods;
12use crate::dom::bindings::num::Finite;
13use crate::dom::bindings::reflector::{Reflector, reflect_dom_object};
14use crate::dom::bindings::root::{DomRoot, MutDom};
15use crate::dom::event::{Event, EventBubbles, EventCancelable};
16use crate::dom::eventtarget::EventTarget;
17use crate::dom::pointerevent::PointerEvent;
18use crate::dom::window::Window;
19use crate::script_runtime::CanGc;
20
21#[dom_struct]
22pub(crate) struct Touch {
23 reflector_: Reflector,
24 identifier: i32,
25 target: MutDom<EventTarget>,
26 screen_x: f64,
27 screen_y: f64,
28 client_x: f64,
29 client_y: f64,
30 page_x: f64,
31 page_y: f64,
32}
33
34impl Touch {
35 #[allow(clippy::too_many_arguments)]
36 fn new_inherited(
37 identifier: i32,
38 target: &EventTarget,
39 screen_x: Finite<f64>,
40 screen_y: Finite<f64>,
41 client_x: Finite<f64>,
42 client_y: Finite<f64>,
43 page_x: Finite<f64>,
44 page_y: Finite<f64>,
45 ) -> Touch {
46 Touch {
47 reflector_: Reflector::new(),
48 identifier,
49 target: MutDom::new(target),
50 screen_x: *screen_x,
51 screen_y: *screen_y,
52 client_x: *client_x,
53 client_y: *client_y,
54 page_x: *page_x,
55 page_y: *page_y,
56 }
57 }
58
59 #[allow(clippy::too_many_arguments)]
60 pub(crate) fn new(
61 window: &Window,
62 identifier: i32,
63 target: &EventTarget,
64 screen_x: Finite<f64>,
65 screen_y: Finite<f64>,
66 client_x: Finite<f64>,
67 client_y: Finite<f64>,
68 page_x: Finite<f64>,
69 page_y: Finite<f64>,
70 can_gc: CanGc,
71 ) -> DomRoot<Touch> {
72 reflect_dom_object(
73 Box::new(Touch::new_inherited(
74 identifier, target, screen_x, screen_y, client_x, client_y, page_x, page_y,
75 )),
76 window,
77 can_gc,
78 )
79 }
80
81 #[allow(clippy::too_many_arguments)]
84 pub(crate) fn to_pointer_event(
85 &self,
86 window: &Window,
87 event_type: &str,
88 pointer_id: i32,
89 is_primary: bool,
90 modifiers: keyboard_types::Modifiers,
91 is_cancelable: bool,
92 point_in_node: Option<euclid::Point2D<f32, style_traits::CSSPixel>>,
93 can_gc: CanGc,
94 ) -> DomRoot<PointerEvent> {
95 let pressure = if event_type == "pointerup" ||
99 event_type == "pointercancel" ||
100 event_type == "pointerout" ||
101 event_type == "pointerleave"
102 {
103 0.0
104 } else {
105 0.5
106 };
107
108 let button = if event_type == "pointermove" ||
112 event_type == "pointerover" ||
113 event_type == "pointerenter" ||
114 event_type == "pointerout" ||
115 event_type == "pointerleave"
116 {
117 -1
118 } else {
119 0
120 };
121
122 let buttons = if event_type == "pointermove" ||
125 event_type == "pointerover" ||
126 event_type == "pointerenter" ||
127 event_type == "pointerdown"
128 {
129 1
130 } else {
131 0
132 };
133
134 let (bubbles, cancelable) = match event_type {
136 "pointerenter" | "pointerleave" => {
137 (EventBubbles::DoesNotBubble, EventCancelable::NotCancelable)
138 },
139 _ => (EventBubbles::Bubbles, EventCancelable::from(is_cancelable)),
140 };
141
142 let pointer_event = PointerEvent::new(
143 window,
144 event_type.into(),
145 bubbles,
146 cancelable,
147 Some(window),
148 0, Point2D::new(*self.ScreenX() as i32, *self.ScreenY() as i32),
150 Point2D::new(*self.ClientX() as i32, *self.ClientY() as i32),
151 Point2D::new(*self.PageX() as i32, *self.PageY() as i32),
152 modifiers,
153 button,
154 buttons,
155 None, point_in_node,
157 pointer_id,
158 1, 1, pressure,
161 0.0, 0, 0, 0, PI / 2.0, 0.0, "touch".into(),
168 is_primary,
169 vec![], vec![], can_gc,
172 );
173
174 let composed = !matches!(event_type, "pointerenter" | "pointerleave");
178 pointer_event.upcast::<Event>().set_composed(composed);
179
180 pointer_event
181 }
182}
183
184impl TouchMethods<crate::DomTypeHolder> for Touch {
185 fn Identifier(&self) -> i32 {
187 self.identifier
188 }
189
190 fn Target(&self) -> DomRoot<EventTarget> {
192 self.target.get()
193 }
194
195 fn ScreenX(&self) -> Finite<f64> {
197 Finite::wrap(self.screen_x)
198 }
199
200 fn ScreenY(&self) -> Finite<f64> {
202 Finite::wrap(self.screen_y)
203 }
204
205 fn ClientX(&self) -> Finite<f64> {
207 Finite::wrap(self.client_x)
208 }
209
210 fn ClientY(&self) -> Finite<f64> {
212 Finite::wrap(self.client_y)
213 }
214
215 fn PageX(&self) -> Finite<f64> {
217 Finite::wrap(self.page_x)
218 }
219
220 fn PageY(&self) -> Finite<f64> {
222 Finite::wrap(self.page_y)
223 }
224}