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