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