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