• 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 #include "core/components_ng/event/gesture_event_hub.h"
17 
18 #include <cstdint>
19 #include <list>
20 #include <memory>
21 #include <string>
22 #include "drag_event.h"
23 
24 #include "base/log/log_wrapper.h"
25 #include "base/memory/ace_type.h"
26 #include "base/subwindow/subwindow_manager.h"
27 #include "base/utils/time_util.h"
28 #include "base/image/image_source.h"
29 #include "core/common/container.h"
30 #include "core/common/interaction/interaction_data.h"
31 #include "core/common/interaction/interaction_interface.h"
32 #include "core/components/common/layout/grid_system_manager.h"
33 #include "core/components/container_modal/container_modal_constants.h"
34 #include "core/components_ng/base/frame_node.h"
35 #include "core/components_ng/event/click_event.h"
36 #include "core/components_ng/event/event_hub.h"
37 #include "core/components_ng/gestures/recognizers/click_recognizer.h"
38 #include "core/components_ng/gestures/recognizers/exclusive_recognizer.h"
39 #include "core/components_ng/gestures/recognizers/long_press_recognizer.h"
40 #include "core/components_ng/gestures/recognizers/pan_recognizer.h"
41 #include "core/components_ng/gestures/recognizers/parallel_recognizer.h"
42 #include "core/components_ng/gestures/recognizers/pinch_recognizer.h"
43 #include "core/components_ng/gestures/recognizers/rotation_recognizer.h"
44 #include "core/components_ng/gestures/recognizers/swipe_recognizer.h"
45 #include "core/components_ng/manager/drag_drop/drag_drop_manager.h"
46 #include "core/components_ng/manager/drag_drop/utils/drag_animation_helper.h"
47 #include "core/components_ng/pattern/image/image_pattern.h"
48 #include "core/components_ng/pattern/text_drag/text_drag_base.h"
49 #include "core/components_ng/pattern/scrollable/scrollable_pattern.h"
50 #include "core/components_ng/pattern/image/image_layout_property.h"
51 #include "core/gestures/gesture_info.h"
52 #include "core/pipeline_ng/pipeline_context.h"
53 
54 #if defined(PIXEL_MAP_SUPPORTED)
55 #include "image_source.h"
56 #endif
57 
58 #include "core/common/udmf/udmf_client.h"
59 #include "core/components_ng/render/adapter/component_snapshot.h"
60 #ifdef WEB_SUPPORTED
61 #if !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM)
62 #include "core/components_ng/pattern/web/web_pattern.h"
63 #else
64 #include "core/components_ng/pattern/web/cross_platform/web_pattern.h"
65 #endif
66 #endif
67 namespace OHOS::Ace::NG {
68 namespace {
69 #if defined(PIXEL_MAP_SUPPORTED)
70 constexpr int32_t CREATE_PIXELMAP_TIME = 30;
71 constexpr int32_t MAX_BUILDER_DEPTH = 5;
72 #endif
73 constexpr uint32_t EXTRA_INFO_MAX_LENGTH = 200;
74 constexpr int32_t PIXELMAP_ANIMATION_DURATION = 250;
75 constexpr float PIXELMAP_OPACITY_RATE = 0.95f;
76 } // namespace
77 const std::string DEFAULT_MOUSE_DRAG_IMAGE { "/system/etc/device_status/drag_icon/Copy_Drag.svg" };
78 constexpr const char* HIT_TEST_MODE[] = {
79     "HitTestMode.Default",
80     "HitTestMode.Block",
81     "HitTestMode.Transparent",
82     "HitTestMode.None",
83 };
84 
GestureEventHub(const WeakPtr<EventHub> & eventHub)85 GestureEventHub::GestureEventHub(const WeakPtr<EventHub>& eventHub) : eventHub_(eventHub) {}
86 
GetFrameNode() const87 RefPtr<FrameNode> GestureEventHub::GetFrameNode() const
88 {
89     auto eventHub = eventHub_.Upgrade();
90     return eventHub ? eventHub->GetFrameNode() : nullptr;
91 }
92 
ProcessTouchTestHit(const OffsetF & coordinateOffset,const TouchRestrict & touchRestrict,TouchTestResult & innerTargets,TouchTestResult & finalResult,int32_t touchId,const PointF & localPoint,const RefPtr<TargetComponent> & targetComponent,ResponseLinkResult & responseLinkResult)93 bool GestureEventHub::ProcessTouchTestHit(const OffsetF& coordinateOffset, const TouchRestrict& touchRestrict,
94     TouchTestResult& innerTargets, TouchTestResult& finalResult, int32_t touchId, const PointF& localPoint,
95     const RefPtr<TargetComponent>& targetComponent, ResponseLinkResult& responseLinkResult)
96 {
97     auto host = GetFrameNode();
98     CHECK_NULL_RETURN(host, false);
99     auto eventHub = eventHub_.Upgrade();
100     auto getEventTargetImpl = eventHub ? eventHub->CreateGetEventTargetImpl() : nullptr;
101     if (scrollableActuator_) {
102         scrollableActuator_->CollectTouchTarget(coordinateOffset, touchRestrict, getEventTargetImpl, innerTargets,
103             localPoint, host, targetComponent, responseLinkResult);
104     }
105     size_t idx = innerTargets.size();
106     size_t newIdx = 0;
107     if (dragEventActuator_) {
108         dragEventActuator_->AddTouchListener(touchRestrict);
109     }
110     if (touchEventActuator_) {
111         touchEventActuator_->OnCollectTouchTarget(
112             coordinateOffset, touchRestrict, getEventTargetImpl, innerTargets, responseLinkResult);
113     }
114     if (clickEventActuator_ && !redirectClick_) {
115         clickEventActuator_->OnCollectTouchTarget(
116             coordinateOffset, touchRestrict, getEventTargetImpl, innerTargets, responseLinkResult);
117     }
118     if (userParallelClickEventActuator_) {
119         auto clickRecognizer = userParallelClickEventActuator_->GetClickRecognizer();
120         if (clickRecognizer) {
121             clickRecognizer->SetGestureInfo(
122                 MakeRefPtr<GestureInfo>(GestureTypeName::CLICK, GestureTypeName::CLICK, true));
123             clickRecognizer->SetOnAction(userParallelClickEventActuator_->GetClickEvent());
124             clickRecognizer->SetCoordinateOffset(Offset(coordinateOffset.GetX(), coordinateOffset.GetY()));
125             clickRecognizer->SetGetEventTargetImpl(getEventTargetImpl);
126         }
127     }
128     if (panEventActuator_) {
129         panEventActuator_->OnCollectTouchTarget(
130             coordinateOffset, touchRestrict, getEventTargetImpl, innerTargets, responseLinkResult);
131     }
132 
133     TouchTestResult dragTargets;
134     if (longPressEventActuator_) {
135         longPressEventActuator_->OnCollectTouchTarget(
136             coordinateOffset, touchRestrict, getEventTargetImpl, dragTargets, responseLinkResult);
137     }
138     if (dragEventActuator_) {
139         dragEventActuator_->OnCollectTouchTarget(
140             coordinateOffset, touchRestrict, getEventTargetImpl, dragTargets, responseLinkResult);
141     }
142 
143     std::list<RefPtr<NGGestureRecognizer>> longPressRecognizers;
144     for (const auto& item : dragTargets) {
145         auto recognizer = AceType::DynamicCast<NGGestureRecognizer>(item);
146         if (recognizer) {
147             recognizer->BeginReferee(touchId);
148             recognizer->AttachFrameNode(WeakPtr<FrameNode>(host));
149             recognizer->SetTargetComponent(targetComponent);
150             if (AceType::InstanceOf<RecognizerGroup>(recognizer)) {
151                 auto group = AceType::DynamicCast<RecognizerGroup>(recognizer);
152                 if (group) {
153                     group->SetChildrenTargetComponent(targetComponent);
154                 }
155             }
156         }
157         longPressRecognizers.emplace_back(AceType::DynamicCast<NGGestureRecognizer>(item));
158     }
159     if (!longPressRecognizers.empty()) {
160         // this node has long press and drag event, combine into parallelRecognizer.
161         if (!nodeParallelRecognizer_) {
162             nodeParallelRecognizer_ = MakeRefPtr<ParallelRecognizer>(std::move(longPressRecognizers));
163         } else {
164             nodeParallelRecognizer_->AddChildren(longPressRecognizers);
165         }
166         innerTargets.emplace_back(nodeParallelRecognizer_);
167     } else {
168         nodeParallelRecognizer_.Reset();
169     }
170 
171     std::list<RefPtr<NGGestureRecognizer>> innerRecognizers;
172     for (auto const& eventTarget : innerTargets) {
173         auto recognizer = AceType::DynamicCast<NGGestureRecognizer>(eventTarget);
174         if (recognizer) {
175             auto recognizerGroup = AceType::DynamicCast<RecognizerGroup>(recognizer);
176             if (!recognizerGroup && newIdx >= idx) {
177                 recognizer->SetNodeId(host->GetId());
178                 recognizer->AttachFrameNode(WeakPtr<FrameNode>(host));
179                 recognizer->SetTargetComponent(targetComponent);
180                 recognizer->SetIsSystemGesture(true);
181             }
182             recognizer->BeginReferee(touchId);
183             innerRecognizers.push_back(std::move(recognizer));
184         } else {
185             eventTarget->SetNodeId(host->GetId());
186             eventTarget->AttachFrameNode(WeakPtr<FrameNode>(host));
187             eventTarget->SetTargetComponent(targetComponent);
188             finalResult.push_back(eventTarget);
189         }
190         newIdx++; // not process previous recognizers
191     }
192 
193     ProcessTouchTestHierarchy(
194         coordinateOffset, touchRestrict, innerRecognizers, finalResult, touchId, targetComponent, responseLinkResult);
195 
196     return false;
197 }
198 
OnModifyDone()199 void GestureEventHub::OnModifyDone()
200 {
201     if (recreateGesture_) {
202         UpdateGestureHierarchy();
203         recreateGesture_ = false;
204     }
205 }
206 
PackInnerRecognizer(const Offset & offset,std::list<RefPtr<NGGestureRecognizer>> & innerRecognizers,int32_t touchId,const RefPtr<TargetComponent> & targetComponent)207 RefPtr<NGGestureRecognizer> GestureEventHub::PackInnerRecognizer(
208     const Offset& offset, std::list<RefPtr<NGGestureRecognizer>>& innerRecognizers, int32_t touchId,
209     const RefPtr<TargetComponent>& targetComponent)
210 {
211     RefPtr<NGGestureRecognizer> current;
212     // Pack inner recognizer include self inner recognizer and children.
213     if (innerRecognizers.size() == 1) {
214         current = *innerRecognizers.begin();
215     } else if (innerRecognizers.size() > 1) {
216         if (!innerExclusiveRecognizer_) {
217             innerExclusiveRecognizer_ = AceType::MakeRefPtr<ExclusiveRecognizer>(std::move(innerRecognizers));
218         } else {
219             innerExclusiveRecognizer_->AddChildren(innerRecognizers);
220         }
221         innerExclusiveRecognizer_->SetCoordinateOffset(offset);
222         innerExclusiveRecognizer_->BeginReferee(touchId);
223         auto host = GetFrameNode();
224         innerExclusiveRecognizer_->AttachFrameNode(WeakPtr<FrameNode>(host));
225         innerExclusiveRecognizer_->SetTargetComponent(targetComponent);
226         current = innerExclusiveRecognizer_;
227     }
228 
229     return current;
230 }
231 
ProcessParallelPriorityGesture(RefPtr<NGGestureRecognizer> & current,std::list<RefPtr<NGGestureRecognizer>> & recognizers,int32_t & parallelIndex,const Offset & offset,int32_t touchId,const RefPtr<TargetComponent> & targetComponent,const RefPtr<FrameNode> & host)232 void GestureEventHub::ProcessParallelPriorityGesture(RefPtr<NGGestureRecognizer>& current,
233     std::list<RefPtr<NGGestureRecognizer>>& recognizers, int32_t& parallelIndex, const Offset& offset, int32_t touchId,
234     const RefPtr<TargetComponent>& targetComponent, const RefPtr<FrameNode>& host)
235 {
236     if (current) {
237         recognizers.push_front(current);
238     }
239     if (recognizers.size() > 1) {
240         if ((static_cast<int32_t>(externalParallelRecognizer_.size()) <= parallelIndex)) {
241             externalParallelRecognizer_.emplace_back(AceType::MakeRefPtr<ParallelRecognizer>(std::move(recognizers)));
242         } else {
243             externalParallelRecognizer_[parallelIndex]->AddChildren(recognizers);
244         }
245         externalParallelRecognizer_[parallelIndex]->SetCoordinateOffset(offset);
246         externalParallelRecognizer_[parallelIndex]->BeginReferee(touchId);
247         externalParallelRecognizer_[parallelIndex]->AttachFrameNode(WeakPtr<FrameNode>(host));
248         externalParallelRecognizer_[parallelIndex]->SetTargetComponent(targetComponent);
249         current = externalParallelRecognizer_[parallelIndex];
250         parallelIndex++;
251     } else if (recognizers.size() == 1) {
252         current = *recognizers.begin();
253     }
254 }
255 
ProcessExternalExclusiveRecognizer(RefPtr<NGGestureRecognizer> & current,std::list<RefPtr<NGGestureRecognizer>> & recognizers,int32_t & exclusiveIndex,const Offset & offset,int32_t touchId,const RefPtr<TargetComponent> & targetComponent,const RefPtr<FrameNode> & host,GesturePriority priority)256 void GestureEventHub::ProcessExternalExclusiveRecognizer(RefPtr<NGGestureRecognizer>& current,
257     std::list<RefPtr<NGGestureRecognizer>>& recognizers, int32_t& exclusiveIndex, const Offset& offset, int32_t touchId,
258     const RefPtr<TargetComponent>& targetComponent, const RefPtr<FrameNode>& host, GesturePriority priority)
259 {
260     if (current) {
261         if (priority == GesturePriority::Low) {
262             recognizers.push_front(current);
263         } else {
264             recognizers.push_back(current);
265         }
266     }
267 
268     if (recognizers.size() > 1) {
269         if ((static_cast<int32_t>(externalExclusiveRecognizer_.size()) <= exclusiveIndex)) {
270             externalExclusiveRecognizer_.emplace_back(AceType::MakeRefPtr<ExclusiveRecognizer>(std::move(recognizers)));
271         } else {
272             externalExclusiveRecognizer_[exclusiveIndex]->AddChildren(recognizers);
273         }
274         externalExclusiveRecognizer_[exclusiveIndex]->SetCoordinateOffset(offset);
275         externalExclusiveRecognizer_[exclusiveIndex]->BeginReferee(touchId);
276         externalExclusiveRecognizer_[exclusiveIndex]->AttachFrameNode(WeakPtr<FrameNode>(host));
277         externalExclusiveRecognizer_[exclusiveIndex]->SetTargetComponent(targetComponent);
278         current = externalExclusiveRecognizer_[exclusiveIndex];
279         exclusiveIndex++;
280     } else if (recognizers.size() == 1) {
281         current = *recognizers.begin();
282     }
283 }
284 
ProcessTouchTestHierarchy(const OffsetF & coordinateOffset,const TouchRestrict & touchRestrict,std::list<RefPtr<NGGestureRecognizer>> & innerRecognizers,TouchTestResult & finalResult,int32_t touchId,const RefPtr<TargetComponent> & targetComponent,ResponseLinkResult & responseLinkResult)285 void GestureEventHub::ProcessTouchTestHierarchy(const OffsetF& coordinateOffset, const TouchRestrict& touchRestrict,
286     std::list<RefPtr<NGGestureRecognizer>>& innerRecognizers, TouchTestResult& finalResult, int32_t touchId,
287     const RefPtr<TargetComponent>& targetComponent, ResponseLinkResult& responseLinkResult)
288 {
289     auto host = GetFrameNode();
290     if (!host) {
291         for (auto&& recognizer : innerRecognizers) {
292             finalResult.emplace_back(std::move(recognizer));
293         }
294         return;
295     }
296 
297     auto offset = Offset(coordinateOffset.GetX(), coordinateOffset.GetY());
298     RefPtr<NGGestureRecognizer> current;
299     current = PackInnerRecognizer(offset, innerRecognizers, touchId, targetComponent);
300     auto eventHub = eventHub_.Upgrade();
301     auto getEventTargetImpl = eventHub ? eventHub->CreateGetEventTargetImpl() : nullptr;
302     int32_t parallelIndex = 0;
303     int32_t exclusiveIndex = 0;
304     for (auto const& recognizer : gestureHierarchy_) {
305         if (!recognizer) {
306             continue;
307         }
308         auto recognizerGroup = AceType::DynamicCast<RecognizerGroup>(recognizer);
309         if (recognizerGroup) {
310             recognizerGroup->SetRecognizerInfoRecursively(offset, host, targetComponent, getEventTargetImpl);
311             recognizerGroup->CollectResponseLinkRecognizersRecursively(responseLinkResult);
312         } else {
313             responseLinkResult.emplace_back(recognizer);
314         }
315         recognizer->SetNodeId(host->GetId());
316         recognizer->AttachFrameNode(WeakPtr<FrameNode>(host));
317         recognizer->SetTargetComponent(targetComponent);
318         recognizer->SetCoordinateOffset(offset);
319         recognizer->BeginReferee(touchId, true);
320         recognizer->SetGetEventTargetImpl(getEventTargetImpl);
321         auto gestureMask = recognizer->GetPriorityMask();
322         if (gestureMask == GestureMask::IgnoreInternal) {
323             // In ignore case, dropped the self inner recognizer and children recognizer.
324             current = recognizer;
325             continue;
326         }
327         auto priority = recognizer->GetPriority();
328         std::list<RefPtr<NGGestureRecognizer>> recognizers { 1, recognizer };
329         if (priority == GesturePriority::Parallel) {
330             ProcessParallelPriorityGesture(current, recognizers, parallelIndex, offset, touchId, targetComponent, host);
331         } else {
332             ProcessExternalExclusiveRecognizer(
333                 current, recognizers, exclusiveIndex, offset, touchId, targetComponent, host, priority);
334         }
335     }
336 
337     if (current) {
338         finalResult.emplace_back(std::move(current));
339     }
340 }
341 
UpdateGestureHierarchy()342 void GestureEventHub::UpdateGestureHierarchy()
343 {
344     auto host = GetFrameNode();
345     CHECK_NULL_VOID(host);
346     bool success = (gestures_.size() + modifierGestures_.size()) == gestureHierarchy_.size() && !needRecollect_;
347     if (success) {
348         auto iter = gestures_.begin();
349         auto recognizerIter = gestureHierarchy_.begin();
350         for (; iter != gestures_.end(); iter++, recognizerIter++) {
351             auto newRecognizer = (*iter)->CreateRecognizer();
352             success = success && (*recognizerIter)->ReconcileFrom(newRecognizer);
353             if (!success) {
354                 break;
355             }
356         }
357     }
358     if (success) {
359         gestures_.clear();
360         return;
361     }
362 
363     gestureHierarchy_.clear();
364     for (const auto& gesture : gestures_) {
365         AddGestureToGestureHierarchy(gesture);
366     }
367     for (const auto& gesture : modifierGestures_) {
368         AddGestureToGestureHierarchy(gesture);
369     }
370     needRecollect_ = false;
371     gestures_.clear();
372 }
373 
AddGestureToGestureHierarchy(const RefPtr<NG::Gesture> & gesture)374 void GestureEventHub::AddGestureToGestureHierarchy(const RefPtr<NG::Gesture>& gesture)
375 {
376     if (!gesture) {
377         return;
378     }
379     auto recognizer = gesture->CreateRecognizer();
380 
381     auto clickRecognizer = AceType::DynamicCast<ClickRecognizer>(recognizer);
382     if (clickRecognizer) {
383         clickRecognizer->SetOnAccessibility(GetOnAccessibilityEventFunc());
384     }
385 
386     auto longPressRecognizer = AceType::DynamicCast<LongPressRecognizer>(recognizer);
387     if (longPressRecognizer) {
388         longPressRecognizer->SetOnAccessibility(GetOnAccessibilityEventFunc());
389         auto host = GetFrameNode();
390         CHECK_NULL_VOID(host);
391         auto pattern = host->GetPattern();
392         if (pattern && longPressRecognizer->HasAction()) {
393             longPressRecognizer->SetOnLongPressRecorder(pattern->GetLongPressEventRecorder());
394         }
395     }
396 
397     if (!recognizer) {
398         return;
399     }
400     auto priority = gesture->GetPriority();
401     auto gestureMask = gesture->GetGestureMask();
402     recognizer->SetPriority(priority);
403     recognizer->SetPriorityMask(gestureMask);
404     gestureHierarchy_.emplace_back(recognizer);
405 }
406 
CombineIntoExclusiveRecognizer(const PointF & globalPoint,const PointF & localPoint,TouchTestResult & result,int32_t touchId)407 void GestureEventHub::CombineIntoExclusiveRecognizer(
408     const PointF& globalPoint, const PointF& localPoint, TouchTestResult& result, int32_t touchId)
409 {
410     TouchTestResult finalResult;
411     std::list<RefPtr<NGGestureRecognizer>> recognizers;
412     const auto coordinateOffset = globalPoint - localPoint;
413     auto offset = Offset(coordinateOffset.GetX(), coordinateOffset.GetY());
414     for (auto const& eventTarget : result) {
415         auto recognizer = AceType::DynamicCast<NGGestureRecognizer>(eventTarget);
416         if (recognizer) {
417             recognizers.push_back(std::move(recognizer));
418         } else {
419             finalResult.push_back(eventTarget);
420         }
421     }
422 
423     RefPtr<NGGestureRecognizer> current;
424     if (recognizers.size() == 1) {
425         current = *recognizers.begin();
426     } else if (recognizers.size() > 1) {
427         if (!nodeExclusiveRecognizer_) {
428             nodeExclusiveRecognizer_ = AceType::MakeRefPtr<ExclusiveRecognizer>(std::move(recognizers));
429         } else {
430             nodeExclusiveRecognizer_->AddChildren(recognizers);
431         }
432         nodeExclusiveRecognizer_->SetCoordinateOffset(offset);
433         nodeExclusiveRecognizer_->BeginReferee(touchId);
434         current = nodeExclusiveRecognizer_;
435     }
436 
437     if (current) {
438         finalResult.emplace_back(std::move(current));
439     }
440     result.swap(finalResult);
441 }
442 
IsPixelMapNeedScale() const443 bool GestureEventHub::IsPixelMapNeedScale() const
444 {
445     CHECK_NULL_RETURN(pixelMap_, false);
446     auto frameNode = GetFrameNode();
447     CHECK_NULL_RETURN(frameNode, false);
448     auto width = pixelMap_->GetWidth();
449     auto maxWidth = DragDropManager::GetMaxWidthBaseOnGridSystem(frameNode->GetContextRefPtr());
450     if (!frameNode->GetDragPreviewOption().isScaleEnabled || width == 0 || width <= maxWidth) {
451         return false;
452     }
453     return true;
454 }
455 
InitDragDropEvent()456 void GestureEventHub::InitDragDropEvent()
457 {
458     auto actionStartTask = [weak = WeakClaim(this)](const GestureEvent& info) {
459         auto gestureEventHub = weak.Upgrade();
460         CHECK_NULL_VOID(gestureEventHub);
461         gestureEventHub->HandleOnDragStart(info);
462     };
463 
464     auto actionUpdateTask = [weak = WeakClaim(this)](const GestureEvent& info) {
465         auto gestureEventHub = weak.Upgrade();
466         CHECK_NULL_VOID(gestureEventHub);
467         gestureEventHub->HandleOnDragUpdate(info);
468     };
469 
470     auto actionEndTask = [weak = WeakClaim(this)](const GestureEvent& info) {
471         auto gestureEventHub = weak.Upgrade();
472         CHECK_NULL_VOID(gestureEventHub);
473         gestureEventHub->HandleOnDragEnd(info);
474     };
475 
476     auto actionCancelTask = [weak = WeakClaim(this)]() {
477         auto gestureEventHub = weak.Upgrade();
478         CHECK_NULL_VOID(gestureEventHub);
479         gestureEventHub->HandleOnDragCancel();
480     };
481 
482     auto dragEvent = MakeRefPtr<DragEvent>(
483         std::move(actionStartTask), std::move(actionUpdateTask), std::move(actionEndTask), std::move(actionCancelTask));
484     auto distance = SystemProperties::GetDragStartPanDistanceThreshold();
485     SetDragEvent(dragEvent, { PanDirection::ALL }, DEFAULT_PAN_FINGER, Dimension(distance, DimensionUnit::VP));
486 }
487 
IsAllowedDrag(RefPtr<EventHub> eventHub)488 bool GestureEventHub::IsAllowedDrag(RefPtr<EventHub> eventHub)
489 {
490     auto frameNode = GetFrameNode();
491     CHECK_NULL_RETURN(frameNode, false);
492     auto pattern = frameNode->GetPattern();
493     CHECK_NULL_RETURN(pattern, false);
494 
495     if (frameNode->IsDraggable()) {
496         if (!eventHub->HasOnDragStart() && !pattern->DefaultSupportDrag()) {
497             return false;
498         }
499     } else {
500         if (frameNode->IsUserSet()) {
501             return false;
502         }
503         if (!eventHub->HasOnDragStart() && !pattern->DefaultSupportDrag()) {
504             return false;
505         }
506     }
507     return true;
508 }
509 
StartLongPressActionForWeb(bool isFloatImage)510 void GestureEventHub::StartLongPressActionForWeb(bool isFloatImage)
511 {
512     TAG_LOGI(AceLogTag::ACE_WEB, "DragDrop start long press action for web");
513     auto pipeline = PipelineContext::GetCurrentContext();
514     CHECK_NULL_VOID(pipeline);
515     auto taskScheduler = pipeline->GetTaskExecutor();
516     CHECK_NULL_VOID(taskScheduler);
517 
518     taskScheduler->PostTask(
519         [weak = WeakClaim(this), isFloatImage]() {
520             auto gestureHub = weak.Upgrade();
521             CHECK_NULL_VOID(gestureHub);
522             auto dragEventActuator = gestureHub->dragEventActuator_;
523             CHECK_NULL_VOID(dragEventActuator);
524             dragEventActuator->StartLongPressActionForWeb(isFloatImage);
525         },
526         TaskExecutor::TaskType::UI, "ArkUIGestureWebStartLongPress");
527 }
528 
CancelDragForWeb()529 void GestureEventHub::CancelDragForWeb()
530 {
531     TAG_LOGD(AceLogTag::ACE_WEB, "DragDrop cancel drag for web");
532     auto pipeline = PipelineContext::GetCurrentContext();
533     CHECK_NULL_VOID(pipeline);
534     auto taskScheduler = pipeline->GetTaskExecutor();
535     CHECK_NULL_VOID(taskScheduler);
536 
537     taskScheduler->PostTask(
538         [weak = WeakClaim(this)]() {
539             auto gestureHub = weak.Upgrade();
540             CHECK_NULL_VOID(gestureHub);
541             auto dragEventActuator = gestureHub->dragEventActuator_;
542             CHECK_NULL_VOID(dragEventActuator);
543             dragEventActuator->CancelDragForWeb();
544         },
545         TaskExecutor::TaskType::UI, "ArkUIGestureWebCancelDrag");
546 }
547 
ResetDragActionForWeb()548 void GestureEventHub::ResetDragActionForWeb()
549 {
550     TAG_LOGD(AceLogTag::ACE_WEB, "DragDrop reset drag action for web");
551     isReceivedDragGestureInfo_ = false;
552     CHECK_NULL_VOID(dragEventActuator_);
553     dragEventActuator_->ResetDragActionForWeb();
554 
555     // fix drag failed when long press drag after 500ms and before 800ms
556     // need to reset the state of the drag manager
557     auto pipeLine = PipelineContext::GetCurrentContext();
558     CHECK_NULL_VOID(pipeLine);
559     auto dragDropManager = pipeLine->GetDragDropManager();
560     CHECK_NULL_VOID(dragDropManager);
561     dragDropManager->ResetDragging();
562 }
563 
StartDragTaskForWeb()564 void GestureEventHub::StartDragTaskForWeb()
565 {
566     if (!isReceivedDragGestureInfo_) {
567         TAG_LOGW(AceLogTag::ACE_WEB, "DragDrop StartDragTaskForWeb failed,"
568             "because not recv gesture info");
569         return;
570     }
571 
572     isReceivedDragGestureInfo_ = false;
573     auto pipeline = PipelineContext::GetCurrentContext();
574     CHECK_NULL_VOID(pipeline);
575     auto taskScheduler = pipeline->GetTaskExecutor();
576     CHECK_NULL_VOID(taskScheduler);
577 
578     TAG_LOGI(AceLogTag::ACE_WEB, "DragDrop post a task to start drag for web");
579     taskScheduler->PostTask(
580         [weak = WeakClaim(this)]() {
581             auto gestureHub = weak.Upgrade();
582             CHECK_NULL_VOID(gestureHub);
583             auto dragEventActuator = gestureHub->dragEventActuator_;
584             CHECK_NULL_VOID(dragEventActuator);
585             CHECK_NULL_VOID(gestureHub->gestureInfoForWeb_);
586             TAG_LOGI(AceLogTag::ACE_WEB, "DragDrop start drag task for web in async task");
587             dragEventActuator->StartDragTaskForWeb(*gestureHub->gestureInfoForWeb_);
588         },
589         TaskExecutor::TaskType::UI, "ArkUIGestureWebStartDrag");
590 }
591 
CreatePixelMapFromString(const std::string & filePath)592 RefPtr<PixelMap> CreatePixelMapFromString(const std::string& filePath)
593 {
594     auto imageSource = ImageSource::Create(filePath);
595     CHECK_NULL_RETURN(imageSource, nullptr);
596     RefPtr<PixelMap> pixelMap = imageSource->CreatePixelMap();
597     return pixelMap;
598 }
599 
CheckInSceneBoardWindow()600 bool CheckInSceneBoardWindow()
601 {
602     auto container = Container::Current();
603     CHECK_NULL_RETURN(container, false);
604     if (!container->IsSubContainer()) {
605         return container->IsScenceBoardWindow();
606     }
607     auto parentContainerId = SubwindowManager::GetInstance()->GetParentContainerId(Container::CurrentId());
608     container = Container::GetContainer(parentContainerId);
609     CHECK_NULL_RETURN(container, false);
610     return container->IsScenceBoardWindow();
611 }
612 
CheckOffsetInPixelMap(OffsetF & result,const SizeF & size)613 void CheckOffsetInPixelMap(OffsetF& result, const SizeF& size)
614 {
615     if (result.GetX() >= 0.0f) {
616         result.SetX(-1.0f);
617     }
618     if (result.GetX() + size.Width() <= 0.0f) {
619         result.SetX(1.0f - size.Width());
620     }
621     if (result.GetY() >= 0.0f) {
622         result.SetY(-1.0f);
623     }
624     if (result.GetY() + size.Height() <= 0.0f) {
625         result.SetY(1.0f - size.Height());
626     }
627 }
628 
ParseInnerRect(const std::string & extraInfo,const SizeF & size)629 RectF ParseInnerRect(const std::string& extraInfo, const SizeF& size)
630 {
631     auto innerRect = RectF();
632     if (!CheckInSceneBoardWindow() || extraInfo.empty()) {
633         return innerRect;
634     }
635     auto extraJson = JsonUtil::ParseJsonString(extraInfo);
636     CHECK_NULL_RETURN(extraJson, innerRect);
637     auto extraOffsetX = extraJson->GetInt("drag_offset_x");
638     auto extraOffsetY = extraJson->GetInt("drag_offset_y");
639     if (extraOffsetX <= 0 || extraOffsetY <= 0) {
640         return innerRect;
641     }
642     innerRect.SetOffset(OffsetF(Dimension(extraOffsetX, DimensionUnit::VP).ConvertToPx(),
643         Dimension(extraOffsetY, DimensionUnit::VP).ConvertToPx()));
644     innerRect.SetSize(size);
645     return innerRect;
646 }
647 
GetPixelMapOffset(const GestureEvent & info,const SizeF & size,const float scale,bool isCalculateInSubwindow,const RectF & innerRect) const648 OffsetF GestureEventHub::GetPixelMapOffset(
649     const GestureEvent& info, const SizeF& size, const float scale, bool isCalculateInSubwindow,
650     const RectF& innerRect) const
651 {
652     OffsetF result = OffsetF(size.Width() * PIXELMAP_WIDTH_RATE, size.Height() * PIXELMAP_HEIGHT_RATE);
653     auto frameNode = GetFrameNode();
654     CHECK_NULL_RETURN(frameNode, result);
655     auto frameTag = frameNode->GetTag();
656     auto coordinateX = frameNodeOffset_.GetX();
657     auto coordinateY = frameNodeOffset_.GetY();
658     if (!innerRect.IsEmpty() && GreatNotEqual(size.Width(), 0.0f) && GreatNotEqual(size.Height(), 0.0f)) {
659         auto rateX = innerRect.Width() / size.Width();
660         auto rateY = innerRect.Height() / size.Height();
661         result.SetX(rateX * (coordinateX + innerRect.GetOffset().GetX() - info.GetGlobalLocation().GetX()));
662         result.SetY(rateY * (coordinateY + innerRect.GetOffset().GetY() - info.GetGlobalLocation().GetY()));
663         CheckOffsetInPixelMap(result, size);
664         return result;
665     }
666     if (NearZero(frameNodeSize_.Width()) || NearZero(frameNodeSize_.Height()) ||
667         NearZero(size.Width())) {
668         result.SetX(scale * (coordinateX - info.GetGlobalLocation().GetX()));
669         result.SetY(scale * (coordinateY - info.GetGlobalLocation().GetY()));
670     } else {
671         auto rateX = (info.GetGlobalLocation().GetX() - coordinateX) / frameNodeSize_.Width();
672         auto rateY = (info.GetGlobalLocation().GetY() - coordinateY) / frameNodeSize_.Height();
673         result.SetX(-rateX * size.Width());
674         result.SetY(-rateY * size.Height());
675     }
676     CheckOffsetInPixelMap(result, size);
677     TAG_LOGD(AceLogTag::ACE_DRAG, "Get pixelMap offset is %{public}f and %{public}f.",
678         result.GetX(), result.GetY());
679     return result;
680 }
681 
GetPreScaledPixelMapIfExist(float targetScale,RefPtr<PixelMap> defaultPixelMap)682 RefPtr<PixelMap> GestureEventHub::GetPreScaledPixelMapIfExist(float targetScale, RefPtr<PixelMap> defaultPixelMap)
683 {
684     float preScale = 1.0f;
685     CHECK_NULL_RETURN(dragEventActuator_, defaultPixelMap);
686     RefPtr<PixelMap> preScaledPixelMap = dragEventActuator_->GetPreScaledPixelMapForDragThroughTouch(preScale);
687     if (preScale == targetScale && preScaledPixelMap != nullptr) {
688         return preScaledPixelMap;
689     }
690 #if defined(PIXEL_MAP_SUPPORTED)
691     preScaledPixelMap = PixelMap::CopyPixelMap(defaultPixelMap);
692     if (!preScaledPixelMap) {
693         TAG_LOGW(AceLogTag::ACE_DRAG, "duplicate PixelMap failed!");
694         preScaledPixelMap = defaultPixelMap;
695     }
696     if (!NearEqual(targetScale, 1.0f)) {
697         preScaledPixelMap->Scale(targetScale, targetScale, AceAntiAliasingOption::HIGH);
698     }
699 #endif
700     return preScaledPixelMap;
701 }
702 
GetPixelMapScale(const int32_t height,const int32_t width) const703 float GestureEventHub::GetPixelMapScale(const int32_t height, const int32_t width) const
704 {
705     float scale = 1.0f;
706     if (height == 0 || width == 0) {
707         return scale;
708     }
709     auto frameNode = GetFrameNode();
710     CHECK_NULL_RETURN(frameNode, scale);
711     auto pipeline = PipelineContext::GetCurrentContext();
712     CHECK_NULL_RETURN(pipeline, scale);
713     auto dragDropManager = pipeline->GetDragDropManager();
714     CHECK_NULL_RETURN(dragDropManager, scale);
715     auto windowScale = dragDropManager->GetWindowScale();
716     if (!frameNode->GetDragPreviewOption().isScaleEnabled || !(frameNode->GetTag() == V2::WEB_ETS_TAG)) {
717         return scale * windowScale;
718     }
719     int32_t deviceHeight = SystemProperties::GetDevicePhysicalHeight();
720     int32_t deviceWidth = SystemProperties::GetDevicePhysicalWidth();
721     int32_t maxDeviceLength = std::max(deviceHeight, deviceWidth);
722     int32_t minDeviceLength = std::min(deviceHeight, deviceWidth);
723     if (maxDeviceLength * PIXELMAP_DEFALUT_LIMIT_SCALE > minDeviceLength) {
724         if (height > minDeviceLength * PIXELMAP_DEFALUT_LIMIT_SCALE) {
725             scale = static_cast<float>(minDeviceLength * PIXELMAP_DEFALUT_LIMIT_SCALE) / height;
726         }
727     } else {
728         if (GetTextDraggable() && height > minDeviceLength / PIXELMAP_DRAG_WGR_SCALE &&
729             width > minDeviceLength * PIXELMAP_DRAG_WGR_TEXT_SCALE / PIXELMAP_DRAG_WGR_SCALE) {
730             scale = fmin(static_cast<float>(minDeviceLength / PIXELMAP_DRAG_WGR_SCALE) / height,
731                 static_cast<float>(minDeviceLength * PIXELMAP_DRAG_WGR_TEXT_SCALE / PIXELMAP_DRAG_WGR_SCALE) / width);
732         } else if (height > minDeviceLength / PIXELMAP_DRAG_WGR_SCALE &&
733                    width > minDeviceLength / PIXELMAP_DRAG_WGR_SCALE) {
734             scale = fmin(static_cast<float>(minDeviceLength / PIXELMAP_DRAG_WGR_SCALE) / height,
735                 static_cast<float>(minDeviceLength / PIXELMAP_DRAG_WGR_SCALE) / width);
736         }
737     }
738     return scale * windowScale;
739 }
740 
GenerateMousePixelMap(const GestureEvent & info)741 void GestureEventHub::GenerateMousePixelMap(const GestureEvent& info)
742 {
743     auto frameNode = GetFrameNode();
744     CHECK_NULL_VOID(frameNode);
745     RefPtr<RenderContext> context;
746     if (GetTextDraggable()) {
747         auto pattern = frameNode->GetPattern<TextDragBase>();
748         CHECK_NULL_VOID(pattern);
749         auto dragNode = pattern->MoveDragNode();
750         CHECK_NULL_VOID(dragNode);
751         auto pipeline = PipelineContext::GetCurrentContext();
752         CHECK_NULL_VOID(pipeline);
753         pipeline->FlushPipelineImmediately();
754         context = dragNode->GetRenderContext();
755     } else {
756         context = frameNode->GetRenderContext();
757     }
758     CHECK_NULL_VOID(context);
759     auto thumbnailPixelMap = context->GetThumbnailPixelMap();
760     CHECK_NULL_VOID(thumbnailPixelMap);
761     SetPixelMap(thumbnailPixelMap);
762 }
763 
HandleNotallowDrag(const GestureEvent & info)764 void GestureEventHub::HandleNotallowDrag(const GestureEvent& info)
765 {
766     auto frameNode = GetFrameNode();
767     CHECK_NULL_VOID(frameNode);
768     if (frameNode->GetTag() == V2::WEB_ETS_TAG) {
769         gestureInfoForWeb_ = std::make_shared<GestureEvent>(info);
770         isReceivedDragGestureInfo_ = true;
771         TAG_LOGD(AceLogTag::ACE_WEB, "DragDrop drag gesture info received");
772     }
773 }
774 
HandleOnDragStart(const GestureEvent & info)775 void GestureEventHub::HandleOnDragStart(const GestureEvent& info)
776 {
777     TAG_LOGD(AceLogTag::ACE_DRAG, "Start handle onDragStart.");
778     auto eventHub = eventHub_.Upgrade();
779     CHECK_NULL_VOID(eventHub);
780     if (!eventHub->HasOnDragStart()) {
781         TAG_LOGI(AceLogTag::ACE_DRAG, "FrameNode is not set onDragStart event.");
782         return;
783     }
784 
785     auto frameNode = GetFrameNode();
786     CHECK_NULL_VOID(frameNode);
787     auto pattern = frameNode->GetPattern();
788     CHECK_NULL_VOID(pattern);
789     if (!IsAllowedDrag(eventHub)) {
790         TAG_LOGI(AceLogTag::ACE_DRAG, "FrameNode is not allow drag, tag is %{public}s, id is %{public}s,"
791             "draggable is %{public}d, drag start event is %{public}d,"
792             "default support drag is %{public}d, user set is %{public}d.",
793             frameNode->GetTag().c_str(), frameNode->GetInspectorId()->c_str(),
794             frameNode->IsDraggable(), eventHub->HasOnDragStart(),
795             pattern->DefaultSupportDrag(), frameNode->IsUserSet());
796         HandleNotallowDrag(info);
797         return;
798     }
799     auto pipeline = PipelineContext::GetCurrentContext();
800     CHECK_NULL_VOID(pipeline);
801     auto eventManager = pipeline->GetEventManager();
802     CHECK_NULL_VOID(eventManager);
803     if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON && eventManager->IsLastMoveBeforeUp()) {
804         TAG_LOGI(AceLogTag::ACE_DRAG, "Drag stop because user release mouse button");
805         return;
806     }
807     if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON) {
808         SetMouseDragMonitorState(true);
809     }
810 
811     RefPtr<OHOS::Ace::DragEvent> event = AceType::MakeRefPtr<OHOS::Ace::DragEvent>();
812     if (frameNode->GetTag() == V2::WEB_ETS_TAG) {
813         event->SetX(pipeline->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetX(), DimensionUnit::PX)));
814         event->SetY(pipeline->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetY(), DimensionUnit::PX)));
815     } else {
816         event->SetX(info.GetGlobalPoint().GetX());
817         event->SetY(info.GetGlobalPoint().GetY());
818     }
819     event->SetScreenX(info.GetScreenLocation().GetX());
820     event->SetScreenY(info.GetScreenLocation().GetY());
821     event->SetDisplayX(info.GetScreenLocation().GetX());
822     event->SetDisplayY(info.GetScreenLocation().GetY());
823     event->SetSourceTool(info.GetSourceTool());
824 
825     auto frameTag = frameNode->GetTag();
826     auto hostPattern = frameNode->GetPattern<TextDragBase>();
827     if (hostPattern && GetTextDraggable() && (frameTag == V2::RICH_EDITOR_ETS_TAG || frameTag == V2::TEXT_ETS_TAG ||
828                         frameTag == V2::TEXTINPUT_ETS_TAG || frameTag == V2::SEARCH_Field_ETS_TAG)) {
829         frameNodeOffset_ = hostPattern->GetDragUpperLeftCoordinates();
830         frameNodeSize_ = SizeF(0.0f, 0.0f);
831     } else {
832         auto geometryNode = frameNode->GetGeometryNode();
833         if (geometryNode) {
834             frameNodeSize_ = geometryNode->GetFrameSize();
835         } else {
836             frameNodeSize_ = SizeF(0.0f, 0.0f);
837         }
838         auto rectCenter = frameNode->GetPaintRectCenter();
839         frameNodeOffset_ = OffsetF(rectCenter.GetX() - frameNodeSize_.Width() / 2.0f,
840             rectCenter.GetY() - frameNodeSize_.Height() / 2.0f);
841 #ifdef WEB_SUPPORTED
842         if (frameTag == V2::WEB_ETS_TAG) {
843             auto webPattern = frameNode->GetPattern<WebPattern>();
844             if (webPattern) {
845                 frameNodeOffset_.SetX(frameNodeOffset_.GetX() + webPattern->GetDragOffset().GetX());
846                 frameNodeOffset_.SetY(frameNodeOffset_.GetY() + webPattern->GetDragOffset().GetY());
847                 frameNodeSize_ = webPattern->GetDragPixelMapSize();
848             }
849         }
850 #endif
851     }
852     /*
853      * Users may remove frameNode in the js callback function "onDragStart "triggered below,
854      * so save the offset of the framenode relative to the window in advance
855      */
856     DragDropInfo dragPreviewInfo;
857     auto dragDropInfo = GetDragDropInfo(info, frameNode, dragPreviewInfo, event);
858     auto dragDropManager = pipeline->GetDragDropManager();
859     CHECK_NULL_VOID(dragDropManager);
860     dragDropManager->SetDraggingPointer(info.GetPointerId());
861     dragDropManager->SetDraggingPressedState(true);
862     if (dragPreviewInfo.inspectorId != "") {
863         auto dragPreviewPixelMap = GetDragPreviewPixelMap();
864         TAG_LOGI(AceLogTag::ACE_DRAG, "InspectorId exist, get thumbnail.");
865         if (dragPreviewPixelMap == nullptr) {
866             dragPreviewPixelMap = DragEventActuator::GetPreviewPixelMap(dragPreviewInfo.inspectorId, frameNode);
867         }
868         dragDropInfo.pixelMap = dragPreviewPixelMap;
869         OnDragStart(info, pipeline, frameNode, dragDropInfo, event);
870         return;
871     }
872     if (info.GetSourceDevice() != SourceType::MOUSE) {
873         if (dragPreviewInfo.pixelMap != nullptr || dragPreviewInfo.customNode != nullptr) {
874             if (dragPreviewPixelMap_ != nullptr) {
875                 TAG_LOGI(AceLogTag::ACE_DRAG, "Non-mouse dragging, get thumbnail.");
876                 dragDropInfo.pixelMap = dragPreviewPixelMap_;
877                 OnDragStart(info, pipeline, frameNode, dragDropInfo, event);
878                 return;
879             }
880         }
881     }
882 
883     if (dragPreviewInfo.pixelMap != nullptr) {
884         dragDropInfo.pixelMap = dragPreviewInfo.pixelMap;
885         TAG_LOGI(AceLogTag::ACE_DRAG, "PixelMap exist, get thumbnail.");
886         OnDragStart(info, pipeline, frameNode, dragDropInfo, event);
887         return;
888     } else if (dragPreviewInfo.customNode != nullptr) {
889         dragDropInfo.customNode = dragPreviewInfo.customNode;
890     }
891 #if defined(PIXEL_MAP_SUPPORTED)
892     if (dragDropInfo.pixelMap == nullptr && dragDropInfo.customNode) {
893         TAG_LOGI(AceLogTag::ACE_DRAG, "CustomNode exist, get thumbnail.");
894         StartDragForCustomBuilder(info, pipeline, frameNode, dragDropInfo, event);
895         return;
896     }
897 #endif
898     TAG_LOGI(AceLogTag::ACE_DRAG, "DragDropInfo is empty.");
899     OnDragStart(info, pipeline, frameNode, dragDropInfo, event);
900 }
901 
OnDragStart(const GestureEvent & info,const RefPtr<PipelineBase> & context,const RefPtr<FrameNode> frameNode,DragDropInfo dragDropInfo,const RefPtr<OHOS::Ace::DragEvent> & dragEvent)902 void GestureEventHub::OnDragStart(const GestureEvent& info, const RefPtr<PipelineBase>& context,
903     const RefPtr<FrameNode> frameNode, DragDropInfo dragDropInfo, const RefPtr<OHOS::Ace::DragEvent>& dragEvent)
904 {
905     auto eventHub = eventHub_.Upgrade();
906     CHECK_NULL_VOID(eventHub);
907     auto pipeline = AceType::DynamicCast<PipelineContext>(context);
908     CHECK_NULL_VOID(pipeline);
909 
910     auto dragDropManager = pipeline->GetDragDropManager();
911     CHECK_NULL_VOID(dragDropManager);
912     if (dragDropProxy_) {
913         dragDropProxy_ = nullptr;
914     }
915     CHECK_NULL_VOID(dragEvent);
916     auto eventRet = dragEvent->GetResult();
917     if (eventRet == DragRet::DRAG_FAIL || eventRet == DragRet::DRAG_CANCEL) {
918         TAG_LOGI(AceLogTag::ACE_DRAG, "Drag result is %{public}d, stop dragging.", eventRet);
919         if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON) {
920             SetMouseDragMonitorState(false);
921         }
922         return;
923     }
924     std::string udKey;
925     int32_t recordsSize = 1;
926     auto unifiedData = GetUnifiedData(frameNode->GetTag(), dragDropInfo, dragEvent);
927     CHECK_NULL_VOID(frameNode);
928     auto pattern = frameNode->GetPattern();
929     CHECK_NULL_VOID(pattern);
930     pattern->ResetDragOption();
931     if (pattern->GetDragRecordSize() >= 0) {
932         recordsSize = pattern->GetDragRecordSize();
933     } else if (unifiedData) {
934         auto recordSize = unifiedData->GetSize();
935         recordsSize = recordSize > 1 ? recordSize : 1;
936     }
937     auto ret = SetDragData(unifiedData, udKey);
938     if (ret != 0) {
939         TAG_LOGI(AceLogTag::ACE_DRAG, "UDMF set data failed, return value is %{public}d", ret);
940     }
941 
942     std::map<std::string, int64_t> summary;
943     ret = UdmfClient::GetInstance()->GetSummary(udKey, summary);
944     if (ret != 0) {
945         TAG_LOGI(AceLogTag::ACE_DRAG, "UDMF get summary failed, return value is %{public}d", ret);
946     }
947     dragDropManager->SetSummaryMap(summary);
948     RefPtr<PixelMap> pixelMap;
949     if (dragDropInfo.pixelMap != nullptr) {
950         pixelMap = dragDropInfo.pixelMap;
951         SetPixelMap(dragDropInfo.pixelMap);
952     } else if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON) {
953         pixelMap = CreatePixelMapFromString(DEFAULT_MOUSE_DRAG_IMAGE);
954         CHECK_NULL_VOID(pixelMap);
955         if (!GetTextDraggable()) {
956             GenerateMousePixelMap(info);
957         }
958         if (pixelMap_) {
959             pixelMap = pixelMap_;
960         }
961     } else {
962         if (pixelMap_ == nullptr) {
963             FireCustomerOnDragEnd(pipeline, eventHub);
964             TAG_LOGW(AceLogTag::ACE_DRAG, "Thumbnail pixelMap is empty.");
965             if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON) {
966                 SetMouseDragMonitorState(false);
967             }
968             return;
969         }
970         pixelMap = pixelMap_;
971     }
972     SetDragGatherPixelMaps(info);
973     dragDropManager->SetIsMouseDrag(info.GetInputEventType() == InputEventType::MOUSE_BUTTON);
974     auto dragPreviewOptions = frameNode->GetDragPreviewOption();
975     auto badgeNumber = dragPreviewOptions.GetCustomerBadgeNumber();
976     if (badgeNumber.has_value()) {
977         recordsSize = badgeNumber.value();
978     }
979     auto dragNodePipeline = frameNode->GetContextRefPtr();
980     CHECK_NULL_VOID(dragNodePipeline);
981     auto overlayManager = dragNodePipeline->GetOverlayManager();
982     bool isSwitchToSubWindow = false;
983     RefPtr<FrameNode> imageNode = nullptr;
984     RefPtr<FrameNode> textNode = nullptr;
985     RefPtr<OverlayManager> subWindowOverlayManager = nullptr;
986     bool isMenuShow = false;
987     auto mainPipeline = PipelineContext::GetMainPipelineContext();
988     bool isStartDraggingFromSubWindow = (pipeline != mainPipeline);
989     auto window = SubwindowManager::GetInstance()->ShowPreviewNG(isStartDraggingFromSubWindow);
990     if (window) {
991         subWindowOverlayManager = window->GetOverlayManager();
992         CHECK_NULL_VOID(subWindowOverlayManager);
993         isMenuShow = subWindowOverlayManager->IsMenuShow();
994     }
995     if (isMenuShow) {
996         dragDropManager->SetIsDragWithContextMenu(true);
997         TAG_LOGI(AceLogTag::ACE_DRAG, "Drag with contextMenu.");
998     } else {
999         dragDropManager->SetIsDragWithContextMenu(false);
1000     }
1001     float defaultPixelMapScale =
1002         info.GetInputEventType() == InputEventType::MOUSE_BUTTON ? 1.0f : DEFALUT_DRAG_PPIXELMAP_SCALE;
1003     // use menuPreviewScale for drag framework. this is not final solution.
1004     if (isMenuShow && GreatNotEqual(menuPreviewScale_, 0.0f)) {
1005         auto menuPreviewRect = DragDropManager::GetMenuPreviewRect();
1006         if (GreatNotEqual(menuPreviewRect.Width(), 0.0f) && GreatNotEqual(menuPreviewRect.Height(), 0.0f)) {
1007             frameNodeOffset_ = menuPreviewRect.GetOffset();
1008             frameNodeSize_ = menuPreviewRect.GetSize();
1009         }
1010         auto originPixelMapWidth = pixelMap->GetWidth();
1011         if (GreatNotEqual(menuPreviewRect.Width(), 0.0f) && GreatNotEqual(originPixelMapWidth, 0.0f) &&
1012             menuPreviewRect.Width() < originPixelMapWidth * menuPreviewScale_) {
1013             defaultPixelMapScale = menuPreviewRect.Width() / originPixelMapWidth;
1014         } else {
1015             defaultPixelMapScale = menuPreviewScale_;
1016         }
1017     }
1018     auto windowScale = dragDropManager->GetWindowScale();
1019     float scale = windowScale * defaultPixelMapScale;
1020     auto focusHub = frameNode->GetFocusHub();
1021     bool hasContextMenu = focusHub == nullptr
1022                               ? false : focusHub->FindContextMenuOnKeyEvent(OnKeyEventType::CONTEXT_MENU);
1023     bool isBindMenuPreview = GetPreviewMode() != MenuPreviewMode::NONE;
1024     if (IsNeedSwitchToSubWindow() || isMenuShow) {
1025         imageNode = overlayManager->GetPixelMapContentNode();
1026         DragEventActuator::CreatePreviewNode(frameNode, imageNode, defaultPixelMapScale);
1027         OffsetF previewOffset;
1028         auto originPoint = imageNode->GetPositionToWindowWithTransform();
1029         if (hasContextMenu || isMenuShow) {
1030             auto previewDragMovePosition = dragDropManager->GetUpdateDragMovePosition();
1031             auto ret = SubwindowManager::GetInstance()->GetMenuPreviewCenter(previewOffset);
1032             if (isBindMenuPreview && ret) {
1033                 previewOffset = previewOffset - OffsetF(pixelMap->GetWidth() / 2.0f, pixelMap->GetHeight() / 2.0f)
1034                                 + previewDragMovePosition;
1035                 DragEventActuator::UpdatePreviewPositionAndScale(imageNode, previewOffset);
1036             } else {
1037                 previewOffset = previewDragMovePosition + originPoint;
1038                 DragEventActuator::UpdatePreviewPositionAndScale(imageNode, previewOffset);
1039             }
1040 
1041             dragDropManager->ResetContextMenuDragPosition();
1042         }
1043 
1044         auto frameTag = frameNode->GetTag();
1045         if (IsPixelMapNeedScale() && GetTextDraggable() && IsTextCategoryComponent(frameTag)) {
1046             auto textDragPattern = frameNode->GetPattern<TextDragBase>();
1047             CHECK_NULL_VOID(textDragPattern);
1048             auto dragNode = textDragPattern->MoveDragNode();
1049             if (dragNode) {
1050                 auto dragNodeOffset = dragNode->GetPaintRectOffset();
1051                 DragEventActuator::UpdatePreviewPositionAndScale(imageNode, dragNodeOffset);
1052             }
1053         }
1054 
1055         if (IsPixelMapNeedScale() && frameTag == V2::WEB_ETS_TAG) {
1056             OffsetF webOffset;
1057             CHECK_NULL_VOID(pipeline);
1058             auto window = pipeline->GetWindow();
1059             CHECK_NULL_VOID(window);
1060             auto offset = window->GetCurrentWindowRect().GetOffset();
1061             webOffset.SetX(frameNodeOffset_.GetX() + offset.GetX());
1062             webOffset.SetY(frameNodeOffset_.GetY() + offset.GetY());
1063             DragEventActuator::UpdatePreviewPositionAndScale(imageNode, webOffset);
1064         }
1065 
1066         CHECK_NULL_VOID(imageNode);
1067         float previewScale =
1068             info.GetInputEventType() == InputEventType::MOUSE_BUTTON ? 1.0f : DEFALUT_DRAG_PPIXELMAP_SCALE;
1069         if (IsPixelMapNeedScale()) {
1070             previewScale = static_cast<float>(imageNode->GetPreviewScaleVal());
1071             scale = previewScale * windowScale;
1072         }
1073         // use menu preview scale replace default pixelMap scale.
1074         if (isMenuShow) {
1075             auto imageGestureEventHub = imageNode->GetOrCreateGestureEventHub();
1076             CHECK_NULL_VOID(imageGestureEventHub);
1077             if (!IsPixelMapNeedScale()) {
1078                 imageGestureEventHub->SetMenuPreviewScale(defaultPixelMapScale);
1079             } else {
1080                 imageGestureEventHub->SetMenuPreviewScale(scale);
1081             }
1082         }
1083         auto childSize = badgeNumber.has_value() ? badgeNumber.value() : GetSelectItemSize();
1084         if (childSize > 1) {
1085             recordsSize = childSize;
1086         }
1087         textNode = DragEventActuator::CreateBadgeTextNode(frameNode, childSize, previewScale, true, previewOffset);
1088         if (window) {
1089             isSwitchToSubWindow = true;
1090             overlayManager->RemovePixelMap();
1091             if (pixelMap_ != nullptr) {
1092                 pixelMap = pixelMap_;
1093             }
1094         }
1095     }
1096     CHECK_NULL_VOID(overlayManager);
1097     if (!overlayManager->GetIsOnAnimation()) {
1098         if (dragEventActuator_ != nullptr) {
1099             dragEventActuator_->SetIsNotInPreviewState(true);
1100         }
1101     }
1102     RefPtr<PixelMap> pixelMapDuplicated = GetPreScaledPixelMapIfExist(scale, pixelMap);
1103     dragEventActuator_->ResetPreScaledPixelMapForDragThroughTouch();
1104     dragPreviewPixelMap_ = nullptr;
1105     auto width = pixelMapDuplicated->GetWidth();
1106     auto height = pixelMapDuplicated->GetHeight();
1107     auto extraInfoLimited = dragDropInfo.extraInfo.size() > EXTRA_INFO_MAX_LENGTH
1108                                 ? dragDropInfo.extraInfo.substr(EXTRA_INFO_MAX_LENGTH + 1)
1109                                 : dragDropInfo.extraInfo;
1110     auto innerRect = ParseInnerRect(extraInfoLimited, SizeF(width, height));
1111     auto pixelMapOffset = OffsetF();
1112     if (isMenuShow && GreatNotEqual(defaultPixelMapScale, 0.0f)) {
1113         pixelMapOffset = GetPixelMapOffset(info, SizeF(width, height), scale / defaultPixelMapScale, true, innerRect);
1114     } else {
1115         pixelMapOffset = GetPixelMapOffset(info, SizeF(width, height), scale);
1116     }
1117     windowScale = NearZero(windowScale) ? 1.0f : windowScale;
1118     dragDropManager->SetPixelMapOffset(pixelMapOffset / windowScale);
1119     DragEventActuator::ResetNode(frameNode);
1120     auto arkExtraInfoJson = JsonUtil::Create(true);
1121     auto dragNodeGrayscale = pipeline->GetDragNodeGrayscale();
1122     auto dipScale = pipeline->GetDipScale();
1123     arkExtraInfoJson->Put("scale", scale);
1124     arkExtraInfoJson->Put("dip_scale", dipScale);
1125     arkExtraInfoJson->Put("drag_node_gray_scale", dragNodeGrayscale);
1126     UpdateExtraInfo(frameNode, arkExtraInfoJson, scale);
1127     auto container = Container::Current();
1128     CHECK_NULL_VOID(container);
1129     auto windowId = container->GetWindowId();
1130     ShadowInfoCore shadowInfo { pixelMapDuplicated, pixelMapOffset.GetX(), pixelMapOffset.GetY() };
1131     DragDataCore dragData { { shadowInfo }, {}, udKey, extraInfoLimited, arkExtraInfoJson->ToString(),
1132         static_cast<int32_t>(info.GetSourceDevice()), recordsSize, info.GetPointerId(), info.GetScreenLocation().GetX(),
1133         info.GetScreenLocation().GetY(), info.GetTargetDisplayId(), windowId, true, false, summary };
1134     std::string summarys;
1135     for (const auto& [udkey, recordSize] : summary) {
1136         std::string str = udkey + "-" + std::to_string(recordSize) + ";";
1137         summarys += str;
1138     }
1139     TAG_LOGI(AceLogTag::ACE_DRAG,
1140         "Start drag, frameNode is %{public}s, id is %{public}s, pixelMap width %{public}d height %{public}d, "
1141         "scale is %{public}f, udkey %{public}s, recordsSize %{public}d, pointerId %{public}d, "
1142         "displayId %{public}d, windowId %{public}d, summary %{public}s.",
1143         frameNode->GetTag().c_str(), frameNode->GetInspectorId()->c_str(), width, height, scale, udKey.c_str(),
1144         recordsSize, info.GetPointerId(), info.GetTargetDisplayId(), windowId, summarys.c_str());
1145     dragDropManager->GetGatherPixelMap(dragData, scale, width, height);
1146     ret = InteractionInterface::GetInstance()->StartDrag(dragData, GetDragCallback(pipeline, eventHub));
1147     if (ret != 0) {
1148         if (dragDropManager->IsNeedDisplayInSubwindow() && subWindowOverlayManager) {
1149             SubwindowManager::GetInstance()->HidePreviewNG();
1150             overlayManager->RemovePixelMap();
1151         }
1152         TAG_LOGW(AceLogTag::ACE_DRAG, "Start drag failed, return value is %{public}d", ret);
1153         return;
1154     }
1155     if (isSwitchToSubWindow && subWindowOverlayManager) {
1156         std::vector<GatherNodeChildInfo> gatherNodeChildrenInfo;
1157         auto gatherNode = DragEventActuator::GetOrCreateGatherNode(overlayManager,
1158             dragEventActuator_, gatherNodeChildrenInfo);
1159         DragEventActuator::MountGatherNode(subWindowOverlayManager, frameNode, gatherNode, gatherNodeChildrenInfo);
1160         DragEventActuator::UpdatePreviewPositionAndScale(
1161             imageNode, imageNode->GetOffsetInSubwindow(window->GetRect().GetOffset()));
1162         if (textNode) {
1163             DragEventActuator::UpdatePreviewPositionAndScale(
1164                 textNode, textNode->GetOffsetInSubwindow(window->GetRect().GetOffset()));
1165         }
1166         DragEventActuator::MountPixelMap(
1167             subWindowOverlayManager, eventHub->GetGestureEventHub(), imageNode, textNode, true);
1168         pipeline->FlushSyncGeometryNodeTasks();
1169         DragAnimationHelper::ShowBadgeAnimation(textNode);
1170         dragDropManager->DoDragStartAnimation(
1171             subWindowOverlayManager, info, eventHub->GetGestureEventHub(), isMenuShow);
1172         if (hasContextMenu) {
1173             //response: 0.347, dampingRatio: 0.99, blendDuration: 0.0
1174             const RefPtr<Curve> curve = AceType::MakeRefPtr<ResponsiveSpringMotion>(0.347f, 0.99f, 0.0f);
1175             AnimationOption option;
1176             option.SetCurve(curve);
1177             option.SetDuration(PIXELMAP_ANIMATION_DURATION);
1178             auto renderContext = imageNode->GetRenderContext();
1179             AnimationUtils::Animate(
1180                 option,
1181                 [renderContext]() {
1182                     if (renderContext) {
1183                         renderContext->UpdateOpacity(PIXELMAP_OPACITY_RATE);
1184                     }
1185                 },
1186                 option.GetOnFinishEvent());
1187         }
1188     }
1189     if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON && IsNeedSwitchToSubWindow()) {
1190         ret = RegisterCoordinationListener(pipeline);
1191         if (ret != 0) {
1192             TAG_LOGW(AceLogTag::ACE_DRAG, "Register coordination listener failed, error is %{public}d", ret);
1193         }
1194     }
1195     dragDropManager->SetPreviewRect(Rect(pixelMapOffset.GetX(), pixelMapOffset.GetY(), width, height));
1196     dragDropManager->ResetRecordSize(static_cast<uint32_t>(recordsSize));
1197     auto eventManager = pipeline->GetEventManager();
1198     CHECK_NULL_VOID(eventManager);
1199     eventManager->DoMouseActionRelease();
1200     eventManager->SetIsDragging(true);
1201     if (info.GetInputEventType() != InputEventType::MOUSE_BUTTON && dragEventActuator_ != nullptr &&
1202         dragEventActuator_->GetIsNotInPreviewState()) {
1203         if (!dragDropManager->IsNeedDisplayInSubwindow() && !isMenuShow) {
1204             overlayManager->RemovePixelMap();
1205             overlayManager->RemovePreviewBadgeNode();
1206             overlayManager->RemoveGatherNode();
1207             pipeline->AddAfterRenderTask([]() { InteractionInterface::GetInstance()->SetDragWindowVisible(true); });
1208         }
1209     } else if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON) {
1210         if (!dragDropManager->IsNeedDisplayInSubwindow() && !isMenuShow) {
1211             pipeline->AddDragWindowVisibleTask([]() {
1212                 InteractionInterface::GetInstance()->SetDragWindowVisible(true);
1213             });
1214         }
1215         dragDropManager->SetIsDragWindowShow(true);
1216     }
1217     dragDropManager->FireOnEditableTextComponent(frameNode, DragEventType::ENTER);
1218     dragDropProxy_ = dragDropManager->CreateFrameworkDragDropProxy();
1219     CHECK_NULL_VOID(dragDropProxy_);
1220     dragDropProxy_->OnDragStart(info, extraInfoLimited, GetFrameNode());
1221     if (!dragDropManager->IsDraggingPressed(info.GetPointerId())) {
1222         dragDropManager->OnDragEnd(
1223             PointerEvent(info.GetGlobalPoint().GetX(), info.GetGlobalPoint().GetY()), extraInfoLimited);
1224     }
1225 }
1226 
UpdateExtraInfo(const RefPtr<FrameNode> & frameNode,std::unique_ptr<JsonValue> & arkExtraInfoJson,float scale)1227 void GestureEventHub::UpdateExtraInfo(const RefPtr<FrameNode>& frameNode,
1228     std::unique_ptr<JsonValue>& arkExtraInfoJson, float scale)
1229 {
1230     double opacity = frameNode->GetDragPreviewOption().options.opacity;
1231     auto optionInfo = frameNode->GetDragPreviewOption().options;
1232     arkExtraInfoJson->Put("dip_opacity", opacity);
1233     TAG_LOGD(AceLogTag::ACE_DRAG, "The info of opacity update to the framework is %{public}s",
1234         arkExtraInfoJson->ToString().c_str());
1235 
1236     if (optionInfo.blurbgEffect.backGroundEffect.radius.IsValid()) {
1237         optionInfo.blurbgEffect.ToJsonValue(arkExtraInfoJson);
1238     }
1239     DragEventActuator::PrepareShadowParametersForDragData(frameNode, arkExtraInfoJson, scale);
1240     DragEventActuator::PrepareRadiusParametersForDragData(frameNode, arkExtraInfoJson);
1241 }
1242 
RegisterCoordinationListener(const RefPtr<PipelineBase> & context)1243 int32_t GestureEventHub::RegisterCoordinationListener(const RefPtr<PipelineBase>& context)
1244 {
1245     auto pipeline = AceType::DynamicCast<PipelineContext>(context);
1246     CHECK_NULL_RETURN(pipeline, -1);
1247     auto callback = [id = Container::CurrentId(), weak = WeakClaim(RawPtr(pipeline))]() {
1248         ContainerScope scope(id);
1249         auto context = weak.Upgrade();
1250         CHECK_NULL_VOID(context);
1251         auto dragDropManager = context->GetDragDropManager();
1252         CHECK_NULL_VOID(dragDropManager);
1253         auto taskScheduler = context->GetTaskExecutor();
1254         CHECK_NULL_VOID(taskScheduler);
1255         taskScheduler->PostTask([dragDropManager]() { dragDropManager->HideDragPreviewOverlay(); },
1256             TaskExecutor::TaskType::UI, "ArkUIGestureHideDragPreviewOverlay");
1257     };
1258     return InteractionInterface::GetInstance()->RegisterCoordinationListener(callback);
1259 }
1260 
HandleOnDragUpdate(const GestureEvent & info)1261 void GestureEventHub::HandleOnDragUpdate(const GestureEvent& info)
1262 {
1263     gestureInfoForWeb_ = std::make_shared<GestureEvent>(info);
1264     CHECK_NULL_VOID(dragDropProxy_);
1265     auto pipeline = PipelineContext::GetCurrentContext();
1266     CHECK_NULL_VOID(pipeline);
1267     auto dragDropManager = pipeline->GetDragDropManager();
1268     if (dragDropManager->IsDragged()) {
1269         dragDropProxy_->OnDragMove(info);
1270     }
1271     if (IsNeedSwitchToSubWindow()) {
1272         PointerEvent pointerEvent = PointerEvent(info.GetGlobalLocation().GetX(), info.GetGlobalLocation().GetY());
1273         dragDropManager->DoDragMoveAnimate(pointerEvent);
1274     }
1275 }
1276 
HandleOnDragEnd(const GestureEvent & info)1277 void GestureEventHub::HandleOnDragEnd(const GestureEvent& info)
1278 {
1279     auto pipeline = NG::PipelineContext::GetCurrentContext();
1280     const static int32_t PLATFORM_VERSION_TEN = 10;
1281     if (pipeline && (pipeline->GetMinPlatformVersion() < PLATFORM_VERSION_TEN)) {
1282         auto eventHub = eventHub_.Upgrade();
1283         CHECK_NULL_VOID(eventHub);
1284 
1285         auto frameNode = GetFrameNode();
1286         CHECK_NULL_VOID(frameNode);
1287 
1288         // Only the onDrop callback of dragged frame node is triggered.
1289         // The onDrop callback of target frame node is triggered in PipelineContext::OnDragEvent.
1290         if (eventHub->HasOnDrop() || eventHub->HasCustomerOnDrop()) {
1291             RefPtr<OHOS::Ace::DragEvent> event = AceType::MakeRefPtr<OHOS::Ace::DragEvent>();
1292             if (frameNode->GetTag() == V2::WEB_ETS_TAG) {
1293                 event->SetX(pipeline->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetX(), DimensionUnit::PX)));
1294                 event->SetY(pipeline->ConvertPxToVp(Dimension(info.GetGlobalPoint().GetY(), DimensionUnit::PX)));
1295             } else {
1296                 event->SetX(info.GetGlobalPoint().GetX());
1297                 event->SetY(info.GetGlobalPoint().GetY());
1298             }
1299             event->SetScreenX(info.GetScreenLocation().GetX());
1300             event->SetScreenY(info.GetScreenLocation().GetY());
1301             event->SetPressedKeyCodes(info.GetPressedKeyCodes());
1302             eventHub->FireCustomerOnDragFunc(DragFuncType::DRAG_DROP, event);
1303             eventHub->HandleInternalOnDrop(event, "");
1304         }
1305     }
1306     CHECK_NULL_VOID(dragDropProxy_);
1307     dragDropProxy_->DestroyDragWindow();
1308     dragDropProxy_ = nullptr;
1309 }
1310 
HandleOnDragCancel()1311 void GestureEventHub::HandleOnDragCancel()
1312 {
1313     CHECK_NULL_VOID(dragDropProxy_);
1314     dragDropProxy_->DestroyDragWindow();
1315     dragDropProxy_ = nullptr;
1316 }
1317 
SetFocusClickEvent(GestureEventFunc && clickEvent)1318 void GestureEventHub::SetFocusClickEvent(GestureEventFunc&& clickEvent)
1319 {
1320     auto eventHub = eventHub_.Upgrade();
1321     CHECK_NULL_VOID(eventHub);
1322     auto focusHub = eventHub->GetFocusHub();
1323     CHECK_NULL_VOID(focusHub);
1324     focusHub->SetOnClickCallback(std::move(clickEvent));
1325 }
1326 
1327 // helper function to ensure clickActuator is initialized
CheckClickActuator()1328 void GestureEventHub::CheckClickActuator()
1329 {
1330     if (!clickEventActuator_) {
1331         clickEventActuator_ = MakeRefPtr<ClickEventActuator>(WeakClaim(this));
1332         clickEventActuator_->SetOnAccessibility(GetOnAccessibilityEventFunc());
1333     }
1334 
1335     if (parallelCombineClick && !userParallelClickEventActuator_) {
1336         userParallelClickEventActuator_ = MakeRefPtr<ClickEventActuator>(WeakClaim(this));
1337         userParallelClickEventActuator_->SetOnAccessibility(GetOnAccessibilityEventFunc());
1338     }
1339 }
1340 
SetUserOnClick(GestureEventFunc && clickEvent,double distanceThreshold)1341 void GestureEventHub::SetUserOnClick(GestureEventFunc&& clickEvent, double distanceThreshold)
1342 {
1343     CheckClickActuator();
1344     if (parallelCombineClick) {
1345         userParallelClickEventActuator_->SetUserCallback(std::move(clickEvent));
1346         SetFocusClickEvent(userParallelClickEventActuator_->GetClickEvent());
1347         auto clickRecognizer = userParallelClickEventActuator_->GetClickRecognizer();
1348         clickRecognizer->SetDistanceThreshold(distanceThreshold);
1349     } else {
1350         clickEventActuator_->SetUserCallback(std::move(clickEvent));
1351         SetFocusClickEvent(clickEventActuator_->GetClickEvent());
1352         auto clickRecognizer = clickEventActuator_->GetClickRecognizer();
1353         clickRecognizer->SetDistanceThreshold(distanceThreshold);
1354     }
1355 }
1356 
SetJSFrameNodeOnClick(GestureEventFunc && clickEvent)1357 void GestureEventHub::SetJSFrameNodeOnClick(GestureEventFunc&& clickEvent)
1358 {
1359     CheckClickActuator();
1360     if (parallelCombineClick) {
1361         userParallelClickEventActuator_->SetJSFrameNodeCallback(std::move(clickEvent));
1362         SetFocusClickEvent(userParallelClickEventActuator_->GetClickEvent());
1363     } else {
1364         clickEventActuator_->SetJSFrameNodeCallback(std::move(clickEvent));
1365         SetFocusClickEvent(clickEventActuator_->GetClickEvent());
1366     }
1367 }
1368 
SetOnGestureJudgeBegin(GestureJudgeFunc && gestureJudgeFunc)1369 void GestureEventHub::SetOnGestureJudgeBegin(GestureJudgeFunc&& gestureJudgeFunc)
1370 {
1371     gestureJudgeFunc_ = std::move(gestureJudgeFunc);
1372 }
1373 
SetOnTouchIntercept(TouchInterceptFunc && touchInterceptFunc)1374 void GestureEventHub::SetOnTouchIntercept(TouchInterceptFunc&& touchInterceptFunc)
1375 {
1376     touchInterceptFunc_ = std::move(touchInterceptFunc);
1377 }
1378 
GetOnTouchIntercept() const1379 TouchInterceptFunc GestureEventHub::GetOnTouchIntercept() const
1380 {
1381     return touchInterceptFunc_;
1382 }
1383 
SetShouldBuildinRecognizerParallelWithFunc(ShouldBuiltInRecognizerParallelWithFunc && parallelGestureToFunc)1384 void GestureEventHub::SetShouldBuildinRecognizerParallelWithFunc(
1385     ShouldBuiltInRecognizerParallelWithFunc&& parallelGestureToFunc)
1386 {
1387     shouldBuildinRecognizerParallelWithFunc_ = std::move(parallelGestureToFunc);
1388 }
1389 
GetParallelInnerGestureToFunc() const1390 ShouldBuiltInRecognizerParallelWithFunc GestureEventHub::GetParallelInnerGestureToFunc() const
1391 {
1392     return shouldBuildinRecognizerParallelWithFunc_;
1393 }
1394 
SetOnGestureRecognizerJudgeBegin(GestureRecognizerJudgeFunc && gestureRecognizerJudgeFunc)1395 void GestureEventHub::SetOnGestureRecognizerJudgeBegin(GestureRecognizerJudgeFunc&& gestureRecognizerJudgeFunc)
1396 {
1397     gestureRecognizerJudgeFunc_ = std::move(gestureRecognizerJudgeFunc);
1398 }
1399 
GetOnGestureRecognizerJudgeBegin() const1400 GestureRecognizerJudgeFunc GestureEventHub::GetOnGestureRecognizerJudgeBegin() const
1401 {
1402     return gestureRecognizerJudgeFunc_;
1403 }
1404 
SetOnGestureJudgeNativeBegin(GestureJudgeFunc && gestureJudgeFunc)1405 void GestureEventHub::SetOnGestureJudgeNativeBegin(GestureJudgeFunc&& gestureJudgeFunc)
1406 {
1407     gestureJudgeNativeFunc_ = std::move(gestureJudgeFunc);
1408 }
1409 
AddClickEvent(const RefPtr<ClickEvent> & clickEvent,double distanceThreshold)1410 void GestureEventHub::AddClickEvent(const RefPtr<ClickEvent>& clickEvent, double distanceThreshold)
1411 {
1412     CheckClickActuator();
1413     clickEventActuator_->AddClickEvent(clickEvent);
1414     clickEventActuator_->AddDistanceThreshold(distanceThreshold);
1415 
1416     SetFocusClickEvent(clickEventActuator_->GetClickEvent());
1417 }
1418 
AddClickAfterEvent(const RefPtr<ClickEvent> & clickEvent)1419 void GestureEventHub::AddClickAfterEvent(const RefPtr<ClickEvent>& clickEvent)
1420 {
1421     CheckClickActuator();
1422     clickEventActuator_->AddClickAfterEvent(clickEvent);
1423 
1424     SetFocusClickEvent(clickEventActuator_->GetClickEvent());
1425 }
1426 
1427 // replace last showMenu callback
BindMenu(GestureEventFunc && showMenu)1428 void GestureEventHub::BindMenu(GestureEventFunc&& showMenu)
1429 {
1430     if (showMenu_) {
1431         RemoveClickEvent(showMenu_);
1432     }
1433     showMenu_ = MakeRefPtr<ClickEvent>(std::move(showMenu));
1434     AddClickEvent(showMenu_);
1435 }
1436 
GetOnAccessibilityEventFunc()1437 OnAccessibilityEventFunc GestureEventHub::GetOnAccessibilityEventFunc()
1438 {
1439     auto callback = [weak = WeakClaim(this)](AccessibilityEventType eventType) {
1440         auto gestureHub = weak.Upgrade();
1441         CHECK_NULL_VOID(gestureHub);
1442         auto node = gestureHub->GetFrameNode();
1443         CHECK_NULL_VOID(node);
1444         node->OnAccessibilityEvent(eventType);
1445     };
1446     return callback;
1447 }
1448 
1449 template<typename T>
AccessibilityRecursionSearchRecognizer(const RefPtr<NGGestureRecognizer> & recognizer)1450 const RefPtr<T> GestureEventHub::AccessibilityRecursionSearchRecognizer(const RefPtr<NGGestureRecognizer>& recognizer)
1451 {
1452     auto CheckRecognizer = [](const RefPtr<NGGestureRecognizer>& recognizer) {
1453         const auto re = AceType::DynamicCast<ClickRecognizer>(recognizer);
1454         if (re != nullptr && re->GetFingers() == 1 && re->GetCount() == 1) {
1455             return true;
1456         } else if (AceType::DynamicCast<LongPressRecognizer>(recognizer) != nullptr &&
1457                    AceType::DynamicCast<LongPressRecognizer>(recognizer)->GetFingers() == 1) {
1458             return true;
1459         }
1460         return false;
1461     };
1462 
1463     const auto re = AceType::DynamicCast<T>(recognizer);
1464     if (re != nullptr && CheckRecognizer(recognizer)) {
1465         return re;
1466     } else if (AceType::DynamicCast<RecognizerGroup>(recognizer) != nullptr) {
1467         for (const auto& recognizerElement : AceType::DynamicCast<RecognizerGroup>(recognizer)->GetGroupRecognizer()) {
1468             const auto& tmpRecognizer = AccessibilityRecursionSearchRecognizer<T>(recognizerElement);
1469             if (tmpRecognizer != nullptr) {
1470                 return tmpRecognizer;
1471             }
1472         }
1473     }
1474     return nullptr;
1475 }
1476 
1477 template<typename T>
GetAccessibilityRecognizer()1478 const RefPtr<T> GestureEventHub::GetAccessibilityRecognizer()
1479 {
1480     for (const auto& recognizer : gestureHierarchy_) {
1481         const auto& re = AccessibilityRecursionSearchRecognizer<T>(recognizer);
1482         if (re != nullptr) {
1483             return re;
1484         }
1485     }
1486     return nullptr;
1487 }
1488 
ActClick(std::shared_ptr<JsonValue> secComphandle)1489 bool GestureEventHub::ActClick(std::shared_ptr<JsonValue> secComphandle)
1490 {
1491     auto host = GetFrameNode();
1492     CHECK_NULL_RETURN(host, false);
1493     GestureEventFunc click;
1494     GestureEvent info;
1495     std::chrono::microseconds microseconds(GetMicroTickCount());
1496     TimeStamp time(microseconds);
1497     info.SetTimeStamp(time);
1498     EventTarget clickEventTarget;
1499     clickEventTarget.id = host->GetId();
1500     clickEventTarget.type = host->GetTag();
1501 #ifdef SECURITY_COMPONENT_ENABLE
1502     info.SetSecCompHandleEvent(secComphandle);
1503 #endif
1504     auto geometryNode = host->GetGeometryNode();
1505     CHECK_NULL_RETURN(geometryNode, false);
1506     auto offset = geometryNode->GetFrameOffset();
1507     auto size = geometryNode->GetFrameSize();
1508     clickEventTarget.area.SetOffset(DimensionOffset(offset));
1509     clickEventTarget.area.SetHeight(Dimension(size.Height()));
1510     clickEventTarget.area.SetWidth(Dimension(size.Width()));
1511     clickEventTarget.origin = DimensionOffset(host->GetOffsetRelativeToWindow() - offset);
1512     info.SetTarget(clickEventTarget);
1513     Offset globalOffset(offset.GetX(), offset.GetY());
1514     info.SetGlobalLocation(globalOffset);
1515     if (clickEventActuator_) {
1516         click = clickEventActuator_->GetClickEvent();
1517         CHECK_NULL_RETURN(click, true);
1518         click(info);
1519         return true;
1520     }
1521     const RefPtr<ClickRecognizer> clickRecognizer = GetAccessibilityRecognizer<ClickRecognizer>();
1522     if (clickRecognizer) {
1523         click = clickRecognizer->GetTapActionFunc();
1524         click(info);
1525         host->OnAccessibilityEvent(AccessibilityEventType::CLICK);
1526         return true;
1527     }
1528     return false;
1529 }
1530 
ActLongClick()1531 bool GestureEventHub::ActLongClick()
1532 {
1533     auto host = GetFrameNode();
1534     CHECK_NULL_RETURN(host, false);
1535     GestureEventFunc click;
1536     GestureEvent info;
1537     std::chrono::microseconds microseconds(GetMicroTickCount());
1538     TimeStamp time(microseconds);
1539     info.SetTimeStamp(time);
1540     EventTarget longPressTarget;
1541     longPressTarget.id = host->GetId();
1542     longPressTarget.type = host->GetTag();
1543     auto geometryNode = host->GetGeometryNode();
1544     CHECK_NULL_RETURN(geometryNode, false);
1545     auto offset = geometryNode->GetFrameOffset();
1546     auto size = geometryNode->GetFrameSize();
1547     longPressTarget.area.SetOffset(DimensionOffset(offset));
1548     longPressTarget.area.SetHeight(Dimension(size.Height()));
1549     longPressTarget.area.SetWidth(Dimension(size.Width()));
1550     longPressTarget.origin = DimensionOffset(host->GetOffsetRelativeToWindow() - offset);
1551     info.SetTarget(longPressTarget);
1552     Offset globalOffset(offset.GetX(), offset.GetY());
1553     info.SetGlobalLocation(globalOffset);
1554     if (longPressEventActuator_) {
1555         click = longPressEventActuator_->GetGestureEventFunc();
1556         CHECK_NULL_RETURN(click, true);
1557         click(info);
1558         return true;
1559     }
1560     RefPtr<LongPressRecognizer> longPressRecognizer;
1561     for (auto gestureRecognizer : gestureHierarchy_) {
1562         longPressRecognizer = AceType::DynamicCast<LongPressRecognizer>(gestureRecognizer);
1563         if (longPressRecognizer && longPressRecognizer->GetFingers() == 1) {
1564             click = longPressRecognizer->GetLongPressActionFunc();
1565             click(info);
1566             host->OnAccessibilityEvent(AccessibilityEventType::LONG_PRESS);
1567             return true;
1568         }
1569     }
1570     return false;
1571 }
1572 
GetHitTestModeStr() const1573 std::string GestureEventHub::GetHitTestModeStr() const
1574 {
1575     auto mode = static_cast<int32_t>(hitTestMode_);
1576     if (mode < 0 || mode >= static_cast<int32_t>(std::size(HIT_TEST_MODE))) {
1577         return HIT_TEST_MODE[0];
1578     }
1579     return HIT_TEST_MODE[mode];
1580 }
1581 
KeyBoardShortCutClick(const KeyEvent & event,const WeakPtr<NG::FrameNode> & node)1582 bool GestureEventHub::KeyBoardShortCutClick(const KeyEvent& event, const WeakPtr<NG::FrameNode>& node)
1583 {
1584     auto host = node.Upgrade();
1585     CHECK_NULL_RETURN(host, false);
1586     CHECK_NULL_RETURN(clickEventActuator_, false);
1587     auto click = clickEventActuator_->GetClickEvent();
1588     CHECK_NULL_RETURN(click, false);
1589     GestureEvent info;
1590     info.SetSourceDevice(event.sourceType);
1591     info.SetTimeStamp(event.timeStamp);
1592     EventTarget target;
1593     target.id = host->GetId();
1594     target.type = host->GetTag();
1595     auto geometryNode = host->GetGeometryNode();
1596     CHECK_NULL_RETURN(geometryNode, false);
1597     auto offset = geometryNode->GetFrameOffset();
1598     auto size = geometryNode->GetFrameSize();
1599     target.area.SetOffset(DimensionOffset(offset));
1600     target.area.SetHeight(Dimension(size.Height()));
1601     target.area.SetWidth(Dimension(size.Width()));
1602     target.origin = DimensionOffset(host->GetOffsetRelativeToWindow() - offset);
1603     info.SetTarget(target);
1604     click(info);
1605     return true;
1606 }
1607 
SetDragData(const RefPtr<UnifiedData> & unifiedData,std::string & udKey)1608 int32_t GestureEventHub::SetDragData(const RefPtr<UnifiedData>& unifiedData, std::string& udKey)
1609 {
1610     CHECK_NULL_RETURN(unifiedData, -1);
1611     return UdmfClient::GetInstance()->SetData(unifiedData, udKey);
1612 }
1613 
GetDragCallback(const RefPtr<PipelineBase> & context,const WeakPtr<EventHub> & hub)1614 OnDragCallbackCore GestureEventHub::GetDragCallback(const RefPtr<PipelineBase>& context, const WeakPtr<EventHub>& hub)
1615 {
1616     auto ret = [](const DragNotifyMsgCore& notifyMessage) {};
1617     auto eventHub = hub.Upgrade();
1618     CHECK_NULL_RETURN(eventHub, ret);
1619     auto pipeline = AceType::DynamicCast<PipelineContext>(context);
1620     CHECK_NULL_RETURN(pipeline, ret);
1621     auto taskScheduler = pipeline->GetTaskExecutor();
1622     CHECK_NULL_RETURN(taskScheduler, ret);
1623     auto dragDropManager = pipeline->GetDragDropManager();
1624     CHECK_NULL_RETURN(dragDropManager, ret);
1625     auto eventManager = pipeline->GetEventManager();
1626     RefPtr<OHOS::Ace::DragEvent> dragEvent = AceType::MakeRefPtr<OHOS::Ace::DragEvent>();
1627     auto callback = [id = Container::CurrentId(), eventHub, dragEvent, taskScheduler, dragDropManager, eventManager](
1628                         const DragNotifyMsgCore& notifyMessage) {
1629         ContainerScope scope(id);
1630         taskScheduler->PostTask(
1631             [eventHub, dragEvent, dragDropManager, eventManager, notifyMessage, id]() {
1632                 dragDropManager->SetDragResult(notifyMessage, dragEvent);
1633                 dragDropManager->SetDragBehavior(notifyMessage, dragEvent);
1634                 dragDropManager->DoDragReset();
1635                 dragDropManager->SetIsDragged(false);
1636                 dragDropManager->SetDraggingPointer(-1);
1637                 dragDropManager->SetDraggingPressedState(false);
1638                 dragDropManager->ResetDragPreviewInfo();
1639                 dragDropManager->HideDragPreviewWindow(id);
1640                 dragEvent->SetPressedKeyCodes(dragDropManager->GetDragDropPointerEvent().pressedKeyCodes_);
1641                 auto ret = InteractionInterface::GetInstance()->UnRegisterCoordinationListener();
1642                 if (ret != 0) {
1643                     TAG_LOGW(AceLogTag::ACE_DRAG, "Unregister coordination listener failed, error is %{public}d", ret);
1644                 }
1645                 if (eventManager) {
1646                     eventManager->DoMouseActionRelease();
1647                 }
1648                 eventHub->FireCustomerOnDragFunc(DragFuncType::DRAG_END, dragEvent);
1649                 if (eventHub->HasOnDragEnd()) {
1650                     (eventHub->GetOnDragEnd())(dragEvent);
1651                 }
1652             },
1653             TaskExecutor::TaskType::UI, "ArkUIGestureDragEnd");
1654     };
1655     return callback;
1656 }
1657 
IsAccessibilityClickable()1658 bool GestureEventHub::IsAccessibilityClickable()
1659 {
1660     return IsClickable() || GetAccessibilityRecognizer<ClickRecognizer>() != nullptr;
1661 }
1662 
IsAccessibilityLongClickable()1663 bool GestureEventHub::IsAccessibilityLongClickable()
1664 {
1665     return IsLongClickable() || GetAccessibilityRecognizer<LongPressRecognizer>() != nullptr;
1666 }
1667 
GetMonopolizeEvents() const1668 bool GestureEventHub::GetMonopolizeEvents() const
1669 {
1670     return monopolizeEvents_;
1671 }
1672 
SetMonopolizeEvents(bool monopolizeEvents)1673 void GestureEventHub::SetMonopolizeEvents(bool monopolizeEvents)
1674 {
1675     monopolizeEvents_ = monopolizeEvents;
1676 }
1677 
ClearUserOnClick()1678 void GestureEventHub::ClearUserOnClick()
1679 {
1680     if (clickEventActuator_) {
1681         clickEventActuator_->ClearUserCallback();
1682     }
1683 }
1684 
ClearUserOnTouch()1685 void GestureEventHub::ClearUserOnTouch()
1686 {
1687     if (touchEventActuator_) {
1688         touchEventActuator_->ClearUserCallback();
1689     }
1690 }
1691 
ClearJSFrameNodeOnClick()1692 void GestureEventHub::ClearJSFrameNodeOnClick()
1693 {
1694     if (clickEventActuator_) {
1695         clickEventActuator_->ClearJSFrameNodeCallback();
1696     }
1697 }
1698 
ClearJSFrameNodeOnTouch()1699 void GestureEventHub::ClearJSFrameNodeOnTouch()
1700 {
1701     if (touchEventActuator_) {
1702         touchEventActuator_->ClearJSFrameNodeCallback();
1703     }
1704 }
1705 
CopyGestures(const RefPtr<GestureEventHub> & gestureEventHub)1706 void GestureEventHub::CopyGestures(const RefPtr<GestureEventHub>& gestureEventHub)
1707 {
1708     CHECK_NULL_VOID(gestureEventHub);
1709     gestures_ = gestureEventHub->backupGestures_;
1710     modifierGestures_ = gestureEventHub->backupModifierGestures_;
1711     recreateGesture_ = true;
1712 }
1713 
CopyEvent(const RefPtr<GestureEventHub> & gestureEventHub)1714 void GestureEventHub::CopyEvent(const RefPtr<GestureEventHub>& gestureEventHub)
1715 {
1716     CHECK_NULL_VOID(gestureEventHub);
1717     auto originalTouchEventActuator = gestureEventHub->touchEventActuator_;
1718     if (originalTouchEventActuator) {
1719         touchEventActuator_ = MakeRefPtr<TouchEventActuator>();
1720         touchEventActuator_->CopyTouchEvent(originalTouchEventActuator);
1721     }
1722 
1723     auto originalClickEventActuator = gestureEventHub->clickEventActuator_;
1724     if (originalClickEventActuator) {
1725         clickEventActuator_ = MakeRefPtr<ClickEventActuator>(WeakClaim(this));
1726         clickEventActuator_->CopyClickEvent(originalClickEventActuator);
1727     }
1728 
1729     auto originalLongPressEventActuator = gestureEventHub->longPressEventActuator_;
1730     if (originalLongPressEventActuator) {
1731         longPressEventActuator_ = MakeRefPtr<LongPressEventActuator>(WeakClaim(this));
1732         longPressEventActuator_->CopyLongPressEvent(originalLongPressEventActuator);
1733     }
1734 
1735     auto originalDragEventActuator = gestureEventHub->dragEventActuator_;
1736     if (originalDragEventActuator) {
1737         dragEventActuator_ = MakeRefPtr<DragEventActuator>(WeakClaim(this), originalDragEventActuator->GetDirection(),
1738             originalDragEventActuator->GetFingers(), originalDragEventActuator->GetDistance());
1739         dragEventActuator_->CopyDragEvent(originalDragEventActuator);
1740     }
1741     auto originalShowMenu = gestureEventHub->showMenu_;
1742     if (originalShowMenu) {
1743         if (showMenu_) {
1744             RemoveClickEvent(showMenu_);
1745         }
1746         auto originalGetGestureEventFunc = originalShowMenu->GetGestureEventFunc();
1747         showMenu_= MakeRefPtr<ClickEvent>(std::move(originalGetGestureEventFunc));
1748         AddClickEvent(showMenu_);
1749     }
1750 }
1751 
IsTextCategoryComponent(const std::string & frameTag)1752 bool GestureEventHub::IsTextCategoryComponent(const std::string& frameTag)
1753 {
1754     return frameTag == V2::TEXTAREA_ETS_TAG || frameTag == V2::TEXT_ETS_TAG ||
1755            frameTag == V2::TEXTINPUT_ETS_TAG || frameTag == V2::SEARCH_Field_ETS_TAG ||
1756            frameTag == V2::RICH_EDITOR_ETS_TAG;
1757 }
1758 
SetDragForbiddenForcely(bool isDragForbiddenForWholeSubTree)1759 void GestureEventHub::SetDragForbiddenForcely(bool isDragForbiddenForWholeSubTree)
1760 {
1761     isDragForbiddenForWholeSubTree_ = isDragForbiddenForWholeSubTree;
1762 }
1763 
IsDragForbidden() const1764 bool GestureEventHub::IsDragForbidden() const
1765 {
1766     return isDragForbiddenForWholeSubTree_;
1767 }
1768 
GetDragDropInfo(const GestureEvent & info,const RefPtr<FrameNode> frameNode,DragDropInfo & dragPreviewInfo,const RefPtr<OHOS::Ace::DragEvent> & dragEvent)1769 DragDropInfo GestureEventHub::GetDragDropInfo(const GestureEvent& info, const RefPtr<FrameNode> frameNode,
1770     DragDropInfo& dragPreviewInfo, const RefPtr<OHOS::Ace::DragEvent>& dragEvent)
1771 {
1772     DragDropInfo dragDropInfo;
1773     CHECK_NULL_RETURN(dragEventActuator_, dragDropInfo);
1774     dragEventActuator_->SetIsDefaultOnDragStartExecuted(false);
1775     auto eventHub = eventHub_.Upgrade();
1776     CHECK_NULL_RETURN(eventHub, dragDropInfo);
1777     auto extraParams = eventHub->GetDragExtraParams(std::string(), info.GetGlobalPoint(), DragEventType::START);
1778     auto onDragStart = eventHub->GetOnDragStart();
1779     if (!onDragStart && eventHub->HasDefaultOnDragStart()) {
1780         onDragStart = eventHub->GetDefaultOnDragStart();
1781         dragEventActuator_->SetIsDefaultOnDragStartExecuted(true);
1782     }
1783     if (GetTextDraggable() && info.GetInputEventType() == InputEventType::MOUSE_BUTTON) {
1784         GenerateMousePixelMap(info);
1785     }
1786     dragEvent->SetPressedKeyCodes(info.GetPressedKeyCodes());
1787     dragDropInfo = onDragStart(dragEvent, extraParams);
1788 
1789     auto frameTag = frameNode->GetTag();
1790     if (GetTextDraggable() && IsTextCategoryComponent(frameTag)) {
1791         TAG_LOGD(AceLogTag::ACE_DRAG, "Get drag drop info, pixelmap and customNode are set to null "
1792             "when frameTag is %{public}s", frameTag.c_str());
1793         dragDropInfo.pixelMap = nullptr;
1794         dragDropInfo.customNode = nullptr;
1795     } else {
1796         dragPreviewInfo = frameNode->GetDragPreview();
1797     }
1798     return dragDropInfo;
1799 }
1800 
GetUnifiedData(const std::string & frameTag,DragDropInfo & dragDropInfo,const RefPtr<OHOS::Ace::DragEvent> & dragEvent)1801 RefPtr<UnifiedData> GestureEventHub::GetUnifiedData(const std::string& frameTag, DragDropInfo& dragDropInfo,
1802     const RefPtr<OHOS::Ace::DragEvent>& dragEvent)
1803 {
1804     auto eventHub = eventHub_.Upgrade();
1805     CHECK_NULL_RETURN(eventHub, nullptr);
1806     auto unifiedData = dragEvent->GetData();
1807     bool hasData = static_cast<bool>(unifiedData);
1808     if (!unifiedData && eventHub->HasDefaultOnDragStart()) {
1809         auto defaultDropInfo = eventHub->GetDefaultOnDragStart()(dragEvent, "");
1810         if (dragDropInfo.extraInfo.empty()) {
1811             dragDropInfo.extraInfo = defaultDropInfo.extraInfo;
1812         }
1813         CHECK_NULL_RETURN(dragEventActuator_, nullptr);
1814         dragEventActuator_->SetIsDefaultOnDragStartExecuted(true);
1815         unifiedData = dragEvent->GetData();
1816     }
1817     auto defaultOnDragStart = eventHub->GetDefaultOnDragStart();
1818     CHECK_NULL_RETURN(defaultOnDragStart, unifiedData);
1819     if (hasData && IsTextCategoryComponent(frameTag) && !dragEventActuator_->IsDefaultOnDragStartExecuted()) {
1820         defaultOnDragStart(dragEvent, "");
1821     }
1822     return unifiedData;
1823 }
1824 
SetOnTouchEvent(TouchEventFunc && touchEventFunc)1825 void GestureEventHub::SetOnTouchEvent(TouchEventFunc&& touchEventFunc)
1826 {
1827     if (!touchEventActuator_) {
1828         touchEventActuator_ = MakeRefPtr<TouchEventActuator>();
1829     }
1830     touchEventActuator_->SetOnTouchEvent(std::move(touchEventFunc));
1831 }
1832 
SetJSFrameNodeOnTouchEvent(TouchEventFunc && touchEventFunc)1833 void GestureEventHub::SetJSFrameNodeOnTouchEvent(TouchEventFunc&& touchEventFunc)
1834 {
1835     if (!touchEventActuator_) {
1836         touchEventActuator_ = MakeRefPtr<TouchEventActuator>();
1837     }
1838     touchEventActuator_->SetJSFrameNodeOnTouchEvent(std::move(touchEventFunc));
1839 }
1840 
SetResponseRegion(const std::vector<DimensionRect> & responseRegion)1841 void GestureEventHub::SetResponseRegion(const std::vector<DimensionRect>& responseRegion)
1842 {
1843     responseRegion_ = responseRegion;
1844     if (!responseRegion_.empty()) {
1845         isResponseRegion_ = true;
1846     }
1847     if (responseRegionFunc_) {
1848         responseRegionFunc_(responseRegion_);
1849     }
1850 }
1851 
RemoveLastResponseRect()1852 void GestureEventHub::RemoveLastResponseRect()
1853 {
1854     if (responseRegion_.empty()) {
1855         isResponseRegion_ = false;
1856         return;
1857     }
1858     responseRegion_.pop_back();
1859     if (responseRegion_.empty()) {
1860         isResponseRegion_ = false;
1861     }
1862 
1863     if (responseRegionFunc_) {
1864         responseRegionFunc_(responseRegion_);
1865     }
1866 }
1867 
RemoveGesturesByTag(const std::string & gestureTag)1868 void GestureEventHub::RemoveGesturesByTag(const std::string& gestureTag)
1869 {
1870     bool needRecollect = false;
1871     for (auto iter = modifierGestures_.begin(); iter != modifierGestures_.end();) {
1872         auto tag = (*iter)->GetTag();
1873         if (tag.has_value() && tag.value() == gestureTag) {
1874             iter = modifierGestures_.erase(iter);
1875             backupModifierGestures_.remove(*iter);
1876             needRecollect = true;
1877         } else {
1878             auto group = AceType::DynamicCast<GestureGroup>(*iter);
1879             if (group) {
1880                 group->RemoveChildrenByTag(gestureTag, needRecollect);
1881             }
1882             iter++;
1883         }
1884     }
1885     if (needRecollect) {
1886         recreateGesture_ = true;
1887         needRecollect_ = true;
1888         OnModifyDone();
1889     }
1890 }
1891 
ClearModifierGesture()1892 void GestureEventHub::ClearModifierGesture()
1893 {
1894     modifierGestures_.clear();
1895     backupModifierGestures_.clear();
1896     recreateGesture_ = true;
1897     OnModifyDone();
1898 }
1899 
IsNeedSwitchToSubWindow() const1900 bool GestureEventHub::IsNeedSwitchToSubWindow() const
1901 {
1902     auto frameNode = GetFrameNode();
1903     CHECK_NULL_RETURN(frameNode, false);
1904     auto focusHub = frameNode->GetFocusHub();
1905     CHECK_NULL_RETURN(focusHub, false);
1906     if (IsPixelMapNeedScale()) {
1907         return true;
1908     }
1909     CHECK_NULL_RETURN(dragEventActuator_, false);
1910     return dragEventActuator_->IsNeedGather();
1911 }
1912 
SetDragGatherPixelMaps(const GestureEvent & info)1913 void GestureEventHub::SetDragGatherPixelMaps(const GestureEvent& info)
1914 {
1915     CHECK_NULL_VOID(dragEventActuator_);
1916     if (!dragEventActuator_->IsNeedGather()) {
1917         return;
1918     }
1919     if (info.GetInputEventType() == InputEventType::MOUSE_BUTTON) {
1920         SetMouseDragGatherPixelMaps();
1921     } else {
1922         SetNotMouseDragGatherPixelMaps();
1923     }
1924 }
1925 
SetMouseDragGatherPixelMaps()1926 void GestureEventHub::SetMouseDragGatherPixelMaps()
1927 {
1928     auto frameNode = GetFrameNode();
1929     CHECK_NULL_VOID(frameNode);
1930     auto pipeline = PipelineContext::GetCurrentContext();
1931     CHECK_NULL_VOID(pipeline);
1932     auto dragDropManager = pipeline->GetDragDropManager();
1933     CHECK_NULL_VOID(dragDropManager);
1934     dragDropManager->ClearGatherPixelMap();
1935     CHECK_NULL_VOID(dragEventActuator_);
1936     auto fatherNode = dragEventActuator_->GetItemParentNode();
1937     CHECK_NULL_VOID(fatherNode);
1938     auto scrollPattern = fatherNode->GetPattern<ScrollablePattern>();
1939     CHECK_NULL_VOID(scrollPattern);
1940     auto children = scrollPattern->GetVisibleSelectedItems();
1941     int cnt = 0;
1942     for (const auto& itemFrameNode : children) {
1943         if (itemFrameNode == frameNode) {
1944             continue;
1945         }
1946         CHECK_NULL_VOID(itemFrameNode);
1947         DragEventActuator::GetFrameNodePreviewPixelMap(itemFrameNode);
1948         auto gestureHub = itemFrameNode->GetOrCreateGestureEventHub();
1949         CHECK_NULL_VOID(gestureHub);
1950         dragDropManager->PushGatherPixelMap(gestureHub->GetDragPreviewPixelMap());
1951         cnt++;
1952         if (cnt > 1) {
1953             break;
1954         }
1955     }
1956 }
1957 
SetNotMouseDragGatherPixelMaps()1958 void GestureEventHub::SetNotMouseDragGatherPixelMaps()
1959 {
1960     auto pipeline = PipelineContext::GetCurrentContext();
1961     CHECK_NULL_VOID(pipeline);
1962     auto dragDropManager = pipeline->GetDragDropManager();
1963     CHECK_NULL_VOID(dragDropManager);
1964     dragDropManager->ClearGatherPixelMap();
1965     auto mainPipeline = PipelineContext::GetMainPipelineContext();
1966     CHECK_NULL_VOID(mainPipeline);
1967     auto overlayManager = mainPipeline->GetOverlayManager();
1968     CHECK_NULL_VOID(overlayManager);
1969     auto gatherNodeChildrenInfo = overlayManager->GetGatherNodeChildrenInfo();
1970     int cnt = 0;
1971     for (auto iter = gatherNodeChildrenInfo.rbegin(); iter != gatherNodeChildrenInfo.rend(); ++iter) {
1972         auto imageNode = (*iter).imageNode.Upgrade();
1973         CHECK_NULL_VOID(imageNode);
1974         auto imageLayoutProperty = imageNode->GetLayoutProperty<ImageLayoutProperty>();
1975         CHECK_NULL_VOID(imageLayoutProperty);
1976         auto imageSourceInfo = imageLayoutProperty->GetImageSourceInfo().value_or(ImageSourceInfo());
1977         dragDropManager->PushGatherPixelMap(imageSourceInfo.GetPixmap());
1978         cnt++;
1979         if (cnt > 1) {
1980             break;
1981         }
1982     }
1983 }
1984 
GetSelectItemSize()1985 int32_t GestureEventHub::GetSelectItemSize()
1986 {
1987     CHECK_NULL_RETURN(dragEventActuator_, 0);
1988     if (!dragEventActuator_->IsNeedGather()) {
1989         return 0;
1990     }
1991     auto fatherNode = dragEventActuator_->GetItemParentNode();
1992     CHECK_NULL_RETURN(fatherNode, 0);
1993     auto scrollPattern = fatherNode->GetPattern<ScrollablePattern>();
1994     CHECK_NULL_RETURN(scrollPattern, 0);
1995     auto children = scrollPattern->GetVisibleSelectedItems();
1996     return children.size();
1997 }
1998 
FireCustomerOnDragEnd(const RefPtr<PipelineBase> & context,const WeakPtr<EventHub> & hub)1999 void GestureEventHub::FireCustomerOnDragEnd(const RefPtr<PipelineBase>& context, const WeakPtr<EventHub>& hub)
2000 {
2001     auto eventHub = hub.Upgrade();
2002     CHECK_NULL_VOID(eventHub);
2003     auto pipeline = AceType::DynamicCast<PipelineContext>(context);
2004     CHECK_NULL_VOID(pipeline);
2005     auto dragDropManager = pipeline->GetDragDropManager();
2006     CHECK_NULL_VOID(dragDropManager);
2007     auto dragEvent = AceType::MakeRefPtr<OHOS::Ace::DragEvent>();
2008     CHECK_NULL_VOID(dragEvent);
2009     dragEvent->SetResult(DragRet::DRAG_FAIL);
2010     dragEvent->SetDragBehavior(DragBehavior::UNKNOWN);
2011     dragDropManager->DoDragReset();
2012     dragDropManager->SetIsDragged(false);
2013     dragDropManager->ResetDragging();
2014     dragDropManager->SetDraggingPointer(-1);
2015     dragDropManager->SetDraggingPressedState(false);
2016     dragDropManager->ResetDragPreviewInfo();
2017     eventHub->FireCustomerOnDragFunc(DragFuncType::DRAG_END, dragEvent);
2018     if (eventHub->HasOnDragEnd()) {
2019         (eventHub->GetOnDragEnd())(dragEvent);
2020     }
2021 }
2022 
2023 #if defined(PIXEL_MAP_SUPPORTED)
PrintBuilderNode(const RefPtr<UINode> & customNode)2024 void GestureEventHub::PrintBuilderNode(const RefPtr<UINode>& customNode)
2025 {
2026     CHECK_NULL_VOID(customNode);
2027     bool hasImageNode = false;
2028     std::list<RefPtr<FrameNode>> imageNodes;
2029     int32_t depth = 1;
2030     PrintIfImageNode(customNode, depth, hasImageNode, imageNodes);
2031     CheckImageDecode(imageNodes);
2032     imageNodes.clear();
2033 }
2034 
PrintIfImageNode(const RefPtr<UINode> & builderNode,int32_t depth,bool & hasImageNode,std::list<RefPtr<FrameNode>> & imageNodes)2035 void GestureEventHub::PrintIfImageNode(
2036     const RefPtr<UINode>& builderNode, int32_t depth, bool& hasImageNode, std::list<RefPtr<FrameNode>>& imageNodes)
2037 {
2038     if (depth > MAX_BUILDER_DEPTH) {
2039         return;
2040     }
2041     if (builderNode->GetTag() == V2::IMAGE_ETS_TAG) {
2042         auto frameNode = AceType::DynamicCast<FrameNode>(builderNode);
2043         CHECK_NULL_VOID(frameNode);
2044         auto pattern = frameNode->GetPattern<ImagePattern>();
2045         CHECK_NULL_VOID(pattern);
2046         hasImageNode = true;
2047         imageNodes.push_back(frameNode);
2048         TAG_LOGI(AceLogTag::ACE_DRAG,
2049             "customNode has ImageNode, nodeId: %{public}d, syncLoad: %{public}d, decode complete: %{public}d",
2050             frameNode->GetId(), pattern->GetSyncLoad(), pattern->GetCanvasImage() != nullptr);
2051     }
2052 
2053     auto children = builderNode->GetChildren();
2054     for (const auto& child : children) {
2055         PrintIfImageNode(child, depth + 1, hasImageNode, imageNodes);
2056     }
2057 }
2058 
CheckImageDecode(std::list<RefPtr<FrameNode>> & imageNodes)2059 void GestureEventHub::CheckImageDecode(std::list<RefPtr<FrameNode>>& imageNodes)
2060 {
2061     if (imageNodes.empty()) {
2062         return;
2063     }
2064 
2065     for (const auto& imageNode : imageNodes) {
2066         auto pattern = imageNode->GetPattern<ImagePattern>();
2067         CHECK_NULL_VOID(pattern);
2068         if (!pattern->GetCanvasImage()) {
2069             TAG_LOGW(
2070                 AceLogTag::ACE_DRAG, "ImageNode did not complete decoding, nodeId: %{public}d", imageNode->GetId());
2071         }
2072     }
2073 }
2074 
StartDragForCustomBuilder(const GestureEvent & info,const RefPtr<PipelineBase> & pipeline,const RefPtr<FrameNode> frameNode,DragDropInfo dragDropInfo,const RefPtr<OHOS::Ace::DragEvent> & event)2075 void GestureEventHub::StartDragForCustomBuilder(const GestureEvent& info, const RefPtr<PipelineBase>& pipeline,
2076     const RefPtr<FrameNode> frameNode, DragDropInfo dragDropInfo, const RefPtr<OHOS::Ace::DragEvent>& event)
2077 {
2078     SnapshotParam param;
2079     param.delay = CREATE_PIXELMAP_TIME;
2080     param.checkImageStatus = true;
2081     param.options.waitUntilRenderFinished = true;
2082     std::shared_ptr<Media::PixelMap> pixelMap = ComponentSnapshot::CreateSync(dragDropInfo.customNode, param);
2083     if (pixelMap != nullptr) {
2084         dragDropInfo.pixelMap = PixelMap::CreatePixelMap(reinterpret_cast<void*>(&pixelMap));
2085         OnDragStart(info, pipeline, frameNode, dragDropInfo, event);
2086         return;
2087     }
2088     TAG_LOGI(AceLogTag::ACE_DRAG, "Snapshot createSync failed, get thumbnail by async.");
2089     auto callback = [id = Container::CurrentId(), pipeline, info, gestureEventHubPtr = AceType::Claim(this),
2090                         frameNode, dragDropInfo, event](
2091                         std::shared_ptr<Media::PixelMap> pixelMap, int32_t arg, std::function<void()>) mutable {
2092         ContainerScope scope(id);
2093         TAG_LOGI(AceLogTag::ACE_DRAG, "Get thumbnail callback executed.");
2094         if (pixelMap != nullptr) {
2095             dragDropInfo.pixelMap = PixelMap::CreatePixelMap(reinterpret_cast<void*>(&pixelMap));
2096         }
2097         auto taskScheduler = pipeline->GetTaskExecutor();
2098         CHECK_NULL_VOID(taskScheduler);
2099         taskScheduler->PostTask(
2100             [pipeline, info, gestureEventHubPtr, frameNode, dragDropInfo, event]() {
2101                 CHECK_NULL_VOID(gestureEventHubPtr);
2102                 CHECK_NULL_VOID(frameNode);
2103                 gestureEventHubPtr->OnDragStart(info, pipeline, frameNode, dragDropInfo, event);
2104             },
2105             TaskExecutor::TaskType::UI, "ArkUIGestureDragStart");
2106     };
2107     NG::ComponentSnapshot::Create(dragDropInfo.customNode, std::move(callback), true, param);
2108     PrintBuilderNode(dragDropInfo.customNode);
2109 }
2110 #endif
2111 
SetMouseDragMonitorState(bool state)2112 void GestureEventHub::SetMouseDragMonitorState(bool state)
2113 {
2114     auto ret = InteractionInterface::GetInstance()->SetMouseDragMonitorState(state);
2115     if (ret != 0) {
2116         TAG_LOGW(AceLogTag::ACE_DRAG, "Set mouse drag monitor state %{public}d failed, return value is %{public}d",
2117             state, ret);
2118         return;
2119     }
2120     TAG_LOGI(AceLogTag::ACE_DRAG, "Set mouse drag monitor state %{public}d success", state);
2121 }
2122 
SetBindMenuStatus(bool setIsShow,bool isShow,MenuPreviewMode previewMode)2123 void GestureEventHub::SetBindMenuStatus(bool setIsShow, bool isShow, MenuPreviewMode previewMode)
2124 {
2125     if (setIsShow) {
2126         bindMenuStatus_.isBindCustomMenu = true;
2127         bindMenuStatus_.isShow = isShow;
2128         bindMenuStatus_.isShowPreviewMode = previewMode;
2129     } else {
2130         bindMenuStatus_.isBindLongPressMenu = true;
2131         bindMenuStatus_.longPressPreviewMode = previewMode;
2132     }
2133 }
2134 } // namespace OHOS::Ace::NG
2135