1 /*
2 * Copyright (c) 2022-2024 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/manager/drag_drop/drag_drop_manager.h"
17
18 #include "base/geometry/point.h"
19 #include "base/geometry/rect.h"
20 #include "base/log/ace_trace.h"
21 #include "base/subwindow/subwindow_manager.h"
22 #include "base/utils/system_properties.h"
23 #include "base/utils/time_util.h"
24 #include "base/utils/utils.h"
25 #include "core/common/container_scope.h"
26 #include "core/common/interaction/interaction_data.h"
27 #include "core/common/interaction/interaction_interface.h"
28 #include "core/components/common/layout/grid_column_info.h"
29 #include "core/components/common/layout/grid_system_manager.h"
30 #include "core/components_ng/base/frame_node.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/drag_drop_spring_loading/drag_drop_spring_loading_detector.h"
35 #include "core/components_ng/manager/drag_drop/utils/drag_animation_helper.h"
36 #include "core/components_ng/pattern/grid/grid_event_hub.h"
37 #include "core/components_ng/pattern/list/list_event_hub.h"
38 #include "core/components_ng/pattern/menu/wrapper/menu_wrapper_pattern.h"
39 #include "core/components_ng/pattern/root/root_pattern.h"
40 #include "core/components_ng/pattern/text_field/text_field_pattern.h"
41 #include "core/components_v2/inspector/inspector_constants.h"
42 #include "core/pipeline_ng/pipeline_context.h"
43 #include "interfaces/inner_api/ui_session/ui_session_manager.h"
44
45 #ifdef ENABLE_ROSEN_BACKEND
46 #include "render_service_client/core/transaction/rs_transaction.h"
47 #include "render_service_client/core/transaction/rs_sync_transaction_controller.h"
48 #include "render_service_client/core/transaction/rs_sync_transaction_handler.h"
49 #include "render_service_client/core/ui/rs_ui_director.h"
50 #endif
51
52
53 namespace OHOS::Ace::NG {
54 namespace {
55 int64_t g_proxyId = 0;
56 constexpr Dimension PRESERVE_HEIGHT = 8.0_vp;
57 constexpr float FIRST_PIXELMAP_OPACITY = 0.6f;
58 constexpr float SECOND_PIXELMAP_OPACITY = 0.3f;
59 constexpr float FIRST_PIXELMAP_ANGLE = 8.0f;
60 constexpr float SECOND_PIXELMAP_ANGLE = -8.0f;
61 constexpr int32_t FIRST_GATHER_PIXEL_MAP = 1;
62 constexpr int32_t SECOND_GATHER_PIXEL_MAP = 2;
63 constexpr int32_t SQUARE_NUMBER = 2;
64 constexpr float TOUCH_DRAG_PIXELMAP_SCALE = 1.05f;
65 constexpr int32_t MAX_RETRY_TIMES = 3;
66 constexpr int32_t MAX_RETRY_DURATION = 800;
67 constexpr float MOVE_DISTANCE_LIMIT = 20.0f;
68 constexpr uint64_t MOVE_TIME_LIMIT = 6L;
69 constexpr float MAX_DISTANCE_TO_PRE_POINTER = 3.0f;
70 constexpr float DEFAULT_SPRING_RESPONSE = 0.347f;
71 constexpr float MIN_SPRING_RESPONSE = 0.05f;
72 constexpr float DEL_SPRING_RESPONSE = 0.005f;
73 constexpr float MIN_UI_EXTENSION_BOUNDARY_DISTANCE = 5.0f;
74 constexpr float MIN_FOLDER_SUBWINDOW_BOUNDARY_DISTANCE = 5.0f;
75 constexpr int32_t RESERVED_DEVICEID_1 = 0xAAAAAAFF;
76 constexpr int32_t RESERVED_DEVICEID_2 = 0xAAAAAAFE;
77 constexpr uint32_t TASK_DELAY_TIME = 5 * 1000;
78 constexpr uint32_t DROP_DELAY_TIME = 2 * 1000;
79 constexpr double DEVICE_TYPE_UNKOWN = 0.0;
80 constexpr double DEVICE_TYPE_SMALL = 600.0;
81 constexpr double DEVICE_TYPE_MEDIUM = 840.0;
82 constexpr int32_t SCALE_TYPE_FIRST = 2;
83 constexpr int32_t SCALE_TYPE_SECOND = 3;
84 constexpr int32_t SCALE_TYPE_THIRD = 4;
85 const RefPtr<InterpolatingSpring> DRAG_TRANSITION_ANIMATION_CURVE =
86 AceType::MakeRefPtr<InterpolatingSpring>(0.0f, 1.0f, 380.0f, 34.0f);
87 } // namespace
88
GetMenuRenderContextFromMenuWrapper(const RefPtr<FrameNode> & menuWrapperNode)89 RefPtr<RenderContext> GetMenuRenderContextFromMenuWrapper(const RefPtr<FrameNode>& menuWrapperNode)
90 {
91 CHECK_NULL_RETURN(menuWrapperNode, nullptr);
92 auto menuWrapperPattern = menuWrapperNode->GetPattern<MenuWrapperPattern>();
93 CHECK_NULL_RETURN(menuWrapperPattern, nullptr);
94 auto menuNode = menuWrapperPattern->GetMenu();
95 CHECK_NULL_RETURN(menuNode, nullptr);
96 return menuNode->GetRenderContext();
97 }
98
GetMenuWrapperNodeFromDrag()99 RefPtr<FrameNode> GetMenuWrapperNodeFromDrag()
100 {
101 auto pipelineContext = PipelineContext::GetMainPipelineContext();
102 CHECK_NULL_RETURN(pipelineContext, nullptr);
103 auto mainDragDropManager = pipelineContext->GetDragDropManager();
104 CHECK_NULL_RETURN(mainDragDropManager, nullptr);
105 return mainDragDropManager->GetMenuWrapperNode();
106 }
107
DragDropManager()108 DragDropManager::DragDropManager()
109 {
110 if (DragDropGlobalController::GetInstance().IsAlreadyGetAppGlobalDrag()) {
111 return;
112 }
113 bool state = false;
114 auto result = InteractionInterface::GetInstance()->GetAppDragSwitchState(state);
115 if (result != 0) {
116 TAG_LOGI(AceLogTag::ACE_DRAG, "get app drag switch state failed!");
117 return;
118 }
119 DragDropGlobalController::GetInstance().SetIsAppGlobalDragEnabled(state);
120 }
121
GetDragMoveLastPointByCurrentPointer(int32_t pointerId)122 const Point DragDropManager::GetDragMoveLastPointByCurrentPointer(int32_t pointerId)
123 {
124 auto it = fingerPointInfo_.find(pointerId);
125 if (it != fingerPointInfo_.end()) {
126 return it->second;
127 }
128 return Point(0, 0);
129 }
130
UpdatePointInfoForFinger(int32_t pointerId,Point point)131 void DragDropManager::UpdatePointInfoForFinger(int32_t pointerId, Point point)
132 {
133 fingerPointInfo_[pointerId] = point;
134 }
135
SetDelayDragCallBack(const std::function<void ()> & cb)136 void DragDropManager::SetDelayDragCallBack(const std::function<void()>& cb) noexcept
137 {
138 DragDropGlobalController::GetInstance().SetAsyncDragCallback(cb);
139 }
140
SetCallAnsyncDragEnd(const std::function<void (DragStartRequestStatus)> & cb)141 void DragDropManager::SetCallAnsyncDragEnd(const std::function<void(DragStartRequestStatus)>& cb)
142 {
143 DragDropGlobalController::GetInstance().SetCallAnsyncDragEnd(cb);
144 }
145
ExecuteDeadlineTimer()146 void DragDropManager::ExecuteDeadlineTimer()
147 {
148 auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
149 CHECK_NULL_VOID(pipeline);
150 auto taskScheduler = pipeline->GetTaskExecutor();
151 CHECK_NULL_VOID(taskScheduler);
152 taskScheduler->PostDelayedTask(
153 [weakManager = WeakClaim(this)]() {
154 auto dragDropManager = weakManager.Upgrade();
155 CHECK_NULL_VOID(dragDropManager);
156 if (DragDropGlobalController::GetInstance().GetAsyncDragCallback()) {
157 DragDropGlobalController::GetInstance().GetAsyncDragCallback()();
158 }
159 dragDropManager->RemoveDeadlineTimer();
160 },
161 TaskExecutor::TaskType::UI, TASK_DELAY_TIME, "ArkUIDragDeadlineTimer");
162 }
163
RemoveDeadlineTimer()164 void DragDropManager::RemoveDeadlineTimer()
165 {
166 DragDropGlobalController::GetInstance().SetAsyncDragCallback(nullptr);
167 DragDropGlobalController::GetInstance().SetDragStartRequestStatus(DragStartRequestStatus::READY);
168 auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
169 CHECK_NULL_VOID(pipeline);
170 auto taskScheduler = pipeline->GetTaskExecutor();
171 CHECK_NULL_VOID(taskScheduler);
172 taskScheduler->RemoveTask(TaskExecutor::TaskType::UI, "ArkUIDragDeadlineTimer");
173 }
174
HandleSyncOnDragStart(DragStartRequestStatus dragStartRequestStatus)175 void DragDropManager::HandleSyncOnDragStart(DragStartRequestStatus dragStartRequestStatus)
176 {
177 if (dragStartRequestStatus == DragStartRequestStatus::WAITING) {
178 ExecuteDeadlineTimer();
179 DragDropGlobalController::GetInstance().SetDragStartRequestStatus(dragStartRequestStatus);
180 }
181 if (dragStartRequestStatus == DragStartRequestStatus::READY &&
182 DragDropGlobalController::GetInstance().GetAsyncDragCallback()) {
183 DragDropGlobalController::GetInstance().SetDragStartRequestStatus(dragStartRequestStatus);
184 DragDropGlobalController::GetInstance().GetAsyncDragCallback()();
185 RemoveDeadlineTimer();
186 }
187 }
188
CreateAndShowItemDragOverlay(const RefPtr<PixelMap> & pixelMap,const GestureEvent & info,const RefPtr<EventHub> & eventHub)189 RefPtr<DragDropProxy> DragDropManager::CreateAndShowItemDragOverlay(
190 const RefPtr<PixelMap>& pixelMap, const GestureEvent& info, const RefPtr<EventHub>& eventHub)
191 {
192 CHECK_NULL_RETURN(pixelMap, nullptr);
193 // create Image for drag
194 auto imageNode = FrameNode::GetOrCreateFrameNode(V2::IMAGE_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
195 []() { return AceType::MakeRefPtr<ImagePattern>(); });
196 CHECK_NULL_RETURN(imageNode, nullptr);
197 auto imagePattern = imageNode->GetPattern<ImagePattern>();
198 CHECK_NULL_RETURN(imagePattern, nullptr);
199 imagePattern->SetSyncLoad(true);
200 auto prop = imageNode->GetLayoutProperty<ImageLayoutProperty>();
201 CHECK_NULL_RETURN(prop, nullptr);
202 prop->UpdateAutoResize(false);
203 prop->UpdateImageSourceInfo(ImageSourceInfo(pixelMap));
204 auto targetSize = CalcSize(NG::CalcLength(pixelMap->GetWidth()), NG::CalcLength(pixelMap->GetHeight()));
205 prop->UpdateUserDefinedIdealSize(targetSize);
206 auto renderProp = imageNode->GetPaintProperty<ImageRenderProperty>();
207 renderProp->UpdateImageInterpolation(ImageInterpolation::HIGH);
208 imageNode->MarkDirtyNode(NG::PROPERTY_UPDATE_MEASURE);
209 imageNode->MarkModifyDone();
210 imageNode->SetLayoutDirtyMarked(true);
211 imageNode->SetActive(true);
212 auto context = imageNode->GetContext();
213 if (context) {
214 context->FlushUITaskWithSingleDirtyNode(imageNode);
215 }
216 auto imageContext = imageNode->GetRenderContext();
217 CHECK_NULL_RETURN(imageContext, nullptr);
218 imageContext->UpdatePosition(
219 OffsetT<Dimension>(Dimension(info.GetGlobalPoint().GetX() - pixelMap->GetWidth() / 2), // 2: Average factor.
220 Dimension(info.GetGlobalPoint().GetY() - pixelMap->GetHeight() / 2))); // 2: Average factor.
221 imageContext->OnModifyDone();
222
223 AddItemDrag(imageNode, eventHub);
224
225 itemDragOverlayNode_ = imageNode;
226 SetIsDragged(true);
227 isDragCancel_ = false;
228 currentId_ = ++g_proxyId;
229 return MakeRefPtr<DragDropProxy>(currentId_);
230 }
231
CreateAndShowItemDragOverlay(const RefPtr<UINode> & customNode,const GestureEvent & info,const RefPtr<EventHub> & eventHub)232 RefPtr<DragDropProxy> DragDropManager::CreateAndShowItemDragOverlay(
233 const RefPtr<UINode>& customNode, const GestureEvent& info, const RefPtr<EventHub>& eventHub)
234 {
235 auto frameNode = DynamicCast<FrameNode>(customNode);
236 CHECK_NULL_RETURN(frameNode, nullptr);
237 auto renderContext = frameNode->GetRenderContext();
238 CHECK_NULL_RETURN(renderContext, nullptr);
239 auto geometryNode = frameNode->GetGeometryNode();
240 CHECK_NULL_RETURN(geometryNode, nullptr);
241 auto frameRect = geometryNode->GetFrameSize();
242 renderContext->UpdatePosition(
243 OffsetT<Dimension>(Dimension(info.GetGlobalPoint().GetX() - frameRect.Width() / 2), // 2: Average factor.
244 Dimension(info.GetGlobalPoint().GetY() - frameRect.Height() / 2))); // 2: Average factor.
245 renderContext->OnModifyDone();
246 AddItemDrag(frameNode, eventHub);
247 itemDragOverlayNode_ = frameNode;
248 SetIsDragged(true);
249 isDragCancel_ = false;
250 currentId_ = ++g_proxyId;
251 return MakeRefPtr<DragDropProxy>(currentId_);
252 }
253
CreateTextDragDropProxy()254 RefPtr<DragDropProxy> DragDropManager::CreateTextDragDropProxy()
255 {
256 SetIsDragged(true);
257 isDragCancel_ = false;
258 currentId_ = ++g_proxyId;
259 return MakeRefPtr<DragDropProxy>(currentId_);
260 }
261
GetWindowId()262 int32_t DragDropManager::GetWindowId()
263 {
264 auto windowId = -1;
265 auto container = Container::Current();
266 CHECK_NULL_RETURN(container, windowId);
267
268 if (!container->IsSceneBoardEnabled()) {
269 isDragWindowSubWindow_ = false;
270 return windowId;
271 }
272
273 if (!container->IsMainWindow()) {
274 // The window manager currently does not support creating child windows within child windows,
275 // so the root main window is used here
276 container = Container::GetContainer(CONTAINER_ID_DIVIDE_SIZE);
277 CHECK_NULL_RETURN(container, windowId);
278 if (!container->IsMainWindow()) {
279 isDragWindowSubWindow_ = false;
280 return windowId;
281 }
282 }
283
284 windowId = static_cast<int32_t>(container->GetWindowId());
285 isDragWindowSubWindow_ = true;
286
287 return windowId;
288 }
289
CreateDragRootNode(const RefPtr<UINode> & customNode)290 RefPtr<FrameNode> DragDropManager::CreateDragRootNode(const RefPtr<UINode>& customNode)
291 {
292 auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
293 CHECK_NULL_RETURN(pipeline, nullptr);
294
295 auto rootNode = FrameNode::CreateFrameNodeWithTree(
296 V2::ROOT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), MakeRefPtr<RootPattern>());
297 rootNode->SetActive(true);
298 rootNode->SetHostRootId(pipeline->GetInstanceId());
299 rootNode->SetHostPageId(-1);
300 rootNode->AddChild(customNode);
301 rootNode->AttachToMainTree(false, AceType::RawPtr(pipeline));
302 rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
303 pipeline->FlushUITasks();
304 return rootNode;
305 }
306
AddItemDrag(const RefPtr<FrameNode> & frameNode,const RefPtr<EventHub> & eventHub)307 void DragDropManager::AddItemDrag(const RefPtr<FrameNode>& frameNode, const RefPtr<EventHub>& eventHub)
308 {
309 auto pipeline = frameNode->GetContext();
310 CHECK_NULL_VOID(pipeline);
311 auto rootNode = pipeline->GetRootElement();
312 auto container = Container::Current();
313 if (container && container->IsSceneBoardWindow()) {
314 auto host = eventHub->GetFrameNode();
315 CHECK_NULL_VOID(host);
316 auto overlayManager = pipeline->GetOverlayManager();
317 CHECK_NULL_VOID(overlayManager);
318 rootNode = DynamicCast<FrameNode>(overlayManager->FindWindowScene(host));
319 }
320 CHECK_NULL_VOID(rootNode);
321 frameNode->MountToParent(rootNode);
322 frameNode->OnMountToParentDone();
323 rootNode->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
324 }
325
RemoveItemDrag()326 void DragDropManager::RemoveItemDrag()
327 {
328 CHECK_NULL_VOID(itemDragOverlayNode_);
329 auto rootNode = itemDragOverlayNode_->GetParent();
330 CHECK_NULL_VOID(rootNode);
331 rootNode->RemoveChild(itemDragOverlayNode_);
332 rootNode->RebuildRenderContextTree();
333 rootNode->MarkDirtyNode(PROPERTY_UPDATE_BY_CHILD_REQUEST);
334 }
335
UpdateItemDragPosition(int32_t globalX,int32_t globalY)336 void DragDropManager::UpdateItemDragPosition(int32_t globalX, int32_t globalY)
337 {
338 CHECK_NULL_VOID(itemDragOverlayNode_);
339 auto rect = itemDragOverlayNode_->GetTransformRectRelativeToWindow();
340 auto pipeline = itemDragOverlayNode_->GetContext();
341 CHECK_NULL_VOID(pipeline);
342 const Rect windowRect = pipeline->GetDisplayWindowRectInfo();
343 auto maxX = static_cast<float>(windowRect.Width() - rect.Width());
344 auto maxY = static_cast<float>(windowRect.Height() - rect.Height());
345 auto renderContext = itemDragOverlayNode_->GetRenderContext();
346 CHECK_NULL_VOID(renderContext);
347 renderContext->UpdatePosition(
348 OffsetT<Dimension>(Dimension(std::min(std::max(globalX - rect.Width() / 2, 0.0f), maxX)), // 2: Average factor.
349 Dimension(std::min(std::max(globalY - rect.Height() / 2, 0.0f), maxY)))); // 2: Average factor.
350 renderContext->OnModifyDone();
351 }
352
HideDragPreviewOverlay()353 void DragDropManager::HideDragPreviewOverlay()
354 {
355 auto pipeline = NG::PipelineContext::GetCurrentContextSafelyWithCheck();
356 CHECK_NULL_VOID(pipeline);
357 auto manager = pipeline->GetOverlayManager();
358 CHECK_NULL_VOID(manager);
359 manager->RemovePixelMap();
360 manager->RemoveGatherNode();
361 manager->RemoveDragPixelMap();
362 SubwindowManager::GetInstance()->HidePreviewNG();
363 }
364
HideDragPreviewWindow(int32_t containerId)365 void DragDropManager::HideDragPreviewWindow(int32_t containerId)
366 {
367 auto overlayManager = GetDragAnimationOverlayManager(containerId);
368 CHECK_NULL_VOID(overlayManager);
369 overlayManager->RemovePixelMap();
370 overlayManager->RemoveGatherNode();
371 overlayManager->RemoveDragPixelMap();
372 SubwindowManager::GetInstance()->HidePreviewNG();
373 }
374
HideSubwindowDragNode()375 void DragDropManager::HideSubwindowDragNode()
376 {
377 auto subwindowOverlayManager = subwindowOverlayManager_.Upgrade();
378 CHECK_NULL_VOID(subwindowOverlayManager);
379 subwindowOverlayManager->RemovePixelMap();
380 subwindowOverlayManager->RemoveGatherNode();
381 subwindowOverlayManager->RemoveDragPixelMap();
382 subwindowOverlayManager_ = nullptr;
383 }
384
FindTargetInChildNodes(const RefPtr<UINode> parentNode,std::vector<RefPtr<FrameNode>> hitFrameNodes,bool findDrop)385 RefPtr<FrameNode> DragDropManager::FindTargetInChildNodes(
386 const RefPtr<UINode> parentNode, std::vector<RefPtr<FrameNode>> hitFrameNodes, bool findDrop)
387 {
388 CHECK_NULL_RETURN(parentNode, nullptr);
389 auto parentFrameNode = AceType::DynamicCast<FrameNode>(parentNode);
390 if (parentFrameNode && (!parentFrameNode->IsActive() || !parentFrameNode->IsVisible())) {
391 return nullptr;
392 }
393 auto children = parentFrameNode->GetFrameChildren();
394
395 for (auto iter = children.rbegin(); iter != children.rend(); iter++) {
396 auto child = iter->Upgrade();
397 if (child == nullptr) {
398 continue;
399 }
400 auto childNode = AceType::DynamicCast<UINode>(child);
401 auto childFindResult = FindTargetInChildNodes(childNode, hitFrameNodes, findDrop);
402 if (childFindResult) {
403 return childFindResult;
404 }
405 }
406
407 CHECK_NULL_RETURN(parentFrameNode, nullptr);
408 for (auto iter : hitFrameNodes) {
409 if (parentFrameNode == iter) {
410 auto eventHub = parentFrameNode->GetOrCreateEventHub<EventHub>();
411 if (!eventHub) {
412 continue;
413 }
414 if ((eventHub->HasOnDrop()) || (eventHub->HasOnItemDrop()) || (eventHub->HasCustomerOnDrop())) {
415 return parentFrameNode;
416 }
417 if (V2::ISOLATED_COMPONENT_ETS_TAG == parentFrameNode->GetTag() ||
418 V2::DYNAMIC_COMPONENT_ETS_TAG == parentFrameNode->GetTag()) {
419 // Extension and Embedded component can potentially show placeholder nodes when not active. Isolated
420 // and Dynamic component appear not to have this capability. So we dont need to check if its showing
421 // the placeholder or not...
422 return parentFrameNode;
423 }
424 if ((V2::UI_EXTENSION_COMPONENT_ETS_TAG == parentFrameNode->GetTag() ||
425 V2::EMBEDDED_COMPONENT_ETS_TAG == parentFrameNode->GetTag()) &&
426 (!IsUIExtensionShowPlaceholder(parentFrameNode))) {
427 return parentFrameNode;
428 }
429 }
430 }
431 return nullptr;
432 }
433
CheckFrameNodeCanDrop(const RefPtr<FrameNode> & node)434 bool DragDropManager::CheckFrameNodeCanDrop(const RefPtr<FrameNode>& node)
435 {
436 CHECK_NULL_RETURN(node, false);
437 auto eventHub = node->GetOrCreateEventHub<EventHub>();
438 CHECK_NULL_RETURN(eventHub, false);
439 if ((eventHub->HasOnDrop()) || (eventHub->HasOnItemDrop()) || (eventHub->HasCustomerOnDrop()) ||
440 (eventHub->HasCustomerOnDragSpringLoading())) {
441 return true;
442 }
443 if (V2::ISOLATED_COMPONENT_ETS_TAG == node->GetTag() || V2::DYNAMIC_COMPONENT_ETS_TAG == node->GetTag()) {
444 return true;
445 }
446 if ((V2::UI_EXTENSION_COMPONENT_ETS_TAG == node->GetTag() ||
447 V2::EMBEDDED_COMPONENT_ETS_TAG == node->GetTag()) &&
448 (!IsUIExtensionShowPlaceholder(node))) {
449 return true;
450 }
451
452 return false;
453 }
454
FindTargetDropNode(const RefPtr<UINode> parentNode,PointF localPoint)455 RefPtr<FrameNode> DragDropManager::FindTargetDropNode(const RefPtr<UINode> parentNode, PointF localPoint)
456 {
457 CHECK_NULL_RETURN(parentNode, nullptr);
458 auto parentFrameNode = AceType::DynamicCast<FrameNode>(parentNode);
459 CHECK_NULL_RETURN(parentFrameNode, nullptr);
460 if (!parentFrameNode->IsActive() || !parentFrameNode->IsVisible()) {
461 return nullptr;
462 }
463 auto renderContext = parentFrameNode->GetRenderContext();
464 CHECK_NULL_RETURN(renderContext, nullptr);
465 auto paintRect = renderContext->GetPaintRectWithoutTransform();
466 FrameNode::MapPointTo(localPoint, parentFrameNode->GetOrRefreshMatrixFromCache().revertMatrix);
467 auto subLocalPoint = localPoint - paintRect.GetOffset();
468
469 auto children = parentFrameNode->GetFrameChildren();
470 for (auto iter = children.rbegin(); iter != children.rend(); iter++) {
471 auto child = iter->Upgrade();
472 if (child == nullptr) {
473 continue;
474 }
475 auto childNode = AceType::DynamicCast<UINode>(child);
476 auto childFindResult = FindTargetDropNode(childNode, subLocalPoint);
477 if (childFindResult) {
478 return childFindResult;
479 }
480 }
481
482 if (paintRect.IsInRegion(localPoint)) {
483 if (parentFrameNode->GetDragHitTestBlock()) {
484 return parentFrameNode;
485 }
486 if (CheckFrameNodeCanDrop(parentFrameNode)) {
487 return parentFrameNode;
488 }
489 }
490 return nullptr;
491 }
492
FilterSubwindowDragRootNode(const RefPtr<FrameNode> & node)493 RefPtr<FrameNode> DragDropManager::FilterSubwindowDragRootNode(const RefPtr<FrameNode>& node)
494 {
495 auto rootNode = node;
496 auto container = Container::Current();
497 CHECK_NULL_RETURN(container, rootNode);
498 auto containerId = container->GetInstanceId();
499 auto pipeline = PipelineContext::GetMainPipelineContext();
500 CHECK_NULL_RETURN(pipeline, rootNode);
501 if (isReDragStart_ && !DragDropFuncWrapper::IsExpandDisplay(pipeline) && containerId >= MIN_SUBCONTAINER_ID) {
502 rootNode = pipeline->GetRootElement();
503 }
504 return rootNode;
505 }
506
FindDragFrameNodeByPosition(float globalX,float globalY,const RefPtr<FrameNode> & node)507 RefPtr<FrameNode> DragDropManager::FindDragFrameNodeByPosition(float globalX, float globalY,
508 const RefPtr<FrameNode>& node)
509 {
510 auto rootNode = node;
511 if (!rootNode) {
512 auto container = Container::Current();
513 CHECK_NULL_RETURN(container, nullptr);
514 auto pipeline = AceType::DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
515 CHECK_NULL_RETURN(pipeline, nullptr);
516 if (container->IsSceneBoardWindow() && draggedFrameNode_) {
517 auto overlayManager = pipeline->GetOverlayManager();
518 CHECK_NULL_RETURN(overlayManager, nullptr);
519 rootNode = AceType::DynamicCast<FrameNode>(overlayManager->FindWindowScene(draggedFrameNode_));
520 }
521 if (!rootNode) {
522 rootNode = pipeline->GetRootElement();
523 }
524 }
525
526 auto result = FindTargetDropNode(rootNode, {globalX, globalY});
527 if (result) {
528 if (CheckFrameNodeCanDrop(result)) {
529 return result;
530 }
531 }
532 return nullptr;
533 }
534
CheckDragDropProxy(int64_t id) const535 bool DragDropManager::CheckDragDropProxy(int64_t id) const
536 {
537 return currentId_ == id;
538 }
539
UpdateDragAllowDrop(const RefPtr<FrameNode> & dragFrameNode,const DragBehavior dragBehavior,const int32_t eventId,bool isCapi)540 void DragDropManager::UpdateDragAllowDrop(
541 const RefPtr<FrameNode>& dragFrameNode, const DragBehavior dragBehavior, const int32_t eventId, bool isCapi)
542 {
543 if (!IsDropAllowed(dragFrameNode)) {
544 // simplified specifications for drag cursor style, no longer showing forbidden drag cursor
545 DragDropGlobalController::GetInstance().GetEnableDropDisallowedBadge()
546 ? UpdateDragStyle(DragCursorStyleCore::FORBIDDEN, eventId)
547 : UpdateDragStyle(DragCursorStyleCore::MOVE, eventId);
548 return;
549 }
550
551 // drop allowed
552 CHECK_NULL_VOID(dragFrameNode);
553 const auto& dragFrameNodeAllowDrop = dragFrameNode->GetAllowDrop();
554 // special handling for no drag data present situation, always show as move
555 // For CAPI ,no ENABLE_DROP and DISABLE_DROP state, skip the judgment and consider it allowed to drop into. Continue
556 // to set dragBehavior.
557 if (!isCapi && (dragFrameNodeAllowDrop.empty() || summaryMap_.empty())) {
558 UpdateDragStyle(DragCursorStyleCore::MOVE, eventId);
559 return;
560 }
561
562 //other case, check drag behavior
563 switch (dragBehavior) {
564 case DragBehavior::UNKNOWN: {
565 // the application does not config the drag behavior, use move when moving within
566 // draggedFrameNode or frameNode is disabled, otherwise use copy
567 auto eventHub = dragFrameNode->GetOrCreateEventHub<EventHub>();
568 if (draggedFrameNode_ == dragFrameNode || !(eventHub && eventHub->IsEnabled()) ||
569 CheckExtraSituation(dragFrameNode)) {
570 UpdateDragStyle(DragCursorStyleCore::MOVE, eventId);
571 } else {
572 UpdateDragStyle(DragCursorStyleCore::COPY, eventId);
573 }
574 break;
575 }
576 case DragBehavior::MOVE: {
577 UpdateDragStyle(DragCursorStyleCore::MOVE, eventId);
578 break;
579 }
580 case DragBehavior::COPY: {
581 UpdateDragStyle(DragCursorStyleCore::COPY, eventId);
582 break;
583 }
584 default: {
585 UpdateDragStyle(DragCursorStyleCore::COPY, eventId);
586 break;
587 }
588 }
589 }
590
CheckExtraSituation(const RefPtr<FrameNode> & dragFrameNode) const591 bool DragDropManager::CheckExtraSituation(const RefPtr<FrameNode>& dragFrameNode) const
592 {
593 return CheckInRichEditor(dragFrameNode);
594 }
595
CheckInRichEditor(const RefPtr<FrameNode> & dragFrameNode) const596 bool DragDropManager::CheckInRichEditor(const RefPtr<FrameNode>& dragFrameNode) const
597 {
598 CHECK_NULL_RETURN(dragFrameNode && draggedFrameNode_, false);
599 auto parent = draggedFrameNode_->GetAncestorNodeOfFrame(false);
600 CHECK_NULL_RETURN(parent && parent->GetTag() == V2::RICH_EDITOR_ETS_TAG, false);
601 return dragFrameNode == parent;
602 }
603
UpdateDragStyle(const DragCursorStyleCore & dragStyle,int32_t eventId)604 void DragDropManager::UpdateDragStyle(const DragCursorStyleCore& dragStyle, int32_t eventId)
605 {
606 if (dragStyle != dragCursorStyleCore_) {
607 ACE_SCOPED_TRACE("drag: update drag style %d", dragStyle);
608 TAG_LOGI(
609 AceLogTag::ACE_DRAG, "Update DragStyle to %{public}d, pointerEventId: %{public}d.", dragStyle, eventId);
610 auto ret = InteractionInterface::GetInstance()->UpdateDragStyle(dragStyle, eventId);
611 if (ret != 0) {
612 TAG_LOGI(AceLogTag::ACE_DRAG,
613 "Update DragStyle to %{public}d failed, keep %{public}d. pointerEventId: %{public}d. ret = %{public}d",
614 dragStyle, dragCursorStyleCore_, eventId, ret);
615 } else {
616 dragCursorStyleCore_ = dragStyle;
617 }
618 }
619 }
620
CheckParentVisible(const RefPtr<FrameNode> & frameNode)621 bool CheckParentVisible(const RefPtr<FrameNode>& frameNode)
622 {
623 CHECK_NULL_RETURN(frameNode, false);
624 bool isVisible = frameNode->IsVisible();
625 if (!isVisible) {
626 return false;
627 }
628 auto parent = frameNode->GetParent();
629 while (parent && parent->GetDepth() != 1) {
630 auto parentFrameNode = AceType::DynamicCast<FrameNode>(parent);
631 if (parentFrameNode && !parentFrameNode->IsVisible()) {
632 isVisible = false;
633 break;
634 }
635 parent = parent->GetParent();
636 }
637 return isVisible;
638 }
639
FindHitFrameNodes(const Point & point)640 std::unordered_set<int32_t> DragDropManager::FindHitFrameNodes(const Point& point)
641 {
642 std::unordered_set<int32_t> frameNodeList;
643 for (auto iter = nodesForDragNotify_.begin(); iter != nodesForDragNotify_.end(); iter++) {
644 auto frameNode = iter->second.Upgrade();
645 if (!frameNode || !frameNode->IsActive() || !frameNode->IsVisible() || !frameNode->IsOnMainTree()) {
646 continue;
647 }
648 auto geometryNode = frameNode->GetGeometryNode();
649 if (!geometryNode) {
650 continue;
651 }
652 auto globalFrameRect = geometryNode->GetFrameRect();
653 globalFrameRect.SetOffset(frameNode->GetTransformRelativeOffset());
654 if (globalFrameRect.IsInRegion(PointF(static_cast<float>(point.GetX()), static_cast<float>(point.GetY())))) {
655 frameNodeList.emplace(frameNode->GetId());
656 }
657 }
658 return frameNodeList;
659 }
660
UpdateDragListener(const Point & point)661 void DragDropManager::UpdateDragListener(const Point& point)
662 {
663 auto hitNodes = FindHitFrameNodes(point);
664 std::unordered_map<int32_t, WeakPtr<FrameNode>> dragEnterNodes;
665 std::unordered_map<int32_t, WeakPtr<FrameNode>> dragMoveNodes;
666 std::unordered_map<int32_t, WeakPtr<FrameNode>> dragLeaveNodes;
667 for (auto iter = nodesForDragNotify_.begin(); iter != nodesForDragNotify_.end(); iter++) {
668 auto localHitResult = hitNodes.find(iter->first) != hitNodes.end();
669 auto preHitResult = parentHitNodes_.find(iter->first) != parentHitNodes_.end();
670 if (localHitResult && preHitResult) {
671 dragMoveNodes[iter->first] = iter->second;
672 }
673 if (localHitResult && !preHitResult) {
674 dragEnterNodes[iter->first] = iter->second;
675 }
676 if (!localHitResult && preHitResult) {
677 dragLeaveNodes[iter->first] = iter->second;
678 }
679 }
680 RefPtr<NotifyDragEvent> notifyEvent = AceType::MakeRefPtr<NotifyDragEvent>();
681 CHECK_NULL_VOID(notifyEvent);
682 UpdateNotifyDragEvent(notifyEvent, point, DragEventType::MOVE);
683
684 NotifyDragRegisterFrameNode(dragMoveNodes, DragEventType::MOVE, notifyEvent);
685 NotifyDragRegisterFrameNode(dragEnterNodes, DragEventType::ENTER, notifyEvent);
686 NotifyDragRegisterFrameNode(dragLeaveNodes, DragEventType::LEAVE, notifyEvent);
687 parentHitNodes_ = std::move(hitNodes);
688 }
689
NotifyDragRegisterFrameNode(std::unordered_map<int32_t,WeakPtr<FrameNode>> nodes,DragEventType dragEventType,RefPtr<NotifyDragEvent> & notifyEvent)690 void DragDropManager::NotifyDragRegisterFrameNode(std::unordered_map<int32_t, WeakPtr<FrameNode>> nodes,
691 DragEventType dragEventType, RefPtr<NotifyDragEvent>& notifyEvent)
692 {
693 for (auto iter = nodes.begin(); iter != nodes.end(); iter++) {
694 auto frameNode = iter->second.Upgrade();
695 if (!frameNode) {
696 continue;
697 }
698 auto eventHub = frameNode->GetOrCreateEventHub<EventHub>();
699 if (!CheckParentVisible(frameNode) || (eventHub && !eventHub->IsEnabled())) {
700 continue;
701 }
702 auto pattern = frameNode->GetPattern<Pattern>();
703 if (!pattern) {
704 continue;
705 }
706 pattern->HandleOnDragStatusCallback(dragEventType, notifyEvent);
707 }
708 }
709
NotifyDragFrameNode(const Point & point,const DragEventType & dragEventType,const DragRet & dragRet)710 void DragDropManager::NotifyDragFrameNode(
711 const Point& point, const DragEventType& dragEventType, const DragRet& dragRet)
712 {
713 RefPtr<NotifyDragEvent> notifyEvent = AceType::MakeRefPtr<NotifyDragEvent>();
714 CHECK_NULL_VOID(notifyEvent);
715 UpdateNotifyDragEvent(notifyEvent, point, dragEventType);
716 notifyEvent->SetResult(dragRet);
717 NotifyDragRegisterFrameNode(nodesForDragNotify_, dragEventType, notifyEvent);
718 }
719
GetRootNode()720 RefPtr<FrameNode> DragDropManager::GetRootNode()
721 {
722 auto pipeline = NG::PipelineContext::GetCurrentContextSafelyWithCheck();
723 CHECK_NULL_RETURN(pipeline, nullptr);
724 return pipeline->GetRootElement();
725 }
726
OnDragStart(const Point & point,const RefPtr<FrameNode> & frameNode)727 void DragDropManager::OnDragStart(const Point& point, const RefPtr<FrameNode>& frameNode)
728 {
729 dragDropState_ = DragDropMgrState::DRAGGING;
730 NotifyDragFrameNode(point, DragEventType::START);
731 CHECK_NULL_VOID(frameNode);
732 preTargetFrameNode_ = frameNode;
733 draggedFrameNode_ = preTargetFrameNode_;
734 preMovePoint_ = point;
735 parentHitNodes_.emplace(frameNode->GetId());
736 DragDropBehaviorReporter::GetInstance().UpdateFrameNodeStartId(frameNode->GetId());
737 DragDropBehaviorReporter::GetInstance().UpdateStartPoint(point);
738 DragDropBehaviorReporter::GetInstance().UpdateLongPressDurationEnd(GetSysTimestamp());
739 DragDropBehaviorReporter::GetInstance().UpdateDropResult(DropResult::DROP_FAIL);
740
741 // Reset hover status when drag start.
742 auto pipeline = frameNode->GetContextRefPtr();
743 CHECK_NULL_VOID(pipeline);
744 auto eventManager = pipeline->GetEventManager();
745 CHECK_NULL_VOID(eventManager);
746 eventManager->CleanHoverStatusForDragBegin();
747
748 auto container = Container::GetContainer(pipeline->GetInstanceId());
749 CHECK_NULL_VOID(container);
750 if (container->IsSceneBoardWindow()) {
751 auto overlayManager = pipeline->GetOverlayManager();
752 CHECK_NULL_VOID(overlayManager);
753 rootNode_ = AceType::DynamicCast<FrameNode>(DragDropFuncWrapper::FindWindowScene(draggedFrameNode_));
754 auto dragDropManager = pipeline->GetDragDropManager();
755 CHECK_NULL_VOID(dragDropManager);
756 dragDropManager->SetRootNode(rootNode_);
757 }
758 }
759
OnDragStart(const Point & point)760 void DragDropManager::OnDragStart(const Point& point)
761 {
762 dragDropState_ = DragDropMgrState::DRAGGING;
763 NotifyDragFrameNode(point, DragEventType::START);
764
765 // Reset hover status when drag start.
766 auto pipeline = PipelineContext::GetCurrentContext();
767 CHECK_NULL_VOID(pipeline);
768 auto eventManager = pipeline->GetEventManager();
769 CHECK_NULL_VOID(eventManager);
770 eventManager->CleanHoverStatusForDragBegin();
771 }
772
PrintDragFrameNode(const OHOS::Ace::DragPointerEvent & pointerEvent,const RefPtr<FrameNode> & dragFrameNode)773 void DragDropManager::PrintDragFrameNode(
774 const OHOS::Ace::DragPointerEvent& pointerEvent, const RefPtr<FrameNode>& dragFrameNode)
775 {
776 CHECK_NULL_VOID(dragFrameNode);
777 auto container = Container::Current();
778 CHECK_NULL_VOID(container);
779 if (preTargetFrameNode_) {
780 TAG_LOGI(AceLogTag::ACE_DRAG,
781 "Current windowId is %{public}d, pointerEventId is %{public}d, "
782 "PreTargetFrameNode is %{public}s, depth is %{public}d, New find "
783 "targetNode is %{public}s, depth is %{public}d.",
784 container->GetWindowId(), pointerEvent.pointerEventId, preTargetFrameNode_->GetTag().c_str(),
785 preTargetFrameNode_->GetDepth(), dragFrameNode->GetTag().c_str(), dragFrameNode->GetDepth());
786 } else {
787 TAG_LOGI(AceLogTag::ACE_DRAG,
788 "Current windowId is %{public}d, pointerEventId is %{public}d, "
789 "PreTargetFrameNode is nullptr, New find targetNode is %{public}s, depth is %{public}d",
790 container->GetWindowId(), pointerEvent.pointerEventId, dragFrameNode->GetTag().c_str(),
791 dragFrameNode->GetDepth());
792 }
793 }
794
PrintGridDragFrameNode(const float globalX,const float globalY,const RefPtr<FrameNode> & dragFrameNode)795 void DragDropManager::PrintGridDragFrameNode(
796 const float globalX, const float globalY, const RefPtr<FrameNode>& dragFrameNode)
797 {
798 CHECK_NULL_VOID(dragFrameNode);
799 auto container = Container::Current();
800 CHECK_NULL_VOID(container);
801 if (preGridTargetFrameNode_) {
802 TAG_LOGI(AceLogTag::ACE_DRAG,
803 "Current windowId is %{public}d"
804 "PreTargetFrameNode is %{public}s, depth is %{public}d,"
805 "New find targetNode is %{public}s, depth is %{public}d.",
806 container->GetWindowId(), preGridTargetFrameNode_->GetTag().c_str(),
807 preGridTargetFrameNode_->GetDepth(), dragFrameNode->GetTag().c_str(), dragFrameNode->GetDepth());
808 } else {
809 TAG_LOGI(AceLogTag::ACE_DRAG,
810 "Current windowId is %{public}d, "
811 "PreTargetFrameNode is nullptr, New find targetNode is %{public}s, depth is %{public}d.",
812 container->GetWindowId(), dragFrameNode->GetTag().c_str(), dragFrameNode->GetDepth());
813 }
814 }
815
TransDragWindowToDragFwk(int32_t windowContainerId)816 void DragDropManager::TransDragWindowToDragFwk(int32_t windowContainerId)
817 {
818 if (isDragFwkShow_) {
819 return;
820 }
821 TAG_LOGI(AceLogTag::ACE_DRAG, "TransDragWindowToDragFwk is %{public}d", isDragFwkShow_);
822 ACE_SCOPED_TRACE("drag: set drag window visible by transfer");
823 if (draggedFrameNode_) {
824 auto gestureHub = draggedFrameNode_->GetOrCreateGestureEventHub();
825 CHECK_NULL_VOID(gestureHub);
826 auto dragEventActuator = gestureHub->GetDragEventActuator();
827 CHECK_NULL_VOID(dragEventActuator);
828 dragEventActuator->NotifyTransDragWindowToFwk();
829 }
830 InteractionInterface::GetInstance()->SetDragWindowVisible(true);
831 DragDropGlobalController::GetInstance().ResetDragDropInitiatingStatus();
832 isDragFwkShow_ = true;
833 HideSubwindowDragNode();
834 auto overlayManager = GetDragAnimationOverlayManager(windowContainerId);
835 CHECK_NULL_VOID(overlayManager);
836 overlayManager->RemoveDragPixelMap();
837 overlayManager->RemoveGatherNode();
838 SubwindowManager::GetInstance()->HidePreviewNG();
839 info_.scale = -1.0;
840 dampingOverflowCount_ = 0;
841 }
842
OnDragMoveOut(const DragPointerEvent & pointerEvent)843 void DragDropManager::OnDragMoveOut(const DragPointerEvent& pointerEvent)
844 {
845 Point point = pointerEvent.GetPoint();
846 auto container = Container::Current();
847 if (container && container->IsSceneBoardWindow()) {
848 if (IsDragged() && IsWindowConsumed()) {
849 SetIsWindowConsumed(false);
850 return;
851 }
852 }
853 isReDragStart_ = false;
854 SetIsWindowConsumed(false);
855 UpdateVelocityTrackerPoint(point, false);
856 UpdateDragListener(Point(-1, -1));
857 NotifyPullEventListener(pointerEvent);
858 if (preTargetFrameNode_) {
859 TAG_LOGI(AceLogTag::ACE_DRAG, "Leave the current window, windowId is %{public}d,"
860 " pointerEventId is %{public}d. PreTargetFrameNode is %{public}s, depth is %{public}d.",
861 container->GetWindowId(), pointerEvent.pointerEventId, preTargetFrameNode_->GetTag().c_str(),
862 preTargetFrameNode_->GetDepth());
863 FireOnDragEvent(preTargetFrameNode_, pointerEvent, DragEventType::LEAVE, extraInfo_);
864 preTargetFrameNode_ = nullptr;
865 }
866 if (IsNeedDisplayInSubwindow() || isDragWithContextMenu_) {
867 TransDragWindowToDragFwk(Container::CurrentId());
868 }
869 ResetBundleInfo();
870 ClearSummary();
871 ClearExtraInfo();
872 SetDragCursorStyleCore(DragCursorStyleCore::DEFAULT);
873 }
874
OnDragThrow(const DragPointerEvent & pointerEvent)875 void DragDropManager::OnDragThrow(const DragPointerEvent& pointerEvent)
876 {
877 auto container = Container::Current();
878 if (container && container->IsSceneBoardWindow()) {
879 if (IsDragged() && IsWindowConsumed()) {
880 SetIsWindowConsumed(false);
881 return;
882 }
883 }
884 SetIsWindowConsumed(false);
885 Point point = pointerEvent.GetPoint();
886 UpdateVelocityTrackerPoint(point, false);
887 UpdateDragListener(Point(-1, -1));
888 if (preTargetFrameNode_) {
889 TAG_LOGI(AceLogTag::ACE_DRAG, "Throw from the current window, windowId is %{public}d,"
890 " pointerEventId is %{public}d. PreTargetFrameNode is %{public}s, depth is %{public}d.",
891 container->GetWindowId(), pointerEvent.pointerEventId, preTargetFrameNode_->GetTag().c_str(),
892 preTargetFrameNode_->GetDepth());
893 FireOnDragEvent(preTargetFrameNode_, pointerEvent, DragEventType::LEAVE, extraInfo_);
894 preTargetFrameNode_ = nullptr;
895 }
896 TransDragWindowToDragFwk(container->GetInstanceId());
897 ClearSummary();
898 ClearExtraInfo();
899 SetDragCursorStyleCore(DragCursorStyleCore::DEFAULT);
900 isPullThrow_ = true;
901 }
902
OnDragPullCancel(const DragPointerEvent & pointerEvent)903 void DragDropManager::OnDragPullCancel(const DragPointerEvent& pointerEvent)
904 {
905 RemoveDeadlineTimer();
906 auto container = Container::Current();
907 auto containerId = container->GetInstanceId();
908 DragDropBehaviorReporter::GetInstance().UpdateContainerId(containerId);
909 DragDropBehaviorReporter::GetInstance().UpdateDragStopResult(DragStopResult::USER_STOP_DRAG);
910 if (container && container->IsSceneBoardWindow()) {
911 if (IsDragged() && IsWindowConsumed()) {
912 SetIsWindowConsumed(false);
913 return;
914 }
915 }
916 SetIsWindowConsumed(false);
917 Point point = pointerEvent.GetPoint();
918 UpdateVelocityTrackerPoint(point, false);
919 UpdateDragListener(Point(-1, -1));
920 if (preTargetFrameNode_) {
921 TAG_LOGI(AceLogTag::ACE_DRAG, "Cancel from the current window, windowId is %{public}d,"
922 " pointerEventId is %{public}d. PreTargetFrameNode is %{public}s, depth is %{public}d.",
923 container->GetWindowId(), pointerEvent.pointerEventId, preTargetFrameNode_->GetTag().c_str(),
924 preTargetFrameNode_->GetDepth());
925 FireOnDragEvent(preTargetFrameNode_, pointerEvent, DragEventType::LEAVE, extraInfo_);
926 preTargetFrameNode_ = nullptr;
927 }
928 DragDropRet dragDropRet { DragRet::DRAG_CANCEL, false, container->GetWindowId(), DragBehavior::MOVE };
929 ResetDragDropStatus(point, dragDropRet, container->GetWindowId());
930 ClearSummary();
931 ClearExtraInfo();
932 ClearVelocityInfo();
933 DoDragReset();
934 }
935
OnDragStartForDragEvent(const DragPointerEvent & pointerEvent,const RefPtr<FrameNode> & frameNode)936 void DragDropManager::OnDragStartForDragEvent(const DragPointerEvent& pointerEvent,
937 const RefPtr<FrameNode>& frameNode)
938 {
939 auto container = Container::Current();
940 CHECK_NULL_VOID(container);
941 ResetPreTargetFrameNode(container->GetInstanceId());
942 RequireSummaryAndDragBundleInfoIfNecessary(pointerEvent);
943 SetDragCursorStyleCore(DragCursorStyleCore::DEFAULT);
944 OnDragMove(pointerEvent, extraInfo_, frameNode);
945 TAG_LOGI(AceLogTag::ACE_DRAG, "start drag, current windowId is %{public}d", container->GetWindowId());
946 }
947
HandleDragEvent(const DragPointerEvent & pointerEvent,DragEventAction action,const RefPtr<FrameNode> & node)948 void DragDropManager::HandleDragEvent(const DragPointerEvent& pointerEvent, DragEventAction action,
949 const RefPtr<FrameNode>& node)
950 {
951 switch (action) {
952 case DragEventAction::DRAG_EVENT_START_FOR_CONTROLLER: {
953 RequireSummary();
954 OnDragStart(pointerEvent.GetPoint());
955 break;
956 }
957 // PULL_OUT
958 case DragEventAction::DRAG_EVENT_OUT: {
959 OnDragMoveOut(pointerEvent);
960 break;
961 }
962 case DragEventAction::DRAG_EVENT_PULL_THROW: {
963 OnDragThrow(pointerEvent);
964 break;
965 }
966 case DragEventAction::DRAG_EVENT_PULL_CANCEL: {
967 OnDragPullCancel(pointerEvent);
968 break;
969 }
970 case DragEventAction::DRAG_EVENT_END: {
971 OnDragEnd(pointerEvent, extraInfo_, node);
972 break;
973 }
974 case DragEventAction::DRAG_EVENT_START: {
975 OnDragStartForDragEvent(pointerEvent, node);
976 break;
977 }
978 default:
979 break;
980 }
981 }
982
OnDragAsyncEnd()983 void DragDropManager::OnDragAsyncEnd()
984 {
985 auto asyncEndCallback = DragDropGlobalController::GetInstance().GetCallAnsyncEnd();
986 DragStartRequestStatus dragStatus = DragDropGlobalController::GetInstance().GetDragStartRequestStatus();
987 if (asyncEndCallback && dragStatus == DragStartRequestStatus::WAITING) {
988 asyncEndCallback(dragStatus);
989 }
990 }
991
isDistanceLimited(const Point & point)992 bool DragDropManager::isDistanceLimited(const Point& point)
993 {
994 auto distance = sqrt(pow(point.GetX() - preMovePoint_.GetX(), 2) + pow(point.GetY() - preMovePoint_.GetY(), 2));
995 TAG_LOGD(AceLogTag::ACE_DRAG, "onDragMove, distance: %{public}f", distance);
996 if (distance < MOVE_DISTANCE_LIMIT) {
997 TAG_LOGD(AceLogTag::ACE_DRAG, "onDragMove, distance is less than limit");
998 return true;
999 }
1000 return false;
1001 }
1002
isTimeLimited(const DragPointerEvent & pointerEvent,const Point & point)1003 bool DragDropManager::isTimeLimited(const DragPointerEvent& pointerEvent, const Point& point)
1004 {
1005 uint64_t currentTimeStamp = static_cast<uint64_t>(
1006 std::chrono::duration_cast<std::chrono::milliseconds>(pointerEvent.time.time_since_epoch()).count());
1007 if (currentTimeStamp > preTimeStamp_ && currentTimeStamp - preTimeStamp_ < MOVE_TIME_LIMIT) {
1008 TAG_LOGD(AceLogTag::ACE_DRAG, "onDragMove, time is less than limit");
1009 return true;
1010 }
1011 return false;
1012 }
1013
ReachMoveLimit(const DragPointerEvent & pointerEvent,const Point & point)1014 bool DragDropManager::ReachMoveLimit(const DragPointerEvent& pointerEvent, const Point& point)
1015 {
1016 if (pointerEvent.sourceTool == SourceTool::MOUSE) {
1017 if (isTimeLimited(pointerEvent, point) && isDistanceLimited(point)) {
1018 return true;
1019 }
1020 }
1021 return false;
1022 }
1023
HandleOnDragMove(const DragPointerEvent & pointerEvent,const std::string & extraInfo,const RefPtr<FrameNode> & dragFrameNode)1024 void DragDropManager::HandleOnDragMove(const DragPointerEvent& pointerEvent, const std::string& extraInfo,
1025 const RefPtr<FrameNode>& dragFrameNode)
1026 {
1027 CHECK_NULL_VOID(dragFrameNode);
1028
1029 if (dragFrameNode == preTargetFrameNode_) {
1030 FireOnDragEvent(dragFrameNode, pointerEvent, DragEventType::MOVE, extraInfo);
1031 return;
1032 }
1033
1034 FireOnDragLeave(preTargetFrameNode_, pointerEvent, extraInfo);
1035 PrintDragFrameNode(pointerEvent, dragFrameNode);
1036 FireOnDragEvent(dragFrameNode, pointerEvent, DragEventType::ENTER, extraInfo);
1037 preTargetFrameNode_ = dragFrameNode;
1038 }
1039
OnDragMove(const DragPointerEvent & pointerEvent,const std::string & extraInfo,const RefPtr<FrameNode> & node)1040 void DragDropManager::OnDragMove(const DragPointerEvent& pointerEvent, const std::string& extraInfo,
1041 const RefPtr<FrameNode>& node)
1042 {
1043 RequireSummaryAndDragBundleInfoIfNecessary(pointerEvent);
1044 Point point = pointerEvent.GetPoint();
1045 auto container = Container::Current();
1046 CHECK_NULL_VOID(container);
1047 if (container && container->IsSceneBoardWindow()) {
1048 if (IsDragged() && IsWindowConsumed()) {
1049 SetIsWindowConsumed(false);
1050 return;
1051 }
1052 }
1053 if (ReachMoveLimit(pointerEvent, point)) {
1054 return;
1055 }
1056 NotifyPullEventListener(pointerEvent);
1057 preMovePoint_ = point;
1058 preDragPointerEvent_ = pointerEvent;
1059 preTimeStamp_ = static_cast<uint64_t>(
1060 std::chrono::duration_cast<std::chrono::milliseconds>(pointerEvent.time.time_since_epoch()).count());
1061 SetIsWindowConsumed(false);
1062 if (isDragFwkShow_) {
1063 auto menuWrapper = GetMenuWrapperNodeFromDrag();
1064 if (menuWrapper) {
1065 OffsetF menuPosition(
1066 static_cast<float>(pointerEvent.GetDisplayX()), static_cast<float>(pointerEvent.GetDisplayY()));
1067 SubwindowManager::GetInstance()->UpdateHideMenuOffsetNG(
1068 menuPosition, 1.0, false, menuWrapper ? menuWrapper->GetId() : -1);
1069 }
1070 }
1071 UpdateVelocityTrackerPoint(point, false);
1072 UpdateDragListener(point);
1073 auto dragFrameNode = FindDragFrameNodeByPosition(
1074 static_cast<float>(point.GetX()), static_cast<float>(point.GetY()), node);
1075 if (!dragFrameNode) {
1076 if (preTargetFrameNode_) {
1077 TAG_LOGI(AceLogTag::ACE_DRAG,
1078 "Not find drag target node, current windowId is %{public}d, pointerEventId is %{public}d, "
1079 "PreTargetFrameNode is %{public}s, depth is %{public}d.",
1080 container->GetWindowId(), pointerEvent.pointerEventId, preTargetFrameNode_->GetTag().c_str(),
1081 preTargetFrameNode_->GetDepth());
1082 FireOnDragEvent(preTargetFrameNode_, pointerEvent, DragEventType::LEAVE, extraInfo);
1083 preTargetFrameNode_ = nullptr;
1084 }
1085 UpdateDragStyle(DragCursorStyleCore::MOVE, pointerEvent.pointerEventId);
1086 return;
1087 }
1088 HandleOnDragMove(pointerEvent, extraInfo, dragFrameNode);
1089 }
1090
ResetDragDropStatus(const Point & point,const DragDropRet & dragDropRet,int32_t windowId)1091 void DragDropManager::ResetDragDropStatus(const Point& point, const DragDropRet& dragDropRet, int32_t windowId)
1092 {
1093 ACE_SCOPED_TRACE("drag: reset drag %d, %d", dragDropRet.result, dragDropRet.hasCustomAnimation);
1094 if (dragDropRet.result != DragRet::DRAG_FAIL || !isMouseDragged_) {
1095 InteractionInterface::GetInstance()->SetDragWindowVisible(!dragDropRet.hasCustomAnimation);
1096 }
1097 InteractionInterface::GetInstance()->StopDrag(dragDropRet);
1098 NotifyDragFrameNode(point, DragEventType::DROP, dragDropRet.result);
1099 ResetPullId();
1100 dragCursorStyleCore_ = DragCursorStyleCore::DEFAULT;
1101 isReDragStart_ = false;
1102 }
1103
ResetPreTargetFrameNode(int32_t instanceId)1104 void DragDropManager::ResetPreTargetFrameNode(int32_t instanceId)
1105 {
1106 auto container = Container::GetContainer(instanceId);
1107 if (container && (container->IsSceneBoardWindow() || container->IsUIExtensionWindow())) {
1108 return;
1109 }
1110 // pull-in subwindow, need to notify showMenu and update menu offset.
1111 if (instanceId > MIN_SUBCONTAINER_ID) {
1112 isDragFwkShow_ = true;
1113 }
1114 preTargetFrameNode_ = nullptr;
1115 }
1116
ResetDragEndOption(const DragNotifyMsgCore & notifyMessage,const RefPtr<OHOS::Ace::DragEvent> & dragEvent,int32_t currentId)1117 void DragDropManager::ResetDragEndOption(
1118 const DragNotifyMsgCore& notifyMessage, const RefPtr<OHOS::Ace::DragEvent>& dragEvent, int32_t currentId)
1119 {
1120 ResetBundleInfo();
1121 SetDragResult(notifyMessage, dragEvent);
1122 SetDragBehavior(notifyMessage, dragEvent);
1123 DoDragReset();
1124 SetIsDragged(false);
1125 SetDraggingPointer(-1);
1126 SetDraggingPressedState(false);
1127 ResetDragPreviewInfo();
1128 HideDragPreviewWindow(currentId);
1129 CHECK_NULL_VOID(dragEvent);
1130 dragEvent->SetDragSource(dragBundleInfo_.bundleName);
1131 dragEvent->SetRemoteDev(dragBundleInfo_.isRemoteDev);
1132 dragEvent->SetPressedKeyCodes(GetDragDropPointerEvent().pressedKeyCodes);
1133 }
1134
DoDragReset()1135 void DragDropManager::DoDragReset()
1136 {
1137 dragDropState_ = DragDropMgrState::IDLE;
1138 preTargetFrameNode_ = nullptr;
1139 draggedFrameNode_ = nullptr;
1140 rootNode_ = nullptr;
1141 menuWrapperNode_ = nullptr;
1142 preMovePoint_ = Point(0, 0);
1143 hasNotifiedTransformation_ = false;
1144 badgeNumber_ = -1;
1145 isDragWithContextMenu_ = false;
1146 dampingOverflowCount_ = 0;
1147 isDragNodeNeedClean_ = false;
1148 isAnyDraggableHit_ = false;
1149 isPullThrow_ = false;
1150 fingerPointInfo_.clear();
1151 dragCursorStyleCore_ = DragCursorStyleCore::DEFAULT;
1152 DragDropGlobalController::GetInstance().ResetDragDropInitiatingStatus();
1153 }
1154
ResetDraggingStatus(const TouchEvent & touchPoint)1155 void DragDropManager::ResetDraggingStatus(const TouchEvent& touchPoint)
1156 {
1157 if (IsDraggingPressed(touchPoint.id)) {
1158 SetDraggingPressedState(false);
1159 }
1160 if (!IsItemDragging() && IsDragging() && IsSameDraggingPointer(touchPoint.id) && !isPullThrow_) {
1161 TAG_LOGI(AceLogTag::ACE_DRAG, "Reset dragging status, stop drag. pointerId: %{public}d", touchPoint.id);
1162 DragPointerEvent dragPointerEvent;
1163 DragDropFuncWrapper::ConvertPointerEvent(touchPoint, dragPointerEvent);
1164 SetIsDisableDefaultDropAnimation(true);
1165 OnDragEnd(dragPointerEvent, "");
1166 }
1167 }
1168
HandleOnDragEnd(const DragPointerEvent & pointerEvent,const std::string & extraInfo,const RefPtr<FrameNode> & dragFrameNode)1169 void DragDropManager::HandleOnDragEnd(const DragPointerEvent& pointerEvent, const std::string& extraInfo,
1170 const RefPtr<FrameNode>& dragFrameNode)
1171 {
1172 CHECK_NULL_VOID(dragFrameNode);
1173 Point point = pointerEvent.GetPoint();
1174 auto container = Container::Current();
1175 CHECK_NULL_VOID(container);
1176 if (!IsDropAllowed(dragFrameNode)) {
1177 TAG_LOGI(AceLogTag::ACE_DRAG,
1178 "DragDropManager onDragEnd, target data is not allowed to fall into. WindowId is %{public}d, "
1179 "pointerEventId is %{public}d.",
1180 container->GetWindowId(), pointerEvent.pointerEventId);
1181 DragDropBehaviorReporter::GetInstance().UpdateDragStopResult(DragStopResult::APP_REFUSE_DATA);
1182 ACE_SCOPED_TRACE("drag: stop drag, not allowed to drop");
1183 ResetDragDrop(container->GetWindowId(), point);
1184 return;
1185 }
1186 TAG_LOGI(AceLogTag::ACE_DRAG, "Current windowId is %{public}d, pointerEventId is %{public}d, "
1187 "TargetNode is %{public}s.",
1188 container->GetWindowId(), pointerEvent.pointerEventId, dragFrameNode->GetTag().c_str());
1189 if (IsUIExtensionOrDynamicComponent(dragFrameNode)) {
1190 auto pattern = dragFrameNode->GetPattern<Pattern>();
1191 pattern->HandleDragEvent(pointerEvent);
1192 NotifyDragFrameNode(point, DragEventType::DROP);
1193 return;
1194 }
1195
1196 RequestDragSummaryInfoAndPrivilege();
1197 std::string udKey;
1198 InteractionInterface::GetInstance()->GetUdKey(udKey);
1199 auto eventHub = dragFrameNode->GetOrCreateEventHub<EventHub>();
1200 CHECK_NULL_VOID(eventHub);
1201 if (!eventHub->GetDisableDataPrefetch()) {
1202 if (!CheckRemoteData(dragFrameNode, pointerEvent, udKey)) {
1203 auto unifiedData = RequestUDMFDataWithUDKey(udKey);
1204 DoDropAction(dragFrameNode, pointerEvent, unifiedData, udKey);
1205 }
1206 } else {
1207 DoDropAction(dragFrameNode, pointerEvent, nullptr, udKey);
1208 }
1209 }
1210
OnDragEnd(const DragPointerEvent & pointerEvent,const std::string & extraInfo,const RefPtr<FrameNode> & node,const bool keyEscape)1211 void DragDropManager::OnDragEnd(const DragPointerEvent& pointerEvent, const std::string& extraInfo,
1212 const RefPtr<FrameNode>& node, const bool keyEscape)
1213 {
1214 NotifyDragSpringLoadingIntercept(extraInfo);
1215 RemoveDeadlineTimer();
1216 Point point = pointerEvent.GetPoint();
1217 DragDropBehaviorReporter::GetInstance().UpdateEndPoint(point);
1218 dragDropPointerEvent_ = pointerEvent;
1219 auto preTargetFrameNode = preTargetFrameNode_;
1220 DoDragReset();
1221 auto container = Container::Current();
1222 auto containerId = container->GetInstanceId();
1223 DragDropBehaviorReporter::GetInstance().UpdateContainerId(containerId);
1224 if (container && container->IsSceneBoardWindow() && (IsDragged() && IsWindowConsumed())) {
1225 TAG_LOGD(AceLogTag::ACE_DRAG, "DragDropManager is dragged or window consumed. WindowId is %{public}d",
1226 container->GetWindowId());
1227 return;
1228 }
1229 UpdateVelocityTrackerPoint(point, true);
1230 auto dragFrameNode = FindDragFrameNodeByPosition(
1231 static_cast<float>(point.GetX()), static_cast<float>(point.GetY()), FilterSubwindowDragRootNode(node));
1232 if (HandleUIExtensionComponentDragCancel(preTargetFrameNode, dragFrameNode, keyEscape, pointerEvent, point)) {
1233 return;
1234 }
1235 if (isDragCancel_) {
1236 DragDropBehaviorReporter::GetInstance().UpdateDragStopResult(DragStopResult::USER_STOP_DRAG);
1237 TAG_LOGI(AceLogTag::ACE_DRAG, "DragDropManager is dragCancel, finish drag. WindowId is %{public}d, "
1238 "pointerEventId is %{public}d.",
1239 container->GetWindowId(), pointerEvent.pointerEventId);
1240 ACE_SCOPED_TRACE("drag: drag cancelled");
1241 DragDropRet dragDropRet { DragRet::DRAG_CANCEL, false, container->GetWindowId(), DragBehavior::UNKNOWN };
1242 ResetDragDropStatus(point, dragDropRet, container->GetWindowId());
1243 FireOnDragEvent(preTargetFrameNode, pointerEvent, DragEventType::LEAVE, extraInfo);
1244 ClearVelocityInfo();
1245 return;
1246 }
1247 if (IsUIExtensionOrDynamicComponent(preTargetFrameNode) && preTargetFrameNode != dragFrameNode) {
1248 HandleUIExtensionDragEvent(preTargetFrameNode, pointerEvent, DragEventType::LEAVE);
1249 }
1250 if (!dragFrameNode) {
1251 DragDropBehaviorReporter::GetInstance().UpdateDragStopResult(DragStopResult::APP_DATA_UNSUPPORT);
1252 TAG_LOGI(AceLogTag::ACE_DRAG,
1253 "DragDropManager onDragEnd, not find drop target, stop drag. WindowId is %{public}d, "
1254 "pointerEventId is %{public}d.",
1255 container->GetWindowId(), pointerEvent.pointerEventId);
1256 ACE_SCOPED_TRACE("drag: drag stop, not find drop target");
1257 ResetDragDrop(container->GetWindowId(), point);
1258 return;
1259 }
1260 HandleOnDragEnd(pointerEvent, extraInfo, dragFrameNode);
1261 }
1262
HandleUIExtensionComponentDragCancel(const RefPtr<FrameNode> & preTargetFrameNode,const RefPtr<FrameNode> & dragFrameNode,const bool keyEscape,const DragPointerEvent & pointerEvent,const Point & point)1263 bool DragDropManager::HandleUIExtensionComponentDragCancel(const RefPtr<FrameNode>& preTargetFrameNode,
1264 const RefPtr<FrameNode>& dragFrameNode, const bool keyEscape, const DragPointerEvent& pointerEvent,
1265 const Point& point)
1266 {
1267 if (!isDragCancel_) {
1268 return false;
1269 }
1270 if (keyEscape && IsUIExtensionOrDynamicComponent(preTargetFrameNode)) {
1271 HandleUIExtensionDragEvent(preTargetFrameNode, pointerEvent, DragEventType::PULL_CANCEL);
1272 NotifyDragFrameNode(point, DragEventType::DROP);
1273 return true;
1274 }
1275 if (IsUIExtensionOrDynamicComponent(dragFrameNode)) {
1276 auto pattern = dragFrameNode->GetPattern<Pattern>();
1277 CHECK_NULL_RETURN(pattern, true);
1278 pattern->HandleDragEvent(pointerEvent);
1279 NotifyDragFrameNode(point, DragEventType::DROP);
1280 return true;
1281 }
1282 return false;
1283 }
1284
IsDropAllowed(const RefPtr<FrameNode> & dragFrameNode)1285 bool DragDropManager::IsDropAllowed(const RefPtr<FrameNode>& dragFrameNode)
1286 {
1287 CHECK_NULL_RETURN(dragFrameNode, false);
1288 // application passed in null to indicate refusing all drag data forcedly
1289 bool isDisallowDropForcedly = dragFrameNode->GetDisallowDropForcedly();
1290 if (isDisallowDropForcedly) {
1291 return false;
1292 }
1293 const auto& dragFrameNodeAllowDrop = dragFrameNode->GetAllowDrop();
1294 // if application does not set allow drop or set with empty, treat as all data types is allowed
1295 if (dragFrameNodeAllowDrop.empty() || summaryMap_.empty()) {
1296 return true;
1297 }
1298 DragDropBehaviorReporter::GetInstance().UpdateAllowDropType(dragFrameNodeAllowDrop);
1299 dragSummaryInfo_.summary = summaryMap_;
1300 return UdmfClient::GetInstance()->IsAppropriateType(dragSummaryInfo_, dragFrameNodeAllowDrop);
1301 }
1302
RequestDragSummaryInfoAndPrivilege()1303 void DragDropManager::RequestDragSummaryInfoAndPrivilege()
1304 {
1305 RequireSummary();
1306 int ret = InteractionInterface::GetInstance()->AddPrivilege();
1307 if (ret != 0 && SystemProperties::GetDebugEnabled()) {
1308 TAG_LOGD(AceLogTag::ACE_DRAG, "Interaction AddPrivilege in DragEnd with code:%{public}d", ret);
1309 }
1310 ShadowOffsetData shadowOffsetData { -1, -1, -1, -1 };
1311 ret = InteractionInterface::GetInstance()->GetShadowOffset(shadowOffsetData);
1312 if (ret == 0) {
1313 previewRect_ =
1314 Rect(shadowOffsetData.offsetX, shadowOffsetData.offsetY, shadowOffsetData.width, shadowOffsetData.height);
1315 } else {
1316 TAG_LOGD(AceLogTag::ACE_DRAG, "Interaction GetShadowOffset in DragEnd with code:%{public}d", ret);
1317 }
1318 }
1319
DoDropAction(const RefPtr<FrameNode> & dragFrameNode,const DragPointerEvent & pointerEvent,const RefPtr<UnifiedData> & unifiedData,const std::string & udKey)1320 void DragDropManager::DoDropAction(const RefPtr<FrameNode>& dragFrameNode, const DragPointerEvent& pointerEvent,
1321 const RefPtr<UnifiedData>& unifiedData, const std::string& udKey)
1322 {
1323 RefPtr<OHOS::Ace::DragEvent> event = AceType::MakeRefPtr<OHOS::Ace::DragEvent>();
1324 CHECK_NULL_VOID(event);
1325 if (!udKey.empty()) {
1326 event->SetUdKey(udKey);
1327 }
1328 if (unifiedData == nullptr) {
1329 event->SetIsGetDataSuccess(false);
1330 } else {
1331 DragDropBehaviorReporter::GetInstance().UpdateRecordSize(unifiedData->GetSize());
1332 event->SetData(unifiedData);
1333 event->SetIsGetDataSuccess(true);
1334 }
1335
1336 OnDragDrop(event, dragFrameNode, pointerEvent);
1337 }
1338
RequestUDMFDataWithUDKey(const std::string & udKey)1339 RefPtr<UnifiedData> DragDropManager::RequestUDMFDataWithUDKey(const std::string& udKey)
1340 {
1341 if (udKey.empty()) {
1342 TAG_LOGI(AceLogTag::ACE_DRAG, "udKey is empty");
1343 return nullptr;
1344 }
1345 ACE_SCOPED_TRACE("drag: get drag data from udmf");
1346 RefPtr<UnifiedData> udData = UdmfClient::GetInstance()->CreateUnifiedData();
1347 auto ret = UdmfClient::GetInstance()->GetData(udData, udKey);
1348 if (ret != 0) {
1349 TAG_LOGI(AceLogTag::ACE_DRAG, "Get udmfData failed");
1350 return nullptr;
1351 }
1352 return udData;
1353 }
1354
TryGetDataBackGround(const RefPtr<FrameNode> & dragFrameNode,const DragPointerEvent & pointerEvent,const std::string & udKey,int32_t count)1355 void DragDropManager::TryGetDataBackGround(const RefPtr<FrameNode>& dragFrameNode, const DragPointerEvent& pointerEvent,
1356 const std::string& udKey, int32_t count)
1357 {
1358 auto pipeline = PipelineContext::GetCurrentContext();
1359 CHECK_NULL_VOID(pipeline);
1360 auto taskScheduler = pipeline->GetTaskExecutor();
1361 CHECK_NULL_VOID(taskScheduler);
1362 taskScheduler->PostTask(
1363 [id = Container::CurrentId(), pipeline, dragFrameNode, pointerEvent, udKey, count,
1364 weakManager = WeakClaim(this)]() {
1365 ContainerScope scope(id);
1366 auto dragDropManager = weakManager.Upgrade();
1367 CHECK_NULL_VOID(dragDropManager);
1368 auto taskScheduler = pipeline->GetTaskExecutor();
1369 CHECK_NULL_VOID(taskScheduler);
1370 auto result = dragDropManager->RequestUDMFDataWithUDKey(udKey);
1371 if (result != nullptr || count >= MAX_RETRY_TIMES) {
1372 taskScheduler->PostTask(
1373 [dragFrameNode, pointerEvent, weakManager, result, udKey]() {
1374 auto dragDropManager = weakManager.Upgrade();
1375 CHECK_NULL_VOID(dragDropManager);
1376 dragDropManager->DoDropAction(dragFrameNode, pointerEvent, result, udKey);
1377 },
1378 TaskExecutor::TaskType::UI, "ArkUIDragDropAction");
1379 } else {
1380 // first temp get udmfData failed, prepare to retryGetData.
1381 taskScheduler->PostDelayedTask(
1382 [dragFrameNode, pointerEvent, weakManager, count, udKey]() {
1383 auto dragDropManager = weakManager.Upgrade();
1384 CHECK_NULL_VOID(dragDropManager);
1385 dragDropManager->TryGetDataBackGround(dragFrameNode, pointerEvent, udKey, count + 1);
1386 },
1387 TaskExecutor::TaskType::UI, MAX_RETRY_DURATION, "ArkUIDragDropRetryGetData");
1388 }
1389 },
1390 TaskExecutor::TaskType::BACKGROUND, "ArkUIDragDropGetDataBackground");
1391 }
1392
CheckRemoteData(const RefPtr<FrameNode> & dragFrameNode,const DragPointerEvent & pointerEvent,const std::string & udKey)1393 bool DragDropManager::CheckRemoteData(
1394 const RefPtr<FrameNode>& dragFrameNode, const DragPointerEvent& pointerEvent, const std::string& udKey)
1395 {
1396 if (udKey.empty()) {
1397 DragDropBehaviorReporter::GetInstance().UpdateDragStopResult(DragStopResult::GET_UDKEY_FAIL);
1398 return false;
1399 }
1400 std::string remoteUdKey = udKey;
1401 auto isRemoteData = UdmfClient::GetInstance()->GetRemoteStatus(remoteUdKey);
1402 if (isRemoteData) {
1403 TAG_LOGI(AceLogTag::ACE_DRAG, "Stop drag with motion drag action.");
1404 TryGetDataBackGround(dragFrameNode, pointerEvent, udKey);
1405 DragDropBehaviorReporter::GetInstance().UpdateDragStopResult(DragStopResult::GET_UDKEY_FAIL);
1406 DragDropBehaviorReporter::GetInstance().UpdateIsCrossing(CrossingEnd::IS_CROSSING);
1407 return isRemoteData;
1408 }
1409 DragDropBehaviorReporter::GetInstance().UpdateIsCrossing(CrossingEnd::NOT_CROSSING);
1410 return isRemoteData;
1411 }
1412
OnDragDrop(RefPtr<OHOS::Ace::DragEvent> & event,const RefPtr<FrameNode> & dragFrameNode,const OHOS::Ace::DragPointerEvent & pointerEvent)1413 void DragDropManager::OnDragDrop(RefPtr<OHOS::Ace::DragEvent>& event, const RefPtr<FrameNode>& dragFrameNode,
1414 const OHOS::Ace::DragPointerEvent& pointerEvent)
1415 {
1416 auto point = pointerEvent.GetPoint();
1417 CHECK_NULL_VOID(dragFrameNode);
1418 auto eventHub = dragFrameNode->GetOrCreateEventHub<EventHub>();
1419 CHECK_NULL_VOID(eventHub);
1420 UpdateDragEvent(event, pointerEvent);
1421 auto extraParams = eventHub->GetDragExtraParams(extraInfo_, point, DragEventType::DROP);
1422 DragDropGlobalController::GetInstance().SetIsOnOnDropPhase(true);
1423 DragDropBehaviorReporter::GetInstance().UpdateFrameNodeDropId(dragFrameNode->GetId());
1424 DragDropBehaviorReporter::GetInstance().UpdateDropResult(DropResult::DROP_SUCCESS);
1425 eventHub->FireCustomerOnDragFunc(DragFuncType::DRAG_DROP, event, extraParams);
1426 if (event->IsDragEndPending() && event->GetRequestIdentify() != -1) {
1427 if (PostStopDrag(dragFrameNode, pointerEvent, event, extraParams)) {
1428 return;
1429 }
1430 }
1431 HandleStopDrag(dragFrameNode, pointerEvent, event, extraParams);
1432 DragDropGlobalController::GetInstance().SetIsOnOnDropPhase(false);
1433 }
1434
HandleStopDrag(const RefPtr<FrameNode> & dragFrameNode,const DragPointerEvent & pointerEvent,const RefPtr<OHOS::Ace::DragEvent> & event,const std::string & extraParams)1435 void DragDropManager::HandleStopDrag(const RefPtr<FrameNode>& dragFrameNode, const DragPointerEvent& pointerEvent,
1436 const RefPtr<OHOS::Ace::DragEvent>& event, const std::string& extraParams)
1437 {
1438 auto point = pointerEvent.GetPoint();
1439 CHECK_NULL_VOID(dragFrameNode);
1440 auto eventHub = dragFrameNode->GetOrCreateEventHub<EventHub>();
1441 CHECK_NULL_VOID(eventHub);
1442 eventHub->HandleInternalOnDrop(event, extraParams);
1443 ClearVelocityInfo();
1444 SetIsDragged(false);
1445 auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
1446 CHECK_NULL_VOID(pipeline);
1447 auto dragResult = event->GetResult();
1448 if (dragResult == DragRet::DRAG_FAIL) {
1449 DragDropBehaviorReporter::GetInstance().UpdateDragStopResult(DragStopResult::APP_RECEIVE_FAIL);
1450 } else if (dragResult == DragRet::DRAG_CANCEL) {
1451 DragDropBehaviorReporter::GetInstance().UpdateDragStopResult(DragStopResult::USER_STOP_DRAG);
1452 }
1453 auto useCustomAnimation = event->IsUseCustomAnimation();
1454 if (event->GetNeedDoInternalDropAnimation() && useCustomAnimation) {
1455 TAG_LOGI(AceLogTag::ACE_DRAG, "Need do internal drop animation, set useCustomAnimation to false.");
1456 useCustomAnimation = false;
1457 }
1458 auto dragBehavior = event->GetDragBehavior();
1459 auto container = Container::Current();
1460 CHECK_NULL_VOID(container);
1461 auto windowId = container->GetWindowId();
1462 ExecuteStopDrag(event, dragResult, useCustomAnimation, windowId, dragBehavior, pointerEvent);
1463 NotifyDragFrameNode(point, DragEventType::DROP, event->GetResult());
1464 dragFrameNode->MarkDirtyNode();
1465 ResetPullId();
1466 dragCursorStyleCore_ = DragCursorStyleCore::DEFAULT;
1467 pipeline->RequestFrame();
1468 }
1469
PostStopDrag(const RefPtr<FrameNode> & dragFrameNode,const DragPointerEvent & pointerEvent,const RefPtr<OHOS::Ace::DragEvent> & event,const std::string & extraParams)1470 bool DragDropManager::PostStopDrag(const RefPtr<FrameNode>& dragFrameNode, const DragPointerEvent& pointerEvent,
1471 const RefPtr<OHOS::Ace::DragEvent>& event, const std::string& extraParams)
1472 {
1473 CHECK_NULL_RETURN(dragFrameNode, false);
1474 CHECK_NULL_RETURN(event, false);
1475 auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
1476 CHECK_NULL_RETURN(pipeline, false);
1477 auto taskScheduler = pipeline->GetTaskExecutor();
1478 CHECK_NULL_RETURN(taskScheduler, false);
1479 taskScheduler->PostDelayedTask(
1480 [pointerEvent, event, extraParams, nodeWeak = WeakClaim(AceType::RawPtr(dragFrameNode)),
1481 weakManager = WeakClaim(this)]() {
1482 if (!DragDropGlobalController::GetInstance().IsCurrentDrag(event->GetRequestIdentify())) {
1483 return;
1484 }
1485 if (!DragDropGlobalController::GetInstance().IsOnOnDropPhase() || !event) {
1486 return;
1487 }
1488 auto dragDropManager = weakManager.Upgrade();
1489 if (dragDropManager) {
1490 auto frameNode = nodeWeak.Upgrade();
1491 event->SetResult(DragRet::DRAG_FAIL);
1492 dragDropManager->HandleStopDrag(frameNode, pointerEvent, event, extraParams);
1493 }
1494 DragDropGlobalController::GetInstance().SetIsOnOnDropPhase(false);
1495 },
1496 TaskExecutor::TaskType::UI, DROP_DELAY_TIME, "ArkUIStopDragDeadlineTimer");
1497 return DragDropGlobalController::GetInstance().RequestDragEndCallback(event->GetRequestIdentify(),
1498 event->GetResult(), GetStopDragCallBack(dragFrameNode, pointerEvent, event, extraParams));
1499 }
1500
GetStopDragCallBack(const RefPtr<FrameNode> & dragFrameNode,const DragPointerEvent & pointerEvent,const RefPtr<OHOS::Ace::DragEvent> & event,const std::string & extraParams)1501 std::function<void(const DragRet&)> DragDropManager::GetStopDragCallBack(const RefPtr<FrameNode>& dragFrameNode,
1502 const DragPointerEvent& pointerEvent, const RefPtr<OHOS::Ace::DragEvent>& event, const std::string& extraParams)
1503 {
1504 auto callback = [id = Container::CurrentId(), pointerEvent, event, extraParams,
1505 nodeWeak = WeakClaim(AceType::RawPtr(dragFrameNode)),
1506 weakManager = WeakClaim(this)] (const DragRet& dragResult) {
1507 ContainerScope scope(id);
1508 auto dragDropManager = weakManager.Upgrade();
1509 CHECK_NULL_VOID(dragDropManager);
1510 CHECK_NULL_VOID(event);
1511 event->SetResult(dragResult);
1512 auto frameNode = nodeWeak.Upgrade();
1513 dragDropManager->HandleStopDrag(frameNode, pointerEvent, event, extraParams);
1514 };
1515 return callback;
1516 }
1517
ExecuteStopDrag(const RefPtr<OHOS::Ace::DragEvent> & event,DragRet dragResult,bool useCustomAnimation,int32_t windowId,DragBehavior dragBehavior,const OHOS::Ace::DragPointerEvent & pointerEvent)1518 void DragDropManager::ExecuteStopDrag(const RefPtr<OHOS::Ace::DragEvent>& event, DragRet dragResult,
1519 bool useCustomAnimation, int32_t windowId, DragBehavior dragBehavior,
1520 const OHOS::Ace::DragPointerEvent& pointerEvent)
1521 {
1522 if (useCustomAnimation && event->HasDropAnimation()) {
1523 ExecuteCustomDropAnimation(event, DragDropRet { dragResult, useCustomAnimation, windowId, dragBehavior });
1524 return;
1525 }
1526 auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
1527 CHECK_NULL_VOID(pipeline);
1528 HideSubwindowDragNode();
1529 auto overlayManager = GetDragAnimationOverlayManager(pipeline->GetInstanceId());
1530 if (overlayManager && !isDragFwkShow_) {
1531 overlayManager->RemoveDragPixelMap();
1532 overlayManager->RemoveFilter();
1533 pipeline->FlushMessages();
1534 }
1535 pipeline->AddAfterRenderTask([dragResult, useCustomAnimation, windowId, dragBehavior,
1536 pointerEventId = pointerEvent.pointerEventId, weak = WeakClaim(this)]() mutable {
1537 auto manager = weak.Upgrade();
1538 if (manager) {
1539 manager->HideDragPreviewOverlay();
1540 useCustomAnimation = manager->IsDisableDefaultDropAnimation() ? true : useCustomAnimation;
1541 }
1542 TAG_LOGI(AceLogTag::ACE_DRAG,
1543 "Stop drag, start do drop animation. useCustomAnimation is %{public}d,"
1544 "WindowId is %{public}d, pointerEventId is %{public}d.",
1545 useCustomAnimation, windowId, pointerEventId);
1546 InteractionInterface::GetInstance()->SetDragWindowVisible(!useCustomAnimation);
1547 DragDropRet dragDropRet { dragResult, useCustomAnimation, windowId, dragBehavior };
1548 InteractionInterface::GetInstance()->StopDrag(dragDropRet);
1549 });
1550 }
1551
SetRSSyncTransaction(OHOS::Rosen::RSSyncTransactionController ** transactionController,std::shared_ptr<Rosen::RSSyncTransactionHandler> & transactionHandler,const RefPtr<NG::PipelineContext> & pipeline)1552 void DragDropManager::SetRSSyncTransaction(OHOS::Rosen::RSSyncTransactionController** transactionController,
1553 std::shared_ptr<Rosen::RSSyncTransactionHandler>& transactionHandler, const RefPtr<NG::PipelineContext>& pipeline)
1554 {
1555 #ifdef ENABLE_ROSEN_BACKEND
1556 if (SystemProperties::GetMultiInstanceEnabled()) {
1557 CHECK_NULL_VOID(pipeline);
1558 auto window = pipeline->GetWindow();
1559 CHECK_NULL_VOID(window);
1560 auto rsUIDirector = window->GetRSUIDirector();
1561 CHECK_NULL_VOID(rsUIDirector);
1562 auto rsUIContext = rsUIDirector->GetRSUIContext();
1563 CHECK_NULL_VOID(rsUIContext);
1564 transactionHandler = rsUIContext->GetSyncTransactionHandler();
1565 } else {
1566 auto rsSyncTransactionController = Rosen::RSSyncTransactionController::GetInstance();
1567 *transactionController = rsSyncTransactionController;
1568 }
1569 #endif
1570 }
1571
ExecuteCustomDropAnimation(const RefPtr<OHOS::Ace::DragEvent> & event,DragDropRet dragDropRet)1572 void DragDropManager::ExecuteCustomDropAnimation(const RefPtr<OHOS::Ace::DragEvent>& event, DragDropRet dragDropRet)
1573 {
1574 CHECK_NULL_VOID(event);
1575 auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
1576 CHECK_NULL_VOID(pipeline);
1577
1578 #ifdef ENABLE_ROSEN_BACKEND
1579 OHOS::Rosen::RSSyncTransactionController* transactionController = nullptr;
1580 std::shared_ptr<Rosen::RSSyncTransactionHandler> transactionHandler;
1581 SetRSSyncTransaction(&transactionController, transactionHandler, pipeline);
1582 if (transactionController) {
1583 transactionController->OpenSyncTransaction();
1584 } else if (transactionHandler) {
1585 transactionHandler->OpenSyncTransaction();
1586 } else {
1587 TAG_LOGE(AceLogTag::ACE_DRAG, "transactionController and handler invalid");
1588 return;
1589 }
1590 event->ExecuteDropAnimation();
1591 auto overlayManager = GetDragAnimationOverlayManager(pipeline->GetInstanceId());
1592 if (overlayManager) {
1593 overlayManager->RemoveDragPixelMap();
1594 overlayManager->RemoveFilter();
1595 }
1596 HideSubwindowDragNode();
1597
1598 if (transactionController) {
1599 auto transaction = transactionController->GetRSTransaction();
1600 InteractionInterface::GetInstance()->SetDragWindowVisible(false, transaction);
1601 pipeline->FlushUITasks();
1602 transactionController->CloseSyncTransaction();
1603 } else if (transactionHandler) {
1604 auto transaction = transactionHandler->GetRSTransaction();
1605 InteractionInterface::GetInstance()->SetDragWindowVisible(false, transaction);
1606 pipeline->FlushUITasks();
1607 transactionHandler->CloseSyncTransaction();
1608 } else {
1609 InteractionInterface::GetInstance()->SetDragWindowVisible(false);
1610 pipeline->FlushMessages();
1611 }
1612 #else
1613 event->ExecuteDropAnimation();
1614 auto overlayManager = GetDragAnimationOverlayManager(pipeline->GetInstanceId());
1615 if (overlayManager) {
1616 overlayManager->RemoveDragPixelMap();
1617 overlayManager->RemoveFilter();
1618 }
1619 HideSubwindowDragNode();
1620 InteractionInterface::GetInstance()->SetDragWindowVisible(false);
1621 pipeline->FlushMessages();
1622 #endif
1623 InteractionInterface::GetInstance()->StopDrag(dragDropRet);
1624 }
1625
RequireSummary()1626 void DragDropManager::RequireSummary()
1627 {
1628 DragSummaryInfo dragSummaryInfo;
1629 int32_t ret =
1630 InteractionInterface::GetInstance()->GetDragSummary(dragSummaryInfo.summary, dragSummaryInfo.detailedSummary,
1631 dragSummaryInfo.summaryFormat, dragSummaryInfo.version, dragSummaryInfo.totalSize);
1632 if (ret != 0) {
1633 TAG_LOGI(AceLogTag::ACE_DRAG, "RequireSummary: Interaction GetSummary failed: %{public}d", ret);
1634 } else {
1635 std::string summarys = DragDropFuncWrapper::GetSummaryString(dragSummaryInfo.summary);
1636 std::string detailedSummarys = DragDropFuncWrapper::GetSummaryString(dragSummaryInfo.detailedSummary);
1637 TAG_LOGI(AceLogTag::ACE_DRAG, "require summary: %{public}s, detailedSummary:%{public}s", summarys.c_str(),
1638 detailedSummarys.c_str());
1639 DragDropBehaviorReporter::GetInstance().UpdateSummaryType(summarys);
1640 }
1641 std::string extraInfo;
1642 ret = InteractionInterface::GetInstance()->GetDragExtraInfo(extraInfo);
1643 if (ret != 0) {
1644 TAG_LOGI(AceLogTag::ACE_DRAG, "GetExtraInfo: Interaction GetExtraInfo failed: %{public}d", ret);
1645 }
1646 previewRect_ = Rect(-1, -1, -1, -1);
1647 extraInfo_ = extraInfo;
1648 summaryMap_ = dragSummaryInfo.summary;
1649 dragSummaryInfo_ = dragSummaryInfo;
1650 }
1651
ResetRecordSize(uint32_t recordSize)1652 void DragDropManager::ResetRecordSize(uint32_t recordSize)
1653 {
1654 recordSize_ = recordSize;
1655 }
1656
GetRecordSize() const1657 uint32_t DragDropManager::GetRecordSize() const
1658 {
1659 return recordSize_;
1660 }
1661
GetDragWindowRect(const Point & point)1662 Rect DragDropManager::GetDragWindowRect(const Point& point)
1663 {
1664 if (!previewRect_.IsValid()) {
1665 ShadowOffsetData shadowOffsetData { -1, -1, -1, -1 };
1666 int ret = InteractionInterface::GetInstance()->GetShadowOffset(shadowOffsetData);
1667 if (ret == 0) {
1668 previewRect_ = Rect(
1669 shadowOffsetData.offsetX,
1670 shadowOffsetData.offsetY,
1671 shadowOffsetData.width,
1672 shadowOffsetData.height);
1673 }
1674 }
1675 return previewRect_ + Offset(point.GetX(), point.GetY());
1676 }
1677
ClearSummary()1678 void DragDropManager::ClearSummary()
1679 {
1680 previewRect_ = Rect(-1, -1, -1, -1);
1681 ResetPullId();
1682 ResetRecordSize();
1683 }
1684
OnTextDragEnd(float globalX,float globalY,const std::string & extraInfo)1685 void DragDropManager::OnTextDragEnd(float globalX, float globalY, const std::string& extraInfo)
1686 {
1687 dragDropState_ = DragDropMgrState::IDLE;
1688 auto dragFrameNode = FindDragFrameNodeByPosition(globalX, globalY);
1689 if (dragFrameNode) {
1690 auto textFieldPattern = dragFrameNode->GetPattern<TextFieldPattern>();
1691 if (textFieldPattern) {
1692 textFieldPattern->InsertValue(extraInfo);
1693 }
1694 }
1695 SetIsDragged(false);
1696 currentId_ = -1;
1697 }
1698
onDragCancel()1699 void DragDropManager::onDragCancel()
1700 {
1701 preTargetFrameNode_ = nullptr;
1702 draggedFrameNode_ = nullptr;
1703 }
1704
FireOnDragEventWithDragType(const RefPtr<EventHub> & eventHub,DragEventType type,RefPtr<OHOS::Ace::DragEvent> & event,const std::string & extraParams)1705 void DragDropManager::FireOnDragEventWithDragType(const RefPtr<EventHub>& eventHub, DragEventType type,
1706 RefPtr<OHOS::Ace::DragEvent>& event, const std::string& extraParams)
1707 {
1708 switch (type) {
1709 case DragEventType::ENTER: {
1710 eventHub->FireCustomerOnDragFunc(DragFuncType::DRAG_ENTER, event, extraParams);
1711 eventHub->FireOnDragEnter(event, extraParams);
1712 break;
1713 }
1714 case DragEventType::MOVE: {
1715 eventHub->FireCustomerOnDragFunc(DragFuncType::DRAG_MOVE, event, extraParams);
1716 eventHub->FireOnDragMove(event, extraParams);
1717 break;
1718 }
1719 case DragEventType::LEAVE: {
1720 eventHub->FireCustomerOnDragFunc(DragFuncType::DRAG_LEAVE, event, extraParams);
1721 eventHub->FireOnDragLeave(event, extraParams);
1722 break;
1723 }
1724 case DragEventType::DROP: {
1725 eventHub->FireCustomerOnDragFunc(DragFuncType::DRAG_DROP, event, extraParams);
1726 eventHub->HandleInternalOnDrop(event, extraParams);
1727 break;
1728 }
1729 default:
1730 break;
1731 }
1732 }
1733
FireOnDragSpringLoadingEventWithDragType(const RefPtr<FrameNode> & frameNode,const RefPtr<EventHub> & eventHub,DragEventType type,const std::string & extraParams)1734 void DragDropManager::FireOnDragSpringLoadingEventWithDragType(const RefPtr<FrameNode>& frameNode,
1735 const RefPtr<EventHub>& eventHub, DragEventType type, const std::string& extraParams)
1736 {
1737 if (!eventHub->HasCustomerOnDragSpringLoading()) {
1738 return;
1739 }
1740 switch (type) {
1741 case DragEventType::ENTER:
1742 case DragEventType::MOVE: {
1743 NotifyDragSpringLoadingMove(frameNode, extraParams);
1744 break;
1745 }
1746 case DragEventType::LEAVE: {
1747 NotifyDragSpringLoadingIntercept(extraParams);
1748 break;
1749 }
1750 default:
1751 break;
1752 }
1753 }
1754
FireOnDragEvent(const RefPtr<FrameNode> & frameNode,const DragPointerEvent & pointerEvent,DragEventType type,const std::string & extraInfo)1755 void DragDropManager::FireOnDragEvent(
1756 const RefPtr<FrameNode>& frameNode, const DragPointerEvent& pointerEvent,
1757 DragEventType type, const std::string& extraInfo)
1758 {
1759 CHECK_NULL_VOID(frameNode);
1760 if (IsUIExtensionOrDynamicComponent(frameNode)) {
1761 HandleUIExtensionDragEvent(frameNode, pointerEvent, type);
1762 return;
1763 }
1764 auto eventHub = frameNode->GetOrCreateEventHub<EventHub>();
1765 CHECK_NULL_VOID(eventHub);
1766 if (!eventHub->HasOnDrop() && !eventHub->HasOnItemDrop() && !eventHub->HasCustomerOnDrop() &&
1767 !eventHub->HasCustomerOnDragSpringLoading()) {
1768 return;
1769 }
1770 auto point = pointerEvent.GetPoint();
1771 auto extraParams = eventHub->GetDragExtraParams(extraInfo_.empty() ? extraInfo : extraInfo_, point, type);
1772 RefPtr<OHOS::Ace::DragEvent> event = AceType::MakeRefPtr<OHOS::Ace::DragEvent>();
1773 CHECK_NULL_VOID(event);
1774 UpdateDragEvent(event, pointerEvent);
1775
1776 FireOnEditableTextComponent(frameNode, type);
1777 FireOnDragSpringLoadingEventWithDragType(frameNode, eventHub, type, extraParams);
1778 FireOnDragEventWithDragType(eventHub, type, event, extraParams);
1779
1780 UpdateDragCursorStyle(frameNode, event, pointerEvent.pointerEventId);
1781 }
1782
UpdateDragCursorStyle(const RefPtr<FrameNode> & frameNode,const RefPtr<OHOS::Ace::DragEvent> & event,const int32_t eventId)1783 void DragDropManager::UpdateDragCursorStyle(const RefPtr<FrameNode>& frameNode,
1784 const RefPtr<OHOS::Ace::DragEvent>& event, const int32_t eventId)
1785 {
1786 if (event->GetResult() == DragRet::ENABLE_DROP) {
1787 if (event->GetDragBehavior() == DragBehavior::MOVE) {
1788 UpdateDragStyle(DragCursorStyleCore::MOVE, eventId);
1789 } else {
1790 UpdateDragStyle(DragCursorStyleCore::COPY, eventId);
1791 }
1792 } else if (event->GetResult() == DragRet::DISABLE_DROP) {
1793 // simplified specifications for drag cursor style, no longer showing forbidden drag cursor
1794 DragDropGlobalController::GetInstance().GetEnableDropDisallowedBadge()
1795 ? UpdateDragStyle(DragCursorStyleCore::FORBIDDEN, eventId)
1796 : UpdateDragStyle(DragCursorStyleCore::MOVE, eventId);
1797 } else {
1798 UpdateDragAllowDrop(frameNode, event->GetDragBehavior(), eventId, event->IsCapi());
1799 }
1800 }
1801
OnItemDragStart(float globalX,float globalY,const RefPtr<FrameNode> & frameNode)1802 void DragDropManager::OnItemDragStart(float globalX, float globalY, const RefPtr<FrameNode>& frameNode)
1803 {
1804 dragDropState_ = DragDropMgrState::DRAGGING;
1805 preGridTargetFrameNode_ = frameNode;
1806 draggedGridFrameNode_ = frameNode;
1807 }
1808
OnItemDragMove(float globalX,float globalY,int32_t draggedIndex,DragType dragType)1809 void DragDropManager::OnItemDragMove(float globalX, float globalY, int32_t draggedIndex, DragType dragType)
1810 {
1811 auto container = Container::Current();
1812 CHECK_NULL_VOID(container);
1813
1814 UpdateItemDragPosition(globalX, globalY);
1815
1816 OHOS::Ace::ItemDragInfo itemDragInfo;
1817 itemDragInfo.SetX(globalX);
1818 itemDragInfo.SetY(globalY);
1819
1820 // use -1 for grid item not in eventGrid
1821 auto getDraggedIndex = [draggedGrid = draggedGridFrameNode_, draggedIndex, dragType](
1822 const RefPtr<FrameNode>& eventGrid) {
1823 return (dragType == DragType::GRID) ? (eventGrid == draggedGrid ? draggedIndex : -1) : draggedIndex;
1824 };
1825
1826 auto dragFrameNode = FindDragFrameNodeByPosition(globalX, globalY);
1827 if (!dragFrameNode) {
1828 if (preGridTargetFrameNode_) {
1829 TAG_LOGI(AceLogTag::ACE_DRAG, "Not find drag target node, current windowId is %{public}d,"
1830 "PreGridTargetFrameNode is %{public}s, depth is %{public}d.",
1831 container->GetWindowId(), preGridTargetFrameNode_->GetTag().c_str(),
1832 preGridTargetFrameNode_->GetDepth());
1833 FireOnItemDragEvent(preGridTargetFrameNode_, dragType, itemDragInfo, DragEventType::LEAVE,
1834 getDraggedIndex(preGridTargetFrameNode_));
1835 preGridTargetFrameNode_ = nullptr;
1836 }
1837 return;
1838 }
1839
1840 if (dragFrameNode == preGridTargetFrameNode_) {
1841 int32_t insertIndex = GetItemIndex(dragFrameNode, dragType, globalX, globalY);
1842 FireOnItemDragEvent(
1843 dragFrameNode, dragType, itemDragInfo, DragEventType::MOVE, getDraggedIndex(dragFrameNode), insertIndex);
1844 return;
1845 }
1846
1847 if (preGridTargetFrameNode_) {
1848 FireOnItemDragEvent(preGridTargetFrameNode_, dragType, itemDragInfo, DragEventType::LEAVE,
1849 getDraggedIndex(preGridTargetFrameNode_));
1850 }
1851
1852 PrintGridDragFrameNode(globalX, globalY, dragFrameNode);
1853 FireOnItemDragEvent(dragFrameNode, dragType, itemDragInfo, DragEventType::ENTER, getDraggedIndex(dragFrameNode));
1854 preGridTargetFrameNode_ = dragFrameNode;
1855 }
1856
GetWindowScale() const1857 float DragDropManager::GetWindowScale() const
1858 {
1859 float scale = 1.0f;
1860 auto container = Container::Current();
1861 CHECK_NULL_RETURN(container, scale);
1862 scale = container->GetWindowScale();
1863 return scale;
1864 }
1865
OnItemDragEnd(float globalX,float globalY,int32_t draggedIndex,DragType dragType)1866 void DragDropManager::OnItemDragEnd(float globalX, float globalY, int32_t draggedIndex, DragType dragType)
1867 {
1868 dragDropState_ = DragDropMgrState::IDLE;
1869 auto windowScale = isDragWindowSubWindow_ ? 1.0f : GetWindowScale();
1870 auto windowX = globalX * windowScale;
1871 auto windowY = globalY * windowScale;
1872
1873 OHOS::Ace::ItemDragInfo itemDragInfo;
1874 itemDragInfo.SetX(windowX);
1875 itemDragInfo.SetY(windowY);
1876 auto dropPositionX = PipelineBase::Px2VpWithCurrentDensity(windowX);
1877 auto dropPositionY = PipelineBase::Px2VpWithCurrentDensity(windowY);
1878
1879 auto dragFrameNode = FindDragFrameNodeByPosition(globalX, globalY);
1880 if (!dragFrameNode) {
1881 // drag on one grid and drop on other area
1882 if (draggedGridFrameNode_) {
1883 if (dragType == DragType::GRID) {
1884 auto eventHub = draggedGridFrameNode_->GetOrCreateEventHub<GridEventHub>();
1885 CHECK_NULL_VOID(eventHub);
1886 eventHub->FireOnItemDrop(itemDragInfo, draggedIndex, -1, false);
1887 } else {
1888 auto eventHub = draggedGridFrameNode_->GetOrCreateEventHub<ListEventHub>();
1889 CHECK_NULL_VOID(eventHub);
1890 eventHub->FireOnItemDrop(itemDragInfo, draggedIndex, -1, false);
1891 }
1892 ReportOnItemDropEvent(dragType, draggedGridFrameNode_, dropPositionX, dropPositionY);
1893 }
1894 } else {
1895 int32_t insertIndex = GetItemIndex(dragFrameNode, dragType, globalX, globalY);
1896 // drag and drop on the same grid
1897 if (dragFrameNode == draggedGridFrameNode_) {
1898 ReportOnItemDropEvent(dragType, draggedGridFrameNode_, dropPositionX, dropPositionY);
1899 FireOnItemDropEvent(dragFrameNode, dragType, itemDragInfo, draggedIndex, insertIndex, true);
1900 } else {
1901 // drag and drop on different grid
1902 ReportOnItemDropEvent(dragType, dragFrameNode, dropPositionX, dropPositionY);
1903 bool isSuccess = FireOnItemDropEvent(dragFrameNode, dragType, itemDragInfo, -1, insertIndex, true);
1904 if (draggedGridFrameNode_) {
1905 ReportOnItemDropEvent(dragType, draggedGridFrameNode_, dropPositionX, dropPositionY);
1906 FireOnItemDropEvent(draggedGridFrameNode_, dragType, itemDragInfo, draggedIndex, -1, isSuccess);
1907 }
1908 }
1909 }
1910
1911 preGridTargetFrameNode_ = nullptr;
1912 draggedGridFrameNode_ = nullptr;
1913 }
1914
onItemDragCancel()1915 void DragDropManager::onItemDragCancel()
1916 {
1917 dragDropState_ = DragDropMgrState::IDLE;
1918 preGridTargetFrameNode_ = nullptr;
1919 draggedGridFrameNode_ = nullptr;
1920 }
1921
FireOnItemDragEvent(const RefPtr<FrameNode> & frameNode,DragType dragType,const OHOS::Ace::ItemDragInfo & itemDragInfo,DragEventType type,int32_t draggedIndex,int32_t insertIndex)1922 void DragDropManager::FireOnItemDragEvent(const RefPtr<FrameNode>& frameNode, DragType dragType,
1923 const OHOS::Ace::ItemDragInfo& itemDragInfo, DragEventType type, int32_t draggedIndex, int32_t insertIndex)
1924 {
1925 CHECK_NULL_VOID(frameNode);
1926 if (dragType == DragType::GRID) {
1927 auto eventHub = frameNode->GetOrCreateEventHub<GridEventHub>();
1928 CHECK_NULL_VOID(eventHub);
1929 switch (type) {
1930 case DragEventType::ENTER:
1931 eventHub->FireOnItemDragEnter(itemDragInfo);
1932 break;
1933 case DragEventType::MOVE:
1934 eventHub->FireOnItemDragMove(itemDragInfo, draggedIndex, insertIndex);
1935 break;
1936 case DragEventType::LEAVE:
1937 eventHub->FireOnItemDragLeave(itemDragInfo, draggedIndex);
1938 break;
1939 default:
1940 break;
1941 }
1942 } else if (dragType == DragType::LIST) {
1943 auto eventHub = frameNode->GetOrCreateEventHub<ListEventHub>();
1944 CHECK_NULL_VOID(eventHub);
1945 switch (type) {
1946 case DragEventType::ENTER:
1947 eventHub->FireOnItemDragEnter(itemDragInfo);
1948 break;
1949 case DragEventType::MOVE:
1950 eventHub->FireOnItemDragMove(itemDragInfo, draggedIndex, insertIndex);
1951 break;
1952 case DragEventType::LEAVE:
1953 eventHub->FireOnItemDragLeave(itemDragInfo, draggedIndex);
1954 break;
1955 default:
1956 break;
1957 }
1958 }
1959 }
1960
FireOnItemDropEvent(const RefPtr<FrameNode> & frameNode,DragType dragType,const OHOS::Ace::ItemDragInfo & itemDragInfo,int32_t draggedIndex,int32_t insertIndex,bool isSuccess)1961 bool DragDropManager::FireOnItemDropEvent(const RefPtr<FrameNode>& frameNode, DragType dragType,
1962 const OHOS::Ace::ItemDragInfo& itemDragInfo, int32_t draggedIndex, int32_t insertIndex, bool isSuccess)
1963 {
1964 CHECK_NULL_RETURN(frameNode, false);
1965 if (dragType == DragType::GRID) {
1966 auto eventHub = frameNode->GetOrCreateEventHub<GridEventHub>();
1967 CHECK_NULL_RETURN(eventHub, false);
1968 return eventHub->FireOnItemDrop(itemDragInfo, draggedIndex, insertIndex, isSuccess);
1969 } else if (dragType == DragType::LIST) {
1970 auto eventHub = frameNode->GetOrCreateEventHub<ListEventHub>();
1971 CHECK_NULL_RETURN(eventHub, false);
1972 return eventHub->FireOnItemDrop(itemDragInfo, draggedIndex, insertIndex, isSuccess);
1973 }
1974 return false;
1975 }
1976
GetItemIndex(const RefPtr<FrameNode> & frameNode,DragType dragType,float globalX,float globalY)1977 int32_t DragDropManager::GetItemIndex(
1978 const RefPtr<FrameNode>& frameNode, DragType dragType, float globalX, float globalY)
1979 {
1980 CHECK_NULL_RETURN(frameNode, -1);
1981 if (dragType == DragType::GRID) {
1982 auto eventHub = frameNode->GetOrCreateEventHub<GridEventHub>();
1983 CHECK_NULL_RETURN(eventHub, -1);
1984 if (frameNode != draggedGridFrameNode_) {
1985 return eventHub->GetInsertPosition(globalX, globalY);
1986 }
1987 auto itemFrameNode = frameNode->FindChildByPositionWithoutChildTransform(globalX, globalY);
1988 if (!itemFrameNode) {
1989 if (eventHub->CheckPostionInGrid(globalX, globalY)) {
1990 return eventHub->GetFrameNodeChildSize();
1991 }
1992 } else {
1993 return eventHub->GetGridItemIndex(itemFrameNode);
1994 }
1995 } else if (dragType == DragType::LIST) {
1996 auto eventHub = frameNode->GetOrCreateEventHub<ListEventHub>();
1997 CHECK_NULL_RETURN(eventHub, -1);
1998 return eventHub->GetListItemIndexByPosition(globalX, globalY);
1999 }
2000 return -1;
2001 }
2002
AddDataToClipboard(const std::string & extraInfo)2003 void DragDropManager::AddDataToClipboard(const std::string& extraInfo)
2004 {
2005 auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
2006 CHECK_NULL_VOID(pipeline);
2007 if (!extraInfo.empty()) {
2008 if (!newData_) {
2009 newData_ = JsonUtil::Create(true);
2010 newData_->Put("customDragInfo", extraInfo.c_str());
2011 } else {
2012 newData_->Replace("customDragInfo", extraInfo.c_str());
2013 }
2014 } else {
2015 return;
2016 }
2017 if (!clipboard_) {
2018 clipboard_ = ClipboardProxy::GetInstance()->GetClipboard(pipeline->GetTaskExecutor());
2019 }
2020 if (!addDataCallback_) {
2021 auto callback = [weakManager = WeakClaim(this), id = Container::CurrentId()](const std::string& data) {
2022 ContainerScope scope(id);
2023 auto dragDropManager = weakManager.Upgrade();
2024 CHECK_NULL_VOID(dragDropManager);
2025 auto addData = dragDropManager->newData_->ToString();
2026 auto clipboardAllData = JsonUtil::Create(true);
2027 clipboardAllData->Put("preData", data.c_str());
2028 clipboardAllData->Put("newData", addData.c_str());
2029 dragDropManager->clipboard_->SetData(clipboardAllData->ToString(), CopyOptions::Local, true);
2030 };
2031 addDataCallback_ = callback;
2032 }
2033 if (clipboard_) {
2034 clipboard_->GetData(addDataCallback_, true);
2035 }
2036 }
2037
GetExtraInfoFromClipboard(std::string & extraInfo)2038 void DragDropManager::GetExtraInfoFromClipboard(std::string& extraInfo)
2039 {
2040 auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
2041 CHECK_NULL_VOID(pipeline);
2042
2043 if (!clipboard_) {
2044 clipboard_ = ClipboardProxy::GetInstance()->GetClipboard(pipeline->GetTaskExecutor());
2045 }
2046
2047 if (!getDataCallback_) {
2048 auto callback = [weak = WeakClaim(this), id = Container::CurrentId()](const std::string& data) {
2049 ContainerScope scope(id);
2050 auto manager = weak.Upgrade();
2051 CHECK_NULL_VOID(manager);
2052 auto json = JsonUtil::ParseJsonString(data);
2053 auto newData = JsonUtil::ParseJsonString(json->GetString("newData"));
2054 manager->extraInfo_ = newData->GetString("customDragInfo");
2055 };
2056 getDataCallback_ = callback;
2057 }
2058
2059 if (getDataCallback_ && clipboard_) {
2060 clipboard_->GetData(getDataCallback_, true);
2061 }
2062
2063 extraInfo = extraInfo_;
2064 }
2065
RestoreClipboardData()2066 void DragDropManager::RestoreClipboardData()
2067 {
2068 auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
2069 CHECK_NULL_VOID(pipeline);
2070
2071 if (!clipboard_) {
2072 clipboard_ = ClipboardProxy::GetInstance()->GetClipboard(pipeline->GetTaskExecutor());
2073 }
2074
2075 if (!deleteDataCallback_) {
2076 auto callback = [weakManager = WeakClaim(this), id = Container::CurrentId()](const std::string& data) {
2077 ContainerScope scope(id);
2078 auto dragDropManager = weakManager.Upgrade();
2079 CHECK_NULL_VOID(dragDropManager);
2080 auto json = JsonUtil::ParseJsonString(data);
2081 if (json->Contains("preData")) {
2082 dragDropManager->clipboard_->SetData(json->GetString("preData"));
2083 }
2084 };
2085 deleteDataCallback_ = callback;
2086 }
2087 if (clipboard_) {
2088 clipboard_->GetData(deleteDataCallback_, true);
2089 }
2090 }
2091
DestroyDragWindow()2092 void DragDropManager::DestroyDragWindow()
2093 {
2094 ResetRecordSize();
2095 if (itemDragOverlayNode_) {
2096 RemoveItemDrag();
2097 itemDragOverlayNode_ = nullptr;
2098 }
2099 SetIsDragged(false);
2100 SetIsDragWindowShow(false);
2101 previewRect_ = Rect(-1, -1, -1, -1);
2102 isMouseDragged_ = false;
2103 currentId_ = -1;
2104 }
2105
CancelItemDrag()2106 void DragDropManager::CancelItemDrag()
2107 {
2108 if (draggedGridFrameNode_) {
2109 auto listEventHub = draggedGridFrameNode_->GetOrCreateEventHub<ListEventHub>();
2110 if (listEventHub) {
2111 listEventHub->HandleOnItemDragCancel();
2112 return;
2113 }
2114 auto gridEventHub = draggedGridFrameNode_->GetOrCreateEventHub<GridEventHub>();
2115 if (gridEventHub) {
2116 gridEventHub->HandleOnItemDragCancel();
2117 return;
2118 }
2119 }
2120 }
2121
CreateFrameworkDragDropProxy()2122 RefPtr<DragDropProxy> DragDropManager::CreateFrameworkDragDropProxy()
2123 {
2124 SetIsDragged(true);
2125 isDragCancel_ = false;
2126 currentId_ = ++g_proxyId;
2127 return MakeRefPtr<DragDropProxy>(currentId_);
2128 }
2129
UpdateNotifyDragEvent(RefPtr<NotifyDragEvent> & notifyEvent,const Point & point,const DragEventType dragEventType)2130 void DragDropManager::UpdateNotifyDragEvent(
2131 RefPtr<NotifyDragEvent>& notifyEvent, const Point& point, const DragEventType dragEventType)
2132 {
2133 CHECK_NULL_VOID(notifyEvent);
2134 notifyEvent->SetX((double)point.GetX());
2135 notifyEvent->SetY((double)point.GetY());
2136 notifyEvent->SetScreenX((double)point.GetScreenX());
2137 notifyEvent->SetScreenY((double)point.GetScreenY());
2138 notifyEvent->SetGlobalDisplayX(point.GetGlobalDisplayX());
2139 notifyEvent->SetGlobalDisplayY(point.GetGlobalDisplayY());
2140 if (dragEventType != DragEventType::START) {
2141 if (dragEventType != DragEventType::DROP) {
2142 notifyEvent->SetVelocity(velocityTracker_.GetVelocity());
2143 }
2144 notifyEvent->SetSummary(summaryMap_);
2145 notifyEvent->SetPreviewRect(GetDragWindowRect(point));
2146 }
2147 }
2148
UpdateDragEvent(RefPtr<OHOS::Ace::DragEvent> & event,const OHOS::Ace::DragPointerEvent & pointerEvent)2149 void DragDropManager::UpdateDragEvent(
2150 RefPtr<OHOS::Ace::DragEvent>& event, const OHOS::Ace::DragPointerEvent& pointerEvent)
2151 {
2152 auto point = pointerEvent.GetPoint();
2153 event->SetX(point.GetX());
2154 event->SetY(point.GetY());
2155 event->SetScreenX(point.GetScreenX());
2156 event->SetScreenY(point.GetScreenY());
2157 event->SetDisplayX((double)pointerEvent.GetDisplayX());
2158 event->SetDisplayY((double)pointerEvent.GetDisplayY());
2159 event->SetGlobalDisplayX(pointerEvent.GetGlobalDisplayX());
2160 event->SetGlobalDisplayY(pointerEvent.GetGlobalDisplayY());
2161 event->SetVelocity(velocityTracker_.GetVelocity());
2162 event->SetSummary(summaryMap_);
2163 event->SetPreviewRect(GetDragWindowRect(point));
2164 event->SetPressedKeyCodes(pointerEvent.pressedKeyCodes);
2165 event->SetSourceTool(pointerEvent.sourceTool);
2166 event->SetDragSource(dragBundleInfo_.bundleName);
2167 event->SetRemoteDev(dragBundleInfo_.isRemoteDev);
2168 event->SetDisplayId(pointerEvent.displayId);
2169 }
2170
GetExtraInfo()2171 std::string DragDropManager::GetExtraInfo()
2172 {
2173 return extraInfo_;
2174 }
2175
SetExtraInfo(const std::string & extraInfo)2176 void DragDropManager::SetExtraInfo(const std::string& extraInfo)
2177 {
2178 extraInfo_ = extraInfo;
2179 }
2180
ClearExtraInfo()2181 void DragDropManager::ClearExtraInfo()
2182 {
2183 extraInfo_.clear();
2184 }
2185
IsMSDPDragging() const2186 bool DragDropManager::IsMSDPDragging() const
2187 {
2188 ACE_SCOPED_TRACE("drag: get drag state from msdp");
2189 return InteractionInterface::GetInstance()->IsDragStart();
2190 }
2191
ClearVelocityInfo()2192 void DragDropManager::ClearVelocityInfo()
2193 {
2194 velocityTracker_.Reset();
2195 }
2196
UpdateVelocityTrackerPoint(const Point & point,bool isEnd)2197 void DragDropManager::UpdateVelocityTrackerPoint(const Point& point, bool isEnd)
2198 {
2199 std::chrono::microseconds microseconds(GetMicroTickCount());
2200 TimeStamp curTime(microseconds);
2201 velocityTracker_.UpdateTrackerPoint(point.GetX(), point.GetY(), curTime, isEnd);
2202 }
2203
GetDragPreviewInfo(const RefPtr<OverlayManager> & overlayManager,DragPreviewInfo & dragPreviewInfo,const RefPtr<GestureEventHub> & gestureHub,PreparedInfoForDrag & data)2204 bool DragDropManager::GetDragPreviewInfo(const RefPtr<OverlayManager>& overlayManager, DragPreviewInfo& dragPreviewInfo,
2205 const RefPtr<GestureEventHub>& gestureHub, PreparedInfoForDrag& data)
2206 {
2207 CHECK_NULL_RETURN(overlayManager, false);
2208 if (!overlayManager->GetHasDragPixelMap()) {
2209 return false;
2210 }
2211 auto imageNode = overlayManager->GetDragPixelMapContentNode();
2212 CHECK_NULL_RETURN(imageNode, false);
2213 auto badgeNode = overlayManager->GetDragPixelMapBadgeNode();
2214 if (badgeNode) {
2215 dragPreviewInfo.relativeContainerNode = data.relativeContainerNode;
2216 dragPreviewInfo.textNode = badgeNode;
2217 }
2218 CHECK_NULL_RETURN(gestureHub, false);
2219 auto frameNode = gestureHub->GetFrameNode();
2220 CHECK_NULL_RETURN(frameNode, false);
2221 auto previewOption = imageNode->GetDragPreviewOption();
2222 auto gestureEvent = frameNode->GetOrCreateGestureEventHub();
2223 CHECK_NULL_RETURN(gestureEvent, false);
2224 auto width = data.dragPreviewRect.Width();
2225 auto height = data.dragPreviewRect.Height();
2226 auto scaleData = DragDropManager::GetScaleInfo(width, height, gestureEvent->GetTextDraggable());
2227 CHECK_NULL_RETURN(scaleData, false);
2228 dragPreviewInfo.scale =
2229 (imageNode->GetTag() != V2::WEB_ETS_TAG && width > 0 && height > 0 && previewOption.isScaleEnabled)
2230 ? scaleData->scale : 1.0f;
2231 if (!isMouseDragged_ && dragPreviewInfo.scale == 1.0f) {
2232 dragPreviewInfo.scale = TOUCH_DRAG_PIXELMAP_SCALE;
2233 }
2234 // set menu preview scale only for no scale menu preview.
2235 if (isDragWithContextMenu_ && (!previewOption.isScaleEnabled || !scaleData->isNeedScale)) {
2236 auto imageGestureEventHub = imageNode->GetOrCreateGestureEventHub();
2237 if (imageGestureEventHub) {
2238 auto menuPreviewScale = imageGestureEventHub->GetMenuPreviewScale();
2239 dragPreviewInfo.scale =
2240 GreatNotEqual(menuPreviewScale, 0.0f) ? menuPreviewScale : TOUCH_DRAG_PIXELMAP_SCALE;
2241 }
2242 }
2243 dragPreviewInfo.height = static_cast<double>(height);
2244 dragPreviewInfo.width = static_cast<double>(width);
2245 dragPreviewInfo.maxWidth = scaleData->shortSide;
2246 dragPreviewInfo.imageNode = imageNode;
2247 dragPreviewInfo.originOffset = imageNode->GetPositionToWindowWithTransform();
2248 dragPreviewInfo.originScale = imageNode->GetTransformScale();
2249 dragPreviewInfo.isDragController = false;
2250 CopyPreparedInfoForDrag(dragPreviewInfo, data);
2251 return true;
2252 }
2253
CopyPreparedInfoForDrag(DragPreviewInfo & dragPreviewInfo,PreparedInfoForDrag & data)2254 void DragDropManager::CopyPreparedInfoForDrag(DragPreviewInfo& dragPreviewInfo, PreparedInfoForDrag& data)
2255 {
2256 dragPreviewInfo.menuPreviewNode = data.menuPreviewNode;
2257 dragPreviewInfo.menuPreviewImageNode = data.menuPreviewImageNode;
2258 dragPreviewInfo.originPreviewRect = data.originPreviewRect;
2259 dragPreviewInfo.dragPreviewRect = data.dragPreviewRect;
2260 dragPreviewInfo.relativeContainerNode = data.relativeContainerNode;
2261 dragPreviewInfo.stackNode = data.stackNode;
2262 dragPreviewInfo.sizeChangeEffect = data.sizeChangeEffect;
2263 dragPreviewInfo.menuNode = data.menuNode;
2264 }
2265
IsNeedDoDragMoveAnimate(const DragPointerEvent & pointerEvent)2266 bool DragDropManager::IsNeedDoDragMoveAnimate(const DragPointerEvent& pointerEvent)
2267 {
2268 if (isDragFwkShow_) {
2269 return false;
2270 }
2271 auto x = pointerEvent.GetPoint().GetX();
2272 auto y = pointerEvent.GetPoint().GetY();
2273 curPointerOffset_ = { x, y };
2274 return true;
2275 }
2276
IsNeedScaleDragPreview()2277 bool DragDropManager::IsNeedScaleDragPreview()
2278 {
2279 return info_.scale > 0 && info_.scale < 1.0f;
2280 }
2281 // calculate the touch position relative to the sub-window which will be used to do animation on,
2282 // the input [x, y] is the position relative to the window which is receiving the touch event,
2283 // and the position is contain the floatTitle offset.
GetTouchOffsetRelativeToSubwindow(int32_t containerId,int32_t x,int32_t y)2284 OffsetF DragDropManager::GetTouchOffsetRelativeToSubwindow(int32_t containerId, int32_t x, int32_t y)
2285 {
2286 auto touchOffset = OffsetF(x, y);
2287 auto pipeline = PipelineContext::GetContextByContainerId(containerId);
2288 CHECK_NULL_RETURN(pipeline, OffsetF(x, y));
2289 auto window = pipeline->GetWindow();
2290 CHECK_NULL_RETURN(window, OffsetF(x, y));
2291 auto windowOffset = window->GetCurrentWindowRect().GetOffset();
2292 touchOffset.SetX(touchOffset.GetX() + windowOffset.GetX());
2293 touchOffset.SetY(touchOffset.GetY() + windowOffset.GetY());
2294 auto subwindow = SubwindowManager::GetInstance()->GetSubwindowByType(containerId >= MIN_SUBCONTAINER_ID ?
2295 SubwindowManager::GetInstance()->GetParentContainerId(containerId) : containerId, SubwindowType::TYPE_MENU);
2296 CHECK_NULL_RETURN(subwindow, OffsetF(x, y));
2297 auto subwindowOffset = subwindow->GetWindowRect().GetOffset();
2298 touchOffset.SetX(touchOffset.GetX() - subwindowOffset.GetX());
2299 touchOffset.SetY(touchOffset.GetY() - subwindowOffset.GetY());
2300 return touchOffset;
2301 }
2302
CalcDragPreviewDistanceWithPoint(const OHOS::Ace::Dimension & preserverHeight,int32_t x,int32_t y,const DragPreviewInfo & info)2303 double DragDropManager::CalcDragPreviewDistanceWithPoint(
2304 const OHOS::Ace::Dimension& preserverHeight, int32_t x, int32_t y, const DragPreviewInfo& info)
2305 {
2306 CHECK_NULL_RETURN(info.imageNode, 0.0);
2307 auto nodeOffset = info.imageNode->GetTransformRelativeOffset();
2308 auto renderContext = info.imageNode->GetRenderContext();
2309 CHECK_NULL_RETURN(renderContext, 0.0);
2310 nodeOffset -= pixelMapOffset_;
2311 auto touchOffset = DragDropManager::GetTouchOffsetRelativeToSubwindow(Container::CurrentId(), x, y);
2312 // calculate distance, so need to pow 2.
2313 return sqrt(pow(nodeOffset.GetX() - touchOffset.GetX(), 2) + pow(nodeOffset.GetY() - touchOffset.GetY(), 2));
2314 }
2315
CalcDragMoveOffset(const OHOS::Ace::Dimension & preserverHeight,int32_t x,int32_t y,const DragPreviewInfo & info)2316 Offset DragDropManager::CalcDragMoveOffset(
2317 const OHOS::Ace::Dimension& preserverHeight, int32_t x, int32_t y, const DragPreviewInfo& info)
2318 {
2319 auto originPoint = info.originOffset;
2320 originPoint.SetX(originPoint.GetX() - pixelMapOffset_.GetX() +
2321 (info.originScale.x - info.scale) * info.width / 2.0f);
2322 originPoint.SetY(originPoint.GetY() - pixelMapOffset_.GetY() +
2323 (info.originScale.y - info.scale) * info.height / 2.0f);
2324 auto touchOffset = DragDropManager::GetTouchOffsetRelativeToSubwindow(Container::CurrentId(), x, y);
2325 Offset newOffset { touchOffset.GetX() - originPoint.GetX(), touchOffset.GetY() - originPoint.GetY() };
2326 return newOffset;
2327 }
2328
CalcContentTrationOffset(const OHOS::Ace::Dimension & preserverHeight,int32_t x,int32_t y,const DragPreviewInfo & info)2329 Offset DragDropManager::CalcContentTrationOffset(
2330 const OHOS::Ace::Dimension& preserverHeight, int32_t x, int32_t y, const DragPreviewInfo& info)
2331 {
2332 auto originPoint = info.originOffset;
2333 auto scalX = info.dragPreviewRect.Width() / info.originPreviewRect.Width() * info.scale;
2334 originPoint.SetX(originPoint.GetX() - pixelMapOffset_.GetX() + info.originPreviewRect.Width() * (1 - scalX));
2335 originPoint.SetY(originPoint.GetY() - pixelMapOffset_.GetY());
2336 auto touchOffset = DragDropManager::GetTouchOffsetRelativeToSubwindow(Container::CurrentId(), x, y);
2337 Offset newOffset { touchOffset.GetX() - originPoint.GetX(), touchOffset.GetY() - originPoint.GetY() };
2338 return newOffset;
2339 }
2340
CalculateNewOffset(const RefPtr<FrameNode> & frameNode,const GestureEvent & event,bool isDragStartPending)2341 Offset DragDropManager::CalculateNewOffset(
2342 const RefPtr<FrameNode>& frameNode, const GestureEvent& event, bool isDragStartPending)
2343 {
2344 Offset newOffset = { 0, 0 };
2345 CHECK_NULL_RETURN(frameNode, newOffset);
2346 auto dragMoveLastPoint = GetDragMoveLastPointByCurrentPointer(event.GetPointerId());
2347 if (info_.sizeChangeEffect == DraggingSizeChangeEffect::DEFAULT && !info_.textNode) {
2348 newOffset =
2349 isDragStartPending
2350 ? CalcDragMoveOffset(PRESERVE_HEIGHT, static_cast<int32_t>(dragMoveLastPoint.GetX()),
2351 static_cast<int32_t>(dragMoveLastPoint.GetY()), info_)
2352 : CalcDragMoveOffset(PRESERVE_HEIGHT, static_cast<int32_t>(event.GetGlobalLocation().GetX()),
2353 static_cast<int32_t>(event.GetGlobalLocation().GetY()), info_);
2354 } else if (info_.sizeChangeEffect == DraggingSizeChangeEffect::SIZE_TRANSITION ||
2355 info_.sizeChangeEffect == DraggingSizeChangeEffect::SIZE_CONTENT_TRANSITION || info_.textNode) {
2356 newOffset =
2357 isDragStartPending
2358 ? CalcContentTrationOffset(PRESERVE_HEIGHT, static_cast<int32_t>(dragMoveLastPoint.GetX()),
2359 static_cast<int32_t>(dragMoveLastPoint.GetY()), info_)
2360 : CalcContentTrationOffset(PRESERVE_HEIGHT, static_cast<int32_t>(event.GetGlobalLocation().GetX()),
2361 static_cast<int32_t>(event.GetGlobalLocation().GetY()), info_);
2362 }
2363 return newOffset;
2364 }
2365
UpdateDragMovePositionFinished(bool needDoDragMoveAnimate,bool isMenuShow,const Offset & newOffset,int32_t containerId)2366 bool DragDropManager::UpdateDragMovePositionFinished(
2367 bool needDoDragMoveAnimate, bool isMenuShow, const Offset& newOffset, int32_t containerId)
2368 {
2369 if (!isDragWithContextMenu_) {
2370 return false;
2371 }
2372
2373 CHECK_NULL_RETURN(info_.imageNode, false);
2374 auto renderContext = info_.imageNode->GetRenderContext();
2375 CHECK_NULL_RETURN(renderContext, false);
2376 SubwindowManager::GetInstance()->ContextMenuSwitchDragPreviewAnimation(info_.imageNode,
2377 OffsetF(newOffset.GetX(), newOffset.GetY()));
2378 if (!needDoDragMoveAnimate) {
2379 renderContext->UpdateTransformTranslate({ newOffset.GetX(), newOffset.GetY(), 0.0f });
2380 if (!isMenuShow) {
2381 TransDragWindowToDragFwk(containerId);
2382 }
2383 return true;
2384 }
2385 return false;
2386 }
2387
GetCurrentDistance(float x,float y)2388 float DragDropManager::GetCurrentDistance(float x, float y)
2389 {
2390 auto distance = sqrt(pow(curPointerOffset_.GetX() - x, 2) + pow(curPointerOffset_.GetY() - y, 2));
2391 CHECK_NULL_RETURN(info_.imageNode, distance);
2392 auto containerId = Container::CurrentId();
2393 auto subwindow = SubwindowManager::GetInstance()->GetSubwindowByType(containerId, SubwindowType::TYPE_MENU);
2394 CHECK_NULL_RETURN(subwindow, distance);
2395 auto overlayManager = subwindow->GetOverlayManager();
2396 auto gatherNodeCenter = DragDropFuncWrapper::GetPaintRectCenter(info_.imageNode);
2397 auto gatherDistance = CalcGatherNodeMaxDistanceWithPoint(overlayManager,
2398 gatherNodeCenter.GetX(), gatherNodeCenter.GetY());
2399 return std::max(distance, gatherDistance);
2400 }
2401
DoDragMoveAnimate(const DragPointerEvent & pointerEvent)2402 void DragDropManager::DoDragMoveAnimate(const DragPointerEvent& pointerEvent)
2403 {
2404 bool needDoDragMoveAnimate = IsNeedDoDragMoveAnimate(pointerEvent);
2405 if (!needDoDragMoveAnimate) {
2406 return;
2407 }
2408 isPullMoveReceivedForCurrentDrag_ = true;
2409 CHECK_NULL_VOID(info_.imageNode);
2410 auto containerId = Container::CurrentId();
2411 auto x = pointerEvent.GetDisplayX();
2412 auto y = pointerEvent.GetDisplayY();
2413 if (CheckIsUIExtensionBoundary(x, y, containerId) || CheckIsFolderSubwindowBoundary(x, y, containerId)) {
2414 SetStartAnimation(false);
2415 TransDragWindowToDragFwk(containerId);
2416 return;
2417 }
2418 auto overlayManager = GetDragAnimationOverlayManager(containerId);
2419 CHECK_NULL_VOID(overlayManager);
2420 auto point = pointerEvent.GetPoint();
2421 Offset newOffset = { 0, 0 };
2422 if ((info_.sizeChangeEffect == DraggingSizeChangeEffect::DEFAULT && !info_.textNode) || info_.isDragController) {
2423 newOffset = CalcDragMoveOffset(PRESERVE_HEIGHT, point.GetX(), point.GetY(), info_);
2424 } else if (info_.sizeChangeEffect == DraggingSizeChangeEffect::SIZE_TRANSITION ||
2425 info_.sizeChangeEffect == DraggingSizeChangeEffect::SIZE_CONTENT_TRANSITION || info_.textNode) {
2426 newOffset = CalcContentTrationOffset(PRESERVE_HEIGHT, point.GetX(), point.GetY(), info_);
2427 }
2428 bool isMenuShow = overlayManager->IsMenuShow();
2429 if (UpdateDragMovePositionFinished(needDoDragMoveAnimate, isMenuShow, newOffset, containerId) ||
2430 !needDoDragMoveAnimate) {
2431 return;
2432 }
2433 DragMoveAnimation(newOffset, overlayManager, point);
2434 }
2435
DragMoveAnimation(const Offset & newOffset,const RefPtr<OverlayManager> & overlayManager,Point point)2436 void DragDropManager::DragMoveAnimation(
2437 const Offset& newOffset, const RefPtr<OverlayManager>& overlayManager, Point point)
2438 {
2439 auto containerId = Container::CurrentId();
2440 bool isMenuShow = overlayManager->IsMenuShow();
2441 AnimationOption option;
2442 auto springResponse =
2443 std::max(DEFAULT_SPRING_RESPONSE - DEL_SPRING_RESPONSE * allAnimationCnt_, MIN_SPRING_RESPONSE);
2444 const RefPtr<Curve> curve = AceType::MakeRefPtr<ResponsiveSpringMotion>(springResponse, 0.99f, 0.0f);
2445 constexpr int32_t animateDuration = 30;
2446 option.SetCurve(curve);
2447 option.SetDuration(animateDuration);
2448 bool dragWithContextMenu = isDragWithContextMenu_;
2449 AddNewDragAnimation();
2450 option.SetOnFinishEvent([weakManager = WeakClaim(this), containerId, dragWithContextMenu, isMenuShow,
2451 x = point.GetX(), y = point.GetY()]() {
2452 auto dragDropManager = weakManager.Upgrade();
2453 CHECK_NULL_VOID(dragDropManager);
2454 if ((dragDropManager->IsAllAnimationFinished() ||
2455 dragDropManager->GetCurrentDistance(x, y) < MAX_DISTANCE_TO_PRE_POINTER) &&
2456 (!dragWithContextMenu || !isMenuShow) && dragDropManager->IsStartAnimationFInished()) {
2457 dragDropManager->SetStartAnimation(false);
2458 dragDropManager->TransDragWindowToDragFwk(containerId);
2459 }
2460 });
2461
2462 if (info_.sizeChangeEffect == DraggingSizeChangeEffect::DEFAULT) {
2463 DragDropManager::DragMoveDefaultAnimation(overlayManager, info_, option, newOffset, point);
2464 } else if ((info_.sizeChangeEffect == DraggingSizeChangeEffect::SIZE_TRANSITION ||
2465 info_.sizeChangeEffect == DraggingSizeChangeEffect::SIZE_CONTENT_TRANSITION)) {
2466 DragDropManager::DragMoveTransitionAnimation(overlayManager, info_, option, newOffset, point);
2467 }
2468 }
2469
DragMoveDefaultAnimation(const RefPtr<OverlayManager> & overlayManager,const DragPreviewInfo & info,AnimationOption option,const Offset & newOffset,Point point)2470 void DragDropManager::DragMoveDefaultAnimation(const RefPtr<OverlayManager>& overlayManager,
2471 const DragPreviewInfo& info, AnimationOption option, const Offset& newOffset, Point point)
2472 {
2473 auto targetNode = info_.textNode && info_.relativeContainerNode ? info_.relativeContainerNode : info_.imageNode;
2474 CHECK_NULL_VOID(targetNode);
2475 auto renderContext = targetNode->GetRenderContext();
2476 CHECK_NULL_VOID(renderContext);
2477 auto context = targetNode->GetContextRefPtr();
2478 CHECK_NULL_VOID(context);
2479 auto offset = OffsetF(point.GetX(), point.GetY());
2480 auto menuWrapperNode = GetMenuWrapperNodeFromDrag();
2481 auto menuPosition = overlayManager->CalculateMenuPosition(menuWrapperNode, offset);
2482 auto menuRenderContext = GetMenuRenderContextFromMenuWrapper(menuWrapperNode);
2483 AnimationUtils::Animate(
2484 option,
2485 [renderContext, localPoint = newOffset, info = info_, overlayManager, menuRenderContext, menuPosition]() {
2486 if (menuRenderContext && !menuPosition.NonOffset()) {
2487 menuRenderContext->UpdatePosition(
2488 OffsetT<Dimension>(Dimension(menuPosition.GetX()), Dimension(menuPosition.GetY())));
2489 }
2490 renderContext->UpdateTransformTranslate({ localPoint.GetX(), localPoint.GetY(), 0.0f });
2491 if (info.isDragController) {
2492 UpdateTextNodePosition(info.textNode, localPoint);
2493 }
2494 UpdateGatherNodePosition(overlayManager, info.imageNode);
2495 },
2496 option.GetOnFinishEvent(), nullptr, context);
2497 }
2498
DragMoveTransitionAnimation(const RefPtr<OverlayManager> & overlayManager,const DragPreviewInfo & info,AnimationOption option,const Offset & newOffset,Point point)2499 void DragDropManager::DragMoveTransitionAnimation(const RefPtr<OverlayManager>& overlayManager,
2500 const DragPreviewInfo& info, AnimationOption option, const Offset& newOffset, Point point)
2501 {
2502 option.SetCurve(DRAG_TRANSITION_ANIMATION_CURVE);
2503 auto renderContext = info_.imageNode->GetRenderContext();
2504 CHECK_NULL_VOID(renderContext);
2505 auto offset = OffsetF(point.GetX(), point.GetY());
2506 auto menuWrapperNode = GetMenuWrapperNodeFromDrag();
2507 CHECK_NULL_VOID(overlayManager);
2508 auto context = info_.imageNode->GetContextRefPtr();
2509 CHECK_NULL_VOID(context);
2510 auto menuPosition = overlayManager->CalculateMenuPosition(menuWrapperNode, offset);
2511 auto menuRenderContext = GetMenuRenderContextFromMenuWrapper(menuWrapperNode);
2512 AnimationUtils::Animate(
2513 option,
2514 [overlayManager, info, newOffset, menuRenderContext, menuPosition]() {
2515 if (menuRenderContext && !menuPosition.NonOffset() && !info.menuNode) {
2516 menuRenderContext->UpdatePosition(
2517 OffsetT<Dimension>(Dimension(menuPosition.GetX()), Dimension(menuPosition.GetY())));
2518 }
2519 CHECK_NULL_VOID(overlayManager);
2520 auto relativeContainerNodeRenderContext = info.relativeContainerNode->GetRenderContext();
2521 CHECK_NULL_VOID(relativeContainerNodeRenderContext);
2522 relativeContainerNodeRenderContext->UpdateTransformTranslate({ newOffset.GetX(), newOffset.GetY(), 0.0f });
2523 UpdateGatherNodePosition(overlayManager, info.imageNode);
2524 },
2525 option.GetOnFinishEvent(), nullptr, context);
2526 }
2527
UpdateDragPreviewScale()2528 void DragDropManager::UpdateDragPreviewScale()
2529 {
2530 CHECK_NULL_VOID(info_.imageNode);
2531 if (IsNeedDisplayInSubwindow()) {
2532 return;
2533 }
2534 auto renderContext = info_.imageNode->GetRenderContext();
2535 CHECK_NULL_VOID(renderContext);
2536 renderContext->UpdateTransformScale({ info_.scale, info_.scale });
2537 }
2538
InitDragAnimationPointerEvent(const GestureEvent & event,bool isDragStartPending)2539 void DragDropManager::InitDragAnimationPointerEvent(const GestureEvent& event, bool isDragStartPending)
2540 {
2541 if (isDragStartPending) {
2542 auto dragMoveLastPoint = GetDragMoveLastPointByCurrentPointer(event.GetPointerId());
2543 dragAnimationPointerEvent_ = DragPointerEvent(dragMoveLastPoint.GetX(),
2544 dragMoveLastPoint.GetY(), dragMoveLastPoint.GetScreenX(), dragMoveLastPoint.GetScreenY(),
2545 dragMoveLastPoint.GetGlobalDisplayX(), dragMoveLastPoint.GetGlobalDisplayY());
2546 return;
2547 }
2548 dragAnimationPointerEvent_ = DragPointerEvent(event.GetGlobalLocation().GetX(),
2549 event.GetGlobalLocation().GetY(), event.GetScreenLocation().GetX(), event.GetScreenLocation().GetY(),
2550 event.GetGlobalDisplayLocation().GetX(), event.GetGlobalDisplayLocation().GetY());
2551 }
2552
DoDragStartAnimation(const RefPtr<OverlayManager> & overlayManager,const GestureEvent & event,const RefPtr<GestureEventHub> & gestureHub,PreparedInfoForDrag & data)2553 void DragDropManager::DoDragStartAnimation(const RefPtr<OverlayManager>& overlayManager, const GestureEvent& event,
2554 const RefPtr<GestureEventHub>& gestureHub, PreparedInfoForDrag& data)
2555 {
2556 auto containerId = Container::CurrentId();
2557 auto deviceId = static_cast<int32_t>(event.GetDeviceId());
2558 if (deviceId == RESERVED_DEVICEID_1 || deviceId == RESERVED_DEVICEID_2) {
2559 isDragFwkShow_ = false;
2560 TAG_LOGI(AceLogTag::ACE_DRAG, "Do not need animation.");
2561 TransDragWindowToDragFwk(containerId);
2562 return;
2563 }
2564 CHECK_NULL_VOID(overlayManager);
2565 CHECK_NULL_VOID(gestureHub);
2566 bool isDragStartPending = DragDropGlobalController::GetInstance().GetAsyncDragCallback() != nullptr;
2567 if (!(GetDragPreviewInfo(overlayManager, info_, gestureHub, data)) ||
2568 (!IsNeedDisplayInSubwindow() && !data.isMenuShow && !isDragWithContextMenu_ && !isDragStartPending)) {
2569 if (isDragWithContextMenu_) {
2570 UpdateDragPreviewScale();
2571 isDragFwkShow_ = false;
2572 }
2573 return;
2574 }
2575 CHECK_NULL_VOID(info_.imageNode);
2576 isDragFwkShow_ = false;
2577 subwindowOverlayManager_ = overlayManager;
2578 InitDragAnimationPointerEvent(event, isDragStartPending);
2579 ResetPullMoveReceivedForCurrentDrag();
2580 Point point = { static_cast<int32_t>(event.GetGlobalLocation().GetX()),
2581 static_cast<int32_t>(event.GetGlobalLocation().GetY()) };
2582 auto frameNode = gestureHub->GetFrameNode();
2583 Offset newOffset = CalculateNewOffset(frameNode, event, isDragStartPending);
2584 curPointerOffset_ = { newOffset.GetX(), newOffset.GetY() };
2585 currentAnimationCnt_ = 0;
2586 allAnimationCnt_ = 0;
2587 isStartAnimationFinished_ = false;
2588 DragStartAnimation(newOffset, overlayManager, data, point);
2589 }
2590
DragStartAnimation(const Offset & newOffset,const RefPtr<OverlayManager> & overlayManager,PreparedInfoForDrag & data,Point point)2591 void DragDropManager::DragStartAnimation(
2592 const Offset& newOffset, const RefPtr<OverlayManager>& overlayManager, PreparedInfoForDrag& data, Point point)
2593 {
2594 CHECK_NULL_VOID(info_.imageNode);
2595 auto containerId = Container::CurrentId();
2596 AnimationOption option;
2597 SetDragStartAnimationOption(option, containerId);
2598 AddNewDragStartAnimation();
2599 auto renderContext = info_.imageNode->GetRenderContext();
2600 CHECK_NULL_VOID(renderContext);
2601 auto callback = [weakManager = WeakClaim(this)](float rate) {
2602 auto dragDropManager = weakManager.Upgrade();
2603 CHECK_NULL_VOID(dragDropManager);
2604 dragDropManager->SetDragStartAnimationRate(rate);
2605 };
2606 auto animateProperty = AceType::MakeRefPtr<NodeAnimatablePropertyFloat>(-1.0, std::move(callback));
2607 CHECK_NULL_VOID(animateProperty);
2608 renderContext->AttachNodeAnimatableProperty(animateProperty);
2609 animateProperty->Set(0.0f);
2610 dragStartAnimationRate_ = 0.0f;
2611 if (info_.sizeChangeEffect == DraggingSizeChangeEffect::DEFAULT) {
2612 //Default transition
2613 StartDragDefaultAnimation(option, newOffset, overlayManager, animateProperty, point);
2614 } else if (info_.sizeChangeEffect == DraggingSizeChangeEffect::SIZE_TRANSITION ||
2615 info_.sizeChangeEffect == DraggingSizeChangeEffect::SIZE_CONTENT_TRANSITION) {
2616 StartDragTransitionAnimation(newOffset, option, overlayManager, animateProperty, point);
2617 }
2618 }
2619
SetDragStartAnimationOption(AnimationOption & option,int32_t containerId)2620 void DragDropManager::SetDragStartAnimationOption(AnimationOption& option, int32_t containerId)
2621 {
2622 const RefPtr<Curve> curve = AceType::MakeRefPtr<ResponsiveSpringMotion>(0.347f, 0.99f, 0.0f);
2623 constexpr int32_t animateDuration = 300;
2624 option.SetCurve(curve);
2625 option.SetDuration(animateDuration);
2626 option.SetOnFinishEvent([weakManager = WeakClaim(this), containerId]() {
2627 auto dragDropManager = weakManager.Upgrade();
2628 CHECK_NULL_VOID(dragDropManager);
2629 dragDropManager->HandleStartDragAnimationFinish(containerId);
2630 });
2631 }
2632
HandleStartDragAnimationFinish(int32_t containerId)2633 void DragDropManager::HandleStartDragAnimationFinish(int32_t containerId)
2634 {
2635 if (IsAllStartAnimationFinished()) {
2636 SetStartAnimation(true);
2637 }
2638 if (!IsPullMoveReceivedForCurrentDrag()) {
2639 TransDragWindowToDragFwk(containerId);
2640 }
2641 auto overlayManager = GetDragAnimationOverlayManager(containerId);
2642 CHECK_NULL_VOID(overlayManager);
2643 auto gatherNode = overlayManager->GetGatherNode();
2644 CHECK_NULL_VOID(gatherNode);
2645 auto info = overlayManager->GetGatherNodeChildrenInfo();
2646 int cnt = 0;
2647 for (auto iter = info.rbegin(); iter != info.rend(); iter++) {
2648 auto imageNode = (*iter).imageNode.Upgrade();
2649 if (cnt > 1) {
2650 gatherNode->RemoveChild(imageNode);
2651 }
2652 cnt++;
2653 }
2654 }
2655
StartDragDefaultAnimation(AnimationOption option,const Offset & newOffset,const RefPtr<OverlayManager> & overlayManager,const RefPtr<NodeAnimatablePropertyFloat> & animateProperty,Point point)2656 void DragDropManager::StartDragDefaultAnimation(AnimationOption option, const Offset& newOffset,
2657 const RefPtr<OverlayManager>& overlayManager, const RefPtr<NodeAnimatablePropertyFloat>& animateProperty,
2658 Point point)
2659 {
2660 auto renderContext = info_.imageNode->GetRenderContext();
2661 CHECK_NULL_VOID(renderContext);
2662 auto context = info_.imageNode->GetContextRefPtr();
2663 CHECK_NULL_VOID(context);
2664 auto animateCallback = [renderContext, info = info_, newOffset, overlayManager, animateProperty, point]() {
2665 CHECK_NULL_VOID(renderContext);
2666 DragAnimationHelper::UpdateStartAnimation(overlayManager, animateProperty, point, info, newOffset);
2667 if (!info.textNode) {
2668 CHECK_NULL_VOID(renderContext);
2669 renderContext->UpdateTransformScale({ info.scale, info.scale });
2670 renderContext->UpdateTransformTranslate({ newOffset.GetX(), newOffset.GetY(), 0.0f });
2671 return;
2672 }
2673 CHECK_NULL_VOID(info.imageNode);
2674 auto imageLayoutProperty = info.imageNode->GetLayoutProperty();
2675 CHECK_NULL_VOID(imageLayoutProperty);
2676 imageLayoutProperty->UpdateUserDefinedIdealSize({ CalcLength(info.width * info.scale, DimensionUnit::PX),
2677 CalcLength(info.height * info.scale, DimensionUnit::PX) });
2678 info.relativeContainerNode->MarkDirtyNode(NG::PROPERTY_UPDATE_MEASURE);
2679 };
2680 if (info_.textNode) {
2681 option.SetCurve(DRAG_TRANSITION_ANIMATION_CURVE);
2682 auto pipeline = info_.relativeContainerNode->GetContext();
2683 CHECK_NULL_VOID(pipeline);
2684 pipeline->Animate(option, option.GetCurve(), animateCallback, option.GetOnFinishEvent());
2685 } else {
2686 AnimationUtils::Animate(option, animateCallback, option.GetOnFinishEvent(), nullptr, context);
2687 }
2688 }
2689
StartDragTransitionAnimation(const Offset & newOffset,AnimationOption option,const RefPtr<OverlayManager> & overlayManager,const RefPtr<NodeAnimatablePropertyFloat> & animateProperty,Point point)2690 void DragDropManager::StartDragTransitionAnimation(const Offset& newOffset, AnimationOption option,
2691 const RefPtr<OverlayManager>& overlayManager, const RefPtr<NodeAnimatablePropertyFloat>& animateProperty,
2692 Point point)
2693 {
2694 CHECK_NULL_VOID(info_.imageNode);
2695 option.SetCurve(DRAG_TRANSITION_ANIMATION_CURVE);
2696 auto callback = [relativeContainerNode = info_.relativeContainerNode, newOffset, info = info_, overlayManager,
2697 animateProperty, point]() {
2698 DragAnimationHelper::UpdateStartAnimation(overlayManager, animateProperty, point, info, newOffset);
2699 CHECK_NULL_VOID(info.stackNode);
2700 auto stackLayoutProperty = info.stackNode->GetLayoutProperty();
2701 CHECK_NULL_VOID(stackLayoutProperty);
2702 stackLayoutProperty->UpdateUserDefinedIdealSize({ CalcLength(info.width * info.scale, DimensionUnit::PX),
2703 CalcLength(info.height * info.scale, DimensionUnit::PX) });
2704 auto stackContext = info.stackNode->GetContext();
2705 CHECK_NULL_VOID(stackContext);
2706 info.stackNode->MarkDirtyNode(NG::PROPERTY_UPDATE_MEASURE);
2707 };
2708 auto pipeline = info_.relativeContainerNode->GetContext();
2709 CHECK_NULL_VOID(pipeline);
2710 pipeline->Animate(option, option.GetCurve(), callback, option.GetOnFinishEvent());
2711 }
2712
NotifyEnterTextEditorArea()2713 void DragDropManager::NotifyEnterTextEditorArea()
2714 {
2715 auto ret = InteractionInterface::GetInstance()->EnterTextEditorArea(true);
2716 if (ret != 0) {
2717 TAG_LOGW(AceLogTag::ACE_DRAG, "Fail to notify entering text editor erea.");
2718 return;
2719 }
2720
2721 hasNotifiedTransformation_ = true;
2722 }
2723
FireOnEditableTextComponent(const RefPtr<FrameNode> & frameNode,DragEventType type)2724 void DragDropManager::FireOnEditableTextComponent(const RefPtr<FrameNode>& frameNode,
2725 DragEventType type)
2726 {
2727 CHECK_NULL_VOID(frameNode);
2728 auto frameTag = frameNode->GetTag();
2729 auto eventHub = frameNode->GetOrCreateEventHub<EventHub>();
2730 if (!IsEditableTextComponent(frameTag) || !(eventHub && eventHub->IsEnabled()) || !isDragFwkShow_) {
2731 return;
2732 }
2733
2734 // When moving in an editable text component whithout animation, and has not notified msdp yet, notify msdp.
2735 if (type == DragEventType::MOVE && IsEditableTextComponent(frameTag) && isDragFwkShow_ &&
2736 !hasNotifiedTransformation_) {
2737 NotifyEnterTextEditorArea();
2738 return;
2739 }
2740 if (type != DragEventType::ENTER && type != DragEventType::LEAVE) {
2741 TAG_LOGD(AceLogTag::ACE_DRAG, "It is an invalid drag type %{public}d", type);
2742 return;
2743 }
2744
2745 if (type == DragEventType::LEAVE) {
2746 TAG_LOGI(AceLogTag::ACE_DRAG, "The current control has been dragged away.");
2747 hasNotifiedTransformation_ = false;
2748 return;
2749 }
2750
2751 if (hasNotifiedTransformation_) {
2752 TAG_LOGI(AceLogTag::ACE_DRAG, "Coordinates have been transformed.");
2753 return;
2754 }
2755
2756 NotifyEnterTextEditorArea();
2757 }
2758
SetDragResult(const DragNotifyMsgCore & notifyMessage,const RefPtr<OHOS::Ace::DragEvent> & dragEvent)2759 void DragDropManager::SetDragResult(
2760 const DragNotifyMsgCore& notifyMessage, const RefPtr<OHOS::Ace::DragEvent>& dragEvent)
2761 {
2762 DragRet result = DragRet::DRAG_FAIL;
2763 switch (notifyMessage.result) {
2764 case DragRet::DRAG_SUCCESS:
2765 result = DragRet::DRAG_SUCCESS;
2766 break;
2767 case DragRet::DRAG_FAIL:
2768 result = DragRet::DRAG_FAIL;
2769 break;
2770 case DragRet::DRAG_CANCEL:
2771 result = DragRet::DRAG_CANCEL;
2772 break;
2773 default:
2774 break;
2775 }
2776 CHECK_NULL_VOID(dragEvent);
2777 dragEvent->SetResult(result);
2778 }
2779
SetDragBehavior(const DragNotifyMsgCore & notifyMessage,const RefPtr<OHOS::Ace::DragEvent> & dragEvent)2780 void DragDropManager::SetDragBehavior(
2781 const DragNotifyMsgCore& notifyMessage, const RefPtr<OHOS::Ace::DragEvent>& dragEvent)
2782 {
2783 DragBehavior dragBehavior = DragBehavior::UNKNOWN;
2784 switch (notifyMessage.dragBehavior) {
2785 case DragBehavior::COPY:
2786 dragBehavior = DragBehavior::COPY;
2787 break;
2788 case DragBehavior::MOVE:
2789 dragBehavior = DragBehavior::MOVE;
2790 break;
2791 default:
2792 break;
2793 }
2794 CHECK_NULL_VOID(dragEvent);
2795 dragEvent->SetDragBehavior(dragBehavior);
2796 }
2797
UpdateGatherNodeAttr(const RefPtr<OverlayManager> & overlayManager,const GatherAnimationInfo & info)2798 void DragDropManager::UpdateGatherNodeAttr(const RefPtr<OverlayManager>& overlayManager,
2799 const GatherAnimationInfo& info)
2800 {
2801 CHECK_NULL_VOID(overlayManager);
2802 auto gatherNodeChildrenInfo = overlayManager->GetGatherNodeChildrenInfo();
2803 BorderRadiusProperty borderRadius;
2804 if (info.borderRadius.has_value()) {
2805 borderRadius = info.borderRadius.value();
2806 }
2807 borderRadius.multiValued = false;
2808 int32_t cnt = static_cast<int>(gatherNodeChildrenInfo.size());
2809 auto scale = info.scale <= 0.0f ? 1.0f : info.scale;
2810 std::vector<std::pair<float, float>> props(cnt, { 0.0, 0.0 });
2811 if (cnt > 0) {
2812 props[cnt - FIRST_GATHER_PIXEL_MAP] = { FIRST_PIXELMAP_ANGLE, FIRST_PIXELMAP_OPACITY };
2813 }
2814 if (cnt > 1) {
2815 props[cnt - SECOND_GATHER_PIXEL_MAP] = { SECOND_PIXELMAP_ANGLE, SECOND_PIXELMAP_OPACITY };
2816 }
2817 for (int32_t i = 0; i < cnt; ++i) {
2818 auto imageNode = gatherNodeChildrenInfo[i].imageNode.Upgrade();
2819 CHECK_NULL_VOID(imageNode);
2820 auto imageContext = imageNode->GetRenderContext();
2821 CHECK_NULL_VOID(imageContext);
2822 auto& childInfo = gatherNodeChildrenInfo[i];
2823 auto updateScale = scale;
2824 if (((childInfo.width > info.width) || (childInfo.height > info.height)) &&
2825 !NearZero(childInfo.width) && !NearZero(childInfo.height)) {
2826 updateScale *= std::min(info.width / childInfo.width, info.height / childInfo.height);
2827 }
2828 imageContext->UpdateTransformScale({ updateScale, updateScale });
2829 imageContext->UpdateBorderRadius(borderRadius);
2830 imageContext->UpdateOpacity(props[i].second);
2831 Vector5F rotate = Vector5F(0.0f, 0.0f, 1.0f, props[i].first, 0.0f);
2832 imageContext->UpdateTransformRotate(rotate);
2833 }
2834 }
2835
UpdateGatherNodePosition(const RefPtr<OverlayManager> & overlayManager,const RefPtr<FrameNode> & imageNode)2836 void DragDropManager::UpdateGatherNodePosition(const RefPtr<OverlayManager>& overlayManager,
2837 const RefPtr<FrameNode>& imageNode)
2838 {
2839 CHECK_NULL_VOID(imageNode);
2840 CHECK_NULL_VOID(overlayManager);
2841 auto gatherNode = overlayManager->GetGatherNode();
2842 CHECK_NULL_VOID(gatherNode);
2843 auto gatherNodeCenter = DragDropFuncWrapper::GetPaintRectCenterToScreen(imageNode);
2844 gatherNodeCenter -= DragDropFuncWrapper::GetCurrentWindowOffset(gatherNode->GetContextRefPtr());
2845 OffsetF offset;
2846 auto info = overlayManager->GetGatherNodeChildrenInfo();
2847 for (auto iter = info.rbegin(); iter != info.rend(); iter++) {
2848 auto& child = (*iter);
2849 auto imageNode = child.imageNode.Upgrade();
2850 CHECK_NULL_VOID(imageNode);
2851 offset.SetX(gatherNodeCenter.GetX() - child.halfWidth);
2852 offset.SetY(gatherNodeCenter.GetY() - child.halfHeight);
2853 DragDropFuncWrapper::UpdateNodePositionToWindow(imageNode, offset);
2854 }
2855 }
2856
UpdateTextNodePosition(const RefPtr<FrameNode> & textNode,const Offset & localPoint)2857 void DragDropManager::UpdateTextNodePosition(const RefPtr<FrameNode>& textNode, const Offset& localPoint)
2858 {
2859 CHECK_NULL_VOID(textNode);
2860 auto textRenderContext = textNode->GetRenderContext();
2861 CHECK_NULL_VOID(textRenderContext);
2862 textRenderContext->UpdateTransformTranslate({ localPoint.GetX(), localPoint.GetY(), 0.0f });
2863 }
2864
CalcGatherNodeMaxDistanceWithPoint(const RefPtr<OverlayManager> & overlayManager,int32_t x,int32_t y)2865 double DragDropManager::CalcGatherNodeMaxDistanceWithPoint(const RefPtr<OverlayManager>& overlayManager,
2866 int32_t x, int32_t y)
2867 {
2868 CHECK_NULL_RETURN(overlayManager, 0.0f);
2869 auto gatherNodeChildrenInfo = overlayManager->GetGatherNodeChildrenInfo();
2870 double maxDistance = 0.0;
2871 for (const auto& child : gatherNodeChildrenInfo) {
2872 auto imageNode = child.imageNode.Upgrade();
2873 CHECK_NULL_RETURN(imageNode, 0.0f);
2874 auto imageContext = imageNode->GetRenderContext();
2875 CHECK_NULL_RETURN(imageContext, 0.0f);
2876 auto renderPosition = imageContext->GetPropertyOfPosition();
2877 double dis = sqrt(pow(renderPosition.GetX() + child.halfWidth - x, SQUARE_NUMBER) +
2878 pow(renderPosition.GetY() + child.halfHeight - y, SQUARE_NUMBER));
2879 maxDistance = std::max(maxDistance, dis);
2880 }
2881 return maxDistance;
2882 }
2883
IsNeedDisplayInSubwindow()2884 bool DragDropManager::IsNeedDisplayInSubwindow()
2885 {
2886 if (IsNeedScaleDragPreview()) {
2887 return true;
2888 }
2889 auto overlayManager = GetDragAnimationOverlayManager(Container::CurrentId());
2890 CHECK_NULL_RETURN(overlayManager, false);
2891 auto gatherNode = overlayManager->GetGatherNode();
2892 return gatherNode != nullptr;
2893 }
2894
PushGatherPixelMap(const RefPtr<PixelMap> & pixelMap)2895 void DragDropManager::PushGatherPixelMap(const RefPtr<PixelMap>& pixelMap)
2896 {
2897 gatherPixelMaps_.push_back(pixelMap);
2898 }
2899
GetGatherPixelMap(DragDataCore & dragData,float scale,float previewWidth,float previewHeight)2900 void DragDropManager::GetGatherPixelMap(
2901 DragDataCore& dragData, float scale, float previewWidth, float previewHeight)
2902 {
2903 for (const auto& gatherPixelMap : gatherPixelMaps_) {
2904 RefPtr<PixelMap> pixelMapDuplicated = gatherPixelMap;
2905 #if defined(PIXEL_MAP_SUPPORTED)
2906 pixelMapDuplicated = PixelMap::CopyPixelMap(gatherPixelMap);
2907 if (!pixelMapDuplicated) {
2908 TAG_LOGW(AceLogTag::ACE_DRAG, "copy pixelMap failed!");
2909 pixelMapDuplicated = gatherPixelMap;
2910 }
2911 #endif
2912 if (!pixelMapDuplicated) {
2913 TAG_LOGW(AceLogTag::ACE_DRAG, "skip null pixelMap.");
2914 continue;
2915 }
2916 auto width = pixelMapDuplicated->GetWidth() * scale;
2917 auto height = pixelMapDuplicated->GetHeight() * scale;
2918 auto updateScale = scale;
2919 if (((width > previewWidth) || (height > previewHeight)) && !NearZero(width) && !NearZero(height)) {
2920 updateScale *= std::min(previewWidth / width, previewHeight / height);
2921 }
2922 pixelMapDuplicated->Scale(updateScale, updateScale, AceAntiAliasingOption::HIGH);
2923 dragData.shadowInfos.push_back({pixelMapDuplicated, 0.0f, 0.0f});
2924 }
2925 gatherPixelMaps_.clear();
2926 return;
2927 }
2928
ResetDragDrop(int32_t windowId,const Point & point)2929 void DragDropManager::ResetDragDrop(int32_t windowId, const Point& point)
2930 {
2931 DragDropRet dragDropRet { DragRet::DRAG_FAIL, isMouseDragged_, windowId, DragBehavior::UNKNOWN };
2932 HideDragPreviewOverlay();
2933 ClearVelocityInfo();
2934 ResetDragDropStatus(point, dragDropRet, windowId);
2935 dragCursorStyleCore_ = DragCursorStyleCore::DEFAULT;
2936 }
2937
FireOnDragLeave(const RefPtr<FrameNode> & preTargetFrameNode,const DragPointerEvent & pointerEvent,const std::string & extraInfo)2938 void DragDropManager::FireOnDragLeave(
2939 const RefPtr<FrameNode>& preTargetFrameNode, const DragPointerEvent& pointerEvent, const std::string& extraInfo)
2940 {
2941 auto point = pointerEvent.GetPoint();
2942 if (preTargetFrameNode) {
2943 auto preRect = preTargetFrameNode->GetTransformRectRelativeToWindow();
2944 // If the point is out of the pre node, it means we are totally inside a new node, notify leave anyway
2945 if (!preRect.IsInnerRegion(PointF(static_cast<float>(point.GetX()), static_cast<float>(point.GetY())))) {
2946 FireOnDragEvent(preTargetFrameNode, pointerEvent, DragEventType::LEAVE, extraInfo);
2947 return;
2948 }
2949
2950 // If reach here, it means we are entering one new node's area, but without leaving the area of the pre
2951 // one, this usually happens when moving from parent into its child.
2952 // Check the configuration to decide the notify to parent node.
2953 if (eventStrictReportingEnabled_) {
2954 FireOnDragEvent(preTargetFrameNode_, pointerEvent, DragEventType::LEAVE, extraInfo);
2955 }
2956 }
2957 }
2958
IsUIExtensionShowPlaceholder(const RefPtr<NG::UINode> & node)2959 bool DragDropManager::IsUIExtensionShowPlaceholder(const RefPtr<NG::UINode>& node)
2960 {
2961 #ifdef WINDOW_SCENE_SUPPORTED
2962 CHECK_NULL_RETURN(node, true);
2963 auto pipeline = PipelineContext::GetCurrentContextSafelyWithCheck();
2964 CHECK_NULL_RETURN(pipeline, true);
2965 auto manager = pipeline->GetUIExtensionManager();
2966 CHECK_NULL_RETURN(manager, true);
2967 return manager->IsShowPlaceholder(node->GetId());
2968 #endif
2969 return true;
2970 }
2971
UpdateDragMovePosition(const NG::OffsetF & offset,bool isRedragStart)2972 void DragDropManager::UpdateDragMovePosition(const NG::OffsetF& offset, bool isRedragStart)
2973 {
2974 if (isRedragStart) {
2975 ResetContextMenuRedragPosition();
2976 }
2977 lastDragMovePosition_ = dragMovePosition_;
2978 dragMovePosition_ = offset;
2979 if (lastDragMovePosition_.NonOffset()) {
2980 return;
2981 }
2982 dragTotalMovePosition_ += (dragMovePosition_ - lastDragMovePosition_);
2983 }
2984
IsUIExtensionOrDynamicComponent(const RefPtr<NG::UINode> & node)2985 bool DragDropManager::IsUIExtensionOrDynamicComponent(const RefPtr<NG::UINode>& node)
2986 {
2987 CHECK_NULL_RETURN(node, false);
2988 if (V2::ISOLATED_COMPONENT_ETS_TAG == node->GetTag() || V2::DYNAMIC_COMPONENT_ETS_TAG == node->GetTag()) {
2989 // As before, we presume that Isolated and Dynamic component can never show any placeholder component.
2990 return true;
2991 }
2992 return (V2::UI_EXTENSION_COMPONENT_ETS_TAG == node->GetTag() || V2::EMBEDDED_COMPONENT_ETS_TAG == node->GetTag()) &&
2993 (!IsUIExtensionShowPlaceholder(node));
2994 }
2995
HandleUIExtensionDragEvent(const RefPtr<FrameNode> & frameNode,const DragPointerEvent & pointerEvent,DragEventType type)2996 void DragDropManager::HandleUIExtensionDragEvent(
2997 const RefPtr<FrameNode>& frameNode, const DragPointerEvent& pointerEvent, DragEventType type)
2998 {
2999 CHECK_NULL_VOID(frameNode);
3000 auto pattern = frameNode->GetPattern<Pattern>();
3001 CHECK_NULL_VOID(pattern);
3002
3003 auto dragEvent = pointerEvent;
3004 if (type == DragEventType::ENTER) {
3005 dragEvent.action = PointerAction::PULL_IN_WINDOW;
3006 } else if (type == DragEventType::LEAVE) {
3007 dragEvent.action = PointerAction::PULL_OUT_WINDOW;
3008 } else if (type == DragEventType::PULL_CANCEL) {
3009 dragEvent.action = PointerAction::PULL_CANCEL;
3010 }
3011 pattern->HandleDragEvent(dragEvent);
3012 }
3013
GetMenuPreviewRect()3014 RectF DragDropManager::GetMenuPreviewRect()
3015 {
3016 auto pipelineContext = PipelineContext::GetCurrentContextSafelyWithCheck();
3017 CHECK_NULL_RETURN(pipelineContext, RectF());
3018 auto dragDropManager = pipelineContext->GetDragDropManager();
3019 CHECK_NULL_RETURN(dragDropManager, RectF());
3020 auto menuWrapperNode = dragDropManager->GetMenuWrapperNode();
3021 CHECK_NULL_RETURN(menuWrapperNode, RectF());
3022 auto menuWrapperPattern = menuWrapperNode->GetPattern<MenuWrapperPattern>();
3023 CHECK_NULL_RETURN(menuWrapperPattern, RectF());
3024 auto menuPreview = menuWrapperPattern->GetPreview();
3025 CHECK_NULL_RETURN(menuPreview, RectF());
3026 auto previewPaintRect = DragDropFuncWrapper::GetPaintRectToScreen(menuPreview);
3027 previewPaintRect -= DragDropFuncWrapper::GetCurrentWindowOffset(pipelineContext);
3028 return previewPaintRect;
3029 }
3030
GetMaxWidthBaseOnGridSystem(const RefPtr<PipelineBase> & pipeline)3031 double DragDropManager::GetMaxWidthBaseOnGridSystem(const RefPtr<PipelineBase>& pipeline)
3032 {
3033 auto context = DynamicCast<NG::PipelineContext>(pipeline);
3034 CHECK_NULL_RETURN(context, -1.0f);
3035 auto dragDropMgr = context->GetDragDropManager();
3036 CHECK_NULL_RETURN(dragDropMgr, -1.0f);
3037 auto& columnInfo = dragDropMgr->columnInfo_;
3038 if (!columnInfo) {
3039 columnInfo = GridSystemManager::GetInstance().GetInfoByType(GridColumnType::DRAG_PANEL);
3040 auto gridContainer = columnInfo->GetParent();
3041 if (gridContainer) {
3042 auto rootWidth = context->GetRootWidth();
3043 if (LessOrEqual(rootWidth, 0.0)) {
3044 auto mainPipeline = PipelineContext::GetMainPipelineContext();
3045 rootWidth = GridSystemManager::GetInstance().GetScreenWidth(mainPipeline);
3046 }
3047 // cannot handle multi-screen
3048 gridContainer->BuildColumnWidth(rootWidth);
3049 }
3050 dragDropMgr->columnInfo_ = columnInfo;
3051 }
3052
3053 auto gridSizeType = GridSystemManager::GetInstance().GetCurrentSize();
3054 if (gridSizeType > GridSizeType::LG) {
3055 gridSizeType = GridSizeType::LG;
3056 }
3057 if (gridSizeType < GridSizeType::SM) {
3058 gridSizeType = GridSizeType::SM;
3059 }
3060 auto columns = columnInfo->GetColumns(gridSizeType);
3061 double maxWidth = columnInfo->GetWidth(columns);
3062 return maxWidth;
3063 }
3064
GetScaleInfo(float width,float height,bool textDraggable)3065 std::shared_ptr<ScaleDataInfo> DragDropManager::GetScaleInfo(float width, float height, bool textDraggable)
3066 {
3067 auto scaleDataInfo = std::make_shared<ScaleDataInfo>();
3068 CHECK_NULL_RETURN(scaleDataInfo, nullptr);
3069 scaleDataInfo->shortSide = fmin(SystemProperties::GetDeviceHeight(), SystemProperties::GetDeviceWidth());
3070 auto shortSide = PipelineBase::Px2VpWithCurrentDensity(scaleDataInfo->shortSide);
3071 if (shortSide <= DEVICE_TYPE_UNKOWN) {
3072 return scaleDataInfo;
3073 } else if (shortSide <= DEVICE_TYPE_SMALL) {
3074 scaleDataInfo = DragDropManager::CalculateScale(width, height,
3075 textDraggable ? scaleDataInfo->shortSide : scaleDataInfo->shortSide / SCALE_TYPE_FIRST,
3076 scaleDataInfo->shortSide / SCALE_TYPE_FIRST);
3077 } else if (shortSide <= DEVICE_TYPE_MEDIUM) {
3078 scaleDataInfo = CalculateScale(width, height,
3079 textDraggable ? scaleDataInfo->shortSide / SCALE_TYPE_FIRST : scaleDataInfo->shortSide / SCALE_TYPE_THIRD,
3080 scaleDataInfo->shortSide / SCALE_TYPE_THIRD);
3081 } else {
3082 scaleDataInfo = CalculateScale(width, height,
3083 textDraggable ? scaleDataInfo->shortSide * SCALE_TYPE_FIRST / SCALE_TYPE_SECOND
3084 : scaleDataInfo->shortSide / SCALE_TYPE_SECOND,
3085 scaleDataInfo->shortSide / SCALE_TYPE_SECOND);
3086 }
3087 return scaleDataInfo;
3088 }
3089
CalculateScale(float width,float height,float widthLimit,float heightLimit)3090 std::shared_ptr<ScaleDataInfo> DragDropManager::CalculateScale(
3091 float width, float height, float widthLimit, float heightLimit)
3092 {
3093 auto scaleDataInfo = std::make_shared<ScaleDataInfo>();
3094 CHECK_NULL_RETURN(scaleDataInfo, nullptr);
3095 if ((width > 0 && height > 0) && (width > widthLimit || height > heightLimit)) {
3096 scaleDataInfo->scale = fmin(widthLimit / width, heightLimit / height);
3097 scaleDataInfo->isNeedScale = true;
3098 }
3099 return scaleDataInfo;
3100 }
3101
GetDragAnimationOverlayManager(int32_t containerId)3102 const RefPtr<NG::OverlayManager> DragDropManager::GetDragAnimationOverlayManager(int32_t containerId)
3103 {
3104 auto subwindow = SubwindowManager::GetInstance()->GetSubwindowByType(containerId >= MIN_SUBCONTAINER_ID ?
3105 SubwindowManager::GetInstance()->GetParentContainerId(containerId) : containerId, SubwindowType::TYPE_MENU);
3106 CHECK_NULL_RETURN(subwindow, nullptr);
3107 return subwindow->GetOverlayManager();
3108 }
3109
RemoveDragFrameNode(int32_t id)3110 void DragDropManager::RemoveDragFrameNode(int32_t id)
3111 {
3112 gridDragFrameNodes_.erase(id);
3113 listDragFrameNodes_.erase(id);
3114 textFieldDragFrameNodes_.erase(id);
3115 }
3116
SetIsDragged(bool isDragged)3117 void DragDropManager::SetIsDragged(bool isDragged)
3118 {
3119 if (isDragged && isDragged_ != isDragged && notifyInDraggedCallback_) {
3120 notifyInDraggedCallback_();
3121 }
3122 isDragged_ = isDragged;
3123 }
3124
RegisterDragStatusListener(int32_t nodeId,const WeakPtr<FrameNode> & node)3125 void DragDropManager::RegisterDragStatusListener(int32_t nodeId, const WeakPtr<FrameNode>& node)
3126 {
3127 auto ret = nodesForDragNotify_.try_emplace(nodeId, node);
3128 if (!ret.second) {
3129 nodesForDragNotify_[nodeId] = node;
3130 }
3131 }
3132
RegisterPullEventListener(int32_t uniqueIdentify,std::function<void (const DragPointerEvent &)> callback)3133 void DragDropManager::RegisterPullEventListener(
3134 int32_t uniqueIdentify, std::function<void(const DragPointerEvent&)> callback)
3135 {
3136 pullEventListener_[uniqueIdentify] = callback;
3137 }
3138
UnRegisterPullEventListener(int32_t uniqueIdentify)3139 void DragDropManager::UnRegisterPullEventListener(int32_t uniqueIdentify)
3140 {
3141 auto it = pullEventListener_.find(uniqueIdentify);
3142 if (it != pullEventListener_.end()) {
3143 pullEventListener_.erase(it);
3144 }
3145 }
3146
NotifyPullEventListener(const DragPointerEvent & pointerEvent)3147 void DragDropManager::NotifyPullEventListener(const DragPointerEvent& pointerEvent)
3148 {
3149 if (pullEventListener_.empty()) {
3150 return;
3151 }
3152 for (const auto& pair : pullEventListener_) {
3153 if (pair.second) {
3154 pair.second(pointerEvent);
3155 }
3156 }
3157 }
3158
IsDraggingPressed(int32_t currentPointerId) const3159 bool DragDropManager::IsDraggingPressed(int32_t currentPointerId) const
3160 {
3161 if (currentPointerId_ == currentPointerId) {
3162 return draggingPressedState_;
3163 }
3164 return false;
3165 }
3166
ResetContextMenuDragPosition()3167 void DragDropManager::ResetContextMenuDragPosition()
3168 {
3169 dragMovePosition_.Reset();
3170 lastDragMovePosition_.Reset();
3171 dragTotalMovePosition_.Reset();
3172 }
3173
ResetContextMenuRedragPosition()3174 void DragDropManager::ResetContextMenuRedragPosition()
3175 {
3176 dragMovePosition_.Reset();
3177 lastDragMovePosition_.Reset();
3178 }
3179
AddNewDragAnimation()3180 void DragDropManager::AddNewDragAnimation()
3181 {
3182 currentAnimationCnt_++;
3183 allAnimationCnt_++;
3184 }
3185
AddNewDragStartAnimation()3186 void DragDropManager::AddNewDragStartAnimation()
3187 {
3188 currentStartAnimationCnt_++;
3189 allStartAnimationCnt_++;
3190 }
3191
IsAllAnimationFinished()3192 bool DragDropManager::IsAllAnimationFinished()
3193 {
3194 currentAnimationCnt_--;
3195 return currentAnimationCnt_ == 0;
3196 }
3197
IsAllStartAnimationFinished()3198 bool DragDropManager::IsAllStartAnimationFinished()
3199 {
3200 currentStartAnimationCnt_--;
3201 return currentStartAnimationCnt_ == 0;
3202 }
3203
CheckIsNewDrag(const DragPointerEvent & pointerEvent) const3204 bool DragDropManager::CheckIsNewDrag(const DragPointerEvent& pointerEvent) const
3205 {
3206 return (pointerEvent.pullId != -1) && (pointerEvent.pullId != currentPullId_);
3207 }
3208
RequireSummaryAndDragBundleInfoIfNecessary(const DragPointerEvent & pointerEvent)3209 void DragDropManager::RequireSummaryAndDragBundleInfoIfNecessary(const DragPointerEvent& pointerEvent)
3210 {
3211 if (CheckIsNewDrag(pointerEvent)) {
3212 currentPullId_ = pointerEvent.pullId;
3213 RequireSummary();
3214 RequireBundleInfo();
3215 }
3216 }
3217
IsAnyDraggableHit(const RefPtr<PipelineBase> & pipeline,int32_t pointId)3218 bool DragDropManager::IsAnyDraggableHit(const RefPtr<PipelineBase>& pipeline, int32_t pointId)
3219 {
3220 if (isAnyDraggableHit_) {
3221 return true;
3222 }
3223
3224 auto pipelineContext = AceType::DynamicCast<PipelineContext>(pipeline);
3225 CHECK_NULL_RETURN(pipelineContext, false);
3226 auto eventManager = pipelineContext->GetEventManager();
3227 CHECK_NULL_RETURN(eventManager, false);
3228 auto touchTestResults = eventManager->touchTestResults_;
3229 const auto iter = touchTestResults.find(pointId);
3230 if (iter == touchTestResults.end() || iter->second.empty()) {
3231 TAG_LOGI(AceLogTag::ACE_DRAG, "touch test result is empty.");
3232 return false;
3233 }
3234 for (const auto& touchTestResult : iter->second) {
3235 auto recognizer = AceType::DynamicCast<NG::NGGestureRecognizer>(touchTestResult);
3236 if (recognizer) {
3237 continue;
3238 }
3239 auto node = touchTestResult->GetAttachedNode().Upgrade();
3240 CHECK_NULL_RETURN(node, false);
3241 if (IsUIExtensionOrDynamicComponent(node)) {
3242 return true;
3243 }
3244 }
3245 return false;
3246 }
3247
CancelUDMFDataLoading(const std::string & key)3248 int32_t DragDropManager::CancelUDMFDataLoading(const std::string& key)
3249 {
3250 return UdmfClient::GetInstance()->Cancel(key);
3251 }
3252
CheckIsFolderSubwindowBoundary(float x,float y,int32_t instanceId)3253 bool DragDropManager::CheckIsFolderSubwindowBoundary(float x, float y, int32_t instanceId)
3254 {
3255 if (!SystemProperties::IsSuperFoldDisplayDevice() || NearZero(info_.scale)) {
3256 return false;
3257 }
3258 auto mainContainerId = instanceId >= MIN_SUBCONTAINER_ID ?
3259 SubwindowManager::GetInstance()->GetParentContainerId(instanceId) : instanceId;
3260 auto container = Container::GetContainer(mainContainerId);
3261 CHECK_NULL_RETURN(container, false);
3262 if (container->GetCurrentFoldStatus() == FoldStatus::EXPAND) {
3263 return false;
3264 }
3265 auto isCrossWindow = container->IsCrossAxisWindow();
3266 auto isSceneBoard = container->IsSceneBoardWindow();
3267 if (isCrossWindow || isSceneBoard) {
3268 return false;
3269 }
3270 auto subwindow =
3271 SubwindowManager::GetInstance()->GetSubwindowByType(Container::CurrentId(), SubwindowType::TYPE_MENU);
3272 CHECK_NULL_RETURN(subwindow, false);
3273 auto rect = subwindow->GetWindowRect();
3274 auto scale = dragStartAnimationRate_ * (info_.scale - info_.originScale.y) + info_.originScale.y;
3275 OffsetF pixelMapOffset = pixelMapOffset_ / info_.scale * scale;
3276 float top = y + pixelMapOffset.GetY();
3277 float bottom = y + pixelMapOffset.GetY() + info_.height * scale;
3278 float distance = std::min(top - rect.Top(), rect.Bottom() - bottom);
3279 return distance < MIN_FOLDER_SUBWINDOW_BOUNDARY_DISTANCE;
3280 }
3281
CheckIsUIExtensionBoundary(float x,float y,int32_t instanceId)3282 bool DragDropManager::CheckIsUIExtensionBoundary(float x, float y, int32_t instanceId)
3283 {
3284 auto container = Container::GetContainer(instanceId);
3285 CHECK_NULL_RETURN(container, false);
3286 if (!container->IsUIExtensionWindow()) {
3287 return false;
3288 }
3289 auto pipeline = container->GetPipelineContext();
3290 CHECK_NULL_RETURN(pipeline, false);
3291 auto rect = pipeline->GetCurrentWindowRect();
3292 auto distance = std::min(std::min(x - rect.Left(), rect.Right() - x),
3293 std::min(y - rect.Top(), rect.Bottom() - y));
3294 return distance < MIN_UI_EXTENSION_BOUNDARY_DISTANCE;
3295 }
3296
ReportOnItemDropEvent(DragType dragType,const RefPtr<FrameNode> & dragFrameNode,double dropPositionX,double dropPositionY)3297 void DragDropManager::ReportOnItemDropEvent(
3298 DragType dragType, const RefPtr<FrameNode>& dragFrameNode, double dropPositionX, double dropPositionY)
3299 {
3300 CHECK_NULL_VOID(dragFrameNode);
3301 auto windowScale = isDragWindowSubWindow_ ? 1.0f : GetWindowScale();
3302 auto windowX = PipelineBase::Px2VpWithCurrentDensity(dragStartPoint_.GetX() * windowScale);
3303 auto windowY = PipelineBase::Px2VpWithCurrentDensity(dragStartPoint_.GetY() * windowScale);
3304
3305 auto params = JsonUtil::Create();
3306 CHECK_NULL_VOID(params);
3307 params->Put("StartX", windowX);
3308 params->Put("StartY", windowY);
3309 params->Put("InsertX", dropPositionX);
3310 params->Put("InsertY", dropPositionY);
3311
3312 std::string eventName;
3313 std::string type;
3314 if (dragType == DragType::GRID) {
3315 eventName = "Grid.onItemDrop";
3316 type = "Grid";
3317 } else {
3318 eventName = "List.onItemDrop";
3319 type = "List";
3320 }
3321 auto event = JsonUtil::Create();
3322 CHECK_NULL_VOID(event);
3323 event->Put("name", eventName.c_str());
3324 event->Put("params", params);
3325
3326 auto json = JsonUtil::Create();
3327 CHECK_NULL_VOID(json);
3328 json->Put("nodeId", dragFrameNode->GetId());
3329 json->Put("event", event);
3330
3331 auto result = JsonUtil::Create();
3332 CHECK_NULL_VOID(result);
3333 result->Put("result", json);
3334 UiSessionManager::GetInstance()->ReportComponentChangeEvent("result", result->ToString());
3335 TAG_LOGI(AceLogTag::ACE_DRAG,
3336 "nodeId:[%{public}d] %{public}s reportComponentChangeEvent onItemDrop StartX:%{public}.15f "
3337 "StartY:%{public}.15f "
3338 "InsertX:%{public}.15f InsertY:%{public}.15f",
3339 dragFrameNode->GetId(), type.c_str(), windowX, windowY, dropPositionX, dropPositionY);
3340 }
3341
SetDragAnimationPointerEvent(const DragPointerEvent & pointerEvent,const RefPtr<NG::FrameNode> & node)3342 void DragDropManager::SetDragAnimationPointerEvent(
3343 const DragPointerEvent& pointerEvent, const RefPtr<NG::FrameNode>& node)
3344 {
3345 auto container = Container::Current();
3346 CHECK_NULL_VOID(container);
3347 if (!container->IsSceneBoardWindow() || node == rootNode_) {
3348 dragAnimationPointerEvent_ = pointerEvent;
3349 }
3350 }
3351
HandleTouchEvent(const TouchEvent & event,const RefPtr<NG::FrameNode> & node)3352 void DragDropManager::HandleTouchEvent(const TouchEvent& event, const RefPtr<NG::FrameNode>& node)
3353 {
3354 if (event.type == TouchType::MOVE && event.pullType != TouchType::PULL_MOVE) {
3355 if (!IsDragging() || !IsSameDraggingPointer(event.id)) {
3356 return;
3357 }
3358 DragPointerEvent dragPointerEvent;
3359 DragDropFuncWrapper::ConvertPointerEvent(event, dragPointerEvent);
3360 SetDragAnimationPointerEvent(dragPointerEvent);
3361 } else if ((event.type == TouchType::UP) || (event.type == TouchType::CANCEL)) {
3362 ResetDraggingStatus(event);
3363 }
3364 }
3365
HandleMouseEvent(const MouseEvent & event)3366 void DragDropManager::HandleMouseEvent(const MouseEvent& event)
3367 {
3368 bool cancelDrag = (event.button == MouseButton::RIGHT_BUTTON &&
3369 (event.action == MouseAction::PRESS || event.action == MouseAction::PULL_UP));
3370 SetIsDragCancel(cancelDrag);
3371 }
3372
HandlePipelineOnHide()3373 void DragDropManager::HandlePipelineOnHide()
3374 {
3375 if (IsItemDragging()) {
3376 CancelItemDrag();
3377 }
3378 }
3379
ResetBundleInfo()3380 void DragDropManager::ResetBundleInfo()
3381 {
3382 auto container = Container::Current();
3383 CHECK_NULL_VOID(container);
3384 auto dragBundleName = container->GetBundleName();
3385 dragBundleInfo_.bundleName = dragBundleName;
3386 dragBundleInfo_.isRemoteDev = false;
3387 }
3388
RequireBundleInfo()3389 void DragDropManager::RequireBundleInfo()
3390 {
3391 DragBundleInfo dragBundleInfo;
3392 InteractionInterface::GetInstance()->GetDragBundleInfo(dragBundleInfo);
3393 dragBundleInfo_ = dragBundleInfo;
3394 }
3395
NotifyDragSpringLoadingMove(const RefPtr<FrameNode> & dragFrameNode,const std::string & extraInfo)3396 void DragDropManager::NotifyDragSpringLoadingMove(const RefPtr<FrameNode>& dragFrameNode, const std::string& extraInfo)
3397 {
3398 if (!dragDropSpringLoadingDetector_) {
3399 dragDropSpringLoadingDetector_ = MakeRefPtr<DragDropSpringLoadingDetector>();
3400 }
3401 dragDropSpringLoadingDetector_->NotifyMove({ preMovePoint_, dragFrameNode, preTimeStamp_, extraInfo });
3402 }
3403
NotifyDragSpringLoadingIntercept(std::string_view extraParams)3404 void DragDropManager::NotifyDragSpringLoadingIntercept(std::string_view extraParams)
3405 {
3406 if (!dragDropSpringLoadingDetector_) {
3407 dragDropSpringLoadingDetector_ = MakeRefPtr<DragDropSpringLoadingDetector>();
3408 }
3409 dragDropSpringLoadingDetector_->NotifyIntercept(extraParams);
3410 }
3411 } // namespace OHOS::Ace::NG
3412