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