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