• 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 
GetOffsetfinal102     Offset GetOffset() const
103     {
104         return Offset(x, y);
105     }
106 
GetScreenOffsetfinal107     Offset GetScreenOffset() const
108     {
109         return Offset(screenX, screenY);
110     }
111 
GetIdfinal112     int32_t GetId() const
113     {
114         if (pressedButtons > 0) {
115             return pressedButtons + MOUSE_BASE_ID;
116         } else {
117             return (int32_t)button + MOUSE_BASE_ID;
118         }
119     }
120 
CreateScaleEventfinal121     MouseEvent CreateScaleEvent(float scale) const
122     {
123         if (NearZero(scale)) {
124             return { .x = x,
125                 .y = y,
126                 .z = z,
127                 .deltaX = deltaX,
128                 .deltaY = deltaY,
129                 .deltaZ = deltaZ,
130                 .scrollX = scrollX,
131                 .scrollY = scrollY,
132                 .scrollZ = scrollZ,
133                 .screenX = screenX,
134                 .screenY = screenY,
135                 .action = action,
136                 .pullAction = pullAction,
137                 .button = button,
138                 .pressedButtons = pressedButtons,
139                 .time = time,
140                 .deviceId = deviceId,
141                 .targetDisplayId = targetDisplayId,
142                 .sourceType = sourceType,
143                 .pointerEvent = pointerEvent };
144         }
145 
146         return { .x = x / scale,
147             .y = y / scale,
148             .z = z / scale,
149             .deltaX = deltaX / scale,
150             .deltaY = deltaY / scale,
151             .deltaZ = deltaZ / scale,
152             .scrollX = scrollX / scale,
153             .scrollY = scrollY / scale,
154             .scrollZ = scrollZ / scale,
155             .screenX = screenX / scale,
156             .screenY = screenY / scale,
157             .action = action,
158             .pullAction = pullAction,
159             .button = button,
160             .pressedButtons = pressedButtons,
161             .time = time,
162             .deviceId = deviceId,
163             .targetDisplayId = targetDisplayId,
164             .sourceType = sourceType,
165             .pointerEvent = pointerEvent };
166     }
167 
CreateTouchPointfinal168     TouchEvent CreateTouchPoint() const
169     {
170         TouchType type = TouchType::UNKNOWN;
171         if (action == MouseAction::PRESS) {
172             type = TouchType::DOWN;
173         } else if (action == MouseAction::RELEASE) {
174             type = TouchType::UP;
175         } else if (action == MouseAction::MOVE) {
176             type = TouchType::MOVE;
177         } else {
178             type = TouchType::UNKNOWN;
179         }
180         int32_t pointId = id;
181         if (sourceType == SourceType::MOUSE) {
182             pointId = GetId();
183         }
184         TouchPoint point { .id = pointId,
185             .x = x,
186             .y = y,
187             .screenX = screenX,
188             .screenY = screenY,
189             .downTime = time,
190             .size = 0.0,
191             .isPressed = (type == TouchType::DOWN) };
192         TouchEvent event { .id = pointId,
193             .x = x,
194             .y = y,
195             .screenX = screenX,
196             .screenY = screenY,
197             .type = type,
198             .time = time,
199             .size = 0.0,
200             .deviceId = deviceId,
201             .targetDisplayId = targetDisplayId,
202             .sourceType = sourceType,
203             .pointerEvent = pointerEvent };
204         event.pointers.emplace_back(std::move(point));
205         return event;
206     }
207 
208     MouseEvent operator-(const Offset& offset) const
209     {
210         return { .x = x - offset.GetX(),
211             .y = y - offset.GetY(),
212             .z = z,
213             .deltaX = deltaX,
214             .deltaY = deltaY,
215             .deltaZ = deltaZ,
216             .scrollX = scrollX,
217             .scrollY = scrollY,
218             .scrollZ = scrollZ,
219             .screenX = screenX - offset.GetX(),
220             .screenY = screenY - offset.GetY(),
221             .action = action,
222             .button = button,
223             .pressedButtons = pressedButtons,
224             .time = time,
225             .deviceId = deviceId,
226             .targetDisplayId = targetDisplayId,
227             .sourceType = sourceType,
228             .pointerEvent = pointerEvent };
229     }
230 };
231 
232 class MouseInfo : public BaseEventInfo {
233     DECLARE_RELATIONSHIP_OF_CLASSES(MouseInfo, BaseEventInfo);
234 
235 public:
MouseInfo()236     MouseInfo() : BaseEventInfo("onMouse") {}
237     ~MouseInfo() override = default;
238 
SetButton(MouseButton button)239     void SetButton(MouseButton button)
240     {
241         button_ = button;
242     }
243 
GetButton()244     MouseButton GetButton() const
245     {
246         return button_;
247     }
248 
SetAction(MouseAction action)249     void SetAction(MouseAction action)
250     {
251         action_ = action;
252     }
253 
GetAction()254     MouseAction GetAction() const
255     {
256         return action_;
257     }
258 
SetGlobalLocation(const Offset & globalLocation)259     MouseInfo& SetGlobalLocation(const Offset& globalLocation)
260     {
261         globalLocation_ = globalLocation;
262         return *this;
263     }
SetLocalLocation(const Offset & localLocation)264     MouseInfo& SetLocalLocation(const Offset& localLocation)
265     {
266         localLocation_ = localLocation;
267         return *this;
268     }
269 
SetScreenLocation(const Offset & screenLocation)270     MouseInfo& SetScreenLocation(const Offset& screenLocation)
271     {
272         screenLocation_ = screenLocation;
273         return *this;
274     }
275 
GetScreenLocation()276     const Offset& GetScreenLocation() const
277     {
278         return screenLocation_;
279     }
280 
GetLocalLocation()281     const Offset& GetLocalLocation() const
282     {
283         return localLocation_;
284     }
GetGlobalLocation()285     const Offset& GetGlobalLocation() const
286     {
287         return globalLocation_;
288     }
289 
SetPointerEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)290     void SetPointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
291     {
292         pointerEvent_ = pointerEvent;
293     }
GetPointerEvent()294     const std::shared_ptr<MMI::PointerEvent> GetPointerEvent() const
295     {
296         return pointerEvent_;
297     }
298 
299 private:
300     std::shared_ptr<MMI::PointerEvent> pointerEvent_;
301     MouseButton button_ = MouseButton::NONE_BUTTON;
302     MouseAction action_ = MouseAction::NONE;
303     // global position at which the touch point contacts the screen.
304     Offset globalLocation_;
305     // Different from global location, The local location refers to the location of the contact point relative to the
306     // current node which has the recognizer.
307     Offset localLocation_;
308     Offset screenLocation_;
309 };
310 
311 using HoverEffectFunc = std::function<void(bool)>;
312 
313 class HoverInfo;
314 class HoverInfo : public BaseEventInfo {
315     DECLARE_RELATIONSHIP_OF_CLASSES(HoverInfo, BaseEventInfo);
316 
317 public:
HoverInfo()318     HoverInfo() : BaseEventInfo("onHover") {}
319     ~HoverInfo() override = default;
320 };
321 
322 using OnHoverFunc = std::function<void(bool, HoverInfo& info)>;
323 using OnHoverEventFunc = std::function<void(bool)>;
324 
325 class MouseEventTarget : public virtual TouchEventTarget {
326     DECLARE_ACE_TYPE(MouseEventTarget, TouchEventTarget);
327 
328 public:
MouseEventTarget(const std::string & nodeName,int32_t nodeId)329     MouseEventTarget(const std::string& nodeName, int32_t nodeId) : TouchEventTarget(nodeName, nodeId) {}
330     ~MouseEventTarget() override = default;
331 
SetCallback(const OnMouseEventFunc & onMouseCallback)332     void SetCallback(const OnMouseEventFunc& onMouseCallback)
333     {
334         onMouseCallback_ = onMouseCallback;
335     }
336 
HandleMouseEvent(const MouseEvent & event)337     bool HandleMouseEvent(const MouseEvent& event)
338     {
339         if (!onMouseCallback_) {
340             return false;
341         }
342         MouseInfo info;
343         info.SetPointerEvent(event.pointerEvent);
344         info.SetButton(event.button);
345         info.SetAction(event.action);
346         info.SetGlobalLocation(event.GetOffset());
347         Offset localLocation = Offset(
348             event.GetOffset().GetX() - coordinateOffset_.GetX(), event.GetOffset().GetY() - coordinateOffset_.GetY());
349         info.SetLocalLocation(localLocation);
350         info.SetScreenLocation(event.GetScreenOffset());
351         info.SetTimeStamp(event.time);
352         info.SetDeviceId(event.deviceId);
353         info.SetTargetDisplayId(event.targetDisplayId);
354         info.SetSourceDevice(event.sourceType);
355         info.SetTarget(GetEventTarget().value_or(EventTarget()));
356         onMouseCallback_(info);
357         return info.IsStopPropagation();
358     }
359 
DispatchEvent(const TouchEvent & point)360     bool DispatchEvent(const TouchEvent& point) override
361     {
362         return false;
363     }
364     // if return false means need to stop event bubbling.
HandleEvent(const TouchEvent & point)365     bool HandleEvent(const TouchEvent& point) override
366     {
367         return false;
368     }
369 
370 private:
371     OnMouseEventFunc onMouseCallback_;
372 };
373 
374 class HoverEventTarget : public virtual TouchEventTarget {
375     DECLARE_ACE_TYPE(HoverEventTarget, TouchEventTarget);
376 
377 public:
HoverEventTarget(const std::string & nodeName,int32_t nodeId)378     HoverEventTarget(const std::string& nodeName, int32_t nodeId) : TouchEventTarget(nodeName, nodeId) {}
379     ~HoverEventTarget() override = default;
380 
SetCallback(const OnHoverEventFunc & onHoverCallback)381     void SetCallback(const OnHoverEventFunc& onHoverCallback)
382     {
383         onHoverCallback_ = onHoverCallback;
384     }
SetCallback(const OnHoverFunc & onHoverEventCallback)385     void SetCallback(const OnHoverFunc& onHoverEventCallback)
386     {
387         onHoverEventCallback_ = onHoverEventCallback;
388     }
389 
390     bool HandleHoverEvent(bool isHovered, const MouseEvent& event);
391 
HandleHoverEvent(bool isHovered)392     bool HandleHoverEvent(bool isHovered)
393     {
394         if (!onHoverCallback_) {
395             return false;
396         }
397         onHoverCallback_(isHovered);
398         return true;
399     }
400 
DispatchEvent(const TouchEvent & point)401     bool DispatchEvent(const TouchEvent& point) override
402     {
403         return false;
404     }
HandleEvent(const TouchEvent & point)405     bool HandleEvent(const TouchEvent& point) override
406     {
407         return false;
408     }
409 
410 private:
411     OnHoverEventFunc onHoverCallback_;
412     OnHoverFunc onHoverEventCallback_;
413 };
414 
415 class HoverEffectTarget : public virtual TouchEventTarget {
416     DECLARE_ACE_TYPE(HoverEffectTarget, TouchEventTarget);
417 
418 public:
HoverEffectTarget(const std::string & nodeName,int32_t nodeId)419     HoverEffectTarget(const std::string& nodeName, int32_t nodeId) : TouchEventTarget(nodeName, nodeId) {}
420     ~HoverEffectTarget() override = default;
421 
SetHoverNode(const WeakPtr<NG::FrameNode> & node)422     void SetHoverNode(const WeakPtr<NG::FrameNode>& node)
423     {
424         hoverNode_ = node;
425     }
GetHoverNode()426     WeakPtr<NG::FrameNode> GetHoverNode() const
427     {
428         return hoverNode_;
429     }
430 
DispatchEvent(const TouchEvent & point)431     bool DispatchEvent(const TouchEvent& point) override
432     {
433         return false;
434     }
435     // if return false means need to stop event bubbling.
HandleEvent(const TouchEvent & point)436     bool HandleEvent(const TouchEvent& point) override
437     {
438         return false;
439     }
440 
441 private:
442     WeakPtr<NG::FrameNode> hoverNode_;
443 };
444 
445 using MouseTestResult = std::list<RefPtr<MouseEventTarget>>;
446 using HoverTestResult = std::list<RefPtr<HoverEventTarget>>;
447 
448 } // namespace OHOS::Ace
449 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_EVENT_MOUSE_EVENT_H
450