• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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_COMPONENTS_NG_EVENT_GESTURE_EVENT_HUB_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_EVENT_GESTURE_EVENT_HUB_H
18 
19 #include <list>
20 #include <vector>
21 
22 #include "base/geometry/ng/point_t.h"
23 #include "base/memory/referenced.h"
24 #include "core/components/common/layout/constants.h"
25 #include "core/components_ng/event/click_event.h"
26 #include "core/components_ng/event/drag_event.h"
27 #include "core/components_ng/event/long_press_event.h"
28 #include "core/components_ng/event/pan_event.h"
29 #include "core/components_ng/event/scrollable_event.h"
30 #include "core/components_ng/event/touch_event.h"
31 #include "core/components_ng/gestures/gesture_info.h"
32 #include "core/components_ng/gestures/recognizers/exclusive_recognizer.h"
33 #include "core/components_ng/gestures/recognizers/parallel_recognizer.h"
34 #include "core/components_ng/manager/drag_drop/drag_drop_proxy.h"
35 
36 #ifdef ENABLE_DRAG_FRAMEWORK
37 namespace OHOS::Msdp::DeviceStatus {
38 struct DragNotifyMsg;
39 }
40 namespace OHOS::Ace {
41 class UnifiedData;
42 }
43 #endif
44 namespace OHOS::Ace::NG {
45 
46 enum class HitTestMode {
47     /**
48      *  Both self and children respond to the hit test for touch events,
49      *  but block hit test of the other nodes which is masked by this node.
50      */
51     HTMDEFAULT = 0,
52 
53     /**
54      * Self respond to the hit test for touch events,
55      * but block hit test of children and other nodes which is masked by this node.
56      */
57     HTMBLOCK,
58 
59     /**
60      * Self and child respond to the hit test for touch events,
61      * and allow hit test of other nodes which is masked by this node.
62      */
63     HTMTRANSPARENT,
64 
65     /**
66      * Self not respond to the hit test for touch events,
67      * but children respond to the hit test for touch events.
68      */
69     HTMNONE,
70 
71     /**
72      * Self and child respond to the hit test for touch events,
73      * when self consumed allow hit test of other nodes which is masked by this node,
74      * when child consumed block hit test of other nodes.
75      */
76     HTMTRANSPARENT_SELF,
77 };
78 
79 enum class HitTestResult {
80     // The touch point is located outside the current component area;
81     OUT_OF_REGION,
82     // node consumption events and prevent bubbling;
83     STOP_BUBBLING,
84     // node process events and bubble;
85     BUBBLING,
86     // node process events and bubble;
87     SELF_TRANSPARENT,
88 };
89 
90 struct DragDropBaseInfo {
91     RefPtr<AceType> node;
92     RefPtr<PixelMap> pixelMap;
93     std::string extraInfo;
94 };
95 
96 using OnDragStartFunc = std::function<DragDropBaseInfo(const RefPtr<OHOS::Ace::DragEvent>&, const std::string&)>;
97 using OnDragDropFunc = std::function<void(const RefPtr<OHOS::Ace::DragEvent>&, const std::string&)>;
98 
99 struct DragDropInfo {
100     RefPtr<UINode> customNode;
101     RefPtr<PixelMap> pixelMap;
102     std::string extraInfo;
103 };
104 
105 #ifdef ENABLE_DRAG_FRAMEWORK
106 using DragNotifyMsg = Msdp::DeviceStatus::DragNotifyMsg;
107 using OnDragCallback = std::function<void(const DragNotifyMsg&)>;
108 constexpr float PIXELMAP_WIDTH_RATE = -0.5f;
109 constexpr float PIXELMAP_HEIGHT_RATE = -0.2f;
110 constexpr float PIXELMAP_DEFALUT_LIMIT_SCALE = 0.5f;
111 constexpr float PIXELMAP_DRAG_WGR_TEXT_SCALE = 2.0f;
112 constexpr float PIXELMAP_DRAG_WGR_SCALE = 3.0f;
113 constexpr float PIXELMAP_DRAG_DEFAULT_HEIGHT = -28.0f;
114 #endif
115 class EventHub;
116 
117 // The gesture event hub is mainly used to handle common gesture events.
118 class ACE_FORCE_EXPORT GestureEventHub : public Referenced {
119 public:
120     explicit GestureEventHub(const WeakPtr<EventHub>& eventHub);
121     ~GestureEventHub() override = default;
122 
AddGesture(const RefPtr<NG::Gesture> & gesture)123     void AddGesture(const RefPtr<NG::Gesture>& gesture)
124     {
125         if (!recreateGesture_) {
126             gestures_.clear();
127         }
128         gestures_.emplace_back(gesture);
129         recreateGesture_ = true;
130     }
131 
AddScrollableEvent(const RefPtr<ScrollableEvent> & scrollableEvent)132     void AddScrollableEvent(const RefPtr<ScrollableEvent>& scrollableEvent)
133     {
134         if (!scrollableActuator_) {
135             scrollableActuator_ = MakeRefPtr<ScrollableActuator>(WeakClaim(this));
136         }
137         scrollableActuator_->AddScrollableEvent(scrollableEvent);
138     }
139 
RemoveScrollableEvent(const RefPtr<ScrollableEvent> & scrollableEvent)140     void RemoveScrollableEvent(const RefPtr<ScrollableEvent>& scrollableEvent)
141     {
142         if (!scrollableActuator_) {
143             return;
144         }
145         scrollableActuator_->RemoveScrollableEvent(scrollableEvent);
146     }
147 
AddScrollEdgeEffect(const Axis & axis,RefPtr<ScrollEdgeEffect> & scrollEffect)148     void AddScrollEdgeEffect(const Axis& axis, RefPtr<ScrollEdgeEffect>& scrollEffect)
149     {
150         if (!scrollableActuator_) {
151             scrollableActuator_ = MakeRefPtr<ScrollableActuator>(WeakClaim(this));
152         }
153         scrollableActuator_->AddScrollEdgeEffect(axis, scrollEffect);
154     }
155 
RemoveScrollEdgeEffect(const RefPtr<ScrollEdgeEffect> & scrollEffect)156     void RemoveScrollEdgeEffect(const RefPtr<ScrollEdgeEffect>& scrollEffect)
157     {
158         if (!scrollableActuator_) {
159             return;
160         }
161         scrollableActuator_->RemoveScrollEdgeEffect(scrollEffect);
162     }
163 
164     // Set by user define, which will replace old one.
SetTouchEvent(TouchEventFunc && touchEventFunc)165     void SetTouchEvent(TouchEventFunc&& touchEventFunc)
166     {
167         if (!touchEventActuator_) {
168             touchEventActuator_ = MakeRefPtr<TouchEventActuator>();
169         }
170         touchEventActuator_->ReplaceTouchEvent(std::move(touchEventFunc));
171     }
172 
AddTouchEvent(const RefPtr<TouchEventImpl> & touchEvent)173     void AddTouchEvent(const RefPtr<TouchEventImpl>& touchEvent)
174     {
175         if (!touchEventActuator_) {
176             touchEventActuator_ = MakeRefPtr<TouchEventActuator>();
177         }
178         touchEventActuator_->AddTouchEvent(touchEvent);
179     }
180 
RemoveTouchEvent(const RefPtr<TouchEventImpl> & touchEvent)181     void RemoveTouchEvent(const RefPtr<TouchEventImpl>& touchEvent)
182     {
183         if (!touchEventActuator_) {
184             return;
185         }
186         touchEventActuator_->RemoveTouchEvent(touchEvent);
187     }
188 
189     void SetFocusClickEvent(GestureEventFunc&& clickEvent);
190 
IsClickable()191     bool IsClickable() const
192     {
193         return clickEventActuator_ != nullptr;
194     }
195 
196     bool IsAccessibilityClickable();
197     bool IsAccessibilityLongClickable();
198 
199     bool ActClick();
200 
201     void CheckClickActuator();
202     // Set by user define, which will replace old one.
203     void SetUserOnClick(GestureEventFunc&& clickEvent);
204 
205     // When the event param is undefined, it will clear the callback.
206     void ClearUserOnClick();
207     void ClearUserOnTouch();
208 
209     void AddClickEvent(const RefPtr<ClickEvent>& clickEvent);
210 
RemoveClickEvent(const RefPtr<ClickEvent> & clickEvent)211     void RemoveClickEvent(const RefPtr<ClickEvent>& clickEvent)
212     {
213         if (!clickEventActuator_) {
214             return;
215         }
216         clickEventActuator_->RemoveClickEvent(clickEvent);
217     }
218 
IsClickEventsEmpty()219     bool IsClickEventsEmpty() const
220     {
221         if (!clickEventActuator_) {
222             return true;
223         }
224         return clickEventActuator_->IsClickEventsEmpty();
225     }
226 
227     void BindMenu(GestureEventFunc&& showMenu);
228 
IsLongClickable()229     bool IsLongClickable() const
230     {
231         return longPressEventActuator_ != nullptr;
232     }
233 
234     bool ActLongClick();
235 
236     void SetLongPressEvent(const RefPtr<LongPressEvent>& event, bool isForDrag = false, bool isDisableMouseLeft = false,
237         int32_t duration = 500)
238     {
239         if (!longPressEventActuator_) {
240             longPressEventActuator_ = MakeRefPtr<LongPressEventActuator>(WeakClaim(this));
241             longPressEventActuator_->SetOnAccessibility(GetOnAccessibilityEventFunc());
242         }
243         longPressEventActuator_->SetLongPressEvent(event, isForDrag, isDisableMouseLeft);
244         longPressEventActuator_->SetDuration(duration);
245     }
246 
247     // Set by user define, which will replace old one.
SetPanEvent(const RefPtr<PanEvent> & panEvent,PanDirection direction,int32_t fingers,Dimension distance)248     void SetPanEvent(const RefPtr<PanEvent>& panEvent, PanDirection direction, int32_t fingers, Dimension distance)
249     {
250         if (!panEventActuator_) {
251             panEventActuator_ =
252                 MakeRefPtr<PanEventActuator>(WeakClaim(this), direction, fingers, distance.ConvertToPx());
253         }
254         panEventActuator_->ReplacePanEvent(panEvent);
255     }
256 
AddPanEvent(const RefPtr<PanEvent> & panEvent,PanDirection direction,int32_t fingers,Dimension distance)257     void AddPanEvent(const RefPtr<PanEvent>& panEvent, PanDirection direction, int32_t fingers, Dimension distance)
258     {
259         if (!panEventActuator_ || direction.type != panEventActuator_->GetDirection().type) {
260             panEventActuator_ =
261                 MakeRefPtr<PanEventActuator>(WeakClaim(this), direction, fingers, distance.ConvertToPx());
262         }
263         panEventActuator_->AddPanEvent(panEvent);
264     }
265 
RemovePanEvent(const RefPtr<PanEvent> & panEvent)266     void RemovePanEvent(const RefPtr<PanEvent>& panEvent)
267     {
268         if (!panEventActuator_) {
269             return;
270         }
271         panEventActuator_->RemovePanEvent(panEvent);
272     }
273 
274     // Set by user define, which will replace old one.
SetDragEvent(const RefPtr<DragEvent> & dragEvent,PanDirection direction,int32_t fingers,Dimension distance)275     void SetDragEvent(const RefPtr<DragEvent>& dragEvent, PanDirection direction, int32_t fingers, Dimension distance)
276     {
277         if (!dragEventActuator_) {
278             dragEventActuator_ =
279                 MakeRefPtr<DragEventActuator>(WeakClaim(this), direction, fingers, distance.ConvertToPx());
280         }
281         dragEventActuator_->ReplaceDragEvent(dragEvent);
282     }
283 
SetCustomDragEvent(const RefPtr<DragEvent> & dragEvent,PanDirection direction,int32_t fingers,Dimension distance)284     void SetCustomDragEvent(
285         const RefPtr<DragEvent>& dragEvent, PanDirection direction, int32_t fingers, Dimension distance)
286     {
287         if (!dragEventActuator_) {
288             dragEventActuator_ =
289                 MakeRefPtr<DragEventActuator>(WeakClaim(this), direction, fingers, distance.ConvertToPx());
290         }
291         dragEventActuator_->SetCustomDragEvent(dragEvent);
292     }
293 
294     // the return value means prevents event bubbling.
295     bool ProcessTouchTestHit(const OffsetF& coordinateOffset, const TouchRestrict& touchRestrict,
296         TouchTestResult& innerTargets, TouchTestResult& finalResult, int32_t touchId, const PointF& localPoint);
297 
298     RefPtr<FrameNode> GetFrameNode() const;
299 
OnContextAttached()300     void OnContextAttached() {}
301 
302     std::string GetHitTestModeStr() const;
303 
GetHitTestMode()304     HitTestMode GetHitTestMode() const
305     {
306         return hitTestMode_;
307     }
308 
SetHitTestMode(HitTestMode hitTestMode)309     void SetHitTestMode(HitTestMode hitTestMode)
310     {
311         hitTestMode_ = hitTestMode;
312     }
313 
RemoveDragEvent()314     void RemoveDragEvent()
315     {
316         if (!dragEventActuator_) {
317             return;
318         }
319         dragEventActuator_->ClearDragEvent();
320     }
321 
322     void CombineIntoExclusiveRecognizer(
323         const PointF& globalPoint, const PointF& localPoint, TouchTestResult& result, int32_t touchId);
324 
IsResponseRegion()325     bool IsResponseRegion() const
326     {
327         return isResponseRegion_;
328     }
MarkResponseRegion(bool isResponseRegion)329     void MarkResponseRegion(bool isResponseRegion)
330     {
331         isResponseRegion_ = isResponseRegion;
332     }
333 
GetResponseRegion()334     const std::vector<DimensionRect>& GetResponseRegion() const
335     {
336         return responseRegion_;
337     }
338 
GetMouseResponseRegion()339     const std::vector<DimensionRect>& GetMouseResponseRegion() const
340     {
341         return mouseResponseRegion_;
342     }
343 
SetResponseRegion(const std::vector<DimensionRect> & responseRegion)344     void SetResponseRegion(const std::vector<DimensionRect>& responseRegion)
345     {
346         responseRegion_ = responseRegion;
347         if (!responseRegion_.empty()) {
348             isResponseRegion_ = true;
349         }
350     }
351 
SetMouseResponseRegion(const std::vector<DimensionRect> & mouseResponseRegion)352     void SetMouseResponseRegion(const std::vector<DimensionRect>& mouseResponseRegion)
353     {
354         mouseResponseRegion_ = mouseResponseRegion;
355         if (!mouseResponseRegion_.empty()) {
356             isResponseRegion_ = true;
357         }
358     }
359 
AddResponseRect(const DimensionRect & responseRect)360     void AddResponseRect(const DimensionRect& responseRect)
361     {
362         responseRegion_.emplace_back(responseRect);
363         isResponseRegion_ = true;
364     }
365 
RemoveLastResponseRect()366     void RemoveLastResponseRect()
367     {
368         if (responseRegion_.empty()) {
369             isResponseRegion_ = false;
370             return;
371         }
372         responseRegion_.pop_back();
373         if (responseRegion_.empty()) {
374             isResponseRegion_ = false;
375         }
376     }
377 
GetTouchable()378     bool GetTouchable() const
379     {
380         return touchable_;
381     }
382 
SetTouchable(bool touchable)383     void SetTouchable(bool touchable)
384     {
385         touchable_ = touchable;
386     }
387 
388 #ifdef ENABLE_DRAG_FRAMEWORK
SetThumbnailCallback(std::function<void (Offset)> && callback)389     void SetThumbnailCallback(std::function<void(Offset)>&& callback)
390     {
391         if (dragEventActuator_) {
392             dragEventActuator_->SetThumbnailCallback(std::move(callback));
393         }
394     }
395 
GetTextDraggable()396     bool GetTextDraggable() const
397     {
398         return textDraggable_;
399     }
400 
SetTextDraggable(bool draggable)401     void SetTextDraggable(bool draggable)
402     {
403         textDraggable_ = draggable;
404     }
405 
SetIsTextDraggable(bool isTextDraggable)406     void SetIsTextDraggable(bool isTextDraggable)
407     {
408         isTextDraggable_ = isTextDraggable;
409     }
410 
GetIsTextDraggable()411     bool GetIsTextDraggable()
412     {
413         return isTextDraggable_;
414     }
415 #endif // ENABLE_DRAG_FRAMEWORK
416 
SetPixelMap(RefPtr<PixelMap> pixelMap)417     void SetPixelMap(RefPtr<PixelMap> pixelMap)
418     {
419         pixelMap_ = pixelMap;
420     }
421 
GetPixelMap()422     RefPtr<PixelMap> GetPixelMap()
423     {
424         return pixelMap_;
425     }
426 
GetLongPressRecognizer()427     RefPtr<LongPressRecognizer> GetLongPressRecognizer() const
428     {
429         CHECK_NULL_RETURN(longPressEventActuator_, nullptr);
430         return longPressEventActuator_->GetLongPressRecognizer();
431     }
432 
433 #ifdef ENABLE_DRAG_FRAMEWORK
434     int32_t SetDragData(const RefPtr<UnifiedData>& unifiedData, std::string& udKey);
435     OnDragCallback GetDragCallback(const RefPtr<PipelineBase>& context, const WeakPtr<EventHub>& hub);
436 
SetThumbnailPixelMapCallback(std::function<void ()> && callback)437     void SetThumbnailPixelMapCallback(std::function<void()>&& callback)
438     {
439         callback_ = std::move(callback);
440     }
441 
HasThumbnailCallback()442     bool HasThumbnailCallback() const
443     {
444         return static_cast<bool>(callback_);
445     }
446 
447     OffsetF GetPixelMapOffset(const GestureEvent& info, const SizeF& size, const float scale = 1.0f) const;
448     float GetPixelMapScale(const int32_t height, const int32_t width) const;
449 #endif // ENABLE_DRAG_FRAMEWORK
450     void InitDragDropEvent();
451     void HandleOnDragStart(const GestureEvent& info);
452     void HandleOnDragUpdate(const GestureEvent& info);
453     void HandleOnDragEnd(const GestureEvent& info);
454     void HandleOnDragCancel();
455 
456     void StartLongPressActionForWeb();
457     void CancelDragForWeb();
458     void StartDragTaskForWeb();
459     void ResetDragActionForWeb();
460 
461     void OnModifyDone();
462     bool KeyBoardShortCutClick(const KeyEvent& event, const WeakPtr<NG::FrameNode>& node);
463     bool IsAllowedDrag(RefPtr<EventHub> eventHub);
464     void HandleNotallowDrag(const GestureEvent& info);
465 
466 private:
467     void ProcessTouchTestHierarchy(const OffsetF& coordinateOffset, const TouchRestrict& touchRestrict,
468         std::list<RefPtr<NGGestureRecognizer>>& innerRecognizers, TouchTestResult& finalResult, int32_t touchId);
469 
470     void UpdateGestureHierarchy();
471 
472     // old path.
473     void UpdateExternalNGGestureRecognizer();
474 
475     OnAccessibilityEventFunc GetOnAccessibilityEventFunc();
476 
477     void OnDragStart(const GestureEvent& info, const RefPtr<PipelineBase>& context, const RefPtr<FrameNode> frameNode,
478         const DragDropInfo dragDropInfo, const RefPtr<OHOS::Ace::DragEvent>& dragEvent);
479 
480     WeakPtr<EventHub> eventHub_;
481     RefPtr<ScrollableActuator> scrollableActuator_;
482     RefPtr<TouchEventActuator> touchEventActuator_;
483     RefPtr<ClickEventActuator> clickEventActuator_;
484     RefPtr<LongPressEventActuator> longPressEventActuator_;
485     RefPtr<PanEventActuator> panEventActuator_;
486     RefPtr<DragEventActuator> dragEventActuator_;
487     RefPtr<ExclusiveRecognizer> innerExclusiveRecognizer_;
488     RefPtr<ExclusiveRecognizer> nodeExclusiveRecognizer_;
489     RefPtr<ParallelRecognizer> nodeParallelRecognizer_;
490     std::vector<RefPtr<ExclusiveRecognizer>> externalExclusiveRecognizer_;
491     std::vector<RefPtr<ParallelRecognizer>> externalParallelRecognizer_;
492     RefPtr<DragDropProxy> dragDropProxy_;
493 
494     // Set by use gesture, priorityGesture and parallelGesture attribute function.
495     std::list<RefPtr<NG::Gesture>> gestures_;
496     std::list<RefPtr<NGGestureRecognizer>> gestureHierarchy_;
497 
498     // used in bindMenu, need to delete the old callback when bindMenu runs again
499     RefPtr<ClickEvent> showMenu_;
500 
501     HitTestMode hitTestMode_ = HitTestMode::HTMDEFAULT;
502     bool recreateGesture_ = true;
503     bool isResponseRegion_ = false;
504     std::vector<DimensionRect> responseRegion_;
505     std::vector<DimensionRect> mouseResponseRegion_;
506     bool touchable_ = true;
507     RefPtr<PixelMap> pixelMap_;
508     OffsetF frameNodeOffset_;
509     GestureEvent gestureInfoForWeb_;
510     bool isReceivedDragGestureInfo_ = false;
511 
512 #ifdef ENABLE_DRAG_FRAMEWORK
513     bool textDraggable_ = false;
514     bool isTextDraggable_ = false;
515     std::function<void()> callback_;
516 #endif
517 };
518 
519 } // namespace OHOS::Ace::NG
520 
521 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_EVENT_GESTURE_EVENT_HUB_H
522