• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 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_MOUSE_EVENT_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_EVENT_MOUSE_EVENT_H
18 
19 #include "base/geometry/ng/offset_t.h"
20 #include "base/geometry/offset.h"
21 #include "base/mousestyle/mouse_style.h"
22 #include "core/event/touch_event.h"
23 #include "core/pipeline_ng/ui_task_scheduler.h"
24 
25 namespace OHOS::MMI {
26 class PointerEvent;
27 } // namespace OHOS::MMI
28 
29 namespace OHOS::Ace {
30 
31 class MouseInfo;
32 constexpr int32_t MOUSE_PRESS_LEFT = 1;
33 static const int32_t MOUSE_BASE_ID = 1000;
34 
35 using OnMouseEventFunc = std::function<void(MouseInfo& info)>;
36 
37 enum class MouseAction : int32_t {
38     NONE = 0,
39     PRESS = 1,
40     RELEASE = 2,
41     MOVE = 3,
42     WINDOW_ENTER = 4,
43     WINDOW_LEAVE = 5,
44     HOVER,
45     HOVER_ENTER,
46     HOVER_MOVE,
47     HOVER_EXIT,
48     PULL_DOWN,
49     PULL_MOVE,
50     PULL_UP
51 };
52 
53 enum class MouseState : int32_t {
54     NONE = 0,
55     HOVER = 1,
56 };
57 
58 enum class MouseButton : int32_t {
59     NONE_BUTTON = 0,
60     LEFT_BUTTON = 1,
61     RIGHT_BUTTON = 2,
62     MIDDLE_BUTTON = 4,
63     BACK_BUTTON = 8,
64     FORWARD_BUTTON = 16,
65     SIDE_BUTTON = 32,
66     EXTRA_BUTTON = 64,
67     TASK_BUTTON = 128,
68 };
69 
70 enum class HoverEffectType : int32_t {
71     NONE,
72     OPACITY,
73     SCALE,
74     BOARD,
75     AUTO,
76     UNKNOWN,
77 };
78 
79 struct MouseEvent final {
80     int32_t id = 0;
81     float x = 0.0f;
82     float y = 0.0f;
83     float z = 0.0f;
84     float deltaX = 0.0f;
85     float deltaY = 0.0f;
86     float deltaZ = 0.0f;
87     float scrollX = 0.0f;
88     float scrollY = 0.0f;
89     float scrollZ = 0.0f;
90     float screenX = 0.0f;
91     float screenY = 0.0f;
92     MouseAction action = MouseAction::NONE;
93     MouseAction pullAction = MouseAction::NONE;
94     MouseButton button = MouseButton::NONE_BUTTON;
95     int32_t pressedButtons = 0; // combined by MouseButtons
96     TimeStamp time;
97     int64_t deviceId = 0;
98     int32_t targetDisplayId = 0;
99     SourceType sourceType = SourceType::NONE;
100     std::shared_ptr<MMI::PointerEvent> pointerEvent;
101     std::vector<uint8_t> enhanceData;
102 
GetOffsetfinal103     Offset GetOffset() const
104     {
105         return Offset(x, y);
106     }
107 
GetScreenOffsetfinal108     Offset GetScreenOffset() const
109     {
110         return Offset(screenX, screenY);
111     }
112 
GetIdfinal113     int32_t GetId() const
114     {
115         if (pressedButtons > 0) {
116             return pressedButtons + MOUSE_BASE_ID;
117         } else {
118             return (int32_t)button + MOUSE_BASE_ID;
119         }
120     }
121 
CreateScaleEventfinal122     MouseEvent CreateScaleEvent(float scale) const
123     {
124         if (NearZero(scale)) {
125             return { .x = x,
126                 .y = y,
127                 .z = z,
128                 .deltaX = deltaX,
129                 .deltaY = deltaY,
130                 .deltaZ = deltaZ,
131                 .scrollX = scrollX,
132                 .scrollY = scrollY,
133                 .scrollZ = scrollZ,
134                 .screenX = screenX,
135                 .screenY = screenY,
136                 .action = action,
137                 .pullAction = pullAction,
138                 .button = button,
139                 .pressedButtons = pressedButtons,
140                 .time = time,
141                 .deviceId = deviceId,
142                 .targetDisplayId = targetDisplayId,
143                 .sourceType = sourceType,
144                 .pointerEvent = pointerEvent,
145                 .enhanceData = enhanceData };
146         }
147 
148         return { .x = x / scale,
149             .y = y / scale,
150             .z = z / scale,
151             .deltaX = deltaX / scale,
152             .deltaY = deltaY / scale,
153             .deltaZ = deltaZ / scale,
154             .scrollX = scrollX / scale,
155             .scrollY = scrollY / scale,
156             .scrollZ = scrollZ / scale,
157             .screenX = screenX / scale,
158             .screenY = screenY / scale,
159             .action = action,
160             .pullAction = pullAction,
161             .button = button,
162             .pressedButtons = pressedButtons,
163             .time = time,
164             .deviceId = deviceId,
165             .targetDisplayId = targetDisplayId,
166             .sourceType = sourceType,
167             .pointerEvent = pointerEvent,
168             .enhanceData = enhanceData };
169     }
170 
CreateTouchPointfinal171     TouchEvent CreateTouchPoint() const
172     {
173         TouchType type = TouchType::UNKNOWN;
174         if (action == MouseAction::PRESS) {
175             type = TouchType::DOWN;
176         } else if (action == MouseAction::RELEASE) {
177             type = TouchType::UP;
178         } else if (action == MouseAction::MOVE) {
179             type = TouchType::MOVE;
180         } else {
181             type = TouchType::UNKNOWN;
182         }
183         int32_t pointId = id;
184         if (sourceType == SourceType::MOUSE) {
185             pointId = GetId();
186         }
187         TouchPoint point { .id = pointId,
188             .x = x,
189             .y = y,
190             .screenX = screenX,
191             .screenY = screenY,
192             .downTime = time,
193             .size = 0.0,
194             .isPressed = (type == TouchType::DOWN) };
195         TouchEvent event { .id = pointId,
196             .x = x,
197             .y = y,
198             .screenX = screenX,
199             .screenY = screenY,
200             .type = type,
201             .time = time,
202             .size = 0.0,
203             .deviceId = deviceId,
204             .targetDisplayId = targetDisplayId,
205             .sourceType = sourceType,
206             .pointerEvent = pointerEvent,
207             .enhanceData = enhanceData };
208         event.pointers.emplace_back(std::move(point));
209         return event;
210     }
211 
212     MouseEvent operator-(const Offset& offset) const
213     {
214         return { .x = x - offset.GetX(),
215             .y = y - offset.GetY(),
216             .z = z,
217             .deltaX = deltaX,
218             .deltaY = deltaY,
219             .deltaZ = deltaZ,
220             .scrollX = scrollX,
221             .scrollY = scrollY,
222             .scrollZ = scrollZ,
223             .screenX = screenX - offset.GetX(),
224             .screenY = screenY - offset.GetY(),
225             .action = action,
226             .button = button,
227             .pressedButtons = pressedButtons,
228             .time = time,
229             .deviceId = deviceId,
230             .targetDisplayId = targetDisplayId,
231             .sourceType = sourceType,
232             .pointerEvent = pointerEvent,
233             .enhanceData = enhanceData };
234     }
235 };
236 
237 class MouseInfo : public BaseEventInfo {
238     DECLARE_RELATIONSHIP_OF_CLASSES(MouseInfo, BaseEventInfo);
239 
240 public:
MouseInfo()241     MouseInfo() : BaseEventInfo("onMouse") {}
242     ~MouseInfo() override = default;
243 
SetButton(MouseButton button)244     void SetButton(MouseButton button)
245     {
246         button_ = button;
247     }
248 
GetButton()249     MouseButton GetButton() const
250     {
251         return button_;
252     }
253 
SetAction(MouseAction action)254     void SetAction(MouseAction action)
255     {
256         action_ = action;
257     }
258 
GetAction()259     MouseAction GetAction() const
260     {
261         return action_;
262     }
263 
SetGlobalLocation(const Offset & globalLocation)264     MouseInfo& SetGlobalLocation(const Offset& globalLocation)
265     {
266         globalLocation_ = globalLocation;
267         return *this;
268     }
SetLocalLocation(const Offset & localLocation)269     MouseInfo& SetLocalLocation(const Offset& localLocation)
270     {
271         localLocation_ = localLocation;
272         return *this;
273     }
274 
SetScreenLocation(const Offset & screenLocation)275     MouseInfo& SetScreenLocation(const Offset& screenLocation)
276     {
277         screenLocation_ = screenLocation;
278         return *this;
279     }
280 
GetScreenLocation()281     const Offset& GetScreenLocation() const
282     {
283         return screenLocation_;
284     }
285 
GetLocalLocation()286     const Offset& GetLocalLocation() const
287     {
288         return localLocation_;
289     }
GetGlobalLocation()290     const Offset& GetGlobalLocation() const
291     {
292         return globalLocation_;
293     }
294 
SetPointerEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)295     void SetPointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
296     {
297         pointerEvent_ = pointerEvent;
298     }
GetPointerEvent()299     const std::shared_ptr<MMI::PointerEvent> GetPointerEvent() const
300     {
301         return pointerEvent_;
302     }
303 
304 private:
305     std::shared_ptr<MMI::PointerEvent> pointerEvent_;
306     MouseButton button_ = MouseButton::NONE_BUTTON;
307     MouseAction action_ = MouseAction::NONE;
308     // global position at which the touch point contacts the screen.
309     Offset globalLocation_;
310     // Different from global location, The local location refers to the location of the contact point relative to the
311     // current node which has the recognizer.
312     Offset localLocation_;
313     Offset screenLocation_;
314 };
315 
316 using HoverEffectFunc = std::function<void(bool)>;
317 
318 class HoverInfo;
319 class HoverInfo : public BaseEventInfo {
320     DECLARE_RELATIONSHIP_OF_CLASSES(HoverInfo, BaseEventInfo);
321 
322 public:
HoverInfo()323     HoverInfo() : BaseEventInfo("onHover") {}
324     ~HoverInfo() override = default;
325 };
326 
327 using OnHoverFunc = std::function<void(bool, HoverInfo& info)>;
328 using OnHoverEventFunc = std::function<void(bool)>;
329 
330 class MouseEventTarget : public virtual TouchEventTarget {
331     DECLARE_ACE_TYPE(MouseEventTarget, TouchEventTarget);
332 
333 public:
MouseEventTarget(const std::string & nodeName,int32_t nodeId)334     MouseEventTarget(const std::string& nodeName, int32_t nodeId) : TouchEventTarget(nodeName, nodeId) {}
335     ~MouseEventTarget() override = default;
336 
SetCallback(const OnMouseEventFunc & onMouseCallback)337     void SetCallback(const OnMouseEventFunc& onMouseCallback)
338     {
339         onMouseCallback_ = onMouseCallback;
340     }
341 
HandleMouseEvent(const MouseEvent & event)342     bool HandleMouseEvent(const MouseEvent& event)
343     {
344         if (!onMouseCallback_) {
345             return false;
346         }
347         MouseInfo info;
348         info.SetPointerEvent(event.pointerEvent);
349         info.SetButton(event.button);
350         info.SetAction(event.action);
351         info.SetGlobalLocation(event.GetOffset());
352         Offset localLocation = Offset(
353             event.GetOffset().GetX() - coordinateOffset_.GetX(), event.GetOffset().GetY() - coordinateOffset_.GetY());
354         info.SetLocalLocation(localLocation);
355         info.SetScreenLocation(event.GetScreenOffset());
356         info.SetTimeStamp(event.time);
357         info.SetDeviceId(event.deviceId);
358         info.SetTargetDisplayId(event.targetDisplayId);
359         info.SetSourceDevice(event.sourceType);
360         info.SetTarget(GetEventTarget().value_or(EventTarget()));
361         onMouseCallback_(info);
362         return info.IsStopPropagation();
363     }
364 
DispatchEvent(const TouchEvent & point)365     bool DispatchEvent(const TouchEvent& point) override
366     {
367         return false;
368     }
369     // if return false means need to stop event bubbling.
HandleEvent(const TouchEvent & point)370     bool HandleEvent(const TouchEvent& point) override
371     {
372         return false;
373     }
374 
375 private:
376     OnMouseEventFunc onMouseCallback_;
377 };
378 
379 class HoverEventTarget : public virtual TouchEventTarget {
380     DECLARE_ACE_TYPE(HoverEventTarget, TouchEventTarget);
381 
382 public:
HoverEventTarget(const std::string & nodeName,int32_t nodeId)383     HoverEventTarget(const std::string& nodeName, int32_t nodeId) : TouchEventTarget(nodeName, nodeId) {}
384     ~HoverEventTarget() override = default;
385 
SetCallback(const OnHoverEventFunc & onHoverCallback)386     void SetCallback(const OnHoverEventFunc& onHoverCallback)
387     {
388         onHoverCallback_ = onHoverCallback;
389     }
SetCallback(const OnHoverFunc & onHoverEventCallback)390     void SetCallback(const OnHoverFunc& onHoverEventCallback)
391     {
392         onHoverEventCallback_ = onHoverEventCallback;
393     }
394 
HandleHoverEvent(bool isHovered,const MouseEvent & event)395     bool HandleHoverEvent(bool isHovered, const MouseEvent& event)
396     {
397         if (!onHoverEventCallback_) {
398             return false;
399         }
400         HoverInfo hoverInfo;
401         hoverInfo.SetTimeStamp(event.time);
402         hoverInfo.SetDeviceId(event.deviceId);
403         hoverInfo.SetSourceDevice(event.sourceType);
404         onHoverEventCallback_(isHovered, hoverInfo);
405         if (hoverInfo.IsStopPropagation()) {
406             return false;
407         }
408         return true;
409     }
410 
HandleHoverEvent(bool isHovered)411     bool HandleHoverEvent(bool isHovered)
412     {
413         if (!onHoverCallback_) {
414             return false;
415         }
416         onHoverCallback_(isHovered);
417         return true;
418     }
419 
DispatchEvent(const TouchEvent & point)420     bool DispatchEvent(const TouchEvent& point) override
421     {
422         return false;
423     }
HandleEvent(const TouchEvent & point)424     bool HandleEvent(const TouchEvent& point) override
425     {
426         return false;
427     }
428 
429 private:
430     OnHoverEventFunc onHoverCallback_;
431     OnHoverFunc onHoverEventCallback_;
432 };
433 
434 class HoverEffectTarget : public virtual TouchEventTarget {
435     DECLARE_ACE_TYPE(HoverEffectTarget, TouchEventTarget);
436 
437 public:
HoverEffectTarget(const std::string & nodeName,int32_t nodeId)438     HoverEffectTarget(const std::string& nodeName, int32_t nodeId) : TouchEventTarget(nodeName, nodeId) {}
439     ~HoverEffectTarget() override = default;
440 
SetHoverNode(const WeakPtr<NG::FrameNode> & node)441     void SetHoverNode(const WeakPtr<NG::FrameNode>& node)
442     {
443         hoverNode_ = node;
444     }
GetHoverNode()445     WeakPtr<NG::FrameNode> GetHoverNode() const
446     {
447         return hoverNode_;
448     }
449 
DispatchEvent(const TouchEvent & point)450     bool DispatchEvent(const TouchEvent& point) override
451     {
452         return false;
453     }
454     // if return false means need to stop event bubbling.
HandleEvent(const TouchEvent & point)455     bool HandleEvent(const TouchEvent& point) override
456     {
457         return false;
458     }
459 
460 private:
461     WeakPtr<NG::FrameNode> hoverNode_;
462 };
463 
464 using MouseTestResult = std::list<RefPtr<MouseEventTarget>>;
465 using HoverTestResult = std::list<RefPtr<HoverEventTarget>>;
466 
467 } // namespace OHOS::Ace
468 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_EVENT_MOUSE_EVENT_H
469