• 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_TOUCH_EVENT_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_EVENT_TOUCH_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 #include "core/event/axis_event.h"
25 
26 namespace OHOS::Ace {
27 
28 enum class TouchType : size_t {
29     DOWN = 0,
30     UP,
31     MOVE,
32     CANCEL,
33     UNKNOWN,
34 };
35 
36 struct TouchPoint final {
37     int32_t id = 0;
38     float x = 0.0f;
39     float y = 0.0f;
40     float screenX = 0.0f;
41     float screenY = 0.0f;
42     TimeStamp downTime;
43     double size = 0.0;
44     float force = 0.0f;
45     std::optional<float> tiltX;
46     std::optional<float> tiltY;
47     SourceTool sourceTool = SourceTool::UNKNOWN;
48     bool isPressed = false;
49 };
50 
51 /**
52  * @brief TouchEvent contains the active change point and a list of all touch points.
53  */
54 struct TouchEvent final {
55     // the active changed point info
56     // The ID is used to identify the point of contact between the finger and the screen. Different fingers have
57     // different ids.
58     int32_t id = 0;
59     float x = 0.0f;
60     float y = 0.0f;
61     float screenX = 0.0f;
62     float screenY = 0.0f;
63     TouchType type = TouchType::UNKNOWN;
64     // nanosecond time stamp.
65     TimeStamp time;
66     double size = 0.0;
67     float force = 0.0f;
68     std::optional<float> tiltX;
69     std::optional<float> tiltY;
70     int64_t deviceId = 0;
71     SourceType sourceType = SourceType::NONE;
72     SourceTool sourceTool = SourceTool::UNKNOWN;
73 
74     // all points on the touch screen.
75     std::vector<TouchPoint> pointers;
76 
GetOffsetfinal77     Offset GetOffset() const
78     {
79         return Offset(x, y);
80     }
81 
GetScreenOffsetfinal82     Offset GetScreenOffset() const
83     {
84         return Offset(screenX, screenY);
85     }
86 
CreateScalePointfinal87     TouchEvent CreateScalePoint(float scale) const
88     {
89         if (NearZero(scale)) {
90             return { id, x, y, screenX, screenY, type, time, size, force, tiltX, tiltY, deviceId, sourceType,
91                 sourceTool, pointers };
92         }
93         auto temp = pointers;
94         std::for_each(temp.begin(), temp.end(), [scale](auto&& point) {
95             point.x = point.x / scale;
96             point.y = point.y / scale;
97             point.screenX = point.screenX / scale;
98             point.screenY = point.screenY / scale;
99         });
100         return { id, x / scale, y / scale, screenX / scale, screenY / scale, type, time, size, force, tiltX, tiltY,
101             deviceId, sourceType, sourceTool, temp };
102     }
103 
UpdateScalePointfinal104     TouchEvent UpdateScalePoint(float scale, float offsetX, float offsetY, int32_t pointId) const
105     {
106         auto temp = pointers;
107         if (NearZero(scale)) {
108             std::for_each(temp.begin(), temp.end(), [offsetX, offsetY](auto&& point) {
109                 point.x = point.x - offsetX;
110                 point.y = point.y - offsetY;
111                 point.screenX = point.screenX - offsetX;
112                 point.screenY = point.screenY - offsetY;
113             });
114             return { pointId, x - offsetX, y - offsetY, screenX - offsetX, screenY - offsetY, type, time, size, force,
115                 tiltX, tiltY, deviceId, sourceType, sourceTool, temp };
116         }
117 
118         std::for_each(temp.begin(), temp.end(), [scale, offsetX, offsetY](auto&& point) {
119             point.x = (point.x - offsetX) / scale;
120             point.y = (point.y - offsetY) / scale;
121             point.screenX = (point.screenX - offsetX) / scale;
122             point.screenY = (point.screenY - offsetY) / scale;
123         });
124         return { pointId, (x - offsetX) / scale, (y - offsetY) / scale, (screenX - offsetX) / scale,
125             (screenY - offsetY) / scale, type, time, size, force, tiltX, tiltY, deviceId, sourceType, sourceTool,
126             temp };
127     }
128 
UpdatePointersfinal129     TouchEvent UpdatePointers() const
130     {
131         TouchPoint point { .id = id,
132             .x = x,
133             .y = y,
134             .screenX = screenX,
135             .screenY = screenY,
136             .downTime = time,
137             .size = size,
138             .force = force,
139             .isPressed = (type == TouchType::DOWN) };
140         TouchEvent event { .id = id,
141             .x = x,
142             .y = y,
143             .screenX = screenX,
144             .screenY = screenY,
145             .type = type,
146             .time = time,
147             .size = size,
148             .force = force,
149             .deviceId = deviceId,
150             .sourceType = sourceType };
151         event.pointers.emplace_back(std::move(point));
152         return event;
153     }
154 };
155 
156 struct TouchRestrict final {
157     static constexpr uint32_t NONE = 0x00000000;
158     static constexpr uint32_t CLICK = 0x00000001;
159     static constexpr uint32_t LONG_PRESS = 0x00000010;
160     static constexpr uint32_t SWIPE_LEFT = 0x00000100;
161     static constexpr uint32_t SWIPE_RIGHT = 0x00000200;
162     static constexpr uint32_t SWIPE_UP = 0x00000400;
163     static constexpr uint32_t SWIPE_DOWN = 0x00000800;
164     static constexpr uint32_t SWIPE = 0x00000F00;
165     static constexpr uint32_t SWIPE_VERTICAL = 0x0000C00;   // Vertical
166     static constexpr uint32_t SWIPE_HORIZONTAL = 0x0000300; // Horizontal
167     static constexpr uint32_t TOUCH = 0xFFFFFFFF;
168 
169     uint32_t forbiddenType = NONE;
170 
UpdateForbiddenTypefinal171     void UpdateForbiddenType(uint32_t gestureType)
172     {
173         forbiddenType |= gestureType;
174     }
175     SourceType sourceType = SourceType::NONE;
176 
177     SourceType hitTestType = SourceType::TOUCH;
178 
179     TouchEvent touchEvent;
180 };
181 
182 class TouchCallBackInfo : public BaseEventInfo {
183     DECLARE_RELATIONSHIP_OF_CLASSES(TouchCallBackInfo, BaseEventInfo);
184 
185 public:
TouchCallBackInfo(TouchType type)186     explicit TouchCallBackInfo(TouchType type) : BaseEventInfo("onTouchEvent"), touchType_(type) {}
187     ~TouchCallBackInfo() override = default;
188 
SetScreenX(float screenX)189     void SetScreenX(float screenX)
190     {
191         screenX_ = screenX;
192     }
GetScreenX()193     float GetScreenX() const
194     {
195         return screenX_;
196     }
SetScreenY(float screenY)197     void SetScreenY(float screenY)
198     {
199         screenY_ = screenY;
200     }
GetScreenY()201     float GetScreenY() const
202     {
203         return screenY_;
204     }
SetLocalX(float localX)205     void SetLocalX(float localX)
206     {
207         localX_ = localX;
208     }
GetLocalX()209     float GetLocalX() const
210     {
211         return localX_;
212     }
SetLocalY(float localY)213     void SetLocalY(float localY)
214     {
215         localY_ = localY;
216     }
GetLocalY()217     float GetLocalY() const
218     {
219         return localY_;
220     }
SetTouchType(TouchType type)221     void SetTouchType(TouchType type)
222     {
223         touchType_ = type;
224     }
GetTouchType()225     TouchType GetTouchType() const
226     {
227         return touchType_;
228     }
SetTimeStamp(const TimeStamp & time)229     void SetTimeStamp(const TimeStamp& time)
230     {
231         time_ = time;
232     }
GetTimeStamp()233     TimeStamp GetTimeStamp() const
234     {
235         return time_;
236     }
237 
238 private:
239     float screenX_ = 0.0f;
240     float screenY_ = 0.0f;
241     float localX_ = 0.0f;
242     float localY_ = 0.0f;
243     TouchType touchType_ = TouchType::UNKNOWN;
244     TimeStamp time_;
245 };
246 
247 class TouchLocationInfo : public BaseEventInfo {
248     DECLARE_RELATIONSHIP_OF_CLASSES(TouchLocationInfo, TypeInfoBase);
249 
250 public:
TouchLocationInfo(int32_t fingerId)251     explicit TouchLocationInfo(int32_t fingerId) : BaseEventInfo("default")
252     {
253         fingerId_ = fingerId;
254     }
TouchLocationInfo(const std::string & type,int32_t fingerId)255     explicit TouchLocationInfo(const std::string& type, int32_t fingerId) : BaseEventInfo(type)
256     {
257         fingerId_ = fingerId;
258     }
259     ~TouchLocationInfo() override = default;
260 
SetGlobalLocation(const Offset & globalLocation)261     TouchLocationInfo& SetGlobalLocation(const Offset& globalLocation)
262     {
263         globalLocation_ = globalLocation;
264         return *this;
265     }
SetLocalLocation(const Offset & localLocation)266     TouchLocationInfo& SetLocalLocation(const Offset& localLocation)
267     {
268         localLocation_ = localLocation;
269         return *this;
270     }
271 
SetScreenLocation(const Offset & screenLocation)272     TouchLocationInfo& SetScreenLocation(const Offset& screenLocation)
273     {
274         screenLocation_ = screenLocation;
275         return *this;
276     }
277 
GetScreenLocation()278     const Offset& GetScreenLocation() const
279     {
280         return screenLocation_;
281     }
282 
GetLocalLocation()283     const Offset& GetLocalLocation() const
284     {
285         return localLocation_;
286     }
GetGlobalLocation()287     const Offset& GetGlobalLocation() const
288     {
289         return globalLocation_;
290     }
GetFingerId()291     int32_t GetFingerId() const
292     {
293         return fingerId_;
294     }
295 
SetSize(double size)296     void SetSize(double size)
297     {
298         size_ = size;
299     }
300 
GetSize()301     double GetSize() const
302     {
303         return size_;
304     }
305 
SetTouchDeviceId(int64_t deviceId)306     void SetTouchDeviceId(int64_t deviceId)
307     {
308         touchDeviceId_ = deviceId;
309     }
310 
GetTouchDeviceId()311     int64_t GetTouchDeviceId() const
312     {
313         return touchDeviceId_;
314     }
315 
GetTouchType()316     TouchType GetTouchType() const
317     {
318         return touchType_;
319     }
SetTouchType(TouchType type)320     void SetTouchType(TouchType type)
321     {
322         touchType_ = type;
323     }
324 
325 private:
326     // The finger id is used to identify the point of contact between the finger and the screen. Different fingers have
327     // different ids.
328     int32_t fingerId_ = -1;
329 
330     // global position at which the touch point contacts the screen.
331     Offset globalLocation_;
332     // Different from global location, The local location refers to the location of the contact point relative to the
333     // current node which has the recognizer.
334     Offset localLocation_;
335 
336     Offset screenLocation_;
337 
338     // finger touch size
339     double size_ = 0.0;
340 
341     // input device id
342     int64_t touchDeviceId_ = 0;
343 
344     // touch type
345     TouchType touchType_ = TouchType::UNKNOWN;
346 };
347 
348 using GetEventTargetImpl = std::function<std::optional<EventTarget>()>;
349 
350 class ACE_EXPORT TouchEventTarget : public virtual AceType {
351     DECLARE_ACE_TYPE(TouchEventTarget, AceType);
352 
353 public:
354     TouchEventTarget() = default;
TouchEventTarget(std::string nodeName,int32_t nodeId)355     TouchEventTarget(std::string nodeName, int32_t nodeId) : nodeName_(std::move(nodeName)), nodeId_(nodeId) {}
356     ~TouchEventTarget() override = default;
357 
358     // if return false means need to stop event dispatch.
359     virtual bool DispatchEvent(const TouchEvent& point) = 0;
360     // if return false means need to stop event bubbling.
361     virtual bool HandleEvent(const TouchEvent& point) = 0;
HandleEvent(const AxisEvent & event)362     virtual bool HandleEvent(const AxisEvent& event)
363     {
364         return true;
365     }
OnFlushTouchEventsBegin()366     virtual void OnFlushTouchEventsBegin() {}
OnFlushTouchEventsEnd()367     virtual void OnFlushTouchEventsEnd() {}
368 
SetTouchRestrict(const TouchRestrict & touchRestrict)369     void SetTouchRestrict(const TouchRestrict& touchRestrict)
370     {
371         touchRestrict_ = touchRestrict;
372     }
373 
SetGetEventTargetImpl(const GetEventTargetImpl & getEventTargetImpl)374     void SetGetEventTargetImpl(const GetEventTargetImpl& getEventTargetImpl)
375     {
376         getEventTargetImpl_ = getEventTargetImpl;
377     }
378 
GetEventTarget()379     std::optional<EventTarget> GetEventTarget() const
380     {
381         if (getEventTargetImpl_) {
382             return getEventTargetImpl_();
383         }
384         return std::nullopt;
385     }
386 
387     // Coordinate offset is used to calculate the local location of the touch point in the render node.
SetCoordinateOffset(const Offset & coordinateOffset)388     void SetCoordinateOffset(const Offset& coordinateOffset)
389     {
390         coordinateOffset_ = coordinateOffset;
391     }
392 
393     // Gets the coordinate offset to calculate the local location of the touch point by manually.
GetCoordinateOffset()394     const Offset& GetCoordinateOffset() const
395     {
396         return coordinateOffset_;
397     }
398 
SetSubPipelineGlobalOffset(const Offset & subPipelineGlobalOffset,float viewScale)399     void SetSubPipelineGlobalOffset(const Offset& subPipelineGlobalOffset, float viewScale)
400     {
401         subPipelineGlobalOffset_ = subPipelineGlobalOffset;
402         viewScale_ = viewScale;
403     }
404 
DispatchMultiContainerEvent(const TouchEvent & point)405     bool DispatchMultiContainerEvent(const TouchEvent& point)
406     {
407 #ifdef OHOS_STANDARD_SYSTEM
408         if (!subPipelineGlobalOffset_.IsZero()) {
409             auto multiContainerPoint = point.UpdateScalePoint(
410                 viewScale_, subPipelineGlobalOffset_.GetX(), subPipelineGlobalOffset_.GetY(), point.id);
411             return DispatchEvent(multiContainerPoint);
412         }
413 #endif
414         return DispatchEvent(point);
415     }
416 
HandleMultiContainerEvent(const TouchEvent & point)417     bool HandleMultiContainerEvent(const TouchEvent& point)
418     {
419 #ifdef OHOS_STANDARD_SYSTEM
420         if (!subPipelineGlobalOffset_.IsZero()) {
421             auto multiContainerPoint = point.UpdateScalePoint(
422                 viewScale_, subPipelineGlobalOffset_.GetX(), subPipelineGlobalOffset_.GetY(), point.id);
423             return HandleEvent(multiContainerPoint);
424         }
425 #endif
426         return HandleEvent(point);
427     }
428 
GetNodeName()429     std::string GetNodeName() const
430     {
431         return nodeName_;
432     }
433 
GetNodeId()434     int32_t GetNodeId() const
435     {
436         return nodeId_;
437     }
438 
439 protected:
440     Offset coordinateOffset_;
441     GetEventTargetImpl getEventTargetImpl_;
442     TouchRestrict touchRestrict_ { TouchRestrict::NONE };
443     Offset subPipelineGlobalOffset_;
444     float viewScale_ = 1.0f;
445     std::string nodeName_ = "NULL";
446     int32_t nodeId_ = -1;
447 };
448 
449 using TouchTestResult = std::list<RefPtr<TouchEventTarget>>;
450 
451 class TouchEventInfo : public BaseEventInfo {
452     DECLARE_RELATIONSHIP_OF_CLASSES(TouchEventInfo, BaseEventInfo);
453 
454 public:
TouchEventInfo(const std::string & type)455     explicit TouchEventInfo(const std::string& type) : BaseEventInfo(type) {}
456     ~TouchEventInfo() override = default;
457 
AddTouchLocationInfo(TouchLocationInfo && info)458     void AddTouchLocationInfo(TouchLocationInfo&& info)
459     {
460         touches_.emplace_back(info);
461     }
AddChangedTouchLocationInfo(TouchLocationInfo && info)462     void AddChangedTouchLocationInfo(TouchLocationInfo&& info)
463     {
464         changedTouches_.emplace_back(info);
465     }
466 
GetTouches()467     const std::list<TouchLocationInfo>& GetTouches() const
468     {
469         return touches_;
470     }
GetChangedTouches()471     const std::list<TouchLocationInfo>& GetChangedTouches() const
472     {
473         return changedTouches_;
474     }
475 
476 private:
477     std::list<TouchLocationInfo> touches_;
478     std::list<TouchLocationInfo> changedTouches_;
479 };
480 
481 using TouchEventFunc = std::function<void(TouchEventInfo&)>;
482 using OnTouchEventCallback = std::function<void(const TouchEventInfo&)>;
483 using CatchTouchEventCallback = std::function<void()>;
484 
485 } // namespace OHOS::Ace
486 
487 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_EVENT_TOUCH_EVENT_H
488