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