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