1use std::f64::consts::PI;
6
7use dom_struct::dom_struct;
8use euclid::Point2D;
9use script_bindings::inheritance::Castable;
10use script_bindings::reflector::{Reflector, reflect_dom_object};
11
12use crate::dom::bindings::codegen::Bindings::TouchBinding::TouchMethods;
13use crate::dom::bindings::num::Finite;
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 pointer_type: &str,
91 modifiers: keyboard_types::Modifiers,
92 is_cancelable: bool,
93 point_in_node: Option<euclid::Point2D<f32, style_traits::CSSPixel>>,
94 can_gc: CanGc,
95 ) -> DomRoot<PointerEvent> {
96 let pressure = if event_type == "pointerup" ||
100 event_type == "pointercancel" ||
101 event_type == "pointerout" ||
102 event_type == "pointerleave"
103 {
104 0.0
105 } else {
106 0.5
107 };
108
109 let button = if event_type == "pointermove" ||
113 event_type == "pointerover" ||
114 event_type == "pointerenter" ||
115 event_type == "pointerout" ||
116 event_type == "pointerleave"
117 {
118 -1
119 } else {
120 0
121 };
122
123 let buttons = if event_type == "pointermove" ||
126 event_type == "pointerover" ||
127 event_type == "pointerenter" ||
128 event_type == "pointerdown"
129 {
130 1
131 } else {
132 0
133 };
134
135 let (bubbles, cancelable) = match event_type {
137 "pointerenter" | "pointerleave" => {
138 (EventBubbles::DoesNotBubble, EventCancelable::NotCancelable)
139 },
140 _ => (EventBubbles::Bubbles, EventCancelable::from(is_cancelable)),
141 };
142
143 let pointer_event = PointerEvent::new(
144 window,
145 event_type.into(),
146 bubbles,
147 cancelable,
148 Some(window),
149 0, Point2D::new(*self.ScreenX() as i32, *self.ScreenY() as i32),
151 Point2D::new(*self.ClientX() as i32, *self.ClientY() as i32),
152 Point2D::new(*self.PageX() as i32, *self.PageY() as i32),
153 modifiers,
154 button,
155 buttons,
156 None, point_in_node,
158 pointer_id,
159 1, 1, pressure,
162 0.0, 0, 0, 0, PI / 2.0, 0.0, pointer_type.into(),
169 is_primary,
170 vec![], vec![], can_gc,
173 );
174
175 let composed = !matches!(event_type, "pointerenter" | "pointerleave");
179 pointer_event.upcast::<Event>().set_composed(composed);
180
181 pointer_event
182 }
183}
184
185impl TouchMethods<crate::DomTypeHolder> for Touch {
186 fn Identifier(&self) -> i32 {
188 self.identifier
189 }
190
191 fn Target(&self) -> DomRoot<EventTarget> {
193 self.target.get()
194 }
195
196 fn ScreenX(&self) -> Finite<f64> {
198 Finite::wrap(self.screen_x)
199 }
200
201 fn ScreenY(&self) -> Finite<f64> {
203 Finite::wrap(self.screen_y)
204 }
205
206 fn ClientX(&self) -> Finite<f64> {
208 Finite::wrap(self.client_x)
209 }
210
211 fn ClientY(&self) -> Finite<f64> {
213 Finite::wrap(self.client_y)
214 }
215
216 fn PageX(&self) -> Finite<f64> {
218 Finite::wrap(self.page_x)
219 }
220
221 fn PageY(&self) -> Finite<f64> {
223 Finite::wrap(self.page_y)
224 }
225}