• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_EVENT_AXIS_EVENT_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_EVENT_AXIS_EVENT_H
18 
19 #include <list>
20 
21 #include "base/geometry/offset.h"
22 #include "base/memory/ace_type.h"
23 #include "core/event/ace_events.h"
24 
25 namespace OHOS::MMI {
26 class PointerEvent;
27 } // namespace OHOS::MMI
28 
29 namespace OHOS::Ace {
30 
31 constexpr double MOUSE_WHEEL_DEGREES = 15.0;
32 constexpr double DP_PER_LINE_DESKTOP = 40.0;
33 constexpr Dimension LINE_HEIGHT_DESKTOP = 21.0_vp;
34 constexpr int32_t LINE_NUMBER_DESKTOP = 3;
35 constexpr int32_t DP_PER_LINE_PHONE = 64;
36 constexpr int32_t LINE_NUMBER_PHONE = 1;
37 
38 enum class AxisDirection : int32_t {
39     NONE = 0,
40     UP = 1,
41     DOWN = 2,
42     LEFT = 4,
43     RIGHT = 8,
44     UP_LEFT = 5,
45     UP_RIGHT = 9,
46     DOWN_LEFT = 6,
47     DOWN_RIGHT = 10,
48 };
49 
50 enum class AxisAction : int32_t {
51     NONE = 0,
52     BEGIN,
53     UPDATE,
54     END,
55     CANCEL,
56 };
57 
58 struct AxisEvent final {
59     int32_t id = 0;
60     float x = 0.0;
61     float y = 0.0;
62     float screenX = 0.0;
63     float screenY = 0.0;
64     double verticalAxis = 0.0;
65     double horizontalAxis = 0.0;
66     double pinchAxisScale = 0.0;
67     AxisAction action;
68     TimeStamp time;
69     int64_t deviceId = 0;
70     SourceType sourceType = SourceType::NONE;
71     SourceTool sourceTool = SourceTool::UNKNOWN;
72     std::shared_ptr<MMI::PointerEvent> pointerEvent;
73 
CreateScaleEventfinal74     AxisEvent CreateScaleEvent(float scale) const
75     {
76         if (NearZero(scale)) {
77             return { .id = id,
78                 .x = x,
79                 .y = y,
80                 .screenX = screenX,
81                 .screenY = screenY,
82                 .verticalAxis = verticalAxis,
83                 .horizontalAxis = horizontalAxis,
84                 .pinchAxisScale = pinchAxisScale,
85                 .action = action,
86                 .time = time,
87                 .deviceId = deviceId,
88                 .sourceType = sourceType,
89                 .sourceTool = sourceTool,
90                 .pointerEvent = pointerEvent };
91         }
92         return { .id = id,
93             .x = x / scale,
94             .y = y / scale,
95             .screenX = screenX / scale,
96             .screenY = screenY / scale,
97             .verticalAxis = verticalAxis,
98             .horizontalAxis = horizontalAxis,
99             .pinchAxisScale = pinchAxisScale,
100             .action = action,
101             .time = time,
102             .deviceId = deviceId,
103             .sourceType = sourceType,
104             .sourceTool = sourceTool,
105             .pointerEvent = pointerEvent };
106     }
107 
GetOffsetfinal108     Offset GetOffset() const
109     {
110         return Offset(x, y);
111     }
112 
GetScreenOffsetfinal113     Offset GetScreenOffset() const
114     {
115         return Offset(screenX, screenY);
116     }
117 
GetDirectionfinal118     AxisDirection GetDirection() const
119     {
120         uint32_t verticalFlag = 0;
121         uint32_t horizontalFlag = 0;
122         if (LessNotEqual(verticalAxis, 0.0)) {
123             verticalFlag = static_cast<uint32_t>(AxisDirection::UP);
124         } else if (GreatNotEqual(verticalAxis, 0.0)) {
125             verticalFlag = static_cast<uint32_t>(AxisDirection::DOWN);
126         }
127         if (LessNotEqual(horizontalAxis, 0.0)) {
128             horizontalFlag = static_cast<uint32_t>(AxisDirection::LEFT);
129         } else if (GreatNotEqual(horizontalAxis, 0.0)) {
130             horizontalFlag = static_cast<uint32_t>(AxisDirection::RIGHT);
131         }
132         return static_cast<AxisDirection>(verticalFlag | horizontalFlag);
133     }
IsDirectionUpfinal134     static bool IsDirectionUp(AxisDirection direction)
135     {
136         return (static_cast<uint32_t>(direction) & static_cast<uint32_t>(AxisDirection::UP));
137     }
IsDirectionDownfinal138     static bool IsDirectionDown(AxisDirection direction)
139     {
140         return (static_cast<uint32_t>(direction) & static_cast<uint32_t>(AxisDirection::DOWN));
141     }
IsDirectionLeftfinal142     static bool IsDirectionLeft(AxisDirection direction)
143     {
144         return (static_cast<uint32_t>(direction) & static_cast<uint32_t>(AxisDirection::LEFT));
145     }
IsDirectionRightfinal146     static bool IsDirectionRight(AxisDirection direction)
147     {
148         return (static_cast<uint32_t>(direction) & static_cast<uint32_t>(AxisDirection::RIGHT));
149     }
150 
151     Offset ConvertToOffset(bool isShiftKeyPressed = false, bool hasDifferentDirectionGesture = false) const
152     {
153         Offset result;
154         if (sourceTool == SourceTool::MOUSE) {
155             // Axis event is made by mouse.
156             if (isShiftKeyPressed) {
157                 result = Offset(-verticalAxis, -horizontalAxis);
158             } else {
159                 if (hasDifferentDirectionGesture) {
160                     result = Offset(-horizontalAxis, -verticalAxis);
161                 } else {
162                     result = Offset(-verticalAxis, -verticalAxis);
163                 }
164             }
165         } else {
166             // Axis event is made by others. Include touch-pad.
167             result = Offset(-horizontalAxis, -verticalAxis);
168         }
169         return result * (LINE_HEIGHT_DESKTOP * LINE_NUMBER_DESKTOP / MOUSE_WHEEL_DEGREES).ConvertToPx();
170     }
171 };
172 
173 class AxisInfo : public BaseEventInfo {
174     DECLARE_RELATIONSHIP_OF_CLASSES(AxisInfo, BaseEventInfo);
175 
176 public:
AxisInfo()177     AxisInfo() : BaseEventInfo("onAxis") {}
AxisInfo(const AxisEvent & event,const Offset & localLocation,const EventTarget & target)178     AxisInfo(const AxisEvent& event, const Offset& localLocation, const EventTarget& target) : BaseEventInfo("onAxis")
179     {
180         action_ = event.action;
181         verticalAxis_ = static_cast<float>(event.verticalAxis);
182         horizontalAxis_ = static_cast<float>(event.horizontalAxis);
183         pinchAxisScale_ = static_cast<float>(event.pinchAxisScale);
184         globalLocation_ = event.GetOffset();
185         localLocation_ = localLocation;
186         screenLocation_ = Offset();
187         SetTimeStamp(event.time);
188         SetDeviceId(event.deviceId);
189         SetSourceDevice(event.sourceType);
190         SetTarget(target);
191     }
192     ~AxisInfo() override = default;
193 
SetAction(AxisAction action)194     void SetAction(AxisAction action)
195     {
196         action_ = action;
197     }
198 
GetAction()199     AxisAction GetAction() const
200     {
201         return action_;
202     }
203 
SetVerticalAxis(float axis)204     void SetVerticalAxis(float axis)
205     {
206         verticalAxis_ = axis;
207     }
208 
GetVerticalAxis()209     float GetVerticalAxis() const
210     {
211         return verticalAxis_;
212     }
213 
SetHorizontalAxis(float axis)214     void SetHorizontalAxis(float axis)
215     {
216         horizontalAxis_ = axis;
217     }
218 
GetHorizontalAxis()219     float GetHorizontalAxis() const
220     {
221         return horizontalAxis_;
222     }
223 
SetPinchAxisScale(float scale)224     void SetPinchAxisScale(float scale)
225     {
226         pinchAxisScale_ = scale;
227     }
228 
GetPinchAxisScale()229     float GetPinchAxisScale() const
230     {
231         return pinchAxisScale_;
232     }
233 
SetGlobalLocation(const Offset & globalLocation)234     AxisInfo& SetGlobalLocation(const Offset& globalLocation)
235     {
236         globalLocation_ = globalLocation;
237         return *this;
238     }
SetLocalLocation(const Offset & localLocation)239     AxisInfo& SetLocalLocation(const Offset& localLocation)
240     {
241         localLocation_ = localLocation;
242         return *this;
243     }
244 
SetScreenLocation(const Offset & screenLocation)245     AxisInfo& SetScreenLocation(const Offset& screenLocation)
246     {
247         screenLocation_ = screenLocation;
248         return *this;
249     }
250 
GetScreenLocation()251     const Offset& GetScreenLocation() const
252     {
253         return screenLocation_;
254     }
255 
GetLocalLocation()256     const Offset& GetLocalLocation() const
257     {
258         return localLocation_;
259     }
GetGlobalLocation()260     const Offset& GetGlobalLocation() const
261     {
262         return globalLocation_;
263     }
264 
265 private:
266     AxisAction action_ = AxisAction::NONE;
267     float verticalAxis_ = 0.0;
268     float horizontalAxis_ = 0.0;
269     float pinchAxisScale_ = 0.0;
270     // global position at which the touch point contacts the screen.
271     Offset globalLocation_;
272     // Different from global location, The local location refers to the location of the contact point relative to the
273     // current node which has the recognizer.
274     Offset localLocation_;
275     Offset screenLocation_;
276 };
277 
278 using OnAxisEventFunc = std::function<void(AxisInfo&)>;
279 using GetEventTargetImpl = std::function<std::optional<EventTarget>()>;
280 
281 class AxisEventTarget : public virtual AceType {
282     DECLARE_ACE_TYPE(AxisEventTarget, AceType);
283 
284 public:
285     AxisEventTarget() = default;
AxisEventTarget(std::string frameName)286     AxisEventTarget(std::string frameName) : frameName_(std::move(frameName)) {}
287     ~AxisEventTarget() override = default;
288 
SetOnAxisCallback(const OnAxisEventFunc & onAxisCallback)289     void SetOnAxisCallback(const OnAxisEventFunc& onAxisCallback)
290     {
291         onAxisCallback_ = onAxisCallback;
292     }
293 
SetCoordinateOffset(const NG::OffsetF & coordinateOffset)294     void SetCoordinateOffset(const NG::OffsetF& coordinateOffset)
295     {
296         coordinateOffset_ = coordinateOffset;
297     }
298 
SetGetEventTargetImpl(const GetEventTargetImpl & getEventTargetImpl)299     void SetGetEventTargetImpl(const GetEventTargetImpl& getEventTargetImpl)
300     {
301         getEventTargetImpl_ = getEventTargetImpl;
302     }
303 
GetEventTarget()304     std::optional<EventTarget> GetEventTarget() const
305     {
306         if (getEventTargetImpl_) {
307             return getEventTargetImpl_();
308         }
309         return std::nullopt;
310     }
311 
SetFrameName(const std::string & frameName)312     void SetFrameName(const std::string& frameName)
313     {
314         frameName_ = frameName;
315     }
316 
GetFrameName()317     std::string GetFrameName() const
318     {
319         return frameName_;
320     }
321 
HandleAxisEvent(const AxisEvent & event)322     bool HandleAxisEvent(const AxisEvent& event)
323     {
324         if (!onAxisCallback_) {
325             return false;
326         }
327         Offset localLocation = Offset(
328             event.GetOffset().GetX() - coordinateOffset_.GetX(), event.GetOffset().GetY() - coordinateOffset_.GetY());
329         AxisInfo info = AxisInfo(event, localLocation, GetEventTarget().value_or(EventTarget()));
330         onAxisCallback_(info);
331         return true;
332     }
333 
HandleEvent(const AxisEvent & event)334     virtual void HandleEvent(const AxisEvent& event) {}
335 
336 private:
337     OnAxisEventFunc onAxisCallback_;
338     NG::OffsetF coordinateOffset_;
339     GetEventTargetImpl getEventTargetImpl_;
340     std::string frameName_ = "Unknown";
341 };
342 
343 using AxisTestResult = std::list<RefPtr<AxisEventTarget>>;
344 
345 } // namespace OHOS::Ace
346 
347 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_EVENT_AXIS_EVENT_H