/src/serenity/Userland/Libraries/LibWeb/UIEvents/PointerEvent.h
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2024, Shannon Booth <shannon@serenityos.org> |
3 | | * |
4 | | * SPDX-License-Identifier: BSD-2-Clause |
5 | | */ |
6 | | |
7 | | #pragma once |
8 | | |
9 | | #include <LibWeb/UIEvents/MouseEvent.h> |
10 | | #include <LibWeb/WebIDL/Types.h> |
11 | | |
12 | | namespace Web::UIEvents { |
13 | | |
14 | | struct PointerEventInit : public MouseEventInit { |
15 | | WebIDL::Long pointer_id { 0 }; |
16 | | double width { 1 }; |
17 | | double height { 1 }; |
18 | | float pressure { 0 }; |
19 | | float tangential_pressure { 0 }; |
20 | | Optional<WebIDL::Long> tilt_x; |
21 | | Optional<WebIDL::Long> tilt_y; |
22 | | WebIDL::Long twist { 0 }; |
23 | | Optional<double> altitude_angle; |
24 | | Optional<double> azimuth_angle; |
25 | | String pointer_type; |
26 | | bool is_primary { false }; |
27 | | WebIDL::Long persistent_device_id { 0 }; |
28 | | AK::Vector<JS::Handle<PointerEvent>> coalesced_events; |
29 | | AK::Vector<JS::Handle<PointerEvent>> predicted_events; |
30 | | }; |
31 | | |
32 | | // https://w3c.github.io/pointerevents/#pointerevent-interface |
33 | | class PointerEvent : public MouseEvent { |
34 | | WEB_PLATFORM_OBJECT(PointerEvent, MouseEvent); |
35 | | JS_DECLARE_ALLOCATOR(PointerEvent); |
36 | | |
37 | | public: |
38 | | [[nodiscard]] static JS::NonnullGCPtr<PointerEvent> create(JS::Realm&, FlyString const& type, PointerEventInit const& = {}, double page_x = 0, double page_y = 0, double offset_x = 0, double offset_y = 0); |
39 | | static WebIDL::ExceptionOr<JS::NonnullGCPtr<PointerEvent>> construct_impl(JS::Realm&, FlyString const& type, PointerEventInit const&); |
40 | | |
41 | | virtual ~PointerEvent() override; |
42 | | |
43 | 0 | WebIDL::Long pointer_id() const { return m_pointer_id; } |
44 | 0 | double width() const { return m_width; } |
45 | 0 | double height() const { return m_height; } |
46 | 0 | float pressure() const { return m_pressure; } |
47 | 0 | float tangential_pressure() const { return m_tangential_pressure; } |
48 | 0 | WebIDL::Long tilt_x() const { return m_tilt_x; } |
49 | 0 | WebIDL::Long tilt_y() const { return m_tilt_y; } |
50 | 0 | WebIDL::Long twist() const { return m_twist; } |
51 | 0 | double altitude_angle() const { return m_altitude_angle; } |
52 | 0 | double azimuth_angle() const { return m_azimuth_angle; } |
53 | 0 | String const& pointer_type() const { return m_pointer_type; } |
54 | 0 | bool is_primary() const { return m_is_primary; } |
55 | 0 | WebIDL::Long persistent_device_id() const { return m_persistent_device_id; } |
56 | 0 | AK::ReadonlySpan<JS::NonnullGCPtr<PointerEvent>> get_coalesced_events() const { return m_coalesced_events; } |
57 | 0 | AK::ReadonlySpan<JS::NonnullGCPtr<PointerEvent>> get_predicted_events() const { return m_predicted_events; } |
58 | | |
59 | | // https://w3c.github.io/pointerevents/#dom-pointerevent-pressure |
60 | | // For hardware and platforms that do not support pressure, the value MUST be 0.5 when in the active buttons state and 0 otherwise. |
61 | | static constexpr float ACTIVE_PRESSURE_DEFAULT_IN_ACTIVE_BUTTON_STATE { 0.5 }; |
62 | | |
63 | | protected: |
64 | | PointerEvent(JS::Realm&, FlyString const& type, PointerEventInit const&, double page_x, double page_y, double offset_x, double offset_y); |
65 | | |
66 | | virtual void initialize(JS::Realm&) override; |
67 | | virtual void visit_edges(Cell::Visitor&) override; |
68 | | |
69 | | private: |
70 | 0 | virtual bool is_pointer_event() const final { return true; } |
71 | | |
72 | | // A unique identifier for the pointer causing the event. |
73 | | // https://w3c.github.io/pointerevents/#dom-pointerevent-pointerid |
74 | | WebIDL::Long m_pointer_id { 0 }; |
75 | | |
76 | | // The width (magnitude on the X axis), in CSS pixels (see [CSS21]), of the contact geometry of the pointer |
77 | | // https://w3c.github.io/pointerevents/#dom-pointerevent-width |
78 | | double m_width { 1 }; |
79 | | |
80 | | // The height (magnitude on the Y axis), in CSS pixels (see [CSS21]), of the contact geometry of the pointer. |
81 | | // https://w3c.github.io/pointerevents/#dom-pointerevent-width |
82 | | double m_height { 1 }; |
83 | | |
84 | | // The normalized pressure of the pointer input in the range of [0,1], where 0 and 1 represent the minimum and |
85 | | // maximum pressure the hardware is capable of detecting, respectively |
86 | | // https://w3c.github.io/pointerevents/#dom-pointerevent-pressure |
87 | | float m_pressure { 0 }; |
88 | | |
89 | | // The normalized tangential pressure (also known as barrel pressure), typically set by an additional control |
90 | | // (e.g. a finger wheel on an airbrush stylus), of the pointer input in the range of [-1,1], where 0 is the |
91 | | // neutral position of the control |
92 | | // https://w3c.github.io/pointerevents/#dom-pointerevent-tangentialpressure |
93 | | float m_tangential_pressure { 0 }; |
94 | | |
95 | | // The plane angle (in degrees, in the range of [-90,90]) between the Y-Z plane and the plane containing both the |
96 | | // transducer (e.g. pen/stylus) axis and the Y axis |
97 | | // https://w3c.github.io/pointerevents/#dom-pointerevent-tiltx |
98 | | WebIDL::Long m_tilt_x { 0 }; |
99 | | |
100 | | // The plane angle (in degrees, in the range of [-90,90]) between the X-Z plane and the plane containing both the |
101 | | // transducer (e.g. pen/stylus) axis and the X axis |
102 | | // https://w3c.github.io/pointerevents/#dom-pointerevent-tilty |
103 | | WebIDL::Long m_tilt_y { 0 }; |
104 | | |
105 | | // The clockwise rotation (in degrees, in the range of [0,359]) of a transducer (e.g. pen/stylus) around its own major axis |
106 | | // https://w3c.github.io/pointerevents/#dom-pointerevent-twist |
107 | | WebIDL::Long m_twist { 0 }; |
108 | | |
109 | | // The altitude (in radians) of the transducer (e.g. pen/stylus), in the range [0,π/2] — where 0 is parallel to the surface |
110 | | // (X-Y plane), and π/2 is perpendicular to the surface |
111 | | // For hardware and platforms that do not report tilt or angle, the value MUST be π/2. |
112 | | // https://w3c.github.io/pointerevents/#dom-pointerevent-altitudeangle |
113 | | static constexpr double DEFAULT_ALTITUDE_ANGLE { AK::Pi<double> / 2 }; |
114 | | double m_altitude_angle { DEFAULT_ALTITUDE_ANGLE }; |
115 | | |
116 | | // The azimuth angle (in radians) of the transducer (e.g. pen/stylus), in the range [0, 2π] — where 0 represents a transducer |
117 | | // whose cap is pointing in the direction of increasing X values (point to "3 o'clock" if looking straight down) on the X-Y |
118 | | // plane, and the values progressively increase when going clockwise (π/2 at "6 o'clock", π at "9 o'clock", 3π/2 at "12 o'clock"). |
119 | | // https://w3c.github.io/pointerevents/#dom-pointerevent-azimuthangle |
120 | | double m_azimuth_angle { 0 }; |
121 | | |
122 | | // Indicates the device type that caused the event (mouse, pen, touch, etc.) |
123 | | // https://w3c.github.io/pointerevents/#dom-pointerevent-pointertype |
124 | | String m_pointer_type; |
125 | | |
126 | | // Indicates if the pointer represents the primary pointer of this pointer type |
127 | | // https://w3c.github.io/pointerevents/#dom-pointerevent-isprimary |
128 | | bool m_is_primary { false }; |
129 | | |
130 | | // A unique identifier for the pointing device. |
131 | | // https://w3c.github.io/pointerevents/#dom-pointerevent-persistentdeviceid |
132 | | WebIDL::Long m_persistent_device_id { 0 }; |
133 | | |
134 | | // https://w3c.github.io/pointerevents/#dom-pointerevent-getcoalescedevents |
135 | | AK::Vector<JS::NonnullGCPtr<PointerEvent>> m_coalesced_events; |
136 | | |
137 | | // https://w3c.github.io/pointerevents/#dom-pointerevent-getpredictedevents |
138 | | AK::Vector<JS::NonnullGCPtr<PointerEvent>> m_predicted_events; |
139 | | }; |
140 | | |
141 | | } |
142 | | |
143 | | namespace Web::DOM { |
144 | | |
145 | | template<> |
146 | 0 | inline bool Event::fast_is<UIEvents::PointerEvent>() const { return is_pointer_event(); } |
147 | | |
148 | | } |