• 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/key_event.h"
23 #include "core/event/touch_event.h"
24 #include "core/pipeline_ng/ui_task_scheduler.h"
25 
26 namespace OHOS::MMI {
27 class PointerEvent;
28 } // namespace OHOS::MMI
29 
30 namespace OHOS::Ace {
31 
32 class MouseInfo;
33 constexpr int32_t MOUSE_PRESS_LEFT = 1;
34 static const int32_t MOUSE_BASE_ID = 1000;
35 
36 using OnMouseEventFunc = std::function<void(MouseInfo& info)>;
37 
38 enum class MouseAction : int32_t {
39     NONE = 0,
40     PRESS = 1,
41     RELEASE = 2,
42     MOVE = 3,
43     WINDOW_ENTER = 4,
44     WINDOW_LEAVE = 5,
45     HOVER,
46     HOVER_ENTER,
47     HOVER_MOVE,
48     HOVER_EXIT,
49     PULL_DOWN,
50     PULL_MOVE,
51     PULL_UP,
52     CANCEL
53 };
54 
55 enum class AccessibilityHoverAction : int32_t {
56     UNKNOWN = -1,
57     HOVER_ENTER,
58     HOVER_MOVE,
59     HOVER_EXIT,
60     HOVER_CANCEL
61 };
62 
63 enum class MouseState : int32_t {
64     NONE = 0,
65     HOVER = 1,
66 };
67 
68 enum class MouseButton : int32_t {
69     NONE_BUTTON = 0,
70     LEFT_BUTTON = 1,
71     RIGHT_BUTTON = 2,
72     MIDDLE_BUTTON = 4,
73     BACK_BUTTON = 8,
74     FORWARD_BUTTON = 16,
75     SIDE_BUTTON = 32,
76     EXTRA_BUTTON = 64,
77     TASK_BUTTON = 128,
78 };
79 
80 enum class HoverEffectType : int32_t {
81     NONE,
82     OPACITY,
83     SCALE,
84     BOARD,
85     AUTO,
86     UNKNOWN,
87 };
88 
89 struct MouseEvent final {
90     int32_t id = 0;
91     float x = 0.0f;
92     float y = 0.0f;
93     float z = 0.0f;
94     float deltaX = 0.0f;
95     float deltaY = 0.0f;
96     float deltaZ = 0.0f;
97     float scrollX = 0.0f;
98     float scrollY = 0.0f;
99     float scrollZ = 0.0f;
100     float screenX = 0.0f;
101     float screenY = 0.0f;
102     MouseAction action = MouseAction::NONE;
103     MouseAction pullAction = MouseAction::NONE;
104     MouseButton button = MouseButton::NONE_BUTTON;
105     int32_t pressedButtons = 0; // combined by MouseButtons
106     TimeStamp time;
107     int64_t deviceId = 0;
108     int32_t targetDisplayId = 0;
109     SourceType sourceType = SourceType::NONE;
110     SourceTool sourceTool = SourceTool::UNKNOWN;
111     std::shared_ptr<MMI::PointerEvent> pointerEvent;
112     int32_t touchEventId = 0;
113     int32_t originalId = 0;
114     std::vector<KeyCode> pressedKeyCodes_;
115     bool isInjected = false;
116     bool isPrivacyMode = false;
117 
GetOffsetfinal118     Offset GetOffset() const
119     {
120         return Offset(x, y);
121     }
122 
GetScreenOffsetfinal123     Offset GetScreenOffset() const
124     {
125         return Offset(screenX, screenY);
126     }
127 
GetIdfinal128     int32_t GetId() const
129     {
130         if (pressedButtons > 0) {
131             return pressedButtons + MOUSE_BASE_ID;
132         } else {
133             return (int32_t)button + MOUSE_BASE_ID;
134         }
135     }
136 
GetPointerIdfinal137     int32_t GetPointerId(int32_t pointerId) const
138     {
139         if (pressedButtons > 0) {
140             return pressedButtons + MOUSE_BASE_ID + pointerId;
141         }
142         return static_cast<int32_t>(button) + MOUSE_BASE_ID + pointerId;
143     }
144 
CloneWithfinal145     MouseEvent CloneWith(float scale) const
146     {
147         return { .x = x / scale,
148             .y = y / scale,
149             .z = z / scale,
150             .deltaX = deltaX / scale,
151             .deltaY = deltaY / scale,
152             .deltaZ = deltaZ / scale,
153             .scrollX = scrollX / scale,
154             .scrollY = scrollY / scale,
155             .scrollZ = scrollZ / scale,
156             .screenX = screenX / scale,
157             .screenY = screenY / scale,
158             .action = action,
159             .pullAction = pullAction,
160             .button = button,
161             .pressedButtons = pressedButtons,
162             .time = time,
163             .deviceId = deviceId,
164             .targetDisplayId = targetDisplayId,
165             .sourceType = sourceType,
166             .sourceTool = sourceTool,
167             .pointerEvent = pointerEvent,
168             .originalId = originalId,
169             .pressedKeyCodes_ = pressedKeyCodes_,
170             .isInjected = isInjected,
171             .isPrivacyMode = isPrivacyMode
172         };
173     }
174 
CreateScaleEventfinal175     MouseEvent CreateScaleEvent(float scale) const
176     {
177         if (NearZero(scale)) {
178             return CloneWith(1);
179         }
180         return CloneWith(scale);
181     }
182 
CreateTouchPointfinal183     TouchEvent CreateTouchPoint() const
184     {
185         TouchType type = TouchType::UNKNOWN;
186         if (action == MouseAction::PRESS) {
187             type = TouchType::DOWN;
188         } else if (action == MouseAction::RELEASE) {
189             type = TouchType::UP;
190         } else if (action == MouseAction::MOVE) {
191             type = TouchType::MOVE;
192         } else if (action == MouseAction::CANCEL) {
193             type = TouchType::CANCEL;
194         } else {
195             type = TouchType::UNKNOWN;
196         }
197         int32_t pointId = id;
198         if (sourceType == SourceType::MOUSE) {
199             pointId = GetPointerId(pointId);
200         }
201         auto pointOriginalId = sourceType == SourceType::MOUSE ? GetId() : originalId;
202         TouchPoint point { .id = pointId,
203             .x = x,
204             .y = y,
205             .screenX = screenX,
206             .screenY = screenY,
207             .downTime = time,
208             .size = 0.0,
209             .isPressed = (type == TouchType::DOWN),
210             .originalId = pointOriginalId };
211         TouchEvent event;
212         event.SetId(pointId)
213             .SetX(x)
214             .SetY(y)
215             .SetScreenX(screenX)
216             .SetScreenY(screenY)
217             .SetType(type)
218             .SetTime(time)
219             .SetSize(0.0)
220             .SetDeviceId(deviceId)
221             .SetTargetDisplayId(targetDisplayId)
222             .SetSourceType(sourceType)
223             .SetSourceTool(sourceTool)
224             .SetPointerEvent(pointerEvent)
225             .SetTouchEventId(touchEventId)
226             .SetOriginalId(pointOriginalId)
227             .SetIsInjected(isInjected);
228         event.isPrivacyMode = isPrivacyMode;
229         event.pointers.emplace_back(std::move(point));
230         event.pressedKeyCodes_ = pressedKeyCodes_;
231         return event;
232     }
233 
234     MouseEvent operator-(const Offset& offset) const
235     {
236         return { .x = x - offset.GetX(),
237             .y = y - offset.GetY(),
238             .z = z,
239             .deltaX = deltaX,
240             .deltaY = deltaY,
241             .deltaZ = deltaZ,
242             .scrollX = scrollX,
243             .scrollY = scrollY,
244             .scrollZ = scrollZ,
245             .screenX = screenX - offset.GetX(),
246             .screenY = screenY - offset.GetY(),
247             .action = action,
248             .button = button,
249             .pressedButtons = pressedButtons,
250             .time = time,
251             .deviceId = deviceId,
252             .targetDisplayId = targetDisplayId,
253             .sourceType = sourceType,
254             .sourceTool = sourceTool,
255             .pointerEvent = pointerEvent,
256             .originalId = originalId,
257             .pressedKeyCodes_ = pressedKeyCodes_,
258             .isInjected = isInjected,
259             .isPrivacyMode = isPrivacyMode
260         };
261     }
262 };
263 
264 class MouseInfo : public BaseEventInfo {
265     DECLARE_RELATIONSHIP_OF_CLASSES(MouseInfo, BaseEventInfo);
266 
267 public:
MouseInfo()268     MouseInfo() : BaseEventInfo("onMouse") {}
269     ~MouseInfo() override = default;
270 
SetButton(MouseButton button)271     void SetButton(MouseButton button)
272     {
273         button_ = button;
274     }
275 
GetButton()276     MouseButton GetButton() const
277     {
278         return button_;
279     }
280 
SetAction(MouseAction action)281     void SetAction(MouseAction action)
282     {
283         action_ = action;
284     }
285 
GetAction()286     MouseAction GetAction() const
287     {
288         return action_;
289     }
290 
SetPullAction(MouseAction pullAction)291     void SetPullAction(MouseAction pullAction)
292     {
293         pullAction_ = pullAction;
294     }
295 
GetPullAction()296     MouseAction GetPullAction() const
297     {
298         return pullAction_;
299     }
300 
SetGlobalLocation(const Offset & globalLocation)301     MouseInfo& SetGlobalLocation(const Offset& globalLocation)
302     {
303         globalLocation_ = globalLocation;
304         return *this;
305     }
SetLocalLocation(const Offset & localLocation)306     MouseInfo& SetLocalLocation(const Offset& localLocation)
307     {
308         localLocation_ = localLocation;
309         return *this;
310     }
311 
SetScreenLocation(const Offset & screenLocation)312     MouseInfo& SetScreenLocation(const Offset& screenLocation)
313     {
314         screenLocation_ = screenLocation;
315         return *this;
316     }
317 
GetScreenLocation()318     const Offset& GetScreenLocation() const
319     {
320         return screenLocation_;
321     }
322 
GetLocalLocation()323     const Offset& GetLocalLocation() const
324     {
325         return localLocation_;
326     }
GetGlobalLocation()327     const Offset& GetGlobalLocation() const
328     {
329         return globalLocation_;
330     }
331 
SetPointerEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)332     void SetPointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
333     {
334         pointerEvent_ = pointerEvent;
335     }
GetPointerEvent()336     const std::shared_ptr<MMI::PointerEvent> GetPointerEvent() const
337     {
338         return pointerEvent_;
339     }
340 
341 private:
342     std::shared_ptr<MMI::PointerEvent> pointerEvent_;
343     MouseButton button_ = MouseButton::NONE_BUTTON;
344     MouseAction action_ = MouseAction::NONE;
345     MouseAction pullAction_ = MouseAction::NONE;
346     // global position at which the touch point contacts the screen.
347     Offset globalLocation_;
348     // Different from global location, The local location refers to the location of the contact point relative to the
349     // current node which has the recognizer.
350     Offset localLocation_;
351     Offset screenLocation_;
352 };
353 
354 using HoverEffectFunc = std::function<void(bool)>;
355 
356 class HoverInfo;
357 class HoverInfo : public BaseEventInfo {
358     DECLARE_RELATIONSHIP_OF_CLASSES(HoverInfo, BaseEventInfo);
359 
360 public:
HoverInfo()361     HoverInfo() : BaseEventInfo("onHover") {}
362     ~HoverInfo() override = default;
363 };
364 
365 class AccessibilityHoverInfo : public BaseEventInfo {
366     DECLARE_RELATIONSHIP_OF_CLASSES(AccessibilityHoverInfo, BaseEventInfo);
367 
368 public:
AccessibilityHoverInfo()369     AccessibilityHoverInfo() : BaseEventInfo("onAccessibilityHover") {}
370     ~AccessibilityHoverInfo() override = default;
371 
SetGlobalLocation(const Offset & globalLocation)372     AccessibilityHoverInfo& SetGlobalLocation(const Offset& globalLocation)
373     {
374         globalLocation_ = globalLocation;
375         return *this;
376     }
SetLocalLocation(const Offset & localLocation)377     AccessibilityHoverInfo& SetLocalLocation(const Offset& localLocation)
378     {
379         localLocation_ = localLocation;
380         return *this;
381     }
382 
SetScreenLocation(const Offset & screenLocation)383     AccessibilityHoverInfo& SetScreenLocation(const Offset& screenLocation)
384     {
385         screenLocation_ = screenLocation;
386         return *this;
387     }
388 
GetScreenLocation()389     const Offset& GetScreenLocation() const
390     {
391         return screenLocation_;
392     }
393 
GetLocalLocation()394     const Offset& GetLocalLocation() const
395     {
396         return localLocation_;
397     }
398 
GetGlobalLocation()399     const Offset& GetGlobalLocation() const
400     {
401         return globalLocation_;
402     }
403 
GetActionType()404     AccessibilityHoverAction GetActionType() const
405     {
406         return actionType_;
407     }
408 
SetActionType(AccessibilityHoverAction type)409     void SetActionType(AccessibilityHoverAction type)
410     {
411         actionType_ = type;
412     }
413 
414 private:
415     // global position at which the touch point contacts the screen.
416     Offset globalLocation_;
417     // Different from global location, The local location refers to the location of the contact point relative to the
418     // current node which has the recognizer.
419     Offset localLocation_;
420 
421     Offset screenLocation_;
422 
423     // touch type
424     AccessibilityHoverAction actionType_ = AccessibilityHoverAction::UNKNOWN;
425 };
426 
427 using OnHoverFunc = std::function<void(bool, HoverInfo& info)>;
428 using OnHoverEventFunc = std::function<void(bool)>;
429 
430 using OnAccessibilityHoverFunc = std::function<void(bool, AccessibilityHoverInfo& info)>;
431 
432 class MouseEventTarget : public virtual TouchEventTarget {
433     DECLARE_ACE_TYPE(MouseEventTarget, TouchEventTarget);
434 
435 public:
MouseEventTarget(const std::string & nodeName,int32_t nodeId)436     MouseEventTarget(const std::string& nodeName, int32_t nodeId) : TouchEventTarget(nodeName, nodeId) {}
437     ~MouseEventTarget() override = default;
438 
SetCallback(const OnMouseEventFunc & onMouseCallback)439     void SetCallback(const OnMouseEventFunc& onMouseCallback)
440     {
441         onMouseCallback_ = onMouseCallback;
442     }
443 
HandleMouseEvent(const MouseEvent & event)444     bool HandleMouseEvent(const MouseEvent& event)
445     {
446         if (!onMouseCallback_) {
447             return false;
448         }
449         MouseInfo info;
450         info.SetPointerEvent(event.pointerEvent);
451         info.SetButton(event.button);
452         info.SetAction(event.action);
453         info.SetPullAction(event.pullAction);
454         info.SetGlobalLocation(event.GetOffset());
455         Offset localLocation = Offset(
456             event.GetOffset().GetX() - coordinateOffset_.GetX(), event.GetOffset().GetY() - coordinateOffset_.GetY());
457         info.SetLocalLocation(localLocation);
458         info.SetScreenLocation(event.GetScreenOffset());
459         info.SetTimeStamp(event.time);
460         info.SetDeviceId(event.deviceId);
461         info.SetTargetDisplayId(event.targetDisplayId);
462         info.SetSourceDevice(event.sourceType);
463         info.SetSourceTool(event.sourceTool);
464         info.SetTarget(GetEventTarget().value_or(EventTarget()));
465         info.SetPressedKeyCodes(event.pressedKeyCodes_);
466         onMouseCallback_(info);
467         return info.IsStopPropagation();
468     }
469 
DispatchEvent(const TouchEvent & point)470     bool DispatchEvent(const TouchEvent& point) override
471     {
472         return false;
473     }
474     // if return false means need to stop event bubbling.
HandleEvent(const TouchEvent & point)475     bool HandleEvent(const TouchEvent& point) override
476     {
477         return false;
478     }
479 
480 private:
481     OnMouseEventFunc onMouseCallback_;
482 };
483 
484 class HoverEventTarget : public virtual TouchEventTarget {
485     DECLARE_ACE_TYPE(HoverEventTarget, TouchEventTarget);
486 
487 public:
HoverEventTarget(const std::string & nodeName,int32_t nodeId)488     HoverEventTarget(const std::string& nodeName, int32_t nodeId) : TouchEventTarget(nodeName, nodeId) {}
489     ~HoverEventTarget() override = default;
490 
SetCallback(const OnHoverEventFunc & onHoverCallback)491     void SetCallback(const OnHoverEventFunc& onHoverCallback)
492     {
493         onHoverCallback_ = onHoverCallback;
494     }
SetCallback(const OnHoverFunc & onHoverEventCallback)495     void SetCallback(const OnHoverFunc& onHoverEventCallback)
496     {
497         onHoverEventCallback_ = onHoverEventCallback;
498     }
499 
SetAccessibilityHoverCallback(const OnAccessibilityHoverFunc & onAccessibilityHoverCallback)500     void SetAccessibilityHoverCallback(const OnAccessibilityHoverFunc& onAccessibilityHoverCallback)
501     {
502         onAccessibilityHoverCallback_ = onAccessibilityHoverCallback;
503     }
504 
SetPenHoverCallback(const OnHoverFunc & onPenHoverEventCallback)505     void SetPenHoverCallback(const OnHoverFunc& onPenHoverEventCallback)
506     {
507         onPenHoverEventCallback_ = onPenHoverEventCallback;
508     }
509 
510     bool HandleHoverEvent(bool isHovered, const MouseEvent& event);
511 
512     void HandleAccessibilityHoverEvent(bool isHovered, const TouchEvent& event);
513 
514     bool HandlePenHoverEvent(bool isHovered, const TouchEvent& event);
515 
IsAccessibilityHoverTarget()516     bool IsAccessibilityHoverTarget()
517     {
518         return onAccessibilityHoverCallback_ != nullptr;
519     }
520 
IsPenHoverTarget()521     bool IsPenHoverTarget() const
522     {
523         return onPenHoverEventCallback_ != nullptr;
524     }
525 
HandleHoverEvent(bool isHovered)526     bool HandleHoverEvent(bool isHovered)
527     {
528         if (!onHoverCallback_) {
529             return false;
530         }
531         onHoverCallback_(isHovered);
532         return true;
533     }
534 
DispatchEvent(const TouchEvent & point)535     bool DispatchEvent(const TouchEvent& point) override
536     {
537         return false;
538     }
HandleEvent(const TouchEvent & point)539     bool HandleEvent(const TouchEvent& point) override
540     {
541         return false;
542     }
543 
544     AccessibilityHoverAction ConvertAccessibilityHoverAction(TouchType type);
545 
546 private:
547     OnHoverEventFunc onHoverCallback_;
548     OnHoverFunc onHoverEventCallback_;
549     OnAccessibilityHoverFunc onAccessibilityHoverCallback_;
550     OnHoverFunc onPenHoverEventCallback_;
551 };
552 
553 class HoverEffectTarget : public virtual TouchEventTarget {
554     DECLARE_ACE_TYPE(HoverEffectTarget, TouchEventTarget);
555 
556 public:
HoverEffectTarget(const std::string & nodeName,int32_t nodeId)557     HoverEffectTarget(const std::string& nodeName, int32_t nodeId) : TouchEventTarget(nodeName, nodeId) {}
558     ~HoverEffectTarget() override = default;
559 
SetHoverNode(const WeakPtr<NG::FrameNode> & node)560     void SetHoverNode(const WeakPtr<NG::FrameNode>& node)
561     {
562         hoverNode_ = node;
563     }
GetHoverNode()564     WeakPtr<NG::FrameNode> GetHoverNode() const
565     {
566         return hoverNode_;
567     }
568 
DispatchEvent(const TouchEvent & point)569     bool DispatchEvent(const TouchEvent& point) override
570     {
571         return false;
572     }
573     // if return false means need to stop event bubbling.
HandleEvent(const TouchEvent & point)574     bool HandleEvent(const TouchEvent& point) override
575     {
576         return false;
577     }
578 
579 private:
580     WeakPtr<NG::FrameNode> hoverNode_;
581 };
582 
583 using MouseTestResult = std::list<RefPtr<MouseEventTarget>>;
584 using HoverTestResult = std::list<RefPtr<HoverEventTarget>>;
585 
586 } // namespace OHOS::Ace
587 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_EVENT_MOUSE_EVENT_H
588