• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "core/components_ng/event/drag_event.h"
17 
18 #include "base/subwindow/subwindow_manager.h"
19 #include "base/utils/system_properties.h"
20 #include "base/utils/utils.h"
21 #include "core/animation/animation_pub.h"
22 #include "core/common/container.h"
23 #include "core/common/interaction/interaction_data.h"
24 #include "core/common/interaction/interaction_interface.h"
25 #include "core/components/common/layout/constants.h"
26 #include "core/components/container_modal/container_modal_constants.h"
27 #include "core/components/theme/blur_style_theme.h"
28 #include "core/components/theme/shadow_theme.h"
29 #include "core/components_ng/base/frame_node.h"
30 #include "core/components_ng/base/inspector.h"
31 #include "core/components_ng/event/gesture_event_hub.h"
32 #include "core/components_ng/event/gesture_info.h"
33 #include "core/components_ng/gestures/recognizers/long_press_recognizer.h"
34 #include "core/components_ng/gestures/recognizers/pan_recognizer.h"
35 #include "core/components_ng/gestures/recognizers/sequenced_recognizer.h"
36 #include "core/components_ng/manager/drag_drop/drag_drop_behavior_reporter/drag_drop_behavior_reporter.h"
37 #include "core/components_ng/manager/drag_drop/utils/drag_animation_helper.h"
38 #include "core/components_ng/pattern/grid/grid_item_pattern.h"
39 #include "core/components_ng/pattern/image/image_layout_property.h"
40 #include "core/components_ng/pattern/image/image_pattern.h"
41 #include "core/components_ng/pattern/linear_layout/linear_layout_pattern.h"
42 #include "core/components_ng/pattern/list/list_item_pattern.h"
43 #include "core/components_ng/pattern/menu/menu_theme.h"
44 #include "core/components_ng/pattern/scrollable/scrollable_pattern.h"
45 #include "core/components_ng/pattern/stack/stack_pattern.h"
46 #include "core/components_ng/pattern/text/text_base.h"
47 #include "core/components_ng/pattern/text/text_pattern.h"
48 #include "core/components_ng/pattern/text_drag/text_drag_base.h"
49 #include "core/components_ng/pattern/text_drag/text_drag_pattern.h"
50 #include "core/components_ng/render/adapter/component_snapshot.h"
51 #include "core/components_ng/render/render_context.h"
52 #include "core/components_v2/inspector/inspector_constants.h"
53 
54 #include "core/pipeline_ng/pipeline_context.h"
55 
56 #ifdef WEB_SUPPORTED
57 #if !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM)
58 #include "core/components_ng/pattern/web/web_pattern.h"
59 #else
60 #include "core/components_ng/pattern/web/cross_platform/web_pattern.h"
61 #endif
62 #endif // WEB_SUPPORTED
63 
64 namespace OHOS::Ace::NG {
65 namespace {
66 constexpr int32_t PAN_FINGER = 1;
67 constexpr double PAN_DISTANCE = 5.0;
68 constexpr int32_t LONG_PRESS_DURATION = 500;
69 constexpr int32_t PREVIEW_LONG_PRESS_RECONGNIZER = 800;
70 constexpr Dimension FILTER_VALUE(0.0f);
71 constexpr float PIXELMAP_DRAG_SCALE_MULTIPLE = 1.05f;
72 constexpr int32_t PIXELMAP_ANIMATION_TIME = 800;
73 constexpr float SCALE_NUMBER = 0.95f;
74 constexpr int32_t FILTER_TIMES = 250;
75 constexpr int32_t PRE_DRAG_TIMER_DEADLINE = 50; // 50ms
76 constexpr int32_t PIXELMAP_ANIMATION_DURATION = 300;
77 constexpr float SPRING_RESPONSE = 0.416f;
78 constexpr float SPRING_DAMPING_FRACTION = 0.73f;
79 constexpr Dimension PIXELMAP_BORDER_RADIUS = 16.0_vp;
80 constexpr Dimension PREVIEW_BORDER_RADIUS = 12.0_vp;
81 constexpr float BLUR_SIGMA_SCALE = 0.57735f;
82 constexpr float SCALE_HALF = 0.5f;
83 constexpr float DEFAULT_ANIMATION_SCALE = 0.95f;
84 constexpr Dimension BADGE_RELATIVE_OFFSET = 8.0_vp;
85 constexpr float DEFAULT_OPACITY = 0.95f;
86 constexpr float MIN_OPACITY { 0.0f };
87 constexpr float MAX_OPACITY { 1.0f };
88 constexpr float MENU_DRAG_SCALE = 0.05f;
89 #if defined(PIXEL_MAP_SUPPORTED)
90 constexpr int32_t CREATE_PIXELMAP_TIME = 80;
91 #endif
92 } // namespace
93 
DragEventActuator(const WeakPtr<GestureEventHub> & gestureEventHub,PanDirection direction,int32_t fingers,float distance)94 DragEventActuator::DragEventActuator(
95     const WeakPtr<GestureEventHub>& gestureEventHub, PanDirection direction, int32_t fingers, float distance)
96     : gestureEventHub_(gestureEventHub), direction_(direction), fingers_(fingers), distance_(distance)
97 {
98     if (fingers_ < PAN_FINGER) {
99         fingers_ = PAN_FINGER;
100     }
101 
102     if (LessOrEqual(distance_, PAN_DISTANCE)) {
103         distance_ = PAN_DISTANCE;
104     }
105 
106     panRecognizer_ = MakeRefPtr<PanRecognizer>(fingers_, direction_, distance_);
107     panRecognizer_->SetGestureInfo(MakeRefPtr<GestureInfo>(GestureTypeName::DRAG, GestureTypeName::DRAG, true));
108     longPressRecognizer_ = AceType::MakeRefPtr<LongPressRecognizer>(LONG_PRESS_DURATION, fingers_, false, true);
109     longPressRecognizer_->SetGestureInfo(MakeRefPtr<GestureInfo>(GestureTypeName::DRAG, GestureTypeName::DRAG, true));
110     previewLongPressRecognizer_ =
111         AceType::MakeRefPtr<LongPressRecognizer>(PREVIEW_LONG_PRESS_RECONGNIZER, fingers_, false, true);
112     previewLongPressRecognizer_->SetGestureInfo(
113         MakeRefPtr<GestureInfo>(GestureTypeName::DRAG, GestureTypeName::DRAG, true));
114     previewLongPressRecognizer_->SetThumbnailDeadline(PRE_DRAG_TIMER_DEADLINE);
115     isNotInPreviewState_ = false;
116 }
117 
StartDragTaskForWeb(const GestureEvent & info)118 void DragEventActuator::StartDragTaskForWeb(const GestureEvent& info)
119 {
120     auto gestureInfo = const_cast<GestureEvent&>(info);
121     if (actionStart_) {
122         TAG_LOGI(AceLogTag::ACE_WEB, "DragDrop start drag task for web success");
123         actionStart_(gestureInfo);
124     } else {
125         TAG_LOGE(AceLogTag::ACE_WEB, "DragDrop start drag task for web failed,"
126             "because actionStart function is null");
127     }
128 }
129 
StartLongPressActionForWeb(bool isFloatImage)130 void DragEventActuator::StartLongPressActionForWeb(bool isFloatImage)
131 {
132     TAG_LOGW(AceLogTag::ACE_WEB, "StartLongPressActionForWeb isFloatImage:%{public}d", isFloatImage);
133     isFloatImage_ = isFloatImage;
134     if (!isReceivedLongPress_) {
135         TAG_LOGW(AceLogTag::ACE_WEB, "DragDrop not received long press action,"
136             "don't start long press action for web");
137         return;
138     }
139     if (longPressUpdate_) {
140         TAG_LOGI(AceLogTag::ACE_WEB, "DragDrop call long press update,"
141             "after update set false again");
142         longPressUpdate_(longPressInfo_);
143     } else {
144         TAG_LOGE(AceLogTag::ACE_WEB, "DragDrop long press update null");
145     }
146     isReceivedLongPress_ = false;
147 }
148 
CancelDragForWeb()149 void DragEventActuator::CancelDragForWeb()
150 {
151     if (actionCancel_) {
152         TAG_LOGD(AceLogTag::ACE_WEB, "DragDrop call action cancel success");
153         actionCancel_();
154     } else {
155         TAG_LOGE(AceLogTag::ACE_WEB, "DragDrop action cancel null");
156     }
157 }
158 
159 /**
160  * Do some nessessary check before returning the gesture recognizer collection result
161  * to parent during the hittest process. For example, if there is one drag operation
162  * already in our system, it is not allowed to start new interation for drag operation.
163  */
IsGlobalStatusSuitableForDragging()164 bool DragEventActuator::IsGlobalStatusSuitableForDragging()
165 {
166     auto pipeline = PipelineContext::GetCurrentContext();
167     CHECK_NULL_RETURN(pipeline, false);
168     auto dragDropManager = pipeline->GetDragDropManager();
169     CHECK_NULL_RETURN(dragDropManager, false);
170     if (dragDropManager->IsDragging()) {
171         TAG_LOGI(AceLogTag::ACE_DRAG, "No need to collect drag gestures result, is dragging status");
172         return false;
173     }
174 
175     if (dragDropManager->IsMSDPDragging()) {
176         TAG_LOGI(AceLogTag::ACE_DRAG, "No need to collect drag gestures result, is msdp dragging status");
177         return false;
178     }
179 
180     return true;
181 }
182 
IsSelfAndParentDragForbidden(const RefPtr<FrameNode> & frameNode) const183 bool DragEventActuator::IsSelfAndParentDragForbidden(const RefPtr<FrameNode>& frameNode) const
184 {
185     auto parent = frameNode;
186     while (parent) {
187         auto eventHub = parent->GetEventHub<EventHub>();
188         parent = parent->GetAncestorNodeOfFrame(true);
189         if (!eventHub) {
190             continue;
191         }
192         auto gestureEventHub = eventHub->GetGestureEventHub();
193         if (!gestureEventHub) {
194             continue;
195         }
196         if (gestureEventHub->IsDragForbidden()) {
197             return true;
198         }
199     }
200     return false;
201 }
202 
203 /**
204  * check the current node's status to decide if it can initiate one drag operation
205  */
IsCurrentNodeStatusSuitableForDragging(const RefPtr<FrameNode> & frameNode,const TouchRestrict & touchRestrict)206 bool DragEventActuator::IsCurrentNodeStatusSuitableForDragging(
207     const RefPtr<FrameNode>& frameNode, const TouchRestrict& touchRestrict)
208 {
209     CHECK_NULL_RETURN(frameNode, false);
210     auto gestureHub = gestureEventHub_.Upgrade();
211     CHECK_NULL_RETURN(gestureHub, false);
212 
213     if (gestureHub->IsDragForbidden() || (!frameNode->IsDraggable() && frameNode->IsCustomerSet()) ||
214         touchRestrict.inputEventType == InputEventType::AXIS || IsBelongToMultiItemNode(frameNode)) {
215         TAG_LOGI(AceLogTag::ACE_DRAG,
216             "No need to collect drag gestures result, drag forbidden set is %{public}d,"
217             "frameNode draggable is %{public}d, custom set is %{public}d",
218             gestureHub->IsDragForbidden(), frameNode->IsDraggable(), frameNode->IsCustomerSet());
219         return false;
220     }
221 
222     if (gestureHub->GetTextDraggable()) {
223         auto pattern = frameNode->GetPattern<TextBase>();
224         if (pattern && !pattern->IsSelected()) {
225             TAG_LOGI(AceLogTag::ACE_DRAG, "No need to collect drag gestures result, text is not selected.");
226             return false;
227         }
228     }
229 
230     if (IsSelfAndParentDragForbidden(frameNode)) {
231         TAG_LOGI(AceLogTag::ACE_DRAG,
232             "No need to collect drag gestures result, parent is drag forbidden.");
233         return false;
234     }
235 
236     return true;
237 }
238 
RestartDragTask(const GestureEvent & info)239 void DragEventActuator::RestartDragTask(const GestureEvent& info)
240 {
241     if (info.GetInputEventType() == InputEventType::AXIS) {
242         TAG_LOGI(AceLogTag::ACE_DRAG, "Trigger drag pan event by axis");
243         return;
244     }
245     auto gestureHub = gestureEventHub_.Upgrade();
246     CHECK_NULL_VOID(gestureHub);
247     auto frameNode = gestureHub->GetFrameNode();
248     CHECK_NULL_VOID(frameNode);
249     UpdatePreviewOptionFromModifier(frameNode);
250     auto gestureInfo = const_cast<GestureEvent&>(info);
251     if (actionStart_) {
252         TAG_LOGI(AceLogTag::ACE_DRAG, "Restart drag for lifting status");
253         actionStart_(gestureInfo);
254     }
255 }
256 
IsNotNeedShowPreviewForWeb(const RefPtr<FrameNode> & frameNode)257 bool DragEventActuator::IsNotNeedShowPreviewForWeb(const RefPtr<FrameNode>& frameNode)
258 {
259 #ifdef WEB_SUPPORTED
260     bool isNotNeedShowPreview = false;
261     if (frameNode && frameNode->GetTag() == V2::WEB_ETS_TAG) {
262         auto webPattern = frameNode->GetPattern<WebPattern>();
263         CHECK_NULL_RETURN(webPattern, false);
264         isNotNeedShowPreview = webPattern->IsPreviewMenuNotNeedShowPreview();
265     }
266     return isNotNeedShowPreview;
267 #else
268     return false;
269 #endif
270 }
271 
272 // this pan cancel only for no drag action.
HandleOnPanActionCancel()273 void DragEventActuator::HandleOnPanActionCancel()
274 {
275     bool isAllowedDrag = IsAllowedDrag();
276     CHECK_NULL_VOID(!isAllowedDrag);
277     CHECK_NULL_VOID(userCallback_);
278     isDragPrepareFinish_ = false;
279     auto userActionCancel = userCallback_->GetActionCancelEventFunc();
280     if (userActionCancel) {
281         userActionCancel();
282     }
283 }
284 
OnCollectTouchTarget(const OffsetF & coordinateOffset,const TouchRestrict & touchRestrict,const GetEventTargetImpl & getEventTargetImpl,TouchTestResult & result,ResponseLinkResult & responseLinkResult)285 void DragEventActuator::OnCollectTouchTarget(const OffsetF& coordinateOffset, const TouchRestrict& touchRestrict,
286     const GetEventTargetImpl& getEventTargetImpl, TouchTestResult& result, ResponseLinkResult& responseLinkResult)
287 {
288     CHECK_NULL_VOID(userCallback_);
289     isDragUserReject_ = false;
290     auto gestureHub = gestureEventHub_.Upgrade();
291     CHECK_NULL_VOID(gestureHub);
292     auto frameNode = gestureHub->GetFrameNode();
293     CHECK_NULL_VOID(frameNode);
294     auto pipeline = PipelineContext::GetCurrentContext();
295     CHECK_NULL_VOID(pipeline);
296     auto dragDropManager = pipeline->GetDragDropManager();
297     CHECK_NULL_VOID(dragDropManager);
298     dragDropManager->SetPrepareDragFrameNode(nullptr);
299     dragDropManager->SetIsDragNodeNeedClean(false);
300     if (!IsGlobalStatusSuitableForDragging() || !IsCurrentNodeStatusSuitableForDragging(frameNode, touchRestrict)) {
301         return;
302     }
303     auto focusHub = frameNode->GetFocusHub();
304     bool hasContextMenuUsingGesture = focusHub == nullptr
305                               ? false : focusHub->FindContextMenuOnKeyEvent(OnKeyEventType::CONTEXT_MENU);
306     dragDropManager->SetPreDragStatus(PreDragStatus::ACTION_DETECTING_STATUS);
307     auto actionStart = [weak = WeakClaim(this), this](GestureEvent& info) {
308         auto containerId = Container::CurrentId();
309         TAG_LOGI(AceLogTag::ACE_DRAG, "Trigger drag action start.");
310         auto actuator = weak.Upgrade();
311         if (!actuator) {
312             DragEventActuator::ResetDragStatus();
313             return;
314         }
315         auto pipeline = PipelineContext::GetCurrentContext();
316         CHECK_NULL_VOID(pipeline);
317         auto dragDropManager = pipeline->GetDragDropManager();
318         CHECK_NULL_VOID(dragDropManager);
319         actuator->ResetResponseRegion();
320         actuator->SetGatherNode(nullptr);
321         actuator->isDragPrepareFinish_ = false;
322         if (dragDropManager->IsDragging() || dragDropManager->IsMSDPDragging()) {
323             DragDropBehaviorReporterTrigger trigger(DragReporterPharse::DRAG_START, containerId);
324             DragDropBehaviorReporter::GetInstance().UpdateDragStartResult(DragStartResult::REPEAT_DRAG_FAIL);
325             TAG_LOGI(AceLogTag::ACE_DRAG,
326                 "It's already dragging now, dragging is %{public}d, MSDP dragging is %{public}d",
327                 dragDropManager->IsDragging(), dragDropManager->IsMSDPDragging());
328             return;
329         }
330         if (dragDropManager->GetPreDragStatus() >= PreDragStatus::PREVIEW_LANDING_FINISHED) {
331             TAG_LOGI(AceLogTag::ACE_DRAG, "Drag preview is landing finished, stop dragging.");
332             return;
333         }
334         if (dragDropManager->IsDragNodeNeedClean()) {
335             TAG_LOGI(AceLogTag::ACE_DRAG, "Drag node have been cleaned by backpress, stop dragging.");
336             return;
337         }
338         dragDropManager->SetHasGatherNode(false);
339         dragDropManager->ResetDragging(DragDropMgrState::ABOUT_TO_PREVIEW);
340         auto gestureHub = actuator->gestureEventHub_.Upgrade();
341         CHECK_NULL_VOID(gestureHub);
342         auto frameNode = gestureHub->GetFrameNode();
343         CHECK_NULL_VOID(frameNode);
344         auto renderContext = frameNode->GetRenderContext();
345         if (info.GetSourceDevice() != SourceType::MOUSE) {
346             if (gestureHub->GetTextDraggable()) {
347                 auto pattern = frameNode->GetPattern<TextBase>();
348                 CHECK_NULL_VOID(pattern);
349                 if (!pattern->IsSelected()) {
350                     dragDropManager->ResetDragging();
351                     gestureHub->SetIsTextDraggable(false);
352                     TAG_LOGW(AceLogTag::ACE_DRAG, "Text is not selected, stop dragging.");
353                     DragDropBehaviorReporterTrigger trigger(DragReporterPharse::DRAG_START, containerId);
354                     DragDropBehaviorReporter::GetInstance().UpdateDragStartResult(DragStartResult::TEXT_NOT_SELECT);
355                     return;
356                 }
357                 if (gestureHub->GetIsTextDraggable()) {
358                     SetTextPixelMap(gestureHub);
359                 } else {
360                     gestureHub->SetPixelMap(nullptr);
361                 }
362             } else {
363                 HideEventColumn();
364                 if (gestureHub->GetTextDraggable()) {
365                     HideTextAnimation(true, info.GetGlobalLocation().GetX(), info.GetGlobalLocation().GetY());
366                 } else {
367                     HideFilter();
368                     RecordMenuWrapperNodeForDrag(frameNode->GetId());
369                     SubwindowManager::GetInstance()->HideMenuNG(false, true);
370                 }
371             }
372             if (!gestureHub->GetTextDraggable()) {
373                 frameNode->SetOptionsAfterApplied(actuator->GetOptionsAfterApplied());
374             }
375         }
376 
377         if (info.GetSourceDevice() == SourceType::MOUSE) {
378             frameNode->MarkModifyDone();
379             dragDropManager->SetIsShowBadgeAnimation(true);
380             auto pattern = frameNode->GetPattern<TextBase>();
381             if (gestureHub->GetTextDraggable() && pattern) {
382                 if (!pattern->IsSelected() || pattern->GetMouseStatus() == MouseStatus::MOVE) {
383                     dragDropManager->ResetDragging();
384                     gestureHub->SetIsTextDraggable(false);
385                     TAG_LOGW(AceLogTag::ACE_DRAG, "Text isSelected: %{public}d, stop dragging.", pattern->IsSelected());
386                     DragDropBehaviorReporterTrigger trigger(DragReporterPharse::DRAG_START, containerId);
387                     DragDropBehaviorReporter::GetInstance().UpdateDragStartResult(DragStartResult::TEXT_NOT_SELECT);
388                     return;
389                 }
390                 if (pattern->BetweenSelectedPosition(info.GetGlobalLocation())) {
391                     gestureHub->SetIsTextDraggable(true);
392                     if (textDragCallback_) {
393                         textDragCallback_(info.GetGlobalLocation());
394                     }
395                 } else if (!gestureHub->GetIsTextDraggable()) {
396                     gestureHub->SetPixelMap(nullptr);
397                 }
398             } else {
399                 HideEventColumn();
400                 HidePixelMap(true, info.GetGlobalLocation().GetX(), info.GetGlobalLocation().GetY());
401                 HideFilter();
402                 RecordMenuWrapperNodeForDrag(frameNode->GetId());
403                 SubwindowManager::GetInstance()->HideMenuNG(false, true);
404                 actuator->UpdatePreviewOptionFromModifier(frameNode);
405             }
406         }
407         if (gestureHub->GetTextDraggable() && !gestureHub->GetIsTextDraggable()) {
408             TAG_LOGI(AceLogTag::ACE_DRAG, "Text category component does not meet the drag condition, forbidden drag.");
409             dragDropManager->ResetDragging();
410             return;
411         }
412        // Trigger drag start event set by user.
413         CHECK_NULL_VOID(actuator->userCallback_);
414         auto userActionStart = actuator->userCallback_->GetActionStartEventFunc();
415         if (userActionStart) {
416             TAG_LOGI(AceLogTag::ACE_DRAG, "Trigger drag start event set by user.");
417             userActionStart(info);
418         }
419         // Trigger custom drag start event
420         CHECK_NULL_VOID(actuator->customCallback_);
421         auto customActionStart = actuator->customCallback_->GetActionStartEventFunc();
422         if (customActionStart) {
423             customActionStart(info);
424         }
425     };
426     actionStart_ = actionStart;
427     panRecognizer_->SetOnActionStart(actionStart);
428 
429     auto actionUpdate = [weak = WeakClaim(this)](GestureEvent& info) {
430         TAG_LOGD(AceLogTag::ACE_DRAG, "DragEvent panRecognizer onActionUpdate.");
431         auto actuator = weak.Upgrade();
432         CHECK_NULL_VOID(actuator);
433         CHECK_NULL_VOID(actuator->userCallback_);
434         auto userActionUpdate = actuator->userCallback_->GetActionUpdateEventFunc();
435         if (userActionUpdate) {
436             userActionUpdate(info);
437         }
438         CHECK_NULL_VOID(actuator->customCallback_);
439         auto customActionUpdate = actuator->customCallback_->GetActionUpdateEventFunc();
440         if (customActionUpdate) {
441             customActionUpdate(info);
442         }
443     };
444     panRecognizer_->SetOnActionUpdate(actionUpdate);
445 
446     auto actionEnd = [weak = WeakClaim(this)](GestureEvent& info) {
447         TAG_LOGI(AceLogTag::ACE_DRAG, "Trigger drag action end.");
448         auto pipelineContext = PipelineContext::GetCurrentContext();
449         CHECK_NULL_VOID(pipelineContext);
450         auto dragDropManager = pipelineContext->GetDragDropManager();
451         CHECK_NULL_VOID(dragDropManager);
452         dragDropManager->SetHasGatherNode(false);
453         if (dragDropManager->IsAboutToPreview()) {
454             dragDropManager->ResetDragging();
455         }
456         dragDropManager->SetIsDragNodeNeedClean(false);
457         auto actuator = weak.Upgrade();
458         if (!actuator) {
459             auto overlayManager = pipelineContext->GetOverlayManager();
460             CHECK_NULL_VOID(overlayManager);
461             overlayManager->RemovePixelMap();
462             return;
463         }
464         CHECK_NULL_VOID(actuator->userCallback_);
465         auto gestureHub = actuator->gestureEventHub_.Upgrade();
466         CHECK_NULL_VOID(gestureHub);
467         actuator->HideEventColumn();
468         if (gestureHub->GetTextDraggable()) {
469             actuator->textPixelMap_ = nullptr;
470             actuator->HideTextAnimation();
471         } else {
472             actuator->HidePixelMap();
473         }
474         auto userActionEnd = actuator->userCallback_->GetActionEndEventFunc();
475         if (userActionEnd) {
476             TAG_LOGI(AceLogTag::ACE_DRAG, "Trigger drag end event set by user.");
477             userActionEnd(info);
478         }
479         CHECK_NULL_VOID(actuator->customCallback_);
480         auto customActionEnd = actuator->customCallback_->GetActionEndEventFunc();
481         if (customActionEnd) {
482             customActionEnd(info);
483         }
484         actuator->SetIsNotInPreviewState(false);
485     };
486     panRecognizer_->SetOnActionEnd(actionEnd);
487     auto actionCancel = [weak = WeakClaim(this), touchSourceType = touchRestrict.sourceType]() {
488         TAG_LOGD(AceLogTag::ACE_DRAG, "Drag event has been canceled.");
489         auto pipelineContext = PipelineContext::GetCurrentContext();
490         CHECK_NULL_VOID(pipelineContext);
491         auto dragDropManager = pipelineContext->GetDragDropManager();
492         CHECK_NULL_VOID(dragDropManager);
493         dragDropManager->SetHasGatherNode(false);
494         auto actuator = weak.Upgrade();
495         if (!actuator) {
496             DragEventActuator::ResetDragStatus();
497             return;
498         }
499         actuator->isDragPrepareFinish_ = false;
500         auto gestureHub = actuator->gestureEventHub_.Upgrade();
501         CHECK_NULL_VOID(gestureHub);
502         auto frameNode = gestureHub->GetFrameNode();
503         CHECK_NULL_VOID(frameNode);
504         auto longPressRecognizer = actuator->longPressRecognizer_;
505         if (touchSourceType != SourceType::MOUSE && longPressRecognizer &&
506             longPressRecognizer->GetGestureState() != RefereeState::SUCCEED &&
507             longPressRecognizer->GetGestureState() != RefereeState::SUCCEED_BLOCKED) {
508             return;
509         }
510         actuator->ResetResponseRegion();
511         actuator->SetGatherNode(nullptr);
512         if (actuator->GetIsNotInPreviewState() && !gestureHub->GetTextDraggable()) {
513             DragEventActuator::ExecutePreDragAction(PreDragStatus::ACTION_CANCELED_BEFORE_DRAG, frameNode);
514         }
515         if (!gestureHub->GetBindMenuStatus().IsNotNeedShowPreview() &&
516             !actuator->IsNotNeedShowPreviewForWeb(frameNode)) {
517             if (gestureHub->GetTextDraggable()) {
518                 if (gestureHub->GetIsTextDraggable()) {
519                     actuator->HideEventColumn();
520                     actuator->textPixelMap_ = nullptr;
521                     actuator->HideTextAnimation();
522                 }
523             } else {
524                 auto renderContext = frameNode->GetRenderContext();
525                 BorderRadiusProperty borderRadius;
526                 if (renderContext->GetBorderRadius().has_value()) {
527                     borderRadius.UpdateWithCheck(renderContext->GetBorderRadius().value());
528                 }
529                 borderRadius.multiValued = false;
530                 AnimationOption option;
531                 option.SetDuration(PIXELMAP_ANIMATION_DURATION);
532                 option.SetCurve(Curves::FRICTION);
533                 AnimationUtils::Animate(
534                     option,
535                     [renderContext_ = renderContext, borderRadius_ = borderRadius]() {
536                         renderContext_->UpdateBorderRadius(borderRadius_);
537                     },
538                     option.GetOnFinishEvent());
539                 actuator->HidePixelMap();
540                 actuator->HideFilter();
541             }
542         } else {
543             if (actuator->panRecognizer_->getDeviceType() == SourceType::MOUSE) {
544                 if (!gestureHub->GetTextDraggable()) {
545                     actuator->HideEventColumn();
546                     actuator->HidePixelMap();
547                     actuator->HideFilter();
548                 }
549             }
550         }
551         actuator->SetIsNotInPreviewState(false);
552         CHECK_NULL_VOID(actuator->userCallback_);
553         auto userActionCancel = actuator->userCallback_->GetActionCancelEventFunc();
554         if (userActionCancel) {
555             userActionCancel();
556         }
557         CHECK_NULL_VOID(actuator->customCallback_);
558         auto customActionCancel = actuator->customCallback_->GetActionCancelEventFunc();
559         if (customActionCancel) {
560             customActionCancel();
561         }
562     };
563     auto panOnReject = [weak = WeakClaim(this)]() {
564         TAG_LOGI(AceLogTag::ACE_DRAG, "Trigger pan onReject");
565         auto actuator = weak.Upgrade();
566         CHECK_NULL_VOID(actuator);
567         auto gestureHub = actuator->gestureEventHub_.Upgrade();
568         CHECK_NULL_VOID(gestureHub);
569         actuator->ResetResponseRegion();
570         auto pipelineContext = PipelineContext::GetCurrentContext();
571         CHECK_NULL_VOID(pipelineContext);
572         auto manager = pipelineContext->GetOverlayManager();
573         CHECK_NULL_VOID(manager);
574         if (manager->IsGatherWithMenu() || !actuator->GetGatherNode()) {
575             return;
576         }
577         TAG_LOGI(AceLogTag::ACE_DRAG, "Pan reject, try remove gather node");
578         actuator->SetGatherNode(nullptr);
579         actuator->ClearGatherNodeChildrenInfo();
580         auto dragDropManager = pipelineContext->GetDragDropManager();
581         CHECK_NULL_VOID(dragDropManager);
582         auto preDragStatus = dragDropManager->GetPreDragStatus();
583         if (preDragStatus <= PreDragStatus::READY_TO_TRIGGER_DRAG_ACTION) {
584             manager->RemoveGatherNode();
585         } else {
586             manager->RemoveGatherNodeWithAnimation();
587         }
588     };
589     panRecognizer_->SetOnReject(panOnReject);
590     panRecognizer_->SetIsForDrag(true);
591     panRecognizer_->SetMouseDistance(DRAG_PAN_DISTANCE_MOUSE.ConvertToPx());
592     actionCancel_ = actionCancel;
593     panRecognizer_->SetCoordinateOffset(Offset(coordinateOffset.GetX(), coordinateOffset.GetY()));
594     panRecognizer_->SetGetEventTargetImpl(getEventTargetImpl);
595     auto panOnActionCancel = [weak = WeakClaim(this)]() {
596         auto actuator = weak.Upgrade();
597         CHECK_NULL_VOID(actuator);
598         actuator->HandleOnPanActionCancel();
599     };
600     panRecognizer_->SetOnActionCancel(panOnActionCancel);
601     if (touchRestrict.sourceType == SourceType::MOUSE) {
602         std::vector<RefPtr<NGGestureRecognizer>> recognizers { panRecognizer_ };
603         SequencedRecognizer_ = AceType::MakeRefPtr<SequencedRecognizer>(recognizers);
604         SequencedRecognizer_->RemainChildOnResetStatus();
605         SequencedRecognizer_->SetCoordinateOffset(Offset(coordinateOffset.GetX(), coordinateOffset.GetY()));
606         SequencedRecognizer_->SetOnActionCancel(actionCancel);
607         SequencedRecognizer_->SetGetEventTargetImpl(getEventTargetImpl);
608         result.emplace_back(SequencedRecognizer_);
609         return;
610     }
611     auto longPressUpdateValue = [weak = WeakClaim(this), hasContextMenuUsingGesture = hasContextMenuUsingGesture](
612                                     GestureEvent& info) {
613         TAG_LOGI(AceLogTag::ACE_DRAG, "Trigger long press for 500ms.");
614         auto actuator = weak.Upgrade();
615         CHECK_NULL_VOID(actuator);
616         actuator->SetIsNotInPreviewState(true);
617         if (actuator->userCallback_ && !actuator->isDragPrepareFinish_) {
618             auto customLongPress = actuator->userCallback_->GetLongPressEventFunc();
619             if (customLongPress) {
620                 customLongPress(info);
621             }
622         }
623         actuator->isDragPrepareFinish_ = true;
624         auto pipelineContext = PipelineContext::GetCurrentContext();
625         CHECK_NULL_VOID(pipelineContext);
626         auto dragDropManager = pipelineContext->GetDragDropManager();
627         CHECK_NULL_VOID(dragDropManager);
628         dragDropManager->SetIsShowBadgeAnimation(true);
629         auto gestureHub = actuator->gestureEventHub_.Upgrade();
630         CHECK_NULL_VOID(gestureHub);
631         auto frameNode = gestureHub->GetFrameNode();
632         CHECK_NULL_VOID(frameNode);
633         dragDropManager->SetPrepareDragFrameNode(frameNode);
634         if (!gestureHub->GetTextDraggable()) {
635             // For the drag initiacating from long press gesture, the preview option set by the modifier
636             // should also be applied in floating pharse, so we need to update the preview option here.
637             actuator->UpdatePreviewOptionFromModifier(frameNode);
638             DragEventActuator::ExecutePreDragAction(PreDragStatus::READY_TO_TRIGGER_DRAG_ACTION, frameNode);
639         }
640         if (hasContextMenuUsingGesture) {
641             actuator->SetDragDampStartPointInfo(info.GetGlobalPoint(), info.GetPointerId());
642         }
643     };
644     longPressRecognizer_->SetOnAction(longPressUpdateValue);
645     auto longPressUpdate = [weak = WeakClaim(this), hasContextMenuUsingGesture = hasContextMenuUsingGesture](
646                                 GestureEvent& info) {
647         TAG_LOGI(AceLogTag::ACE_DRAG, "Trigger long press for 800ms.");
648         auto pipeline = PipelineContext::GetCurrentContext();
649         CHECK_NULL_VOID(pipeline);
650 
651         auto overlayManager = pipeline->GetOverlayManager();
652         CHECK_NULL_VOID(overlayManager);
653         if (overlayManager->GetHasPixelMap()) {
654             return;
655         }
656 
657         auto dragDropManager = pipeline->GetDragDropManager();
658         CHECK_NULL_VOID(dragDropManager);
659         if (dragDropManager->IsAboutToPreview() || dragDropManager->IsDragging() ||
660             dragDropManager->IsDragNodeNeedClean()) {
661             TAG_LOGI(AceLogTag::ACE_DRAG, "No need to show drag preview, is about to preview: %{public}d,"
662                 "is dragging: %{public}d, is need clean drag node: %{public}d",
663                 dragDropManager->IsAboutToPreview(), dragDropManager->IsDragging(),
664                 dragDropManager->IsDragNodeNeedClean());
665             return;
666         }
667         auto actuator = weak.Upgrade();
668         CHECK_NULL_VOID(actuator);
669         actuator->isOnBeforeLiftingAnimation = false;
670         auto gestureHub = actuator->gestureEventHub_.Upgrade();
671         CHECK_NULL_VOID(gestureHub);
672         if (gestureHub->GetBindMenuStatus().IsNotNeedShowPreview()) {
673             TAG_LOGI(AceLogTag::ACE_DRAG, "Not need to show drag preview because of bind context menu");
674             return;
675         }
676         auto frameNode = gestureHub->GetFrameNode();
677         CHECK_NULL_VOID(frameNode);
678         auto dragPreviewOption = frameNode->GetDragPreviewOption();
679         if (!dragPreviewOption.isDragPreviewEnabled || dragPreviewOption.isLiftingDisabled) {
680             TAG_LOGI(AceLogTag::ACE_DRAG, "Not need to show drag preview because disable drag preview");
681             return;
682         }
683         if (gestureHub->GetTextDraggable()) {
684             actuator->SetIsNotInPreviewState(false);
685             if (gestureHub->GetIsTextDraggable()) {
686                 actuator->SetTextAnimation(gestureHub, info.GetGlobalLocation());
687                 actuator->SetEventColumn(actuator);
688             }
689             return;
690         }
691         if (!actuator->isFloatImage_) {
692             actuator->isFloatImage_ = true;
693             return;
694         }
695 
696         bool isAllowedDrag = actuator->IsAllowedDrag();
697         if (!isAllowedDrag) {
698             actuator->longPressInfo_ = info;
699             actuator->isReceivedLongPress_ = true;
700             TAG_LOGD(AceLogTag::ACE_WEB, "DragDrop long press and info received");
701             return;
702         }
703         dragDropManager->SetPrepareDragFrameNode(frameNode);
704         if (frameNode->GetTag() == V2::WEB_ETS_TAG) {
705             actuator->SetFilter(actuator);
706         }
707         auto manager = pipeline->GetOverlayManager();
708         CHECK_NULL_VOID(manager);
709         actuator->SetIsNotInPreviewState(false);
710         actuator->SetGatherNodeAboveFilter(actuator);
711         actuator->SetPixelMap(actuator);
712         auto motion = AceType::MakeRefPtr<ResponsiveSpringMotion>(SPRING_RESPONSE, SPRING_DAMPING_FRACTION, 0);
713         auto column = manager->GetPixelMapNode();
714         CHECK_NULL_VOID(column);
715 
716         auto imageNode = AceType::DynamicCast<FrameNode>(column->GetFirstChild());
717         CHECK_NULL_VOID(imageNode);
718         auto imageContext = imageNode->GetRenderContext();
719         CHECK_NULL_VOID(imageContext);
720         if (actuator->IsNeedGather()) {
721             DragAnimationHelper::PlayGatherAnimation(imageNode, manager);
722             actuator->ShowPreviewBadgeAnimation(actuator, manager);
723         }
724         AnimationOption option;
725         option.SetDuration(PIXELMAP_ANIMATION_TIME);
726         option.SetCurve(motion);
727         DragEventActuator::ExecutePreDragAction(PreDragStatus::PREVIEW_LIFT_STARTED);
728         dragDropManager->SetDraggingPointer(info.GetPointerId());
729         dragDropManager->SetDraggingPressedState(true);
730         option.SetOnFinishEvent(
731             [id = Container::CurrentId(), pointerId = info.GetPointerId(), hasContextMenuUsingGesture]() {
732                 ContainerScope scope(id);
733                 auto pipeline = PipelineContext::GetCurrentContext();
734                 CHECK_NULL_VOID(pipeline);
735                 auto dragDropManager = pipeline->GetDragDropManager();
736                 CHECK_NULL_VOID(dragDropManager);
737                 if (dragDropManager->IsDraggingPressed(pointerId) || hasContextMenuUsingGesture) {
738                     DragEventActuator::ExecutePreDragAction(PreDragStatus::PREVIEW_LIFT_FINISHED);
739                 }
740             });
741         AnimationUtils::Animate(
742             option,
743             [imageContext]() {
744                 imageContext->UpdateTransformScale({ PIXELMAP_DRAG_SCALE_MULTIPLE, PIXELMAP_DRAG_SCALE_MULTIPLE });
745             },
746             option.GetOnFinishEvent());
747         actuator->SetEventColumn(actuator);
748     };
749     auto longPressCancel = [weak = WeakClaim(this)] {
750         // remove drag overlay info by Cancel event.
751         TAG_LOGD(AceLogTag::ACE_DRAG, "Long press event has been canceled.");
752         auto actuator = weak.Upgrade();
753         CHECK_NULL_VOID(actuator);
754         actuator->HideEventColumn();
755         actuator->HidePixelMap(true, 0, 0, false);
756         actuator->HideFilter();
757         actuator->SetIsNotInPreviewState(false);
758     };
759     longPressUpdate_ = longPressUpdate;
760     auto preDragCallback = [weak = WeakClaim(this)](Offset point) {
761         auto actuator = weak.Upgrade();
762         CHECK_NULL_VOID(actuator);
763         auto gestureHub = actuator->gestureEventHub_.Upgrade();
764         CHECK_NULL_VOID(gestureHub);
765         auto frameNode = gestureHub->GetFrameNode();
766         CHECK_NULL_VOID(frameNode);
767         if (!gestureHub->GetTextDraggable()) {
768             DragEventActuator::ExecutePreDragAction(PreDragStatus::ACTION_DETECTING_STATUS, frameNode);
769         }
770     };
771     previewLongPressRecognizer_->SetOnAction(longPressUpdate);
772     previewLongPressRecognizer_->SetOnActionCancel(longPressCancel);
773     previewLongPressRecognizer_->SetThumbnailCallback(std::move(preDragCallback));
774     previewLongPressRecognizer_->SetGestureHub(gestureEventHub_);
775     auto eventHub = frameNode->GetEventHub<EventHub>();
776     CHECK_NULL_VOID(eventHub);
777     bool isAllowedDrag = gestureHub->IsAllowedDrag(eventHub);
778     if (!longPressRecognizer_->HasThumbnailCallback() && isAllowedDrag) {
779         auto callback = [weakPtr = gestureEventHub_, weak = WeakClaim(this)](Offset point) {
780             TAG_LOGI(AceLogTag::ACE_DRAG, "Trigger 150ms timer Thumbnail callback.");
781             auto gestureHub = weakPtr.Upgrade();
782             CHECK_NULL_VOID(gestureHub);
783             auto frameNode = gestureHub->GetFrameNode();
784             CHECK_NULL_VOID(frameNode);
785             auto pipeline = PipelineContext::GetCurrentContext();
786             CHECK_NULL_VOID(pipeline);
787             auto actuator = weak.Upgrade();
788             CHECK_NULL_VOID(actuator);
789             auto dragPreviewInfo = frameNode->GetDragPreview();
790             if (dragPreviewInfo.inspectorId != "") {
791                 TAG_LOGI(AceLogTag::ACE_DRAG, "Get thumbnail through inspectorId.");
792                 auto previewPixelMap = GetPreviewPixelMap(dragPreviewInfo.inspectorId, frameNode);
793                 gestureHub->SetPixelMap(previewPixelMap);
794                 gestureHub->SetDragPreviewPixelMap(previewPixelMap);
795                 actuator->PrepareFinalPixelMapForDragThroughTouch(previewPixelMap, false);
796             } else if (dragPreviewInfo.pixelMap != nullptr) {
797                 TAG_LOGI(AceLogTag::ACE_DRAG, "Get thumbnail through pixelMap.");
798                 gestureHub->SetPixelMap(dragPreviewInfo.pixelMap);
799                 gestureHub->SetDragPreviewPixelMap(dragPreviewInfo.pixelMap);
800                 actuator->PrepareFinalPixelMapForDragThroughTouch(dragPreviewInfo.pixelMap, false);
801             } else if (dragPreviewInfo.customNode || (dragPreviewInfo.delayCreating && dragPreviewInfo.buildFunc)) {
802                 if (!dragPreviewInfo.customNode && dragPreviewInfo.delayCreating && dragPreviewInfo.buildFunc) {
803                     dragPreviewInfo.customNode = dragPreviewInfo.buildFunc();
804                 }
805                 frameNode->SetDragPreview(dragPreviewInfo);
806 #if defined(PIXEL_MAP_SUPPORTED)
807                 TAG_LOGI(AceLogTag::ACE_DRAG, "Get thumbnail through customNode.");
808                 auto callback = [id = Container::CurrentId(), pipeline, gestureHub, weak]
809                     (std::shared_ptr<Media::PixelMap> pixelMap, int32_t arg, std::function<void()> finishCallback) {
810                     ContainerScope scope(id);
811                     CHECK_NULL_VOID(pipeline);
812                     auto taskScheduler = pipeline->GetTaskExecutor();
813                     CHECK_NULL_VOID(taskScheduler);
814                     taskScheduler->PostTask(
815                         [finishCallback]() {
816                             if (finishCallback) {
817                                 finishCallback();
818                             }
819                         },
820                         TaskExecutor::TaskType::UI, "ArkUIDragRemoveCustomNode");
821                     if (pixelMap != nullptr) {
822                         auto customPixelMap = PixelMap::CreatePixelMap(reinterpret_cast<void*>(&pixelMap));
823                         taskScheduler->PostTask(
824                             [gestureHub, customPixelMap, weak]() {
825                                 CHECK_NULL_VOID(gestureHub);
826                                 gestureHub->SetPixelMap(customPixelMap);
827                                 gestureHub->SetDragPreviewPixelMap(customPixelMap);
828                                 auto actuator = weak.Upgrade();
829                                 CHECK_NULL_VOID(actuator);
830                                 actuator->PrepareFinalPixelMapForDragThroughTouch(customPixelMap, true);
831                             },
832                             TaskExecutor::TaskType::UI, "ArkUIDragSetCustomPixelMap");
833                     } else {
834                         TAG_LOGI(AceLogTag::ACE_DRAG, "PixelMap is null.");
835                         DragDropBehaviorReporter::GetInstance().UpdateDragStartResult(DragStartResult::SNAPSHOT_FAIL);
836                     }
837                 };
838                 SnapshotParam param;
839                 param.delay = CREATE_PIXELMAP_TIME;
840                 param.checkImageStatus = true;
841                 param.options.waitUntilRenderFinished = true;
842                 OHOS::Ace::NG::ComponentSnapshot::Create(
843                     dragPreviewInfo.customNode, std::move(callback), true, param);
844                 gestureHub->PrintBuilderNode(dragPreviewInfo.customNode);
845 #endif
846             } else {
847                 actuator->GetThumbnailPixelMapAsync(gestureHub);
848             }
849             auto dragPreviewOption = frameNode->GetDragPreviewOption();
850             auto longPressRecognizer = actuator->longPressRecognizer_;
851             if (longPressRecognizer && longPressRecognizer->GetGestureDisposal() != GestureDisposal::REJECT &&
852                 !dragPreviewOption.isLiftingDisabled) {
853                 if (!CreateGatherNode(actuator)) {
854                     actuator->isOnBeforeLiftingAnimation = false;
855                     return;
856                 }
857                 actuator->isOnBeforeLiftingAnimation = true;
858                 DragAnimationHelper::PlayGatherAnimationBeforeLifting(actuator);
859                 DragAnimationHelper::PlayNodeAnimationBeforeLifting(frameNode);
860                 actuator->SetResponseRegionFull();
861             } else {
862                 actuator->isOnBeforeLiftingAnimation = false;
863             }
864         };
865 
866         longPressRecognizer_->SetThumbnailCallback(std::move(callback));
867     }
868     std::vector<RefPtr<NGGestureRecognizer>> recognizers { longPressRecognizer_, panRecognizer_ };
869     SequencedRecognizer_ = AceType::MakeRefPtr<SequencedRecognizer>(recognizers);
870     SequencedRecognizer_->RemainChildOnResetStatus();
871     previewLongPressRecognizer_->SetCoordinateOffset(Offset(coordinateOffset.GetX(), coordinateOffset.GetY()));
872     previewLongPressRecognizer_->SetGetEventTargetImpl(getEventTargetImpl);
873     longPressRecognizer_->SetCoordinateOffset(Offset(coordinateOffset.GetX(), coordinateOffset.GetY()));
874     longPressRecognizer_->SetGetEventTargetImpl(getEventTargetImpl);
875     SequencedRecognizer_->SetCoordinateOffset(Offset(coordinateOffset.GetX(), coordinateOffset.GetY()));
876     SequencedRecognizer_->SetOnActionCancel(actionCancel);
877     SequencedRecognizer_->SetGetEventTargetImpl(getEventTargetImpl);
878     SequencedRecognizer_->SetIsEventHandoverNeeded(true);
879     result.emplace_back(SequencedRecognizer_);
880     result.emplace_back(previewLongPressRecognizer_);
881 }
882 
ResetDragStatus()883 void DragEventActuator::ResetDragStatus()
884 {
885     auto pipelineContext = PipelineContext::GetCurrentContext();
886     CHECK_NULL_VOID(pipelineContext);
887     auto overlayManager = pipelineContext->GetOverlayManager();
888     CHECK_NULL_VOID(overlayManager);
889     overlayManager->RemovePreviewBadgeNode();
890     overlayManager->RemoveGatherNode();
891     overlayManager->RemovePixelMap();
892     overlayManager->RemoveEventColumn();
893 }
894 
SetDragDampStartPointInfo(const Point & point,int32_t pointerId)895 void DragEventActuator::SetDragDampStartPointInfo(const Point& point, int32_t pointerId)
896 {
897     auto pipeline = PipelineContext::GetCurrentContext();
898     CHECK_NULL_VOID(pipeline);
899     auto dragDropManager = pipeline->GetDragDropManager();
900     CHECK_NULL_VOID(dragDropManager);
901     dragDropManager->ResetContextMenuDragPosition();
902     dragDropManager->SetDragDampStartPoint(point);
903     dragDropManager->SetDraggingPointer(pointerId);
904     isRedragStart_ = false;
905 }
906 
HandleDragDampingMove(const Point & point,int32_t pointerId,bool isRedragStart)907 void DragEventActuator::HandleDragDampingMove(const Point& point, int32_t pointerId, bool isRedragStart)
908 {
909     auto pipeline = PipelineContext::GetCurrentContext();
910     CHECK_NULL_VOID(pipeline);
911     auto dragDropManager = pipeline->GetDragDropManager();
912     CHECK_NULL_VOID(dragDropManager);
913     auto overlayManager = pipeline->GetOverlayManager();
914     CHECK_NULL_VOID(overlayManager);
915     if (dragDropManager->IsAboutToPreview() ||
916         dragDropManager->IsDragging() || !dragDropManager->IsSameDraggingPointer(pointerId)) {
917         return;
918     }
919     auto startPoint = dragDropManager->GetDragDampStartPoint();
920     //get the number with VP unit
921     auto distance = SystemProperties::GetDragStartPanDistanceThreshold();
922     auto dragPanDistance = Dimension(distance, DimensionUnit::VP).ConvertToPx();
923     auto dragStartDampingRatio = SystemProperties::GetDragStartDampingRatio();
924     auto dragTotalDistance = dragDropManager->GetUpdateDragMovePosition();
925     auto delta = Offset(dragTotalDistance.GetX(), dragTotalDistance.GetY());
926     // delta.GetDistance(): pixelMap real move distance
927     if (delta.GetDistance() > dragPanDistance * dragStartDampingRatio) {
928         if (dragDropManager->GetDampingOverflowCount() == 1) {
929             return;
930         }
931         dragDropManager->SetDampingOverflowCount();
932     }
933     // linear decrease for menu scale from 100% to 95% within drag damping range
934     auto previewMenuSacle = 1.0f - delta.GetDistance() / (dragPanDistance * dragStartDampingRatio) * MENU_DRAG_SCALE;
935     auto updateOffset =
936         OffsetF(dragStartDampingRatio * point.GetX() + (1 - dragStartDampingRatio) * startPoint.GetX(),
937             dragStartDampingRatio * point.GetY() + (1 - dragStartDampingRatio) * startPoint.GetY());
938     auto menuWrapperNode = dragDropManager->GetMenuWrapperNode();
939     auto menuWrapperId = menuWrapperNode ? menuWrapperNode->GetId() : -1;
940     if (isRedragStart && !isRedragStart_) {
941         isRedragStart_ = true;
942         SubwindowManager::GetInstance()->UpdateHideMenuOffsetNG(updateOffset, previewMenuSacle, true, menuWrapperId);
943         dragDropManager->UpdateDragMovePosition(updateOffset, true);
944     } else {
945         SubwindowManager::GetInstance()->UpdateHideMenuOffsetNG(updateOffset, previewMenuSacle, false, menuWrapperId);
946         dragDropManager->UpdateDragMovePosition(updateOffset, false);
947     }
948     SubwindowManager::GetInstance()->UpdatePreviewPosition();
949 }
950 
SetFilter(const RefPtr<DragEventActuator> & actuator)951 void DragEventActuator::SetFilter(const RefPtr<DragEventActuator>& actuator)
952 {
953     TAG_LOGD(AceLogTag::ACE_DRAG, "DragEvent start setFilter.");
954     auto gestureHub = actuator->gestureEventHub_.Upgrade();
955     CHECK_NULL_VOID(gestureHub);
956     auto frameNode = gestureHub->GetFrameNode();
957     CHECK_NULL_VOID(frameNode);
958     auto parent = frameNode->GetParent();
959     CHECK_NULL_VOID(parent);
960     while (parent && parent->GetDepth() != 1) {
961         parent = parent->GetParent();
962     }
963     if (!parent) {
964         TAG_LOGD(AceLogTag::ACE_DRAG, "DragFrameNode is %{public}s, depth %{public}d, can not find filter root",
965             frameNode->GetTag().c_str(), frameNode->GetDepth());
966         return;
967     }
968     auto pipelineContext = PipelineContext::GetCurrentContext();
969     CHECK_NULL_VOID(pipelineContext);
970     auto manager = pipelineContext->GetOverlayManager();
971     CHECK_NULL_VOID(manager);
972     if (!manager->GetHasFilter() && !manager->GetIsOnAnimation()) {
973         if (frameNode->GetTag() == V2::WEB_ETS_TAG) {
974 #ifdef WEB_SUPPORTED
975             auto webPattern = frameNode->GetPattern<WebPattern>();
976             CHECK_NULL_VOID(webPattern);
977             bool isWebmageDrag = webPattern->IsImageDrag();
978             WebInfoType type = webPattern->GetWebInfoType();
979             CHECK_NULL_VOID(isWebmageDrag && type == WebInfoType::TYPE_MOBILE);
980 #endif
981         } else {
982             bool isBindOverlayValue = frameNode->GetLayoutProperty()->GetIsBindOverlayValue(false);
983             CHECK_NULL_VOID(isBindOverlayValue && SystemProperties::GetDeviceType() == DeviceType::PHONE);
984         }
985         // insert columnNode to rootNode
986         auto columnNode = FrameNode::CreateFrameNode(V2::COLUMN_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
987             AceType::MakeRefPtr<LinearLayoutPattern>(true));
988         columnNode->GetLayoutProperty()->UpdateMeasureType(MeasureType::MATCH_PARENT);
989         // set filter
990         TAG_LOGI(AceLogTag::ACE_DRAG, "User Device use default Filter");
991         auto container = Container::Current();
992         if (container && container->IsScenceBoardWindow()) {
993             auto windowScene = manager->FindWindowScene(frameNode);
994             manager->MountFilterToWindowScene(columnNode, windowScene);
995         } else {
996             columnNode->MountToParent(parent);
997             columnNode->OnMountToParentDone();
998             manager->SetHasFilter(true);
999             manager->SetFilterColumnNode(columnNode);
1000             parent->MarkDirtyNode(NG::PROPERTY_UPDATE_BY_CHILD_REQUEST);
1001         }
1002         AnimationOption option;
1003         BlurStyleOption styleOption;
1004         styleOption.blurStyle = static_cast<BlurStyle>(BlurStyle::BACKGROUND_THIN);
1005         styleOption.colorMode = static_cast<ThemeColorMode>(static_cast<int32_t>(ThemeColorMode::SYSTEM));
1006         option.SetDuration(FILTER_TIMES);
1007         option.SetCurve(Curves::SHARP);
1008         option.SetOnFinishEvent([pipelineWeak = WeakClaim(RawPtr(pipelineContext))] {
1009             auto pipelineContext = pipelineWeak.Upgrade();
1010             CHECK_NULL_VOID(pipelineContext);
1011             auto manager = pipelineContext->GetOverlayManager();
1012             CHECK_NULL_VOID(manager);
1013             manager->SetFilterActive(false);
1014         });
1015         columnNode->GetRenderContext()->UpdateBackBlurRadius(FILTER_VALUE);
1016         AnimationUtils::Animate(
1017             option, [columnNode, styleOption]() { columnNode->GetRenderContext()->UpdateBackBlurStyle(styleOption); },
1018             option.GetOnFinishEvent());
1019     }
1020     TAG_LOGD(AceLogTag::ACE_DRAG, "DragEvent set filter success.");
1021 }
1022 
GetFloatImageOffset(const RefPtr<FrameNode> & frameNode,const RefPtr<PixelMap> & pixelMap)1023 OffsetF DragEventActuator::GetFloatImageOffset(const RefPtr<FrameNode>& frameNode, const RefPtr<PixelMap>& pixelMap)
1024 {
1025     CHECK_NULL_RETURN(frameNode, OffsetF());
1026     auto centerPosition = frameNode->GetPaintRectCenter(true);
1027     float width = 0.0f;
1028     float height = 0.0f;
1029     if (pixelMap) {
1030         width = pixelMap->GetWidth();
1031         height = pixelMap->GetHeight();
1032     }
1033     auto offsetX = centerPosition.GetX() - width / 2.0f;
1034     auto offsetY = centerPosition.GetY() - height / 2.0f;
1035 #ifdef WEB_SUPPORTED
1036     if (frameNode->GetTag() == V2::WEB_ETS_TAG) {
1037         auto webPattern = frameNode->GetPattern<WebPattern>();
1038         if (webPattern) {
1039             auto offsetToWindow = frameNode->GetPaintRectOffset();
1040             offsetX = offsetToWindow.GetX() + webPattern->GetDragOffset().GetX();
1041             offsetY = offsetToWindow.GetY() + webPattern->GetDragOffset().GetY();
1042         }
1043     }
1044 #endif
1045     // Check web tag.
1046     auto pipelineContext = PipelineContext::GetCurrentContext();
1047     CHECK_NULL_RETURN(pipelineContext, OffsetF());
1048     if (pipelineContext->HasFloatTitle()) {
1049         offsetX -= static_cast<float>((CONTAINER_BORDER_WIDTH + CONTENT_PADDING).ConvertToPx());
1050         offsetY -= static_cast<float>((pipelineContext->GetCustomTitleHeight() + CONTAINER_BORDER_WIDTH).ConvertToPx());
1051     }
1052     return OffsetF(offsetX, offsetY);
1053 }
1054 
UpdatePreviewPositionAndScale(const RefPtr<FrameNode> & imageNode,const OffsetF & frameOffset,float scale)1055 void DragEventActuator::UpdatePreviewPositionAndScale(
1056     const RefPtr<FrameNode>& imageNode, const OffsetF& frameOffset, float scale)
1057 {
1058     auto imageContext = imageNode->GetRenderContext();
1059     CHECK_NULL_VOID(imageContext);
1060     imageContext->UpdatePosition(OffsetT<Dimension>(Dimension(frameOffset.GetX()), Dimension(frameOffset.GetY())));
1061     if (GreatNotEqual(scale, 0.0f)) {
1062         imageContext->UpdateTransformScale({ scale, scale });
1063     }
1064     ClickEffectInfo clickEffectInfo;
1065     clickEffectInfo.level = ClickEffectLevel::LIGHT;
1066     clickEffectInfo.scaleNumber = SCALE_NUMBER;
1067     imageContext->UpdateClickEffectLevel(clickEffectInfo);
1068 }
1069 
UpdatePreviewAttr(const RefPtr<FrameNode> & frameNode,const RefPtr<FrameNode> & imageNode)1070 void DragEventActuator::UpdatePreviewAttr(const RefPtr<FrameNode>& frameNode, const RefPtr<FrameNode>& imageNode)
1071 {
1072     CHECK_NULL_VOID(frameNode);
1073     auto frameTag = frameNode->GetTag();
1074     auto gestureHub = frameNode->GetOrCreateGestureEventHub();
1075     CHECK_NULL_VOID(gestureHub);
1076     CHECK_NULL_VOID(imageNode);
1077     auto imageContext = imageNode->GetRenderContext();
1078     CHECK_NULL_VOID(imageContext);
1079     auto dragPreviewOption = frameNode->GetDragPreviewOption();
1080     if (gestureHub->IsTextCategoryComponent(frameTag) && gestureHub->GetTextDraggable()) {
1081         if (dragPreviewOption.options.shadow.has_value()) {
1082             auto shadow = dragPreviewOption.options.shadow.value();
1083             shadow.SetIsFilled(true);
1084             imageContext->UpdateBackShadow(shadow);
1085         }
1086         return;
1087     }
1088     imageContext->UpdateOpacity(dragPreviewOption.options.opacity);
1089     if (dragPreviewOption.options.shadow.has_value()) {
1090         imageContext->UpdateBackShadow(dragPreviewOption.options.shadow.value());
1091     }
1092     if (dragPreviewOption.options.borderRadius.has_value()) {
1093         imageContext->UpdateBorderRadius(dragPreviewOption.options.borderRadius.value());
1094         imageContext->UpdateClipEdge(true);
1095     }
1096     auto optionsFromModifier = frameNode->GetDragPreviewOption().options;
1097     if (optionsFromModifier.blurbgEffect.backGroundEffect.radius.IsValid()) {
1098         ACE_UPDATE_NODE_RENDER_CONTEXT(BackgroundEffect, optionsFromModifier.blurbgEffect.backGroundEffect, imageNode);
1099     }
1100 }
1101 
CreatePreviewNode(const RefPtr<FrameNode> & frameNode,RefPtr<FrameNode> & imageNode,float dragPreviewScale)1102 void DragEventActuator::CreatePreviewNode(
1103     const RefPtr<FrameNode>& frameNode, RefPtr<FrameNode>& imageNode, float dragPreviewScale)
1104 {
1105     CHECK_NULL_VOID(frameNode);
1106     auto pixelMap = frameNode->GetPixelMap();
1107     CHECK_NULL_VOID(pixelMap);
1108     auto center = frameNode->GetPaintRectCenter();
1109     auto frameOffset = OffsetF(center.GetX() - (pixelMap->GetWidth() / 2.0f),
1110         center.GetY() - (pixelMap->GetHeight() / 2.0f));
1111     imageNode = FrameNode::GetOrCreateFrameNode(V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
1112         []() {return AceType::MakeRefPtr<ImagePattern>(); });
1113     CHECK_NULL_VOID(imageNode);
1114     imageNode->SetDragPreviewOptions(frameNode->GetDragPreviewOption());
1115 
1116     auto renderProps = imageNode->GetPaintProperty<ImageRenderProperty>();
1117     renderProps->UpdateImageInterpolation(ImageInterpolation::HIGH);
1118     auto props = imageNode->GetLayoutProperty<ImageLayoutProperty>();
1119     props->UpdateAutoResize(false);
1120     props->UpdateImageSourceInfo(ImageSourceInfo(pixelMap));
1121     auto targetSize = CalcSize(NG::CalcLength(pixelMap->GetWidth()), NG::CalcLength(pixelMap->GetHeight()));
1122     props->UpdateUserDefinedIdealSize(targetSize);
1123 
1124     auto imagePattern = imageNode->GetPattern<ImagePattern>();
1125     CHECK_NULL_VOID(imagePattern);
1126     imagePattern->SetSyncLoad(true);
1127 
1128     UpdatePreviewPositionAndScale(imageNode, frameOffset, dragPreviewScale);
1129     UpdatePreviewAttr(frameNode, imageNode);
1130     imageNode->MarkDirtyNode(NG::PROPERTY_UPDATE_MEASURE);
1131     imageNode->MarkModifyDone();
1132     imageNode->SetLayoutDirtyMarked(true);
1133     imageNode->SetActive(true);
1134     auto context = imageNode->GetContext();
1135     if (context) {
1136         context->FlushUITaskWithSingleDirtyNode(imageNode);
1137     }
1138     FlushSyncGeometryNodeTasks();
1139 }
1140 
SetPreviewDefaultAnimateProperty(const RefPtr<FrameNode> & imageNode)1141 void DragEventActuator::SetPreviewDefaultAnimateProperty(const RefPtr<FrameNode>& imageNode)
1142 {
1143     if (imageNode->IsPreviewNeedScale()) {
1144         auto imageContext = imageNode->GetRenderContext();
1145         CHECK_NULL_VOID(imageContext);
1146         imageContext->UpdateTransformScale({ 1.0f, 1.0f });
1147         imageContext->UpdateTransformTranslate({ 0.0f, 0.0f, 0.0f });
1148     }
1149 }
1150 
MountPixelMap(const RefPtr<OverlayManager> & manager,const RefPtr<GestureEventHub> & gestureHub,const RefPtr<FrameNode> & imageNode,const RefPtr<FrameNode> & textNode,bool isDragPixelMap)1151 void DragEventActuator::MountPixelMap(const RefPtr<OverlayManager>& manager, const RefPtr<GestureEventHub>& gestureHub,
1152     const RefPtr<FrameNode>& imageNode, const RefPtr<FrameNode>& textNode, bool isDragPixelMap)
1153 {
1154     CHECK_NULL_VOID(manager);
1155     CHECK_NULL_VOID(imageNode);
1156     CHECK_NULL_VOID(gestureHub);
1157     auto columnNode = FrameNode::CreateFrameNode(V2::COLUMN_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
1158         AceType::MakeRefPtr<LinearLayoutPattern>(true));
1159     columnNode->AddChild(imageNode);
1160     auto hub = columnNode->GetOrCreateGestureEventHub();
1161     CHECK_NULL_VOID(hub);
1162     hub->SetPixelMap(gestureHub->GetPixelMap());
1163     if (textNode) {
1164         columnNode->AddChild(textNode);
1165     }
1166     auto container = Container::Current();
1167     if (container && container->IsScenceBoardWindow()) {
1168         auto frameNode = gestureHub->GetFrameNode();
1169         CHECK_NULL_VOID(frameNode);
1170         auto windowScene = manager->FindWindowScene(frameNode);
1171         manager->MountPixelMapToWindowScene(columnNode, windowScene, isDragPixelMap);
1172     } else {
1173         manager->MountPixelMapToRootNode(columnNode, isDragPixelMap);
1174     }
1175     SetPreviewDefaultAnimateProperty(imageNode);
1176     columnNode->MarkDirtyNode(NG::PROPERTY_UPDATE_MEASURE);
1177     columnNode->MarkModifyDone();
1178     columnNode->SetActive(true);
1179     auto context = columnNode->GetContext();
1180     if (context) {
1181         context->FlushUITaskWithSingleDirtyNode(columnNode);
1182     }
1183     FlushSyncGeometryNodeTasks();
1184 }
1185 
1186 /* Retrieves a preview PixelMap for a given drag event action.
1187  * This function attempts to obtain a screenshot of a frameNode associated with an inspector ID.
1188  * If the frameNode with the given ID does not exist or hasn't been rendered,
1189  * it falls back to taking a screenshot of the provided frame node.
1190  *
1191  * @param inspectorId A string representing the unique identifier for the frameNode's ID.
1192  * @param selfFrameNode A RefPtr to the frame node associated with the drag event.
1193  * @return A RefPtr to a PixelMap containing the preview image, or nullptr if not found.
1194  */
GetPreviewPixelMap(const std::string & inspectorId,const RefPtr<FrameNode> & selfFrameNode)1195 RefPtr<PixelMap> DragEventActuator::GetPreviewPixelMap(
1196     const std::string& inspectorId, const RefPtr<FrameNode>& selfFrameNode)
1197 {
1198     // Attempt to retrieve the PixelMap using the inspector ID.
1199     auto previewPixelMap = GetPreviewPixelMapByInspectorId(inspectorId);
1200     // If a preview PixelMap was found, return it.
1201     if (previewPixelMap != nullptr) {
1202         return previewPixelMap;
1203     }
1204 
1205     // If not found by inspector ID, attempt to get a screenshot of the frame node.
1206     return GetScreenShotPixelMap(selfFrameNode);
1207 }
1208 
1209 /* Retrieves a preview PixelMap based on an inspector ID.
1210  * This function attempts to find a frame node associated with the given inspector ID and then takes a screenshot of it.
1211  *
1212  * @param inspectorId The unique identifier for a frameNode.
1213  * @return A RefPtr to a PixelMap containing the preview image, or nullptr if not found or the ID is empty.
1214  */
GetPreviewPixelMapByInspectorId(const std::string & inspectorId)1215 RefPtr<PixelMap> DragEventActuator::GetPreviewPixelMapByInspectorId(const std::string& inspectorId)
1216 {
1217     // Check for an empty inspector ID and return nullptr if it is empty.
1218     if (inspectorId == "") {
1219         return nullptr;
1220     }
1221 
1222     // Retrieve the frame node using the inspector's ID.
1223     auto dragPreviewFrameNode = Inspector::GetFrameNodeByKey(inspectorId);
1224     CHECK_NULL_RETURN(dragPreviewFrameNode, nullptr);
1225 
1226     auto layoutProperty = dragPreviewFrameNode->GetLayoutProperty();
1227     CHECK_NULL_RETURN(layoutProperty, nullptr);
1228 
1229     auto visibility = layoutProperty->GetVisibilityValue(VisibleType::VISIBLE);
1230     if (visibility == VisibleType::INVISIBLE || visibility == VisibleType::GONE) {
1231         return nullptr;
1232     }
1233 
1234     // Take a screenshot of the frame node and return it as a PixelMap.
1235     return GetScreenShotPixelMap(dragPreviewFrameNode);
1236 }
1237 
1238 /* Captures a screenshot of the specified frame node and encapsulates it in a PixelMap.
1239  *
1240  * @param frameNode A RefPtr reference to the frame node from which to capture the screenshot.
1241  * @return A RefPtr to a PixelMap containing the screenshot.
1242  */
GetScreenShotPixelMap(const RefPtr<FrameNode> & frameNode)1243 RefPtr<PixelMap> DragEventActuator::GetScreenShotPixelMap(const RefPtr<FrameNode>& frameNode)
1244 {
1245     // Ensure the frame node is not nulls before proceeding.
1246     CHECK_NULL_RETURN(frameNode, nullptr);
1247 
1248     // Obtain the rendering context from the frame node.
1249     auto context = frameNode->GetRenderContext();
1250 
1251     // If the rendering context is not available, return nullptr.
1252     CHECK_NULL_RETURN(context, nullptr);
1253 
1254     // Capture and return the thumbnail PixelMap from the rendering context.
1255     return context->GetThumbnailPixelMap(true);
1256 }
1257 
SetPixelMap(const RefPtr<DragEventActuator> & actuator)1258 void DragEventActuator::SetPixelMap(const RefPtr<DragEventActuator>& actuator)
1259 {
1260     TAG_LOGD(AceLogTag::ACE_DRAG, "DragEvent start set pixelMap");
1261     auto pipelineContext = PipelineContext::GetCurrentContext();
1262     CHECK_NULL_VOID(pipelineContext);
1263     auto manager = pipelineContext->GetOverlayManager();
1264     CHECK_NULL_VOID(manager);
1265     if (manager->GetHasPixelMap()) {
1266         TAG_LOGI(AceLogTag::ACE_DRAG, "Dragging animation is currently executing, unable to float other pixelMap.");
1267         return;
1268     }
1269     auto gestureHub = actuator->gestureEventHub_.Upgrade();
1270     CHECK_NULL_VOID(gestureHub);
1271     auto frameNode = gestureHub->GetFrameNode();
1272     CHECK_NULL_VOID(frameNode);
1273     RefPtr<PixelMap> pixelMap = gestureHub->GetPixelMap();
1274     CHECK_NULL_VOID(pixelMap);
1275     auto width = pixelMap->GetWidth();
1276     auto height = pixelMap->GetHeight();
1277     auto offset = GetFloatImageOffset(frameNode, pixelMap);
1278     // create imageNode
1279     auto imageNode = FrameNode::GetOrCreateFrameNode(V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
1280         []() { return AceType::MakeRefPtr<ImagePattern>(); });
1281     CHECK_NULL_VOID(imageNode);
1282     auto imagePattern = imageNode->GetPattern<ImagePattern>();
1283     CHECK_NULL_VOID(imagePattern);
1284     imagePattern->SetSyncLoad(true);
1285     imageNode->SetDragPreviewOptions(frameNode->GetDragPreviewOption());
1286     auto renderProps = imageNode->GetPaintProperty<ImageRenderProperty>();
1287     renderProps->UpdateImageInterpolation(ImageInterpolation::HIGH);
1288     auto props = imageNode->GetLayoutProperty<ImageLayoutProperty>();
1289     props->UpdateAutoResize(false);
1290     props->UpdateImageSourceInfo(ImageSourceInfo(pixelMap));
1291     auto targetSize = CalcSize(NG::CalcLength(width), NG::CalcLength(height));
1292     props->UpdateUserDefinedIdealSize(targetSize);
1293     auto imageContext = imageNode->GetRenderContext();
1294     CHECK_NULL_VOID(imageContext);
1295     imageContext->UpdatePosition(OffsetT<Dimension>(Dimension(offset.GetX()), Dimension(offset.GetY())));
1296     ClickEffectInfo clickEffectInfo;
1297     clickEffectInfo.level = ClickEffectLevel::LIGHT;
1298     clickEffectInfo.scaleNumber = SCALE_NUMBER;
1299     imageContext->UpdateClickEffectLevel(clickEffectInfo);
1300     // create columnNode
1301     auto columnNode = FrameNode::CreateFrameNode(V2::COLUMN_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
1302         AceType::MakeRefPtr<LinearLayoutPattern>(true));
1303     columnNode->AddChild(imageNode);
1304     auto hub = columnNode->GetOrCreateGestureEventHub();
1305     CHECK_NULL_VOID(hub);
1306     hub->SetPixelMap(gestureHub->GetPixelMap());
1307     // mount to rootNode
1308     auto container = Container::Current();
1309     if (container && container->IsScenceBoardWindow()) {
1310         auto windowScene = manager->FindWindowScene(frameNode);
1311         manager->MountPixelMapToWindowScene(columnNode, windowScene);
1312     } else {
1313         manager->MountPixelMapToRootNode(columnNode);
1314     }
1315     imageNode->MarkModifyDone();
1316     imageNode->SetLayoutDirtyMarked(true);
1317     imageNode->SetActive(true);
1318     auto context = imageNode->GetContext();
1319     if (context) {
1320         context->FlushUITaskWithSingleDirtyNode(imageNode);
1321     }
1322     FlushSyncGeometryNodeTasks();
1323     auto focusHub = frameNode->GetFocusHub();
1324     bool hasContextMenu = focusHub == nullptr
1325                               ? false : focusHub->FindContextMenuOnKeyEvent(OnKeyEventType::CONTEXT_MENU);
1326     ShowPixelMapAnimation(imageNode, frameNode, hasContextMenu);
1327     TAG_LOGD(AceLogTag::ACE_DRAG, "DragEvent set pixelMap success.");
1328     SetPreviewDefaultAnimateProperty(imageNode);
1329 }
1330 
1331 // called when the preview floating or drag begin, this method will try to execute the modifier
1332 // on one temporary frame node, and then get the value user setted from the modifier
UpdatePreviewOptionFromModifier(const RefPtr<FrameNode> & frameNode)1333 void DragEventActuator::UpdatePreviewOptionFromModifier(const RefPtr<FrameNode>& frameNode)
1334 {
1335     UpdatePreviewOptionDefaultAttr(frameNode);
1336     auto modifierOnApply = frameNode->GetDragPreviewOption().onApply;
1337     if (!modifierOnApply) {
1338         optionsAfterApplied_ = frameNode->GetDragPreviewOption().options;
1339         return;
1340     }
1341 
1342     // create one temporary frame node for receiving the value from the modifier
1343     auto imageNode = FrameNode::GetOrCreateFrameNode(V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
1344         []() { return AceType::MakeRefPtr<ImagePattern>(); });
1345     CHECK_NULL_VOID(imageNode);
1346 
1347     // execute the modifier
1348     modifierOnApply(WeakClaim(RawPtr(imageNode)));
1349 
1350     // get values from the temporary frame node
1351     auto imageContext = imageNode->GetRenderContext();
1352     CHECK_NULL_VOID(imageContext);
1353     auto opacity = imageContext->GetOpacity();
1354 
1355     OptionsAfterApplied options = frameNode->GetDragPreviewOption().options;
1356     if (opacity.has_value() && (opacity.value()) <= MAX_OPACITY && (opacity.value()) > MIN_OPACITY) {
1357         options.opacity = opacity.value();
1358     } else {
1359         options.opacity = DEFAULT_OPACITY;
1360     }
1361 
1362     auto shadow = imageContext->GetBackShadow();
1363     if (shadow.has_value()) {
1364         options.shadow = shadow;
1365     }
1366 
1367     auto borderRadius = imageContext->GetBorderRadius();
1368     if (borderRadius.has_value()) {
1369         options.borderRadius = borderRadius;
1370     }
1371 
1372     // get the old preview option
1373     DragPreviewOption dragPreviewOption = frameNode->GetDragPreviewOption();
1374     auto bgEffect = imageContext->GetBackgroundEffect();
1375     if (bgEffect.has_value()) {
1376         options.blurbgEffect.backGroundEffect = bgEffect.value();
1377     } else {
1378         auto blurstyletmp = imageContext->GetBackBlurStyle();
1379         if (blurstyletmp.has_value()) {
1380             bgEffect = BrulStyleToEffection(blurstyletmp);
1381             if (bgEffect.has_value()) {
1382                 options.blurbgEffect.backGroundEffect = bgEffect.value();
1383             }
1384         }
1385     }
1386     dragPreviewOption.options = options; // replace the options with the new one after applied
1387     frameNode->SetDragPreviewOptions(dragPreviewOption);
1388     optionsAfterApplied_ = options;
1389 }
1390 
UpdatePreviewOptionDefaultAttr(const RefPtr<FrameNode> & frameNode)1391 void DragEventActuator::UpdatePreviewOptionDefaultAttr(const RefPtr<FrameNode>& frameNode)
1392 {
1393     auto dragPreviewOption = frameNode->GetDragPreviewOption();
1394     dragPreviewOption.options.opacity = DEFAULT_OPACITY;
1395     if (dragPreviewOption.isDefaultShadowEnabled) {
1396         dragPreviewOption.options.shadow = GetDefaultShadow();
1397     } else {
1398         dragPreviewOption.options.shadow = std::nullopt;
1399     }
1400     if (dragPreviewOption.isDefaultRadiusEnabled || dragPreviewOption.isMultiSelectionEnabled) {
1401         dragPreviewOption.options.borderRadius = GetDefaultBorderRadius();
1402     } else {
1403         dragPreviewOption.options.borderRadius = std::nullopt;
1404     }
1405     frameNode->SetDragPreviewOptions(dragPreviewOption); // replace the options with the new one
1406 }
1407 
RadiusToSigma(float radius)1408 float DragEventActuator::RadiusToSigma(float radius)
1409 {
1410     return GreatNotEqual(radius, 0.0f) ? BLUR_SIGMA_SCALE * radius + SCALE_HALF : 0.0f;
1411 }
1412 
BrulStyleToEffection(const std::optional<BlurStyleOption> & blurStyleOp)1413 std::optional<EffectOption> DragEventActuator::BrulStyleToEffection(const std::optional<BlurStyleOption>& blurStyleOp)
1414 {
1415     auto pipeline = PipelineContext::GetCurrentContext();
1416     CHECK_NULL_RETURN(pipeline, std::nullopt);
1417     auto blurStyleTheme = pipeline->GetTheme<BlurStyleTheme>();
1418     if (!blurStyleTheme) {
1419         LOGW("cannot find theme of blurStyle, create blurStyle failed");
1420         return std::nullopt;
1421     }
1422     ThemeColorMode colorMode = blurStyleOp->colorMode;
1423     if (blurStyleOp->colorMode == ThemeColorMode::SYSTEM) {
1424         colorMode = SystemProperties::GetColorMode() == ColorMode::DARK ? ThemeColorMode::DARK : ThemeColorMode::LIGHT;
1425     }
1426     auto blurParam = blurStyleTheme->GetBlurParameter(blurStyleOp->blurStyle, colorMode);
1427     CHECK_NULL_RETURN(blurParam, std::nullopt);
1428     auto ratio = blurStyleOp->scale;
1429     auto maskColor = blurParam->maskColor.BlendOpacity(ratio);
1430     auto radiusPx = blurParam->radius * pipeline->GetDipScale();
1431     auto radiusBlur = RadiusToSigma(radiusPx) * ratio;
1432     auto saturation = (blurParam->saturation - 1) * ratio + 1.0;
1433     auto brightness = (blurParam->brightness - 1) * ratio + 1.0;
1434     Dimension dimen(radiusBlur);
1435     EffectOption bgEffection = {dimen, saturation, brightness, maskColor,
1436         blurStyleOp->adaptiveColor, blurStyleOp->blurOption};
1437     return std::optional<EffectOption>(bgEffection);
1438 }
1439 
ApplyNewestOptionExecutedFromModifierToNode(const RefPtr<FrameNode> & optionHolderNode,const RefPtr<FrameNode> & targetNode)1440 void DragEventActuator::ApplyNewestOptionExecutedFromModifierToNode(
1441     const RefPtr<FrameNode>& optionHolderNode, const RefPtr<FrameNode>& targetNode)
1442 {
1443     auto optionsFromModifier = targetNode->GetDragPreviewOption().options;
1444     ACE_UPDATE_NODE_RENDER_CONTEXT(Opacity, optionsFromModifier.opacity, targetNode);
1445     if (optionsFromModifier.blurbgEffect.backGroundEffect.radius.IsValid()) {
1446         ACE_UPDATE_NODE_RENDER_CONTEXT(BackgroundEffect, optionsFromModifier.blurbgEffect.backGroundEffect, targetNode);
1447     }
1448     if (optionsFromModifier.shadow.has_value()) {
1449         // if shadow is unfilled, set shadow after animation
1450         if (optionsFromModifier.shadow->GetIsFilled()) {
1451             ACE_UPDATE_NODE_RENDER_CONTEXT(BackShadow, optionsFromModifier.shadow.value(), targetNode);
1452         }
1453     }
1454 
1455     const auto& target = targetNode->GetRenderContext();
1456     if (optionsFromModifier.borderRadius.has_value()) {
1457         target->UpdateBorderRadius(optionsFromModifier.borderRadius.value());
1458         target->UpdateClipEdge(true);
1459     }
1460 }
1461 
SetEventColumn(const RefPtr<DragEventActuator> & actuator)1462 void DragEventActuator::SetEventColumn(const RefPtr<DragEventActuator>& actuator)
1463 {
1464     TAG_LOGI(AceLogTag::ACE_DRAG, "DragEvent start set eventColumn.");
1465     auto pipelineContext = PipelineContext::GetCurrentContext();
1466     CHECK_NULL_VOID(pipelineContext);
1467     auto manager = pipelineContext->GetOverlayManager();
1468     CHECK_NULL_VOID(manager);
1469     if (manager->GetHasEvent()) {
1470         return;
1471     }
1472     auto rootNode = pipelineContext->GetRootElement();
1473     CHECK_NULL_VOID(rootNode);
1474     auto geometryNode = rootNode->GetGeometryNode();
1475     CHECK_NULL_VOID(geometryNode);
1476     auto width = geometryNode->GetFrameSize().Width();
1477     auto height = geometryNode->GetFrameSize().Height();
1478     // create columnNode
1479     auto columnNode = FrameNode::CreateFrameNode(V2::COLUMN_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
1480         AceType::MakeRefPtr<LinearLayoutPattern>(true));
1481     auto props = columnNode->GetLayoutProperty<LinearLayoutProperty>();
1482     auto targetSize = CalcSize(NG::CalcLength(width), NG::CalcLength(height));
1483     props->UpdateUserDefinedIdealSize(targetSize);
1484     BindClickEvent(columnNode);
1485     columnNode->MarkModifyDone();
1486     auto container = Container::Current();
1487     if (container && container->IsScenceBoardWindow()) {
1488         auto gestureHub = actuator->gestureEventHub_.Upgrade();
1489         CHECK_NULL_VOID(gestureHub);
1490         auto frameNode = gestureHub->GetFrameNode();
1491         CHECK_NULL_VOID(frameNode);
1492         auto windowScene = manager->FindWindowScene(frameNode);
1493         manager->MountEventToWindowScene(columnNode, windowScene);
1494     } else {
1495         manager->MountEventToRootNode(columnNode);
1496     }
1497     TAG_LOGI(AceLogTag::ACE_DRAG, "DragEvent set eventColumn success.");
1498 }
1499 
HideFilter()1500 void DragEventActuator::HideFilter()
1501 {
1502     auto gestureEventHub = gestureEventHub_.Upgrade();
1503     CHECK_NULL_VOID(gestureEventHub);
1504     auto frameNode = gestureEventHub->GetFrameNode();
1505     CHECK_NULL_VOID(frameNode);
1506     if (frameNode->GetTag() != V2::WEB_ETS_TAG) {
1507         return;
1508     }
1509     auto pipelineContext = PipelineContext::GetCurrentContext();
1510     CHECK_NULL_VOID(pipelineContext);
1511     auto manager = pipelineContext->GetOverlayManager();
1512     CHECK_NULL_VOID(manager);
1513     manager->RemoveFilterAnimation();
1514 }
1515 
HidePixelMap(bool startDrag,double x,double y,bool showAnimation)1516 void DragEventActuator::HidePixelMap(bool startDrag, double x, double y, bool showAnimation)
1517 {
1518     auto gestureEventHub = gestureEventHub_.Upgrade();
1519     CHECK_NULL_VOID(gestureEventHub);
1520     auto frameNode = gestureEventHub->GetFrameNode();
1521     CHECK_NULL_VOID(frameNode);
1522     auto pipelineContext = frameNode->GetContextRefPtr();
1523     CHECK_NULL_VOID(pipelineContext);
1524     auto manager = pipelineContext->GetOverlayManager();
1525     CHECK_NULL_VOID(manager);
1526     if (!startDrag) {
1527         manager->RemovePreviewBadgeNode();
1528         manager->RemoveGatherNodeWithAnimation();
1529     }
1530 
1531     if (showAnimation) {
1532         manager->RemovePixelMapAnimation(startDrag, x, y);
1533     } else {
1534         manager->RemovePixelMap();
1535     }
1536 }
1537 
HideEventColumn()1538 void DragEventActuator::HideEventColumn()
1539 {
1540     auto pipelineContext = PipelineContext::GetCurrentContext();
1541     CHECK_NULL_VOID(pipelineContext);
1542     auto manager = pipelineContext->GetOverlayManager();
1543     CHECK_NULL_VOID(manager);
1544     manager->RemoveEventColumn();
1545 }
1546 
BindClickEvent(const RefPtr<FrameNode> & columnNode)1547 void DragEventActuator::BindClickEvent(const RefPtr<FrameNode>& columnNode)
1548 {
1549     auto callback = [weak = WeakClaim(this)](GestureEvent& /* info */) {
1550         TAG_LOGI(AceLogTag::ACE_DRAG, "start click event callback");
1551         auto actuator = weak.Upgrade();
1552         CHECK_NULL_VOID(actuator);
1553         auto gestureHub = actuator->gestureEventHub_.Upgrade();
1554         CHECK_NULL_VOID(gestureHub);
1555         actuator->HideEventColumn();
1556         if (gestureHub->GetTextDraggable()) {
1557             actuator->HideTextAnimation();
1558         } else {
1559             actuator->HidePixelMap();
1560             actuator->HideFilter();
1561         }
1562     };
1563     auto columnGestureHub = columnNode->GetOrCreateGestureEventHub();
1564     CHECK_NULL_VOID(columnGestureHub);
1565     auto clickListener = MakeRefPtr<ClickEvent>(std::move(callback));
1566     columnGestureHub->AddClickEvent(clickListener);
1567     if (!GetIsBindOverlayValue(Claim(this))) {
1568         columnGestureHub->SetHitTestMode(HitTestMode::HTMBLOCK);
1569     }
1570 }
1571 
ShowPixelMapAnimation(const RefPtr<FrameNode> & imageNode,const RefPtr<FrameNode> & frameNode,bool hasContextMenu)1572 void DragEventActuator::ShowPixelMapAnimation(const RefPtr<FrameNode>& imageNode,
1573     const RefPtr<FrameNode>& frameNode, bool hasContextMenu)
1574 {
1575     CHECK_NULL_VOID(imageNode);
1576     auto imageContext = imageNode->GetRenderContext();
1577     CHECK_NULL_VOID(imageContext);
1578     CHECK_NULL_VOID(frameNode);
1579     frameNode->SetOptionsAfterApplied(optionsAfterApplied_);
1580     SetImageNodeInitAttr(frameNode, imageNode);
1581     // pixel map animation
1582     AnimationOption option;
1583     option.SetDuration(PIXELMAP_ANIMATION_DURATION);
1584     option.SetCurve(Curves::SHARP);
1585     option.SetOnFinishEvent([imageNode, frameNode]() {
1586         DragEventActuator::SetImageNodeFinishAttr(frameNode, imageNode);
1587     });
1588 
1589     AnimationUtils::Animate(
1590         option,
1591         [imageNode, hasContextMenu, weak = WeakClaim(RawPtr(frameNode))]() mutable {
1592             auto imageContext = imageNode->GetRenderContext();
1593             CHECK_NULL_VOID(imageContext);
1594             auto frameNode = weak.Upgrade();
1595             ApplyNewestOptionExecutedFromModifierToNode(frameNode, imageNode);
1596             if (hasContextMenu) {
1597                 BorderRadiusProperty borderRadius;
1598                 borderRadius.SetRadius(PIXELMAP_BORDER_RADIUS);
1599                 imageContext->UpdateBorderRadius(borderRadius);
1600             }
1601             DragEventActuator::ResetNode(frameNode);
1602         },
1603         option.GetOnFinishEvent());
1604 }
1605 
ExecutePreDragAction(const PreDragStatus preDragStatus,const RefPtr<FrameNode> & frameNode)1606 void DragEventActuator::ExecutePreDragAction(const PreDragStatus preDragStatus, const RefPtr<FrameNode>& frameNode)
1607 {
1608     auto mainPipeline = PipelineContext::GetMainPipelineContext();
1609     CHECK_NULL_VOID(mainPipeline);
1610     auto dragDropManager = mainPipeline->GetDragDropManager();
1611     CHECK_NULL_VOID(dragDropManager);
1612     if (dragDropManager->IsDragging() || dragDropManager->IsMSDPDragging()) {
1613         return;
1614     }
1615     RefPtr<EventHub> eventHub;
1616     if (frameNode) {
1617         eventHub = frameNode->GetEventHub<EventHub>();
1618     } else {
1619         auto preDragFrameNode = dragDropManager->GetPrepareDragFrameNode().Upgrade();
1620         CHECK_NULL_VOID(preDragFrameNode);
1621         eventHub = preDragFrameNode->GetEventHub<EventHub>();
1622     }
1623     CHECK_NULL_VOID(eventHub);
1624     auto gestureHub = eventHub->GetOrCreateGestureEventHub();
1625     CHECK_NULL_VOID(gestureHub);
1626     if (!gestureHub->IsAllowedDrag(eventHub) || gestureHub->GetTextDraggable()) {
1627         return;
1628     }
1629     auto onPreDragStatus = PreDragStatus::ACTION_CANCELED_BEFORE_DRAG;
1630     if (dragDropManager->GetPreDragStatus() <= preDragStatus &&
1631         preDragStatus != PreDragStatus::ACTION_CANCELED_BEFORE_DRAG) {
1632         auto nextPreDragStatus = static_cast<PreDragStatus>(static_cast<int32_t>(preDragStatus) + 1);
1633         dragDropManager->SetPreDragStatus(nextPreDragStatus);
1634         onPreDragStatus = preDragStatus;
1635     }
1636     auto onPreDragFunc = eventHub->GetOnPreDrag();
1637     CHECK_NULL_VOID(onPreDragFunc);
1638     if (preDragStatus == PreDragStatus::PREVIEW_LIFT_FINISHED ||
1639         preDragStatus == PreDragStatus::PREVIEW_LANDING_FINISHED) {
1640         auto taskScheduler = mainPipeline->GetTaskExecutor();
1641         CHECK_NULL_VOID(taskScheduler);
1642         taskScheduler->PostTask(
1643             [onPreDragStatus, callback = onPreDragFunc]() {
1644                 CHECK_NULL_VOID(callback);
1645                 callback(onPreDragStatus);
1646             },
1647             TaskExecutor::TaskType::UI, "ArkUIDragExecutePreDrag");
1648     } else {
1649         onPreDragFunc(onPreDragStatus);
1650     }
1651 }
1652 
SetThumbnailCallback(std::function<void (Offset)> && callback)1653 void DragEventActuator::SetThumbnailCallback(std::function<void(Offset)>&& callback)
1654 {
1655     textDragCallback_ = callback;
1656     longPressRecognizer_->SetThumbnailCallback(std::move(callback));
1657 }
1658 
SetTextPixelMap(const RefPtr<GestureEventHub> & gestureHub)1659 void DragEventActuator::SetTextPixelMap(const RefPtr<GestureEventHub>& gestureHub)
1660 {
1661     auto frameNode = gestureHub->GetFrameNode();
1662     CHECK_NULL_VOID(frameNode);
1663     auto pattern = frameNode->GetPattern<TextDragBase>();
1664     CHECK_NULL_VOID(pattern);
1665 
1666     auto dragNode = pattern->MoveDragNode();
1667     pattern->CloseSelectOverlay();
1668     CHECK_NULL_VOID(dragNode);
1669     auto pixelMap = dragNode->GetRenderContext()->GetThumbnailPixelMap();
1670     if (textPixelMap_) {
1671         gestureHub->SetPixelMap(textPixelMap_);
1672         textPixelMap_ = nullptr;
1673     } else if (pixelMap) {
1674         gestureHub->SetPixelMap(pixelMap);
1675     } else {
1676         gestureHub->SetPixelMap(nullptr);
1677     }
1678 }
1679 
SetTextAnimation(const RefPtr<GestureEventHub> & gestureHub,const Offset & globalLocation)1680 void DragEventActuator::SetTextAnimation(const RefPtr<GestureEventHub>& gestureHub, const Offset& globalLocation)
1681 {
1682     TAG_LOGD(AceLogTag::ACE_DRAG, "DragEvent start set textAnimation.");
1683     auto pipelineContext = PipelineContext::GetCurrentContext();
1684     CHECK_NULL_VOID(pipelineContext);
1685     auto manager = pipelineContext->GetOverlayManager();
1686     CHECK_NULL_VOID(manager);
1687     manager->SetHasFilter(false);
1688     CHECK_NULL_VOID(gestureHub);
1689     auto frameNode = gestureHub->GetFrameNode();
1690     CHECK_NULL_VOID(frameNode);
1691     auto pattern = frameNode->GetPattern<TextDragBase>();
1692     auto textBase = frameNode->GetPattern<TextBase>();
1693     CHECK_NULL_VOID(pattern);
1694     CHECK_NULL_VOID(textBase);
1695     if (!textBase->BetweenSelectedPosition(globalLocation)) {
1696         TAG_LOGD(AceLogTag::ACE_DRAG, "Position is between selected position, stop set text animation.");
1697         return;
1698     }
1699     auto isHandlesShow = pattern->IsHandlesShow();
1700     auto dragNode = pattern->MoveDragNode();
1701     CHECK_NULL_VOID(dragNode);
1702     dragNode->SetDragPreviewOptions(frameNode->GetDragPreviewOption());
1703     // create columnNode
1704     auto columnNode = FrameNode::CreateFrameNode(V2::COLUMN_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
1705         AceType::MakeRefPtr<LinearLayoutPattern>(true));
1706     columnNode->AddChild(dragNode);
1707     auto columnRenderContext = columnNode->GetRenderContext();
1708     if (columnRenderContext) {
1709         columnRenderContext->UpdatePosition(OffsetT<Dimension>(Dimension(0.0f), Dimension(0.0f)));
1710     }
1711     // mount to rootNode
1712     manager->MountPixelMapToRootNode(columnNode);
1713     auto textDragPattern = dragNode->GetPattern<TextDragPattern>();
1714     CHECK_NULL_VOID(textDragPattern);
1715     auto modifier = textDragPattern->GetOverlayModifier();
1716     CHECK_NULL_VOID(modifier);
1717     modifier->UpdateHandlesShowFlag(isHandlesShow);
1718     auto renderContext = dragNode->GetRenderContext();
1719     if (renderContext) {
1720         textPixelMap_ = renderContext->GetThumbnailPixelMap();
1721     }
1722     modifier->StartFloatingAnimate();
1723     pattern->CloseHandleAndSelect();
1724     TAG_LOGD(AceLogTag::ACE_DRAG, "DragEvent set text animation success.");
1725 }
1726 
HideTextAnimation(bool startDrag,double globalX,double globalY)1727 void DragEventActuator::HideTextAnimation(bool startDrag, double globalX, double globalY)
1728 {
1729     TAG_LOGD(AceLogTag::ACE_DRAG, "DragEvent start hide text animation.");
1730     auto gestureHub = gestureEventHub_.Upgrade();
1731     CHECK_NULL_VOID(gestureHub);
1732     bool isAllowedDrag = IsAllowedDrag();
1733     if (!gestureHub->GetTextDraggable() || !isAllowedDrag) {
1734         TAG_LOGD(AceLogTag::ACE_DRAG, "Text is not draggable, stop set hide text animation.");
1735         return;
1736     }
1737     auto frameNode = gestureHub->GetFrameNode();
1738     CHECK_NULL_VOID(frameNode);
1739     auto pattern = frameNode->GetPattern<TextDragBase>();
1740     CHECK_NULL_VOID(pattern);
1741     auto node = pattern->MoveDragNode();
1742     CHECK_NULL_VOID(node);
1743     auto textDragPattern = node->GetPattern<TextDragPattern>();
1744     CHECK_NULL_VOID(textDragPattern);
1745     auto modifier = textDragPattern->GetOverlayModifier();
1746     CHECK_NULL_VOID(modifier);
1747     auto removeColumnNode = [id = Container::CurrentId(), startDrag, weakPattern = WeakPtr<TextDragBase>(pattern),
1748             weakEvent = gestureEventHub_, weakModifier = WeakPtr<TextDragOverlayModifier>(modifier)] {
1749         ContainerScope scope(id);
1750         if (!startDrag) {
1751             auto pattern = weakPattern.Upgrade();
1752             CHECK_NULL_VOID(pattern);
1753             auto modifier = weakModifier.Upgrade();
1754             CHECK_NULL_VOID(modifier);
1755             pattern->ShowHandles(modifier->IsHandlesShow());
1756         }
1757         auto pipeline = PipelineContext::GetCurrentContext();
1758         CHECK_NULL_VOID(pipeline);
1759         auto manager = pipeline->GetOverlayManager();
1760         CHECK_NULL_VOID(manager);
1761         manager->RemovePixelMap();
1762         TAG_LOGD(AceLogTag::ACE_DRAG, "In removeColumnNode callback, set DragWindowVisible true.");
1763         auto gestureHub = weakEvent.Upgrade();
1764         CHECK_NULL_VOID(gestureHub);
1765         if (!gestureHub->IsPixelMapNeedScale()) {
1766             InteractionInterface::GetInstance()->SetDragWindowVisible(true);
1767         }
1768         gestureHub->SetPixelMap(nullptr);
1769     };
1770     AnimationOption option;
1771     option.SetDuration(PIXELMAP_ANIMATION_DURATION);
1772     option.SetCurve(Curves::SHARP);
1773     option.SetOnFinishEvent(removeColumnNode);
1774 
1775     auto pipeline = PipelineContext::GetCurrentContext();
1776     CHECK_NULL_VOID(pipeline);
1777     auto manager = pipeline->GetOverlayManager();
1778     auto dragNode = manager->GetPixelMapNode();
1779     CHECK_NULL_VOID(dragNode);
1780     auto dragFrame = dragNode->GetGeometryNode()->GetFrameRect();
1781     auto frameWidth = dragFrame.Width();
1782     auto frameHeight = dragFrame.Height();
1783     auto pixelMap = gestureHub->GetPixelMap();
1784     float scale = 1.0f;
1785     if (pixelMap) {
1786         scale = gestureHub->GetPixelMapScale(pixelMap->GetHeight(), pixelMap->GetWidth());
1787     }
1788     auto context = dragNode->GetRenderContext();
1789     CHECK_NULL_VOID(context);
1790     context->UpdateTransformScale(VectorF(1.0f, 1.0f));
1791     AnimationUtils::Animate(
1792         option,
1793         [context, startDrag, globalX, globalY, frameWidth, frameHeight, scale]() {
1794             if (startDrag) {
1795                 context->UpdatePosition(OffsetT<Dimension>(Dimension(globalX + frameWidth * PIXELMAP_WIDTH_RATE),
1796                     Dimension(globalY + frameHeight * PIXELMAP_HEIGHT_RATE)));
1797                 context->UpdateTransformScale(VectorF(scale, scale));
1798                 context->OnModifyDone();
1799             }
1800         },
1801         option.GetOnFinishEvent());
1802     TAG_LOGD(AceLogTag::ACE_DRAG, "DragEvent set hide text animation success.");
1803 }
1804 
1805 // update ImageNode default attr before floating
SetImageNodeInitAttr(const RefPtr<FrameNode> & frameNode,const RefPtr<FrameNode> & imageNode)1806 void DragEventActuator::SetImageNodeInitAttr(const RefPtr<FrameNode>& frameNode, const RefPtr<FrameNode>& imageNode)
1807 {
1808     CHECK_NULL_VOID(imageNode);
1809     CHECK_NULL_VOID(frameNode);
1810     auto imageContext = imageNode->GetRenderContext();
1811     CHECK_NULL_VOID(imageContext);
1812     auto dragPreviewOption = frameNode->GetDragPreviewOption();
1813 
1814     // update default scale
1815     bool defaultAnimationBeforeLifting = dragPreviewOption.defaultAnimationBeforeLifting;
1816     if (defaultAnimationBeforeLifting) {
1817         auto layoutProperty = frameNode->GetLayoutProperty();
1818         if (layoutProperty) {
1819             layoutProperty->UpdateVisibility(VisibleType::INVISIBLE);
1820         }
1821         imageContext->UpdateTransformScale({ DEFAULT_ANIMATION_SCALE, DEFAULT_ANIMATION_SCALE });
1822     } else {
1823         imageContext->UpdateTransformScale({ 1.0f, 1.0f });
1824     }
1825 
1826     // update shadow
1827     auto shadow = Shadow::CreateShadow(ShadowStyle::None);
1828     if (dragPreviewOption.options.shadow.has_value()) {
1829         shadow = dragPreviewOption.options.shadow.value();
1830         shadow.SetColor(Color(0x00000000));
1831     }
1832     imageContext->UpdateBackShadow(shadow);
1833 
1834     // update radius
1835     BorderRadiusProperty borderRadius;
1836     borderRadius.SetRadius(0.0_vp);
1837     imageContext->UpdateBorderRadius(borderRadius);
1838 
1839     // update opacity
1840     imageContext->UpdateOpacity(1.0f);
1841 }
1842 
SetImageNodeFinishAttr(const RefPtr<FrameNode> & frameNode,const RefPtr<FrameNode> & imageNode)1843 void DragEventActuator::SetImageNodeFinishAttr(const RefPtr<FrameNode>& frameNode,
1844     const RefPtr<FrameNode>& imageNode)
1845 {
1846     CHECK_NULL_VOID(imageNode);
1847     CHECK_NULL_VOID(frameNode);
1848     auto imageContext = imageNode->GetRenderContext();
1849     CHECK_NULL_VOID(imageContext);
1850     auto dragPreviewOption = frameNode->GetDragPreviewOption();
1851     if (dragPreviewOption.options.shadow.has_value() && !dragPreviewOption.options.shadow->GetIsFilled()) {
1852         imageContext->UpdateBackShadow(dragPreviewOption.options.shadow.value());
1853     }
1854 }
1855 
GetIsBindOverlayValue(const RefPtr<DragEventActuator> & actuator)1856 bool DragEventActuator::GetIsBindOverlayValue(const RefPtr<DragEventActuator>& actuator)
1857 {
1858     auto gestureHub = actuator->gestureEventHub_.Upgrade();
1859     CHECK_NULL_RETURN(gestureHub, true);
1860     auto frameNode = gestureHub->GetFrameNode();
1861     CHECK_NULL_RETURN(frameNode, true);
1862     bool isBindOverlayValue = frameNode->GetLayoutProperty()->GetIsBindOverlayValue(false);
1863     return isBindOverlayValue;
1864 }
1865 
IsAllowedDrag()1866 bool DragEventActuator::IsAllowedDrag()
1867 {
1868     auto gestureHub = gestureEventHub_.Upgrade();
1869     CHECK_NULL_RETURN(gestureHub, false);
1870     auto frameNode = gestureHub->GetFrameNode();
1871     CHECK_NULL_RETURN(frameNode, false);
1872     auto eventHub = frameNode->GetEventHub<EventHub>();
1873     CHECK_NULL_RETURN(eventHub, false);
1874     bool isAllowedDrag = gestureHub->IsAllowedDrag(eventHub);
1875     return isAllowedDrag;
1876 }
1877 
CopyDragEvent(const RefPtr<DragEventActuator> & dragEventActuator)1878 void DragEventActuator::CopyDragEvent(const RefPtr<DragEventActuator>& dragEventActuator)
1879 {
1880     userCallback_ = dragEventActuator->userCallback_;
1881     customCallback_ = dragEventActuator->customCallback_;
1882     panRecognizer_ = MakeRefPtr<PanRecognizer>(fingers_, direction_, distance_);
1883     panRecognizer_->SetGestureInfo(MakeRefPtr<GestureInfo>(GestureTypeName::DRAG, GestureTypeName::DRAG, true));
1884     longPressRecognizer_ = AceType::MakeRefPtr<LongPressRecognizer>(LONG_PRESS_DURATION, fingers_, false, false);
1885     longPressRecognizer_->SetGestureInfo(MakeRefPtr<GestureInfo>(GestureTypeName::DRAG, GestureTypeName::DRAG, true));
1886     previewLongPressRecognizer_ =
1887         AceType::MakeRefPtr<LongPressRecognizer>(PREVIEW_LONG_PRESS_RECONGNIZER, fingers_, false, false);
1888     previewLongPressRecognizer_->SetGestureInfo(
1889         MakeRefPtr<GestureInfo>(GestureTypeName::DRAG, GestureTypeName::DRAG, true));
1890     isNotInPreviewState_ = false;
1891     actionStart_ = dragEventActuator->actionStart_;
1892     longPressUpdate_ = dragEventActuator->longPressUpdate_;
1893     actionCancel_ = dragEventActuator->actionCancel_;
1894     textDragCallback_ = dragEventActuator->textDragCallback_;
1895     longPressInfo_ = dragEventActuator->longPressInfo_;
1896 }
1897 
FlushSyncGeometryNodeTasks()1898 void DragEventActuator::FlushSyncGeometryNodeTasks()
1899 {
1900     auto pipeline = PipelineBase::GetCurrentContext();
1901     CHECK_NULL_VOID(pipeline);
1902     pipeline->FlushSyncGeometryNodeTasks();
1903 }
1904 
SetGatherNodeAboveFilter(const RefPtr<DragEventActuator> & actuator)1905 void DragEventActuator::SetGatherNodeAboveFilter(const RefPtr<DragEventActuator>& actuator)
1906 {
1907     CHECK_NULL_VOID(actuator);
1908     if (!actuator->IsNeedGather()) {
1909         return;
1910     }
1911     auto pipelineContext = PipelineContext::GetCurrentContext();
1912     CHECK_NULL_VOID(pipelineContext);
1913     auto manager = pipelineContext->GetOverlayManager();
1914     CHECK_NULL_VOID(manager);
1915     auto gestureHub = actuator->gestureEventHub_.Upgrade();
1916     CHECK_NULL_VOID(gestureHub);
1917     auto frameNode = gestureHub->GetFrameNode();
1918     CHECK_NULL_VOID(frameNode);
1919     auto gatherNode = manager->GetGatherNode();
1920     auto gatherNodeChildrenInfo = manager->GetGatherNodeChildrenInfo();
1921     manager->RemoveGatherNode();
1922     MountGatherNode(manager, frameNode, gatherNode, gatherNodeChildrenInfo);
1923 }
1924 
GetOrCreateGatherNode(const RefPtr<NG::OverlayManager> & overlayManager,const RefPtr<DragEventActuator> & actuator,std::vector<GatherNodeChildInfo> & gatherNodeChildrenInfo)1925 RefPtr<FrameNode> DragEventActuator::GetOrCreateGatherNode(const RefPtr<NG::OverlayManager>& overlayManager,
1926     const RefPtr<DragEventActuator>& actuator, std::vector<GatherNodeChildInfo>& gatherNodeChildrenInfo)
1927 {
1928     CHECK_NULL_RETURN(actuator, nullptr);
1929     if (!actuator->IsNeedGather()) {
1930         return nullptr;
1931     }
1932     auto gestureHub = actuator->gestureEventHub_.Upgrade();
1933     CHECK_NULL_RETURN(gestureHub, nullptr);
1934     auto frameNode = gestureHub->GetFrameNode();
1935     CHECK_NULL_RETURN(frameNode, nullptr);
1936     auto previewOptions = frameNode->GetDragPreviewOption();
1937     if (!previewOptions.isMultiSelectionEnabled) {
1938         return nullptr;
1939     }
1940     CHECK_NULL_RETURN(overlayManager, nullptr);
1941     auto gatherNode = overlayManager->GetGatherNode();
1942     if (!gatherNode) {
1943         auto gatherNode = CreateGatherNode(actuator);
1944         if (gatherNode) {
1945             MarkDirtyGatherNode(gatherNode);
1946         }
1947         gatherNodeChildrenInfo = actuator->GetGatherNodeChildrenInfo();
1948         actuator->ClearGatherNodeChildrenInfo();
1949         actuator->SetGatherNode(nullptr);
1950         return gatherNode;
1951     } else {
1952         gatherNodeChildrenInfo = overlayManager->GetGatherNodeChildrenInfo();
1953         overlayManager->RemoveGatherNode();
1954     }
1955     return gatherNode;
1956 }
1957 
CreateGatherNode(const RefPtr<DragEventActuator> & actuator)1958 RefPtr<FrameNode> DragEventActuator::CreateGatherNode(const RefPtr<DragEventActuator>& actuator)
1959 {
1960     CHECK_NULL_RETURN(actuator, nullptr);
1961     auto gestureHub = actuator->gestureEventHub_.Upgrade();
1962     CHECK_NULL_RETURN(gestureHub, nullptr);
1963     auto frameNode = gestureHub->GetFrameNode();
1964     CHECK_NULL_RETURN(frameNode, nullptr);
1965 
1966     auto pipelineContext = PipelineContext::GetCurrentContext();
1967     CHECK_NULL_RETURN(pipelineContext, nullptr);
1968     auto manager = pipelineContext->GetOverlayManager();
1969     CHECK_NULL_RETURN(manager, nullptr);
1970 
1971     if (manager->GetHasGatherNode()) {
1972         TAG_LOGW(AceLogTag::ACE_DRAG, "Not need create gather node, already have");
1973         return nullptr;
1974     }
1975 
1976     if (!actuator->IsNeedGather()) {
1977         TAG_LOGI(AceLogTag::ACE_DRAG, "Not need create gather node, not need gather");
1978         return nullptr;
1979     }
1980     auto fatherNode = actuator->itemParentNode_.Upgrade();
1981     CHECK_NULL_RETURN(fatherNode, nullptr);
1982     auto scrollPattern = fatherNode->GetPattern<ScrollablePattern>();
1983     CHECK_NULL_RETURN(scrollPattern, nullptr);
1984     auto children = scrollPattern->GetVisibleSelectedItems();
1985     if (children.size() < 1) {
1986         return nullptr;
1987     }
1988     auto stackNode = FrameNode::GetOrCreateFrameNode(V2::STACK_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
1989         []() { return AceType::MakeRefPtr<StackPattern>(); });
1990     actuator->ClearGatherNodeChildrenInfo();
1991     auto geometryNode = stackNode->GetGeometryNode();
1992     CHECK_NULL_RETURN(geometryNode, nullptr);
1993     geometryNode->SetFrameOffset({0.0f, 0.0f});
1994 
1995     for (auto iter = children.rbegin(); iter != children.rend(); iter++) {
1996         auto itemFrameNode = (*iter);
1997         if (itemFrameNode == frameNode) {
1998             continue;
1999         }
2000         GatherNodeChildInfo gatherNodeChildInfo;
2001         auto imageNode = CreateImageNode(itemFrameNode, gatherNodeChildInfo);
2002         CHECK_NULL_RETURN(imageNode, nullptr);
2003         stackNode->AddChild(imageNode);
2004         actuator->PushBackGatherNodeChild(gatherNodeChildInfo);
2005     }
2006     actuator->SetGatherNode(stackNode);
2007     TAG_LOGI(AceLogTag::ACE_DRAG, "Create gather node success, count %{public}d",
2008         static_cast<int32_t>(children.size()));
2009     return stackNode;
2010 }
2011 
CreateImageNode(const RefPtr<FrameNode> & frameNode,GatherNodeChildInfo & gatherNodeChildInfo)2012 RefPtr<FrameNode> DragEventActuator::CreateImageNode(const RefPtr<FrameNode>& frameNode,
2013     GatherNodeChildInfo& gatherNodeChildInfo)
2014 {
2015     auto context = frameNode->GetRenderContext();
2016     CHECK_NULL_RETURN(context, nullptr);
2017     GetFrameNodePreviewPixelMap(frameNode);
2018     auto gestureHub = frameNode->GetOrCreateGestureEventHub();
2019     CHECK_NULL_RETURN(gestureHub, nullptr);
2020     auto pixelMap = gestureHub->GetDragPreviewPixelMap();
2021     int32_t width = 0;
2022     int32_t height = 0;
2023     if (pixelMap) {
2024         width = pixelMap->GetWidth();
2025         height = pixelMap->GetHeight();
2026     }
2027     auto offset = GetFloatImageOffset(frameNode, pixelMap);
2028     auto imageNode = FrameNode::GetOrCreateFrameNode(V2::IMAGE_ETS_TAG,
2029         ElementRegister::GetInstance()->MakeUniqueId(), []() { return AceType::MakeRefPtr<ImagePattern>(); });
2030 
2031     imageNode->SetDragPreviewOptions(frameNode->GetDragPreviewOption());
2032     auto renderProps = imageNode->GetPaintProperty<ImageRenderProperty>();
2033     CHECK_NULL_RETURN(renderProps, nullptr);
2034     renderProps->UpdateImageInterpolation(ImageInterpolation::HIGH);
2035     renderProps->UpdateNeedBorderRadius(false);
2036     auto props = imageNode->GetLayoutProperty<ImageLayoutProperty>();
2037     CHECK_NULL_RETURN(props, nullptr);
2038     props->UpdateAutoResize(false);
2039     props->UpdateImageSourceInfo(ImageSourceInfo(pixelMap));
2040     auto targetSize = CalcSize(NG::CalcLength(width), NG::CalcLength(height));
2041     props->UpdateUserDefinedIdealSize(targetSize);
2042     auto imageContext = imageNode->GetRenderContext();
2043     CHECK_NULL_RETURN(imageContext, nullptr);
2044     imageContext->UpdatePosition(OffsetT<Dimension>(Dimension(offset.GetX()), Dimension(offset.GetY())));
2045     Vector5F rotate = Vector5F(0.0f, 0.0f, 1.0f, 0.0f, 0.0f);
2046     imageContext->UpdateTransformRotate(rotate);
2047     imageContext->UpdateClipEdge(true);
2048     imageContext->UpdateBorderRadius(BorderRadiusProperty(Dimension()));
2049     imageContext->UpdateOpacity(1.0f);
2050     ClickEffectInfo clickEffectInfo;
2051     clickEffectInfo.level = ClickEffectLevel::LIGHT;
2052     clickEffectInfo.scaleNumber = SCALE_NUMBER;
2053     imageContext->UpdateClickEffectLevel(clickEffectInfo);
2054 
2055     gatherNodeChildInfo = {imageNode, offset, width, height, width / 2.0f, height / 2.0f};
2056     return imageNode;
2057 }
2058 
MarkDirtyGatherNode(const RefPtr<FrameNode> & gatherNode)2059 void DragEventActuator::MarkDirtyGatherNode(const RefPtr<FrameNode>& gatherNode)
2060 {
2061     CHECK_NULL_VOID(gatherNode);
2062     gatherNode->MarkModifyDone();
2063     gatherNode->SetLayoutDirtyMarked(true);
2064     auto context = gatherNode->GetContext();
2065     if (context) {
2066         context->FlushUITaskWithSingleDirtyNode(gatherNode);
2067     }
2068 
2069     auto children = gatherNode->GetChildren();
2070     for (const auto& child : children) {
2071         CHECK_NULL_VOID(child);
2072         auto imageNode = AceType::DynamicCast<FrameNode>(child);
2073         CHECK_NULL_VOID(imageNode);
2074         imageNode->MarkModifyDone();
2075         imageNode->SetLayoutDirtyMarked(true);
2076         if (context) {
2077             context->FlushUITaskWithSingleDirtyNode(imageNode);
2078         }
2079     }
2080 }
2081 
ResetNode(const RefPtr<FrameNode> & frameNode)2082 void DragEventActuator::ResetNode(const RefPtr<FrameNode>& frameNode)
2083 {
2084     CHECK_NULL_VOID(frameNode);
2085     bool defaultAnimationBeforeLifting = frameNode->GetDragPreviewOption().defaultAnimationBeforeLifting;
2086     if (!defaultAnimationBeforeLifting) {
2087         return;
2088     }
2089     auto frameContext = frameNode->GetRenderContext();
2090     CHECK_NULL_VOID(frameContext);
2091     frameContext->UpdateTransformScale({ 1.0f, 1.0f });
2092     auto layoutProperty = frameNode->GetLayoutProperty();
2093     if (layoutProperty) {
2094         layoutProperty->UpdateVisibility(VisibleType::VISIBLE);
2095     }
2096 }
2097 
MountGatherNode(const RefPtr<OverlayManager> & overlayManager,const RefPtr<FrameNode> & frameNode,const RefPtr<FrameNode> & gatherNode,const std::vector<GatherNodeChildInfo> & gatherNodeChildrenInfo)2098 void DragEventActuator::MountGatherNode(const RefPtr<OverlayManager>& overlayManager,
2099     const RefPtr<FrameNode>& frameNode, const RefPtr<FrameNode>& gatherNode,
2100     const std::vector<GatherNodeChildInfo>& gatherNodeChildrenInfo)
2101 {
2102     if (!overlayManager || !frameNode || !gatherNode) {
2103         return;
2104     }
2105     TAG_LOGI(AceLogTag::ACE_DRAG, "Mount gather node");
2106     auto container = Container::Current();
2107     if (container && container->IsScenceBoardWindow()) {
2108         auto windowScene = overlayManager->FindWindowScene(frameNode);
2109         overlayManager->MountGatherNodeToWindowScene(gatherNode, gatherNodeChildrenInfo, windowScene);
2110     } else {
2111         overlayManager->MountGatherNodeToRootNode(gatherNode, gatherNodeChildrenInfo);
2112     }
2113     MarkDirtyGatherNode(gatherNode);
2114 }
2115 
GetFrameNodePreviewPixelMap(const RefPtr<FrameNode> & frameNode)2116 void DragEventActuator::GetFrameNodePreviewPixelMap(const RefPtr<FrameNode>& frameNode)
2117 {
2118     CHECK_NULL_VOID(frameNode);
2119     auto gestureHub = frameNode->GetOrCreateGestureEventHub();
2120     CHECK_NULL_VOID(gestureHub);
2121     auto dragPreviewInfo = frameNode->GetDragPreview();
2122     auto pipeline = PipelineContext::GetCurrentContext();
2123     CHECK_NULL_VOID(pipeline);
2124     if (dragPreviewInfo.inspectorId != "") {
2125         auto previewPixelMap = GetPreviewPixelMap(dragPreviewInfo.inspectorId, frameNode);
2126         gestureHub->SetDragPreviewPixelMap(previewPixelMap);
2127         return;
2128     } else if (dragPreviewInfo.pixelMap != nullptr) {
2129         gestureHub->SetDragPreviewPixelMap(dragPreviewInfo.pixelMap);
2130         return;
2131     }
2132     auto context = frameNode->GetRenderContext();
2133     CHECK_NULL_VOID(context);
2134     auto pixelMap = context->GetThumbnailPixelMap(true);
2135     gestureHub->SetDragPreviewPixelMap(pixelMap);
2136 }
2137 
IsBelongToMultiItemNode(const RefPtr<FrameNode> & frameNode)2138 bool DragEventActuator::IsBelongToMultiItemNode(const RefPtr<FrameNode>& frameNode)
2139 {
2140     CHECK_NULL_RETURN(frameNode, false);
2141     auto pipeline = PipelineContext::GetCurrentContext();
2142     CHECK_NULL_RETURN(pipeline, false);
2143     auto dragDropManager = pipeline->GetDragDropManager();
2144     CHECK_NULL_RETURN(dragDropManager, false);
2145     if (IsSelectedItemNode(frameNode)) {
2146         isSelectedItemNode_ = true;
2147         FindItemParentNode(frameNode);
2148         return false;
2149     }
2150     isSelectedItemNode_ = false;
2151     auto uiNode = frameNode->GetParent();
2152     CHECK_NULL_RETURN(uiNode, false);
2153     while (!IsSelectedItemNode(uiNode)) {
2154         uiNode = uiNode->GetParent();
2155         CHECK_NULL_RETURN(uiNode, false);
2156     }
2157     return true;
2158 }
2159 
IsSelectedItemNode(const RefPtr<UINode> & uiNode)2160 bool DragEventActuator::IsSelectedItemNode(const RefPtr<UINode>& uiNode)
2161 {
2162     auto frameNode = AceType::DynamicCast<FrameNode>(uiNode);
2163     CHECK_NULL_RETURN(frameNode, false);
2164     auto gestureHub = frameNode->GetOrCreateGestureEventHub();
2165     CHECK_NULL_RETURN(gestureHub, false);
2166     auto eventHub = frameNode->GetEventHub<EventHub>();
2167     CHECK_NULL_RETURN(eventHub, false);
2168     auto dragPreview = frameNode->GetDragPreviewOption();
2169     if (!dragPreview.isMultiSelectionEnabled) {
2170         return false;
2171     }
2172     bool isAllowedDrag = gestureHub->IsAllowedDrag(eventHub);
2173     if (!isAllowedDrag) {
2174         return false;
2175     }
2176     if (frameNode->GetTag() == V2::GRID_ITEM_ETS_TAG) {
2177         auto itemPattern = frameNode->GetPattern<GridItemPattern>();
2178         CHECK_NULL_RETURN(itemPattern, false);
2179         if (itemPattern->IsSelected()) {
2180             return true;
2181         }
2182     }
2183     if (frameNode->GetTag() == V2::LIST_ITEM_ETS_TAG) {
2184         auto itemPattern = frameNode->GetPattern<ListItemPattern>();
2185         CHECK_NULL_RETURN(itemPattern, false);
2186         if (itemPattern->IsSelected()) {
2187             return true;
2188         }
2189     }
2190     return false;
2191 }
2192 
FindItemParentNode(const RefPtr<FrameNode> & frameNode)2193 void DragEventActuator::FindItemParentNode(const RefPtr<FrameNode>& frameNode)
2194 {
2195     itemParentNode_ = nullptr;
2196     CHECK_NULL_VOID(frameNode);
2197     if (frameNode->GetTag() != V2::GRID_ITEM_ETS_TAG && frameNode->GetTag() != V2::LIST_ITEM_ETS_TAG) {
2198         return;
2199     }
2200     auto parentType = frameNode->GetTag() == V2::GRID_ITEM_ETS_TAG ? V2::GRID_ETS_TAG : V2::LIST_ETS_TAG;
2201     auto uiNode = frameNode->GetParent();
2202     CHECK_NULL_VOID(uiNode);
2203     while (uiNode->GetTag() != parentType) {
2204         uiNode = uiNode->GetParent();
2205         CHECK_NULL_VOID(uiNode);
2206     }
2207     auto parentNode = AceType::DynamicCast<FrameNode>(uiNode);
2208     itemParentNode_ = parentNode;
2209 }
2210 
IsNeedGather() const2211 bool DragEventActuator::IsNeedGather() const
2212 {
2213     auto fatherNode = itemParentNode_.Upgrade();
2214     CHECK_NULL_RETURN(fatherNode, false);
2215     auto scrollPattern = fatherNode->GetPattern<ScrollablePattern>();
2216     CHECK_NULL_RETURN(scrollPattern, false);
2217     auto children = scrollPattern->GetVisibleSelectedItems();
2218     if (!isSelectedItemNode_ || children.size() < 1) {
2219         return false;
2220     }
2221     return true;
2222 }
2223 
AddTouchListener(const TouchRestrict & touchRestrict)2224 void DragEventActuator::AddTouchListener(const TouchRestrict& touchRestrict)
2225 {
2226     CHECK_NULL_VOID(userCallback_);
2227     auto gestureHub = gestureEventHub_.Upgrade();
2228     CHECK_NULL_VOID(gestureHub);
2229     auto frameNode = gestureHub->GetFrameNode();
2230     CHECK_NULL_VOID(frameNode);
2231     if (!IsGlobalStatusSuitableForDragging() || !IsCurrentNodeStatusSuitableForDragging(frameNode, touchRestrict)) {
2232         gestureHub->RemoveTouchEvent(touchListener_);
2233         return;
2234     }
2235     auto focusHub = frameNode->GetFocusHub();
2236     bool hasContextMenuUsingGesture = focusHub ?
2237         focusHub->FindContextMenuOnKeyEvent(OnKeyEventType::CONTEXT_MENU) : false;
2238     auto touchTask = [hasContextMenuUsingGesture, weak = WeakClaim(this)](const TouchEventInfo& info) {
2239         auto actuator = weak.Upgrade();
2240         CHECK_NULL_VOID(actuator);
2241         if (info.GetTouches().empty()) {
2242             return;
2243         }
2244         if (info.GetTouches().front().GetTouchType() == TouchType::UP) {
2245             actuator->HandleTouchUpEvent();
2246         } else if (info.GetTouches().front().GetTouchType() == TouchType::CANCEL) {
2247             actuator->HandleTouchCancelEvent();
2248         } else if (info.GetTouches().front().GetTouchType() == TouchType::MOVE) {
2249             if (hasContextMenuUsingGesture) {
2250                 auto point = Point(info.GetTouches().front().GetGlobalLocation().GetX(),
2251                                    info.GetTouches().front().GetGlobalLocation().GetY());
2252                 actuator->HandleDragDampingMove(point, info.GetTouches().front().GetFingerId());
2253             }
2254             actuator->HandleTouchMoveEvent();
2255         }
2256     };
2257     gestureHub->RemoveTouchEvent(touchListener_);
2258     touchListener_ = AceType::MakeRefPtr<TouchEventImpl>(std::move(touchTask));
2259     gestureHub->AddTouchEvent(touchListener_);
2260 }
2261 
HandleTouchUpEvent()2262 void DragEventActuator::HandleTouchUpEvent()
2263 {
2264     auto pipelineContext = PipelineContext::GetCurrentContext();
2265     CHECK_NULL_VOID(pipelineContext);
2266     auto dragDropManager = pipelineContext->GetDragDropManager();
2267     CHECK_NULL_VOID(dragDropManager);
2268     dragDropManager->SetHasGatherNode(false);
2269     DragAnimationHelper::PlayNodeResetAnimation(Claim(this));
2270     ResetResponseRegion();
2271     auto manager = pipelineContext->GetOverlayManager();
2272     CHECK_NULL_VOID(manager);
2273     if (IsNeedGather() && !manager->IsGatherWithMenu()) {
2274         SetGatherNode(nullptr);
2275         ClearGatherNodeChildrenInfo();
2276         auto manager = pipelineContext->GetOverlayManager();
2277         CHECK_NULL_VOID(manager);
2278         manager->RemoveGatherNodeWithAnimation();
2279     }
2280 }
2281 
HandleTouchCancelEvent()2282 void DragEventActuator::HandleTouchCancelEvent()
2283 {
2284     auto pipelineContext = PipelineContext::GetCurrentContext();
2285     CHECK_NULL_VOID(pipelineContext);
2286     auto dragDropManager = pipelineContext->GetDragDropManager();
2287     CHECK_NULL_VOID(dragDropManager);
2288     dragDropManager->SetHasGatherNode(false);
2289     ResetResponseRegion();
2290 }
2291 
HandleTouchMoveEvent()2292 void DragEventActuator::HandleTouchMoveEvent()
2293 {
2294     if (longPressRecognizer_ && isOnBeforeLiftingAnimation &&
2295         longPressRecognizer_->GetGestureDisposal() == GestureDisposal::REJECT) {
2296         SetGatherNode(nullptr);
2297         ClearGatherNodeChildrenInfo();
2298         auto pipelineContext = PipelineContext::GetCurrentContext();
2299         CHECK_NULL_VOID(pipelineContext);
2300         auto manager = pipelineContext->GetOverlayManager();
2301         CHECK_NULL_VOID(manager);
2302         manager->RemoveGatherNode();
2303         isOnBeforeLiftingAnimation = false;
2304         ResetResponseRegion();
2305     }
2306 }
2307 
SetGatherNode(const RefPtr<FrameNode> & gatherNode)2308 void DragEventActuator::SetGatherNode(const RefPtr<FrameNode>& gatherNode)
2309 {
2310     gatherNode_ = gatherNode;
2311 }
2312 
GetGatherNode() const2313 RefPtr<FrameNode> DragEventActuator::GetGatherNode() const
2314 {
2315     return gatherNode_;
2316 }
2317 
GetGatherNodeChildrenInfo() const2318 const std::vector<GatherNodeChildInfo>& DragEventActuator::GetGatherNodeChildrenInfo() const
2319 {
2320     return gatherNodeChildrenInfo_;
2321 }
2322 
ClearGatherNodeChildrenInfo()2323 void DragEventActuator::ClearGatherNodeChildrenInfo()
2324 {
2325     gatherNodeChildrenInfo_.clear();
2326 }
2327 
PushBackGatherNodeChild(GatherNodeChildInfo & gatherNodeChild)2328 void DragEventActuator::PushBackGatherNodeChild(GatherNodeChildInfo& gatherNodeChild)
2329 {
2330     gatherNodeChildrenInfo_.emplace_back(gatherNodeChild);
2331 }
2332 
GetItemParentNode() const2333 const RefPtr<FrameNode> DragEventActuator::GetItemParentNode() const
2334 {
2335     return itemParentNode_.Upgrade();
2336 }
2337 
GetFrameNode()2338 RefPtr<FrameNode> DragEventActuator::GetFrameNode()
2339 {
2340     auto gestureHub = gestureEventHub_.Upgrade();
2341     CHECK_NULL_RETURN(gestureHub, nullptr);
2342     auto frameNode = gestureHub->GetFrameNode();
2343     return frameNode;
2344 }
2345 
PrepareShadowParametersForDragData(const RefPtr<FrameNode> & frameNode,std::unique_ptr<JsonValue> & arkExtraInfoJson,float scale)2346 void DragEventActuator::PrepareShadowParametersForDragData(const RefPtr<FrameNode>& frameNode,
2347     std::unique_ptr<JsonValue>& arkExtraInfoJson, float scale)
2348 {
2349     CHECK_NULL_VOID(frameNode);
2350     CHECK_NULL_VOID(arkExtraInfoJson);
2351     auto dragPreviewOption = frameNode->GetDragPreviewOption();
2352     auto shadow = dragPreviewOption.options.shadow;
2353     if (!shadow.has_value() || !shadow->IsValid()) {
2354         arkExtraInfoJson->Put("shadow_enable", false);
2355         return;
2356     }
2357     auto frameTag = frameNode->GetTag();
2358     auto gestureHub = frameNode->GetOrCreateGestureEventHub();
2359     CHECK_NULL_VOID(gestureHub);
2360     if (gestureHub->IsTextCategoryComponent(frameTag) && gestureHub->GetTextDraggable() &&
2361         gestureHub->GetIsTextDraggable()) {
2362         auto stringPath = dragPreviewOption.options.shadowPath;
2363         RSPath path;
2364         if (path.BuildFromSVGString(stringPath)) {
2365             RSMatrix matrix;
2366             matrix.Set(RSMatrix::SCALE_X, scale);
2367             matrix.Set(RSMatrix::SCALE_Y, scale);
2368             path.Transform(matrix);
2369             stringPath = path.ConvertToSVGString();
2370         }
2371         arkExtraInfoJson->Put("drag_type", "text");
2372         arkExtraInfoJson->Put("drag_shadow_path", stringPath.c_str());
2373     } else {
2374         arkExtraInfoJson->Put("drag_type", "non-text");
2375     }
2376     arkExtraInfoJson->Put("shadow_enable", true);
2377     ParseShadowInfo(shadow.value(), arkExtraInfoJson);
2378 }
2379 
ParseShadowInfo(Shadow & shadow,std::unique_ptr<JsonValue> & arkExtraInfoJson)2380 void DragEventActuator::ParseShadowInfo(Shadow& shadow, std::unique_ptr<JsonValue>& arkExtraInfoJson)
2381 {
2382     arkExtraInfoJson->Put("shadow_is_filled", shadow.GetIsFilled());
2383     arkExtraInfoJson->Put("drag_shadow_OffsetX", shadow.GetOffset().GetX());
2384     arkExtraInfoJson->Put("drag_shadow_OffsetY", shadow.GetOffset().GetY());
2385     arkExtraInfoJson->Put("shadow_mask", shadow.GetShadowType() == ShadowType::BLUR);
2386     int32_t argb = static_cast<int32_t>(shadow.GetColor().GetValue());
2387     arkExtraInfoJson->Put("drag_shadow_argb", argb);
2388     int64_t strategy = static_cast<int64_t>(shadow.GetShadowColorStrategy());
2389     arkExtraInfoJson->Put("shadow_color_strategy", strategy);
2390     arkExtraInfoJson->Put("shadow_corner", shadow.GetBlurRadius());
2391     arkExtraInfoJson->Put("shadow_elevation", shadow.GetElevation());
2392     arkExtraInfoJson->Put("shadow_is_hardwareacceleration", shadow.GetHardwareAcceleration());
2393 }
2394 
GetDefaultShadow()2395 std::optional<Shadow> DragEventActuator::GetDefaultShadow()
2396 {
2397     auto pipelineContext = PipelineContext::GetCurrentContext();
2398     CHECK_NULL_RETURN(pipelineContext, std::nullopt);
2399     auto shadowTheme = pipelineContext->GetTheme<ShadowTheme>();
2400     CHECK_NULL_RETURN(shadowTheme, std::nullopt);
2401     auto colorMode = SystemProperties::GetColorMode();
2402     auto shadow = shadowTheme->GetShadow(ShadowStyle::OuterFloatingSM, colorMode);
2403     shadow.SetIsFilled(true);
2404     return shadow;
2405 }
2406 
PrepareRadiusParametersForDragData(const RefPtr<FrameNode> & frameNode,std::unique_ptr<JsonValue> & arkExtraInfoJson)2407 void DragEventActuator::PrepareRadiusParametersForDragData(const RefPtr<FrameNode>& frameNode,
2408     std::unique_ptr<JsonValue>& arkExtraInfoJson)
2409 {
2410     CHECK_NULL_VOID(frameNode);
2411     CHECK_NULL_VOID(arkExtraInfoJson);
2412     auto dragPreviewOption = frameNode->GetDragPreviewOption();
2413     auto borderRadius = dragPreviewOption.options.borderRadius;
2414     if (borderRadius.has_value()) {
2415         if (borderRadius.value().radiusTopLeft.has_value()) {
2416             arkExtraInfoJson->Put("drag_corner_radius1", borderRadius.value().radiusTopLeft.value().Value());
2417         }
2418         if (borderRadius.value().radiusTopRight.has_value()) {
2419             arkExtraInfoJson->Put("drag_corner_radius2", borderRadius.value().radiusTopRight.value().Value());
2420         }
2421         if (borderRadius.value().radiusBottomRight.has_value()) {
2422             arkExtraInfoJson->Put("drag_corner_radius3", borderRadius.value().radiusBottomRight.value().Value());
2423         }
2424         if (borderRadius.value().radiusBottomLeft.has_value()) {
2425             arkExtraInfoJson->Put("drag_corner_radius4", borderRadius.value().radiusBottomLeft.value().Value());
2426         }
2427     }
2428 }
2429 
GetDefaultBorderRadius()2430 std::optional<BorderRadiusProperty> DragEventActuator::GetDefaultBorderRadius()
2431 {
2432     BorderRadiusProperty borderRadius;
2433     borderRadius.SetRadius(PREVIEW_BORDER_RADIUS);
2434     return borderRadius;
2435 }
2436 
ShowPreviewBadgeAnimation(const RefPtr<DragEventActuator> & actuator,const RefPtr<OverlayManager> & manager)2437 void DragEventActuator::ShowPreviewBadgeAnimation(
2438     const RefPtr<DragEventActuator>& actuator, const RefPtr<OverlayManager>& manager)
2439 {
2440     auto gestureEventHub = actuator->gestureEventHub_.Upgrade();
2441     CHECK_NULL_VOID(gestureEventHub);
2442     auto frameNode = gestureEventHub->GetFrameNode();
2443     CHECK_NULL_VOID(frameNode);
2444     auto dragPreviewOptions = frameNode->GetDragPreviewOption();
2445     auto badgeNumber = dragPreviewOptions.GetCustomerBadgeNumber();
2446     int32_t childSize = badgeNumber.has_value() ? badgeNumber.value()
2447                                             : static_cast<int32_t>(manager->GetGatherNodeChildrenInfo().size()) + 1;
2448     auto textNode = CreateBadgeTextNode(frameNode, childSize, PIXELMAP_DRAG_SCALE_MULTIPLE, true);
2449     CHECK_NULL_VOID(textNode);
2450     auto column = manager->GetPixelMapNode();
2451     CHECK_NULL_VOID(column);
2452     column->AddChild(textNode);
2453 
2454     DragAnimationHelper::ShowBadgeAnimation(textNode);
2455 }
2456 
CreateBadgeTextNode(const RefPtr<FrameNode> & frameNode,int32_t childSize,float previewScale,bool isUsePixelMapOffset,OffsetF previewOffset)2457 RefPtr<FrameNode> DragEventActuator::CreateBadgeTextNode(const RefPtr<FrameNode>& frameNode, int32_t childSize,
2458     float previewScale, bool isUsePixelMapOffset, OffsetF previewOffset)
2459 {
2460     if (childSize <= 1) {
2461         return nullptr;
2462     }
2463     CHECK_NULL_RETURN(frameNode, nullptr);
2464     auto textNode = FrameNode::GetOrCreateFrameNode(V2::TEXT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
2465         []() { return AceType::MakeRefPtr<TextPattern>(); });
2466     CHECK_NULL_RETURN(textNode, nullptr);
2467     auto badgeLength = std::to_string(childSize).size();
2468     DragAnimationHelper::UpdateBadgeLayoutAndRenderContext(textNode, badgeLength, childSize);
2469 
2470     auto textRenderContext = textNode->GetRenderContext();
2471     CHECK_NULL_RETURN(textRenderContext, nullptr);
2472     auto pixelMap = frameNode->GetPixelMap();
2473     CHECK_NULL_RETURN(pixelMap, nullptr);
2474     auto width = pixelMap->GetWidth();
2475     auto height = pixelMap->GetHeight();
2476     auto offset = isUsePixelMapOffset ? GetFloatImageOffset(frameNode, pixelMap) : frameNode->GetPaintRectOffset();
2477     if (!previewOffset.NonOffset()) {
2478         offset = previewOffset;
2479     }
2480     double textOffsetX = offset.GetX() + width * (previewScale + 1) / 2 -
2481         BADGE_RELATIVE_OFFSET.ConvertToPx() - (BADGE_RELATIVE_OFFSET.ConvertToPx() * badgeLength);
2482     double textOffsetY = offset.GetY() - height * (previewScale - 1) / 2 - BADGE_RELATIVE_OFFSET.ConvertToPx();
2483     textRenderContext->UpdatePosition(OffsetT<Dimension>(Dimension(textOffsetX), Dimension(textOffsetY)));
2484     textNode->MarkDirtyNode(NG::PROPERTY_UPDATE_MEASURE);
2485     textNode->MarkModifyDone();
2486     textNode->SetLayoutDirtyMarked(true);
2487     textNode->SetActive(true);
2488     auto context = textNode->GetContext();
2489     if (context) {
2490         context->FlushUITaskWithSingleDirtyNode(textNode);
2491     }
2492     FlushSyncGeometryNodeTasks();
2493     return textNode;
2494 }
2495 
GetThumbnailPixelMapAsync(const RefPtr<GestureEventHub> & gestureHub)2496 void DragEventActuator::GetThumbnailPixelMapAsync(const RefPtr<GestureEventHub>& gestureHub)
2497 {
2498     CHECK_NULL_VOID(gestureHub);
2499     auto callback = [id = Container::CurrentId(), weakGestureHub = AceType::WeakClaim(AceType::RawPtr(gestureHub))](
2500                         const RefPtr<PixelMap>& pixelMap) {
2501         ContainerScope scope(id);
2502         if (pixelMap != nullptr) {
2503             auto taskScheduler = Container::CurrentTaskExecutor();
2504             CHECK_NULL_VOID(taskScheduler);
2505             auto gestureHub = weakGestureHub.Upgrade();
2506             CHECK_NULL_VOID(gestureHub);
2507             taskScheduler->PostTask(
2508                 [gestureHub, pixelMap]() {
2509                     CHECK_NULL_VOID(gestureHub);
2510                     gestureHub->SetPixelMap(pixelMap);
2511                     TAG_LOGI(AceLogTag::ACE_DRAG, "Set thumbnail pixelMap async success.");
2512                 },
2513                 TaskExecutor::TaskType::UI, "ArkUIDragSetPixelMap");
2514         }
2515     };
2516     auto frameNode = gestureHub->GetFrameNode();
2517     CHECK_NULL_VOID(frameNode);
2518     auto context = frameNode->GetRenderContext();
2519     CHECK_NULL_VOID(context);
2520     if (!context->CreateThumbnailPixelMapAsyncTask(true, std::move(callback))) {
2521         DragDropBehaviorReporter::GetInstance().UpdateDragStartResult(DragStartResult::SNAPSHOT_FAIL);
2522         TAG_LOGW(AceLogTag::ACE_DRAG, "Create thumbnail pixelMap async task failed!");
2523     }
2524 }
2525 
SetResponseRegionFull()2526 void DragEventActuator::SetResponseRegionFull()
2527 {
2528     if (!IsNeedGather() || isResponseRegionFull) {
2529         return;
2530     }
2531     auto gestureHub = gestureEventHub_.Upgrade();
2532     CHECK_NULL_VOID(gestureHub);
2533 
2534     responseRegion_ = gestureHub->GetResponseRegion();
2535     DimensionRect hotZoneRegion;
2536 
2537     auto frameNode = gestureHub->GetFrameNode();
2538     CHECK_NULL_VOID(frameNode);
2539     auto renderContext = frameNode->GetRenderContext();
2540     CHECK_NULL_VOID(renderContext);
2541     auto paintRect = renderContext->GetPaintRectWithoutTransform();
2542     hotZoneRegion.SetOffset(DimensionOffset(Dimension(-paintRect.GetOffset().GetX()),
2543         Dimension(-paintRect.GetOffset().GetY())));
2544 
2545     auto pipelineContext = frameNode->GetContextRefPtr();
2546     CHECK_NULL_VOID(pipelineContext);
2547     auto rootNode = pipelineContext->GetRootElement();
2548     CHECK_NULL_VOID(rootNode);
2549     auto geometryNode = rootNode->GetGeometryNode();
2550     CHECK_NULL_VOID(geometryNode);
2551     auto width = geometryNode->GetFrameSize().Width();
2552     auto height = geometryNode->GetFrameSize().Height();
2553     hotZoneRegion.SetSize(DimensionSize(Dimension(width), Dimension(height)));
2554     gestureHub->SetResponseRegion(std::vector<DimensionRect>({ hotZoneRegion }));
2555     isResponseRegionFull = true;
2556 }
2557 
ResetResponseRegion()2558 void DragEventActuator::ResetResponseRegion()
2559 {
2560     if (isResponseRegionFull) {
2561         auto gestureHub = gestureEventHub_.Upgrade();
2562         CHECK_NULL_VOID(gestureHub);
2563         gestureHub->SetResponseRegion(responseRegion_);
2564         isResponseRegionFull = false;
2565     }
2566 }
2567 
PrepareFinalPixelMapForDragThroughTouch(RefPtr<PixelMap> pixelMap,bool immediately)2568 void DragEventActuator::PrepareFinalPixelMapForDragThroughTouch(RefPtr<PixelMap> pixelMap, bool immediately)
2569 {
2570     ResetPreScaledPixelMapForDragThroughTouch();
2571     auto pipeline = PipelineContext::GetCurrentContext();
2572     CHECK_NULL_VOID(pipeline);
2573     auto dragDropManager = pipeline->GetDragDropManager();
2574     CHECK_NULL_VOID(dragDropManager);
2575     auto windowScale = dragDropManager->GetWindowScale();
2576     float scale = windowScale * PIXELMAP_DRAG_SCALE_MULTIPLE;
2577 
2578     auto task = [weak = WeakClaim(this), pixelMap, scale] () {
2579         auto actuator = weak.Upgrade();
2580         CHECK_NULL_VOID(actuator);
2581         actuator->DoPixelMapScaleForDragThroughTouch(pixelMap, scale);
2582     };
2583 
2584     if (immediately) {
2585         task();
2586         return;
2587     }
2588 
2589     auto taskScheduler = pipeline->GetTaskExecutor();
2590     CHECK_NULL_VOID(taskScheduler);
2591     taskScheduler->PostTask(task, TaskExecutor::TaskType::UI, "ArkUIPrepareScaledPixel", PriorityType::VIP);
2592 }
2593 
DoPixelMapScaleForDragThroughTouch(RefPtr<PixelMap> pixelMap,float targetScale)2594 void DragEventActuator::DoPixelMapScaleForDragThroughTouch(RefPtr<PixelMap> pixelMap, float targetScale)
2595 {
2596 #if defined(PIXEL_MAP_SUPPORTED)
2597     preScaledPixelMap_ = PixelMap::CopyPixelMap(pixelMap);
2598     if (!preScaledPixelMap_) {
2599         TAG_LOGW(AceLogTag::ACE_DRAG, "Copy preScaledPixelMap_ is failure!");
2600         return;
2601     }
2602     preScaledPixelMap_->Scale(targetScale, targetScale, AceAntiAliasingOption::HIGH);
2603     preScaleValue_ = targetScale;
2604 #endif
2605 }
2606 
GetPreScaledPixelMapForDragThroughTouch(float & preScale)2607 RefPtr<PixelMap> DragEventActuator::GetPreScaledPixelMapForDragThroughTouch(float& preScale)
2608 {
2609     preScale = preScaleValue_;
2610     return preScaledPixelMap_;
2611 }
2612 
ResetPreScaledPixelMapForDragThroughTouch()2613 void DragEventActuator::ResetPreScaledPixelMapForDragThroughTouch()
2614 {
2615     preScaledPixelMap_ = nullptr;
2616     preScaleValue_ = 1.0f;
2617 }
2618 
RecordMenuWrapperNodeForDrag(int32_t targetId)2619 void DragEventActuator::RecordMenuWrapperNodeForDrag(int32_t targetId)
2620 {
2621     auto subWindow = SubwindowManager::GetInstance()->GetCurrentWindow();
2622     CHECK_NULL_VOID(subWindow);
2623     auto overlayManager = subWindow->GetOverlayManager();
2624     CHECK_NULL_VOID(overlayManager);
2625     auto menuWrapperNode = overlayManager->GetMenuNode(targetId);
2626     if (!menuWrapperNode) {
2627         auto rootNode = overlayManager->GetRootNode().Upgrade();
2628         CHECK_NULL_VOID(rootNode);
2629         for (const auto& child : rootNode->GetChildren()) {
2630             auto node = AceType::DynamicCast<FrameNode>(child);
2631             if (node && node->GetTag() == V2::MENU_WRAPPER_ETS_TAG) {
2632                 menuWrapperNode = node;
2633                 break;
2634             }
2635         }
2636     }
2637     CHECK_NULL_VOID(menuWrapperNode);
2638 
2639     auto pipeline = PipelineContext::GetCurrentContext();
2640     CHECK_NULL_VOID(pipeline);
2641     auto dragDropManager = pipeline->GetDragDropManager();
2642     CHECK_NULL_VOID(dragDropManager);
2643     dragDropManager->SetMenuWrapperNode(menuWrapperNode);
2644 }
2645 } // namespace OHOS::Ace::NG
2646