1 /*
2 * Copyright (c) 2022-2023 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/ng/offset_t.h"
19 #include "base/geometry/point.h"
20 #include "base/subwindow/subwindow_manager.h"
21 #include "base/utils/utils.h"
22 #include "core/common/interaction/interaction_data.h"
23 #include "core/common/interaction/interaction_interface.h"
24 #include "core/components/common/layout/grid_system_manager.h"
25 #include "core/components_ng/pattern/grid/grid_event_hub.h"
26 #include "core/components_ng/pattern/list/list_event_hub.h"
27 #include "core/components_ng/pattern/root/root_pattern.h"
28 #include "core/components_ng/pattern/text_field/text_field_pattern.h"
29 #include "core/components_v2/inspector/inspector_constants.h"
30 #include "core/pipeline_ng/pipeline_context.h"
31 #include "base/utils/time_util.h"
32
33 #include "base/geometry/rect.h"
34 #include "core/common/udmf/udmf_client.h"
35
36 namespace OHOS::Ace::NG {
37 namespace {
38 int64_t g_proxyId = 0;
39 constexpr float PIXELMAP_POSITION_WIDTH = 0.5f;
40 constexpr float PIXELMAP_POSITION_HEIGHT = 0.2f;
41 } // namespace
42
CreateAndShowDragWindow(const RefPtr<PixelMap> & pixelMap,const GestureEvent & info)43 RefPtr<DragDropProxy> DragDropManager::CreateAndShowDragWindow(
44 const RefPtr<PixelMap>& pixelMap, const GestureEvent& info)
45 {
46 CHECK_NULL_RETURN(pixelMap, nullptr);
47 SetIsDragged(true);
48 isDragCancel_ = false;
49 #if !defined(PREVIEW)
50 auto windowScale = GetWindowScale();
51 pixelMap->Scale(windowScale, windowScale, AceAntiAliasingOption::HIGH);
52 CreateDragWindow(info, pixelMap->GetWidth(), pixelMap->GetHeight());
53 CHECK_NULL_RETURN(dragWindow_, nullptr);
54 dragWindow_->DrawPixelMap(pixelMap);
55 #endif
56 currentId_ = ++g_proxyId;
57 return MakeRefPtr<DragDropProxy>(currentId_);
58 }
59
CreateAndShowDragWindow(const RefPtr<UINode> & customNode,const GestureEvent & info)60 RefPtr<DragDropProxy> DragDropManager::CreateAndShowDragWindow(
61 const RefPtr<UINode>& customNode, const GestureEvent& info)
62 {
63 dragWindowRootNode_ = CreateDragRootNode(customNode);
64 CHECK_NULL_RETURN(dragWindowRootNode_, nullptr);
65 SetIsDragged(true);
66 isDragCancel_ = false;
67 #if !defined(PREVIEW)
68 if (dragWindow_) {
69 return nullptr;
70 }
71
72 auto geometryNode = dragWindowRootNode_->GetGeometryNode();
73 CHECK_NULL_RETURN(geometryNode, nullptr);
74
75 auto frameRect = geometryNode->GetFrameSize();
76 CreateDragWindow(info, static_cast<uint32_t>(frameRect.Width()), static_cast<uint32_t>(frameRect.Height()));
77 if (!dragWindow_) {
78 return nullptr;
79 }
80 dragWindow_->DrawFrameNode(dragWindowRootNode_);
81 #endif
82 currentId_ = ++g_proxyId;
83 return MakeRefPtr<DragDropProxy>(currentId_);
84 }
85
CreateTextDragDropProxy()86 RefPtr<DragDropProxy> DragDropManager::CreateTextDragDropProxy()
87 {
88 SetIsDragged(true);
89 isDragCancel_ = false;
90 currentId_ = ++g_proxyId;
91 return MakeRefPtr<DragDropProxy>(currentId_);
92 }
93
CreateDragWindow(const GestureEvent & info,uint32_t width,uint32_t height)94 void DragDropManager::CreateDragWindow(const GestureEvent& info, uint32_t width, uint32_t height)
95 {
96 #if !defined(PREVIEW)
97 auto pipeline = PipelineContext::GetCurrentContext();
98 CHECK_NULL_VOID(pipeline);
99 auto rect = pipeline->GetDisplayWindowRectInfo();
100 auto windowScale = GetWindowScale();
101 int32_t windowX = static_cast<int32_t>(info.GetGlobalPoint().GetX() * windowScale);
102 int32_t windowY = static_cast<int32_t>(info.GetGlobalPoint().GetY() * windowScale);
103 dragWindow_ = DragWindow::CreateDragWindow("APP_DRAG_WINDOW",
104 windowX + rect.Left(), windowY + rect.Top(), width, height);
105 if (dragWindow_) {
106 dragWindow_->SetOffset(rect.Left(), rect.Top());
107 }
108 #endif
109 }
110
CreateDragRootNode(const RefPtr<UINode> & customNode)111 RefPtr<FrameNode> DragDropManager::CreateDragRootNode(const RefPtr<UINode>& customNode)
112 {
113 auto pipeline = PipelineContext::GetCurrentContext();
114 CHECK_NULL_RETURN(pipeline, nullptr);
115
116 auto rootNode = FrameNode::CreateFrameNodeWithTree(
117 V2::ROOT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), MakeRefPtr<RootPattern>());
118 rootNode->SetActive(true);
119 rootNode->SetHostRootId(pipeline->GetInstanceId());
120 rootNode->SetHostPageId(-1);
121 rootNode->AddChild(customNode);
122 rootNode->AttachToMainTree();
123 rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
124 pipeline->FlushUITasks();
125 return rootNode;
126 }
127
UpdateDragWindowPosition(int32_t globalX,int32_t globalY)128 void DragDropManager::UpdateDragWindowPosition(int32_t globalX, int32_t globalY)
129 {
130 #if !defined(PREVIEW)
131 CHECK_NULL_VOID(dragWindow_);
132 dragWindow_->MoveTo(globalX, globalY);
133 #endif
134 }
135
UpdatePixelMapPosition(int32_t globalX,int32_t globalY)136 void DragDropManager::UpdatePixelMapPosition(int32_t globalX, int32_t globalY)
137 {
138 auto pipeline = NG::PipelineContext::GetCurrentContext();
139 CHECK_NULL_VOID(pipeline);
140 auto manager = pipeline->GetOverlayManager();
141 CHECK_NULL_VOID(manager);
142 auto rootNode = pipeline->GetRootElement();
143 CHECK_NULL_VOID(rootNode);
144 if (manager->GetHasPixelMap()) {
145 auto columnNode = AceType::DynamicCast<NG::FrameNode>(rootNode->GetLastChild());
146 CHECK_NULL_VOID(columnNode);
147 auto imageNode = AceType::DynamicCast<NG::FrameNode>(columnNode->GetLastChild());
148 CHECK_NULL_VOID(imageNode);
149 auto geometryNode = imageNode->GetGeometryNode();
150 CHECK_NULL_VOID(geometryNode);
151 auto width = geometryNode->GetFrameSize().Width();
152 auto height = geometryNode->GetFrameSize().Height();
153 auto imageContext = imageNode->GetRenderContext();
154 CHECK_NULL_VOID(imageContext);
155 CHECK_NULL_VOID(draggedFrameNode_);
156 auto hub = draggedFrameNode_->GetOrCreateGestureEventHub();
157 CHECK_NULL_VOID(hub);
158 if (!hub->GetTextDraggable()) {
159 hub = columnNode->GetOrCreateGestureEventHub();
160 CHECK_NULL_VOID(hub);
161 }
162 RefPtr<PixelMap> pixelMap = hub->GetPixelMap();
163 CHECK_NULL_VOID(pixelMap);
164 float scale = NearZero(width) ? 1.0f : pixelMap->GetWidth() / width;
165 imageContext->UpdatePosition(NG::OffsetT<Dimension>(
166 Dimension(globalX - width * PIXELMAP_POSITION_WIDTH * scale - width / 2.0f + width * scale / 2.0f),
167 Dimension(globalY - height * PIXELMAP_POSITION_HEIGHT * scale - height / 2.0f + height * scale / 2.0f)));
168 imageContext->OnModifyDone();
169 }
170 }
171
HideDragPreviewOverlay()172 void DragDropManager::HideDragPreviewOverlay()
173 {
174 auto pipeline = NG::PipelineContext::GetCurrentContext();
175 CHECK_NULL_VOID(pipeline);
176 auto manager = pipeline->GetOverlayManager();
177 CHECK_NULL_VOID(manager);
178 manager->RemovePixelMap();
179 SubwindowManager::GetInstance()->HidePreviewNG();
180 }
181
FindTargetInChildNodes(const RefPtr<UINode> parentNode,std::vector<RefPtr<FrameNode>> hitFrameNodes,bool findDrop)182 RefPtr<FrameNode> DragDropManager::FindTargetInChildNodes(
183 const RefPtr<UINode> parentNode, std::vector<RefPtr<FrameNode>> hitFrameNodes, bool findDrop)
184 {
185 CHECK_NULL_RETURN(parentNode, nullptr);
186 auto parentFrameNode = AceType::DynamicCast<FrameNode>(parentNode);
187 if (parentFrameNode && (!parentFrameNode->IsActive() || !parentFrameNode->IsVisible())) {
188 return nullptr;
189 }
190 auto children = parentFrameNode->GetFrameChildren();
191
192 for (auto iter = children.rbegin(); iter != children.rend(); iter++) {
193 auto child = iter->Upgrade();
194 if (child == nullptr) {
195 continue;
196 }
197 auto childNode = AceType::DynamicCast<UINode>(child);
198 auto childFindResult = FindTargetInChildNodes(childNode, hitFrameNodes, findDrop);
199 if (childFindResult) {
200 return childFindResult;
201 }
202 }
203
204 CHECK_NULL_RETURN(parentFrameNode, nullptr);
205 for (auto iter : hitFrameNodes) {
206 if (parentFrameNode == iter) {
207 auto eventHub = parentFrameNode->GetEventHub<EventHub>();
208 if (!eventHub) {
209 continue;
210 }
211 if (eventHub->HasOnDrop() || eventHub->HasOnItemDrop() || eventHub->HasCustomerOnDrop()
212 || V2::UI_EXTENSION_COMPONENT_ETS_TAG == parentFrameNode->GetTag()) {
213 return parentFrameNode;
214 }
215 }
216 }
217 return nullptr;
218 }
219
FindDragFrameNodeByPosition(float globalX,float globalY,DragType dragType,bool findDrop)220 RefPtr<FrameNode> DragDropManager::FindDragFrameNodeByPosition(
221 float globalX, float globalY, DragType dragType, bool findDrop)
222 {
223 std::map<int32_t, WeakPtr<FrameNode>> frameNodes;
224 switch (dragType) {
225 case DragType::COMMON:
226 frameNodes = dragFrameNodes_;
227 break;
228 case DragType::GRID:
229 frameNodes = gridDragFrameNodes_;
230 break;
231 case DragType::LIST:
232 frameNodes = listDragFrameNodes_;
233 break;
234 case DragType::TEXT:
235 frameNodes = textFieldDragFrameNodes_;
236 break;
237 default:
238 break;
239 }
240
241 if (frameNodes.empty()) {
242 return nullptr;
243 }
244
245 auto pipeline = NG::PipelineContext::GetCurrentContext();
246 CHECK_NULL_RETURN(pipeline, nullptr);
247 auto nanoTimestamp = pipeline->GetVsyncTime();
248 PointF point(globalX, globalY);
249 std::vector<RefPtr<FrameNode>> hitFrameNodes;
250 for (auto iterOfFrameNode = frameNodes.begin(); iterOfFrameNode != frameNodes.end(); iterOfFrameNode++) {
251 auto frameNode = iterOfFrameNode->second.Upgrade();
252 if (!frameNode || !frameNode->IsVisible()) {
253 continue;
254 }
255 auto geometryNode = frameNode->GetGeometryNode();
256 if (!geometryNode) {
257 continue;
258 }
259 auto globalFrameRect = geometryNode->GetFrameRect();
260 globalFrameRect.SetOffset(frameNode->CalculateCachedTransformRelativeOffset(nanoTimestamp));
261 if (globalFrameRect.IsInRegion(point)) {
262 hitFrameNodes.push_back(frameNode);
263 }
264 }
265
266 if (hitFrameNodes.empty()) {
267 TAG_LOGD(AceLogTag::ACE_DRAG, "Cannot find targetNodes.");
268 return nullptr;
269 }
270 auto manager = pipeline->GetOverlayManager();
271 CHECK_NULL_RETURN(manager, nullptr);
272 auto rootNode = pipeline->GetRootElement();
273
274 auto result = FindTargetInChildNodes(rootNode, hitFrameNodes, findDrop);
275 if (result) {
276 return result;
277 }
278 return nullptr;
279 }
280
CheckDragDropProxy(int64_t id) const281 bool DragDropManager::CheckDragDropProxy(int64_t id) const
282 {
283 return currentId_ == id;
284 }
285
UpdateDragAllowDrop(const RefPtr<FrameNode> & dragFrameNode,const bool isCopy)286 void DragDropManager::UpdateDragAllowDrop(const RefPtr<FrameNode>& dragFrameNode, const bool isCopy)
287 {
288 const auto& dragFrameNodeAllowDrop = dragFrameNode->GetAllowDrop();
289 if (dragFrameNodeAllowDrop.empty() || summaryMap_.empty()) {
290 UpdateDragStyle(DragCursorStyleCore::MOVE);
291 return;
292 }
293 for (const auto& it : summaryMap_) {
294 if (dragFrameNodeAllowDrop.find(it.first) == dragFrameNodeAllowDrop.end()) {
295 UpdateDragStyle(DragCursorStyleCore::FORBIDDEN);
296 return;
297 }
298 }
299 UpdateDragStyle(isCopy ? DragCursorStyleCore::COPY : DragCursorStyleCore::MOVE);
300 }
301
UpdateDragStyle(const DragCursorStyleCore & dragStyle)302 void DragDropManager::UpdateDragStyle(const DragCursorStyleCore& dragStyle)
303 {
304 if (dragStyle != dragCursorStyleCore_) {
305 dragCursorStyleCore_ = dragStyle;
306 InteractionInterface::GetInstance()->UpdateDragStyle(dragCursorStyleCore_);
307 }
308 }
309
CheckParentVisible(const RefPtr<FrameNode> & frameNode)310 bool CheckParentVisible(const RefPtr<FrameNode>& frameNode)
311 {
312 bool isVisible = frameNode->IsVisible();
313 if (!isVisible) {
314 return false;
315 }
316 auto parent = frameNode->GetParent();
317 while (parent && parent->GetDepth() != 1) {
318 auto parentFrameNode = AceType::DynamicCast<FrameNode>(parent);
319 if (parentFrameNode && !parentFrameNode->IsVisible()) {
320 isVisible = false;
321 break;
322 }
323 parent = parent->GetParent();
324 }
325 return isVisible;
326 }
327
FindHitFrameNodes(const Point & point)328 std::unordered_set<int32_t> DragDropManager::FindHitFrameNodes(const Point& point)
329 {
330 std::unordered_set<int32_t> frameNodeList;
331 for (auto iter = nodesForDragNotify_.begin(); iter != nodesForDragNotify_.end(); iter++) {
332 auto frameNode = iter->second.Upgrade();
333 if (!frameNode || !frameNode->IsActive() || !frameNode->IsVisible()) {
334 continue;
335 }
336 auto geometryNode = frameNode->GetGeometryNode();
337 if (!geometryNode) {
338 continue;
339 }
340 auto globalFrameRect = geometryNode->GetFrameRect();
341 globalFrameRect.SetOffset(frameNode->GetTransformRelativeOffset());
342 if (globalFrameRect.IsInRegion(PointF(static_cast<float>(point.GetX()), static_cast<float>(point.GetY())))) {
343 frameNodeList.emplace(frameNode->GetId());
344 }
345 }
346 return frameNodeList;
347 }
348
UpdateDragListener(const Point & point)349 void DragDropManager::UpdateDragListener(const Point& point)
350 {
351 auto hitNodes = FindHitFrameNodes(point);
352 std::unordered_map<int32_t, WeakPtr<FrameNode>> dragEnterNodes;
353 std::unordered_map<int32_t, WeakPtr<FrameNode>> dragMoveNodes;
354 std::unordered_map<int32_t, WeakPtr<FrameNode>> dragLeaveNodes;
355 for (auto iter = nodesForDragNotify_.begin(); iter != nodesForDragNotify_.end(); iter++) {
356 auto localHitResult = hitNodes.find(iter->first) != hitNodes.end();
357 auto preHitResult = parentHitNodes_.find(iter->first) != parentHitNodes_.end();
358 if (localHitResult && preHitResult) {
359 dragMoveNodes[iter->first] = iter->second;
360 }
361 if (localHitResult && !preHitResult) {
362 dragEnterNodes[iter->first] = iter->second;
363 }
364 if (!localHitResult && preHitResult) {
365 dragLeaveNodes[iter->first] = iter->second;
366 }
367 }
368 RefPtr<NotifyDragEvent> notifyEvent = AceType::MakeRefPtr<NotifyDragEvent>();
369 UpdateNotifyDragEvent(notifyEvent, point, DragEventType::MOVE);
370
371 NotifyDragRegisterFrameNode(dragMoveNodes, DragEventType::MOVE, notifyEvent);
372 NotifyDragRegisterFrameNode(dragEnterNodes, DragEventType::ENTER, notifyEvent);
373 NotifyDragRegisterFrameNode(dragLeaveNodes, DragEventType::LEAVE, notifyEvent);
374 parentHitNodes_ = std::move(hitNodes);
375 }
376
NotifyDragRegisterFrameNode(std::unordered_map<int32_t,WeakPtr<FrameNode>> nodes,DragEventType dragEventType,RefPtr<NotifyDragEvent> & notifyEvent)377 void DragDropManager::NotifyDragRegisterFrameNode(std::unordered_map<int32_t, WeakPtr<FrameNode>> nodes,
378 DragEventType dragEventType, RefPtr<NotifyDragEvent>& notifyEvent)
379 {
380 for (auto iter = nodes.begin(); iter != nodes.end(); iter++) {
381 auto frameNode = iter->second.Upgrade();
382 if (!frameNode) {
383 continue;
384 }
385 auto eventHub = frameNode->GetEventHub<EventHub>();
386 if (!CheckParentVisible(frameNode) || (eventHub && !eventHub->IsEnabled())) {
387 continue;
388 }
389 auto pattern = frameNode->GetPattern<Pattern>();
390 if (!pattern) {
391 continue;
392 }
393 pattern->HandleOnDragStatusCallback(dragEventType, notifyEvent);
394 }
395 }
396
NotifyDragFrameNode(const Point & point,const DragEventType & dragEventType,const DragRet & dragRet)397 void DragDropManager::NotifyDragFrameNode(
398 const Point& point, const DragEventType& dragEventType, const DragRet& dragRet)
399 {
400 RefPtr<NotifyDragEvent> notifyEvent = AceType::MakeRefPtr<NotifyDragEvent>();
401 UpdateNotifyDragEvent(notifyEvent, point, dragEventType);
402 notifyEvent->SetResult(dragRet);
403 NotifyDragRegisterFrameNode(nodesForDragNotify_, dragEventType, notifyEvent);
404 }
405
OnDragStart(const Point & point,const RefPtr<FrameNode> & frameNode)406 void DragDropManager::OnDragStart(const Point& point, const RefPtr<FrameNode>& frameNode)
407 {
408 dragDropState_ = DragDropMgrState::DRAGGING;
409 NotifyDragFrameNode(point, DragEventType::START);
410 CHECK_NULL_VOID(frameNode);
411 preTargetFrameNode_ = frameNode;
412 draggedFrameNode_ = preTargetFrameNode_;
413 parentHitNodes_.emplace(frameNode->GetId());
414 }
415
OnDragStart(const Point & point)416 void DragDropManager::OnDragStart(const Point& point)
417 {
418 dragDropState_ = DragDropMgrState::DRAGGING;
419 NotifyDragFrameNode(point, DragEventType::START);
420 }
421
PrintDragFrameNode(const Point & point,const RefPtr<FrameNode> & dragFrameNode)422 void DragDropManager::PrintDragFrameNode(const Point& point, const RefPtr<FrameNode>& dragFrameNode)
423 {
424 CHECK_NULL_VOID(dragFrameNode);
425 auto container = Container::Current();
426 CHECK_NULL_VOID(container);
427 if (preTargetFrameNode_) {
428 TAG_LOGI(AceLogTag::ACE_DRAG, "Current windowId is %{public}d, drag position is (%{public}f, %{public}f),"
429 "PreTargetFrameNode is %{public}s, depth is %{public}d, id is %{public}s,"
430 "New find targetNode is %{public}s, depth is %{public}d, id is %{public}s.",
431 container->GetWindowId(), static_cast<float>(point.GetX()), static_cast<float>(point.GetY()),
432 preTargetFrameNode_->GetTag().c_str(), preTargetFrameNode_->GetDepth(),
433 preTargetFrameNode_->GetInspectorId()->c_str(),
434 dragFrameNode->GetTag().c_str(), dragFrameNode->GetDepth(), dragFrameNode->GetInspectorId()->c_str());
435 } else {
436 TAG_LOGI(AceLogTag::ACE_DRAG, "Current windowId is %{public}d, drag position is (%{public}f, %{public}f), "
437 "PreTargetFrameNode is nullptr, New find targetNode is %{public}s, depth is %{public}d, id is %{public}s.",
438 container->GetWindowId(), static_cast<float>(point.GetX()), static_cast<float>(point.GetY()),
439 dragFrameNode->GetTag().c_str(), dragFrameNode->GetDepth(), dragFrameNode->GetInspectorId()->c_str());
440 }
441 }
442
TransDragWindowToDragFwk(int32_t windowContainerId)443 void DragDropManager::TransDragWindowToDragFwk(int32_t windowContainerId)
444 {
445 if (isDragFwkShow_) {
446 return;
447 }
448 InteractionInterface::GetInstance()->SetDragWindowVisible(true);
449 isDragFwkShow_ = true;
450 auto subwindow = SubwindowManager::GetInstance()->GetSubwindow(windowContainerId);
451 CHECK_NULL_VOID(subwindow);
452 auto overlayManager = subwindow->GetOverlayManager();
453 overlayManager->RemovePixelMap();
454 SubwindowManager::GetInstance()->HidePreviewNG();
455 info_.scale = -1.0;
456 }
457
OnDragMoveOut(const PointerEvent & pointerEvent)458 void DragDropManager::OnDragMoveOut(const PointerEvent& pointerEvent)
459 {
460 Point point = pointerEvent.GetPoint();
461 auto container = Container::Current();
462 if (container && container->IsScenceBoardWindow()) {
463 if (IsDragged() && IsWindowConsumed()) {
464 SetIsWindowConsumed(false);
465 return;
466 }
467 }
468 SetIsWindowConsumed(false);
469 UpdateVelocityTrackerPoint(point, false);
470 UpdateDragListener(Point(-1, -1));
471 if (preTargetFrameNode_) {
472 TAG_LOGI(AceLogTag::ACE_DRAG, "Leave the current window, windowId is %{public}d,"
473 "drag Position is (%{public}f, %{public}f),"
474 "PreTargetFrameNode is %{public}s, depth is %{public}d, id is %{public}s",
475 container->GetWindowId(), static_cast<float>(point.GetX()), static_cast<float>(point.GetY()),
476 preTargetFrameNode_->GetTag().c_str(), preTargetFrameNode_->GetDepth(),
477 preTargetFrameNode_->GetInspectorId()->c_str());
478 FireOnDragEvent(preTargetFrameNode_, point, DragEventType::LEAVE, extraInfo_);
479 preTargetFrameNode_ = nullptr;
480 }
481 if (IsNeedScaleDragPreview()) {
482 TransDragWindowToDragFwk(Container::CurrentId());
483 }
484 }
485
OnDragMove(const PointerEvent & pointerEvent,const std::string & extraInfo)486 void DragDropManager::OnDragMove(const PointerEvent& pointerEvent, const std::string& extraInfo)
487 {
488 Point point = pointerEvent.GetPoint();
489 auto container = Container::Current();
490 CHECK_NULL_VOID(container);
491 if (container && container->IsScenceBoardWindow()) {
492 if (IsDragged() && IsWindowConsumed()) {
493 SetIsWindowConsumed(false);
494 return;
495 }
496 }
497 SetIsWindowConsumed(false);
498 SubwindowManager::GetInstance()->UpdateHideMenuOffsetNG(OffsetF(static_cast<float>(point.GetX()),
499 static_cast<float>(point.GetY())));
500 UpdateVelocityTrackerPoint(point, false);
501 UpdateDragListener(point);
502 auto dragFrameNode = FindDragFrameNodeByPosition(
503 static_cast<float>(point.GetX()), static_cast<float>(point.GetY()), DragType::COMMON, false);
504 if (!dragFrameNode) {
505 if (preTargetFrameNode_) {
506 TAG_LOGI(AceLogTag::ACE_DRAG, "Not find drag target node, current windowId is %{public}d,"
507 "drag Position is (%{public}f, %{public}f),"
508 "PreTargetFrameNode is %{public}s, depth is %{public}d, id is %{public}s",
509 container->GetWindowId(), static_cast<float>(point.GetX()), static_cast<float>(point.GetY()),
510 preTargetFrameNode_->GetTag().c_str(), preTargetFrameNode_->GetDepth(),
511 preTargetFrameNode_->GetInspectorId()->c_str());
512 FireOnDragEvent(preTargetFrameNode_, point, DragEventType::LEAVE, extraInfo);
513 preTargetFrameNode_ = nullptr;
514 }
515
516 if (!isMouseDragged_ || isDragWindowShow_) {
517 UpdateDragStyle(DragCursorStyleCore::MOVE);
518 }
519 return;
520 }
521
522 if (V2::UI_EXTENSION_COMPONENT_ETS_TAG == dragFrameNode->GetTag()) {
523 auto pattern = dragFrameNode->GetPattern<Pattern>();
524 pattern->HandleDragEvent(pointerEvent);
525 return;
526 }
527
528 if (dragFrameNode == preTargetFrameNode_) {
529 FireOnDragEvent(dragFrameNode, point, DragEventType::MOVE, extraInfo);
530 return;
531 }
532
533 if (preTargetFrameNode_) {
534 auto preRect = preTargetFrameNode_->GetTransformRectRelativeToWindow();
535 if (!preRect.IsInnerRegion(PointF(static_cast<float>(point.GetX()), static_cast<float>(point.GetY())))) {
536 FireOnDragEvent(preTargetFrameNode_, point, DragEventType::LEAVE, extraInfo);
537 }
538 }
539 PrintDragFrameNode(point, dragFrameNode);
540 FireOnDragEvent(dragFrameNode, point, DragEventType::ENTER, extraInfo);
541 preTargetFrameNode_ = dragFrameNode;
542 }
543
OnDragEnd(const PointerEvent & pointerEvent,const std::string & extraInfo)544 void DragDropManager::OnDragEnd(const PointerEvent& pointerEvent, const std::string& extraInfo)
545 {
546 Point point = pointerEvent.GetPoint();
547 dragDropState_ = DragDropMgrState::IDLE;
548 preTargetFrameNode_ = nullptr;
549 draggedFrameNode_ = nullptr;
550 hasNotifiedTransformation_ = false;
551 auto container = Container::Current();
552 if (container && container->IsScenceBoardWindow()) {
553 if (IsDragged() && IsWindowConsumed()) {
554 TAG_LOGD(AceLogTag::ACE_DRAG, "DragDropManager is dragged or window consumed. WindowId is %{public}d",
555 container->GetWindowId());
556 return;
557 }
558 }
559 HideDragPreviewOverlay();
560 if (isDragCancel_) {
561 TAG_LOGI(AceLogTag::ACE_DRAG, "DragDropManager is dragCancel, finish drag. WindowId is %{public}d.",
562 container->GetWindowId());
563 InteractionInterface::GetInstance()->SetDragWindowVisible(false);
564 DragDropRet dragDropRet { DragRet::DRAG_CANCEL, false, container->GetWindowId() };
565 InteractionInterface::GetInstance()->StopDrag(dragDropRet);
566 NotifyDragFrameNode(point, DragEventType::DROP, DragRet::DRAG_CANCEL);
567 summaryMap_.clear();
568 parentHitNodes_.clear();
569 ClearVelocityInfo();
570 return;
571 }
572 UpdateVelocityTrackerPoint(point, true);
573 auto dragFrameNode = FindDragFrameNodeByPosition(
574 static_cast<float>(point.GetX()), static_cast<float>(point.GetY()), DragType::COMMON, true);
575 if (!dragFrameNode) {
576 TAG_LOGI(AceLogTag::ACE_DRAG,
577 "DragDropManager onDragEnd, not find drop target, stop drag. WindowId is %{public}d.",
578 container->GetWindowId());
579 DragDropRet dragDropRet { DragRet::DRAG_FAIL, isMouseDragged_, container->GetWindowId() };
580 InteractionInterface::GetInstance()->StopDrag(dragDropRet);
581 NotifyDragFrameNode(point, DragEventType::DROP, DragRet::DRAG_FAIL);
582 summaryMap_.clear();
583 parentHitNodes_.clear();
584 return;
585 }
586 TAG_LOGI(AceLogTag::ACE_DRAG, "Current windowId is %{public}d, drag position is (%{public}f, %{public}f)."
587 "TargetNode is %{public}s, id is %{public}s",
588 container->GetWindowId(), static_cast<float>(point.GetX()), static_cast<float>(point.GetY()),
589 dragFrameNode->GetTag().c_str(), dragFrameNode->GetInspectorId()->c_str());
590 if (V2::UI_EXTENSION_COMPONENT_ETS_TAG == dragFrameNode->GetTag()) {
591 auto pattern = dragFrameNode->GetPattern<Pattern>();
592 pattern->HandleDragEvent(pointerEvent);
593 return;
594 }
595
596 auto eventHub = dragFrameNode->GetEventHub<EventHub>();
597 CHECK_NULL_VOID(eventHub);
598 RefPtr<OHOS::Ace::DragEvent> event = AceType::MakeRefPtr<OHOS::Ace::DragEvent>();
599 UpdateDragEvent(event, point);
600 auto extraParams = eventHub->GetDragExtraParams(extraInfo_, point, DragEventType::DROP);
601 eventHub->FireCustomerOnDragFunc(DragFuncType::DRAG_DROP, event, extraParams);
602 eventHub->HandleInternalOnDrop(event, extraParams);
603 ClearVelocityInfo();
604 SetIsDragged(false);
605 auto pipeline = PipelineContext::GetCurrentContext();
606 CHECK_NULL_VOID(pipeline);
607 auto dragResult = event->GetResult();
608 auto useCustomAnimation = event->IsUseCustomAnimation();
609 auto windowId = container->GetWindowId();
610 pipeline->AddAfterRenderTask([dragResult, useCustomAnimation, windowId]() {
611 TAG_LOGI(AceLogTag::ACE_DRAG,
612 "Stop drag, start do drop animation. UseCustomAnimation is %{public}d,"
613 "WindowId is %{public}d.",
614 useCustomAnimation, windowId);
615 InteractionInterface::GetInstance()->SetDragWindowVisible(!useCustomAnimation);
616 DragDropRet dragDropRet { dragResult, useCustomAnimation, windowId };
617 InteractionInterface::GetInstance()->StopDrag(dragDropRet);
618 });
619 NotifyDragFrameNode(point, DragEventType::DROP, event->GetResult());
620 dragFrameNode->MarkDirtyNode();
621 summaryMap_.clear();
622 parentHitNodes_.clear();
623 }
624
RequireSummary()625 void DragDropManager::RequireSummary()
626 {
627 std::map<std::string, int64_t> summary;
628 int32_t ret = InteractionInterface::GetInstance()->GetDragSummary(summary);
629 if (ret != 0) {
630 TAG_LOGI(AceLogTag::ACE_DRAG, "RequireSummary: Interaction GetSummary failed: %{public}d", ret);
631 }
632 std::string extraInfo;
633 ret = InteractionInterface::GetInstance()->GetDragExtraInfo(extraInfo);
634 if (ret != 0) {
635 TAG_LOGI(AceLogTag::ACE_DRAG, "GetExtraInfo: Interaction GetExtraInfo failed: %{public}d", ret);
636 }
637 previewRect_ = Rect(-1, -1, -1, -1);
638 extraInfo_ = extraInfo;
639 summaryMap_ = summary;
640 UpdateDragStyle();
641 }
642
ResetRecordSize(uint32_t recordSize)643 void DragDropManager::ResetRecordSize(uint32_t recordSize)
644 {
645 recordSize_ = recordSize;
646 }
647
GetRecordSize() const648 uint32_t DragDropManager::GetRecordSize() const
649 {
650 return recordSize_;
651 }
652
GetDragWindowRect(const Point & point)653 Rect DragDropManager::GetDragWindowRect(const Point& point)
654 {
655 if (!previewRect_.IsValid()) {
656 ShadowOffsetData shadowOffsetData { -1, -1, -1, -1 };
657 int ret = InteractionInterface::GetInstance()->GetShadowOffset(shadowOffsetData);
658 if (ret == 0) {
659 previewRect_ = Rect(
660 shadowOffsetData.offsetX,
661 shadowOffsetData.offsetY,
662 shadowOffsetData.width,
663 shadowOffsetData.height);
664 }
665 }
666 return previewRect_ + Offset(point.GetX(), point.GetY());
667 }
668
ClearSummary()669 void DragDropManager::ClearSummary()
670 {
671 previewRect_ = Rect(-1, -1, -1, -1);
672 summaryMap_.clear();
673 parentHitNodes_.clear();
674 ResetRecordSize();
675 }
676
OnTextDragEnd(float globalX,float globalY,const std::string & extraInfo)677 void DragDropManager::OnTextDragEnd(float globalX, float globalY, const std::string& extraInfo)
678 {
679 dragDropState_ = DragDropMgrState::IDLE;
680 auto dragFrameNode = FindDragFrameNodeByPosition(globalX, globalY, DragType::TEXT, true);
681 if (dragFrameNode) {
682 auto textFieldPattern = dragFrameNode->GetPattern<TextFieldPattern>();
683 if (textFieldPattern) {
684 textFieldPattern->InsertValue(extraInfo);
685 }
686 }
687 SetIsDragged(false);
688 currentId_ = -1;
689 }
690
onDragCancel()691 void DragDropManager::onDragCancel()
692 {
693 preTargetFrameNode_ = nullptr;
694 draggedFrameNode_ = nullptr;
695 }
696
FireOnDragEventWithDragType(const RefPtr<EventHub> & eventHub,DragEventType type,RefPtr<OHOS::Ace::DragEvent> & event,const std::string & extraParams)697 void DragDropManager::FireOnDragEventWithDragType(const RefPtr<EventHub>& eventHub, DragEventType type,
698 RefPtr<OHOS::Ace::DragEvent>& event, const std::string& extraParams)
699 {
700 switch (type) {
701 case DragEventType::ENTER: {
702 eventHub->FireCustomerOnDragFunc(DragFuncType::DRAG_ENTER, event, extraParams);
703 eventHub->FireOnDragEnter(event, extraParams);
704 break;
705 }
706 case DragEventType::MOVE: {
707 eventHub->FireCustomerOnDragFunc(DragFuncType::DRAG_MOVE, event, extraParams);
708 eventHub->FireOnDragMove(event, extraParams);
709 break;
710 }
711 case DragEventType::LEAVE: {
712 eventHub->FireCustomerOnDragFunc(DragFuncType::DRAG_LEAVE, event, extraParams);
713 eventHub->FireOnDragLeave(event, extraParams);
714 break;
715 }
716 case DragEventType::DROP: {
717 eventHub->FireCustomerOnDragFunc(DragFuncType::DRAG_DROP, event, extraParams);
718 eventHub->HandleInternalOnDrop(event, extraParams);
719 break;
720 }
721 default:
722 break;
723 }
724 }
725
FireOnDragEvent(const RefPtr<FrameNode> & frameNode,const Point & point,DragEventType type,const std::string & extraInfo)726 void DragDropManager::FireOnDragEvent(
727 const RefPtr<FrameNode>& frameNode, const Point& point, DragEventType type, const std::string& extraInfo)
728 {
729 auto eventHub = frameNode->GetEventHub<EventHub>();
730 CHECK_NULL_VOID(eventHub);
731 auto pipeline = PipelineContext::GetCurrentContext();
732 CHECK_NULL_VOID(pipeline);
733 if (!eventHub->HasOnDrop() && !eventHub->HasOnItemDrop() && !eventHub->HasCustomerOnDrop()) {
734 return;
735 }
736 auto extraParams = eventHub->GetDragExtraParams(extraInfo_.empty() ? extraInfo : extraInfo_, point, type);
737 RefPtr<OHOS::Ace::DragEvent> event = AceType::MakeRefPtr<OHOS::Ace::DragEvent>();
738 event->SetX((double)point.GetX());
739 event->SetY((double)point.GetY());
740 event->SetScreenX((double)point.GetScreenX());
741 event->SetScreenY((double)point.GetScreenY());
742 event->SetVelocity(velocityTracker_.GetVelocity());
743 event->SetSummary(summaryMap_);
744 event->SetPreviewRect(GetDragWindowRect(point));
745
746 FireOnEditableTextComponent(frameNode, type);
747 FireOnDragEventWithDragType(eventHub, type, event, extraParams);
748
749 if (isMouseDragged_ && !isDragWindowShow_) {
750 return;
751 }
752 if (event->GetResult() == DragRet::ENABLE_DROP) {
753 if (event->IsCopy()) {
754 UpdateDragStyle(DragCursorStyleCore::COPY);
755 } else {
756 UpdateDragStyle(DragCursorStyleCore::MOVE);
757 }
758 } else if (event->GetResult() == DragRet::DISABLE_DROP) {
759 UpdateDragStyle(DragCursorStyleCore::FORBIDDEN);
760 } else {
761 UpdateDragAllowDrop(frameNode, event->IsCopy());
762 }
763 }
764
OnItemDragStart(float globalX,float globalY,const RefPtr<FrameNode> & frameNode)765 void DragDropManager::OnItemDragStart(float globalX, float globalY, const RefPtr<FrameNode>& frameNode)
766 {
767 dragDropState_ = DragDropMgrState::DRAGGING;
768 preGridTargetFrameNode_ = frameNode;
769 draggedGridFrameNode_ = frameNode;
770 }
771
OnItemDragMove(float globalX,float globalY,int32_t draggedIndex,DragType dragType)772 void DragDropManager::OnItemDragMove(float globalX, float globalY, int32_t draggedIndex, DragType dragType)
773 {
774 auto pipeline = PipelineContext::GetCurrentContext();
775 CHECK_NULL_VOID(pipeline);
776
777 auto windowScale = GetWindowScale();
778 auto windowX = globalX * windowScale;
779 auto windowY = globalY * windowScale;
780 UpdateDragWindowPosition(static_cast<int32_t>(windowX), static_cast<int32_t>(windowY));
781
782 OHOS::Ace::ItemDragInfo itemDragInfo;
783 itemDragInfo.SetX(pipeline->ConvertPxToVp(Dimension(windowX, DimensionUnit::PX)));
784 itemDragInfo.SetY(pipeline->ConvertPxToVp(Dimension(windowY, DimensionUnit::PX)));
785
786 // use -1 for grid item not in eventGrid
787 auto getDraggedIndex = [draggedGrid = draggedGridFrameNode_, draggedIndex, dragType](
788 const RefPtr<FrameNode>& eventGrid) {
789 return (dragType == DragType::GRID) ? (eventGrid == draggedGrid ? draggedIndex : -1) : draggedIndex;
790 };
791
792 auto dragFrameNode = FindDragFrameNodeByPosition(windowX, windowY, dragType, false);
793 if (!dragFrameNode) {
794 if (preGridTargetFrameNode_) {
795 FireOnItemDragEvent(preGridTargetFrameNode_, dragType, itemDragInfo, DragEventType::LEAVE,
796 getDraggedIndex(preGridTargetFrameNode_));
797 preGridTargetFrameNode_ = nullptr;
798 }
799 return;
800 }
801
802 if (dragFrameNode == preGridTargetFrameNode_) {
803 int32_t insertIndex = GetItemIndex(dragFrameNode, dragType, windowX, windowY);
804 FireOnItemDragEvent(
805 dragFrameNode, dragType, itemDragInfo, DragEventType::MOVE, getDraggedIndex(dragFrameNode), insertIndex);
806 return;
807 }
808
809 if (preGridTargetFrameNode_) {
810 FireOnItemDragEvent(preGridTargetFrameNode_, dragType, itemDragInfo, DragEventType::LEAVE,
811 getDraggedIndex(preGridTargetFrameNode_));
812 }
813
814 FireOnItemDragEvent(dragFrameNode, dragType, itemDragInfo, DragEventType::ENTER, getDraggedIndex(dragFrameNode));
815 preGridTargetFrameNode_ = dragFrameNode;
816 }
817
GetWindowScale() const818 float DragDropManager::GetWindowScale() const
819 {
820 float scale = 1.0f;
821 auto container = Container::Current();
822 CHECK_NULL_RETURN(container, scale);
823 scale = container->GetWindowScale();
824 return scale;
825 }
826
OnItemDragEnd(float globalX,float globalY,int32_t draggedIndex,DragType dragType)827 void DragDropManager::OnItemDragEnd(float globalX, float globalY, int32_t draggedIndex, DragType dragType)
828 {
829 dragDropState_ = DragDropMgrState::IDLE;
830 auto pipeline = PipelineContext::GetCurrentContext();
831 CHECK_NULL_VOID(pipeline);
832 auto windowScale = GetWindowScale();
833 auto windowX = globalX * windowScale;
834 auto windowY = globalY * windowScale;
835
836 OHOS::Ace::ItemDragInfo itemDragInfo;
837 itemDragInfo.SetX(pipeline->ConvertPxToVp(Dimension(windowX, DimensionUnit::PX)));
838 itemDragInfo.SetY(pipeline->ConvertPxToVp(Dimension(windowY, DimensionUnit::PX)));
839
840 auto dragFrameNode = FindDragFrameNodeByPosition(windowX, windowY, dragType, true);
841 if (!dragFrameNode) {
842 // drag on one grid and drop on other area
843 if (draggedGridFrameNode_) {
844 if (dragType == DragType::GRID) {
845 auto eventHub = draggedGridFrameNode_->GetEventHub<GridEventHub>();
846 CHECK_NULL_VOID(eventHub);
847 eventHub->FireOnItemDrop(itemDragInfo, draggedIndex, -1, false);
848 } else {
849 auto eventHub = draggedGridFrameNode_->GetEventHub<ListEventHub>();
850 CHECK_NULL_VOID(eventHub);
851 eventHub->FireOnItemDrop(itemDragInfo, draggedIndex, -1, false);
852 }
853 }
854 } else {
855 int32_t insertIndex = GetItemIndex(dragFrameNode, dragType, windowX, windowY);
856 // drag and drop on the same grid
857 if (dragFrameNode == draggedGridFrameNode_) {
858 FireOnItemDropEvent(dragFrameNode, dragType, itemDragInfo, draggedIndex, insertIndex, true);
859 } else {
860 // drag and drop on different grid
861 bool isSuccess = FireOnItemDropEvent(dragFrameNode, dragType, itemDragInfo, -1, insertIndex, true);
862 if (draggedGridFrameNode_) {
863 FireOnItemDropEvent(draggedGridFrameNode_, dragType, itemDragInfo, draggedIndex, -1, isSuccess);
864 }
865 }
866 }
867
868 preGridTargetFrameNode_ = nullptr;
869 draggedGridFrameNode_ = nullptr;
870 }
871
onItemDragCancel()872 void DragDropManager::onItemDragCancel()
873 {
874 dragDropState_ = DragDropMgrState::IDLE;
875 preGridTargetFrameNode_ = nullptr;
876 draggedGridFrameNode_ = nullptr;
877 }
878
FireOnItemDragEvent(const RefPtr<FrameNode> & frameNode,DragType dragType,const OHOS::Ace::ItemDragInfo & itemDragInfo,DragEventType type,int32_t draggedIndex,int32_t insertIndex)879 void DragDropManager::FireOnItemDragEvent(const RefPtr<FrameNode>& frameNode, DragType dragType,
880 const OHOS::Ace::ItemDragInfo& itemDragInfo, DragEventType type, int32_t draggedIndex, int32_t insertIndex)
881 {
882 if (dragType == DragType::GRID) {
883 auto eventHub = frameNode->GetEventHub<GridEventHub>();
884 CHECK_NULL_VOID(eventHub);
885 switch (type) {
886 case DragEventType::ENTER:
887 eventHub->FireOnItemDragEnter(itemDragInfo);
888 break;
889 case DragEventType::MOVE:
890 eventHub->FireOnItemDragMove(itemDragInfo, draggedIndex, insertIndex);
891 break;
892 case DragEventType::LEAVE:
893 eventHub->FireOnItemDragLeave(itemDragInfo, draggedIndex);
894 break;
895 default:
896 break;
897 }
898 } else if (dragType == DragType::LIST) {
899 auto eventHub = frameNode->GetEventHub<ListEventHub>();
900 CHECK_NULL_VOID(eventHub);
901 switch (type) {
902 case DragEventType::ENTER:
903 eventHub->FireOnItemDragEnter(itemDragInfo);
904 break;
905 case DragEventType::MOVE:
906 eventHub->FireOnItemDragMove(itemDragInfo, draggedIndex, insertIndex);
907 break;
908 case DragEventType::LEAVE:
909 eventHub->FireOnItemDragLeave(itemDragInfo, draggedIndex);
910 break;
911 default:
912 break;
913 }
914 }
915 }
916
FireOnItemDropEvent(const RefPtr<FrameNode> & frameNode,DragType dragType,const OHOS::Ace::ItemDragInfo & itemDragInfo,int32_t draggedIndex,int32_t insertIndex,bool isSuccess)917 bool DragDropManager::FireOnItemDropEvent(const RefPtr<FrameNode>& frameNode, DragType dragType,
918 const OHOS::Ace::ItemDragInfo& itemDragInfo, int32_t draggedIndex, int32_t insertIndex, bool isSuccess)
919 {
920 if (dragType == DragType::GRID) {
921 auto eventHub = frameNode->GetEventHub<GridEventHub>();
922 CHECK_NULL_RETURN(eventHub, false);
923 return eventHub->FireOnItemDrop(itemDragInfo, draggedIndex, insertIndex, isSuccess);
924 } else if (dragType == DragType::LIST) {
925 auto eventHub = frameNode->GetEventHub<ListEventHub>();
926 CHECK_NULL_RETURN(eventHub, false);
927 return eventHub->FireOnItemDrop(itemDragInfo, draggedIndex, insertIndex, isSuccess);
928 }
929 return false;
930 }
931
GetItemIndex(const RefPtr<FrameNode> & frameNode,DragType dragType,float globalX,float globalY)932 int32_t DragDropManager::GetItemIndex(
933 const RefPtr<FrameNode>& frameNode, DragType dragType, float globalX, float globalY)
934 {
935 CHECK_NULL_RETURN(frameNode, -1);
936 if (dragType == DragType::GRID) {
937 auto eventHub = frameNode->GetEventHub<GridEventHub>();
938 CHECK_NULL_RETURN(eventHub, -1);
939 if (frameNode != draggedGridFrameNode_) {
940 return eventHub->GetInsertPosition(globalX, globalY);
941 }
942 auto itemFrameNode = frameNode->FindChildByPosition(globalX, globalY);
943 if (!itemFrameNode) {
944 if (eventHub->CheckPostionInGrid(globalX, globalY)) {
945 return eventHub->GetFrameNodeChildSize();
946 }
947 } else {
948 return eventHub->GetGridItemIndex(itemFrameNode);
949 }
950 } else if (dragType == DragType::LIST) {
951 auto eventHub = frameNode->GetEventHub<ListEventHub>();
952 CHECK_NULL_RETURN(eventHub, -1);
953 return eventHub->GetListItemIndexByPosition(globalX, globalY);
954 }
955 return -1;
956 }
957
AddDataToClipboard(const std::string & extraInfo)958 void DragDropManager::AddDataToClipboard(const std::string& extraInfo)
959 {
960 auto pipeline = PipelineContext::GetCurrentContext();
961 CHECK_NULL_VOID(pipeline);
962 if (!extraInfo.empty()) {
963 if (!newData_) {
964 newData_ = JsonUtil::Create(true);
965 newData_->Put("customDragInfo", extraInfo.c_str());
966 } else {
967 newData_->Replace("customDragInfo", extraInfo.c_str());
968 }
969 } else {
970 return;
971 }
972 if (!clipboard_) {
973 clipboard_ = ClipboardProxy::GetInstance()->GetClipboard(pipeline->GetTaskExecutor());
974 }
975 if (!addDataCallback_) {
976 auto callback = [weakManager = WeakClaim(this)](const std::string& data) {
977 auto dragDropManager = weakManager.Upgrade();
978 auto addData = dragDropManager->newData_->ToString();
979 CHECK_NULL_VOID(dragDropManager);
980 auto clipboardAllData = JsonUtil::Create(true);
981 clipboardAllData->Put("preData", data.c_str());
982 clipboardAllData->Put("newData", addData.c_str());
983 dragDropManager->clipboard_->SetData(clipboardAllData->ToString(), CopyOptions::Local, true);
984 };
985 addDataCallback_ = callback;
986 }
987 if (clipboard_) {
988 clipboard_->GetData(addDataCallback_, true);
989 }
990 }
991
GetExtraInfoFromClipboard(std::string & extraInfo)992 void DragDropManager::GetExtraInfoFromClipboard(std::string& extraInfo)
993 {
994 auto pipeline = PipelineContext::GetCurrentContext();
995 CHECK_NULL_VOID(pipeline);
996
997 if (!clipboard_) {
998 clipboard_ = ClipboardProxy::GetInstance()->GetClipboard(pipeline->GetTaskExecutor());
999 }
1000
1001 if (!getDataCallback_) {
1002 auto callback = [weak = WeakClaim(this)](const std::string& data) {
1003 auto manager = weak.Upgrade();
1004 CHECK_NULL_VOID(manager);
1005 auto json = JsonUtil::ParseJsonString(data);
1006 auto newData = JsonUtil::ParseJsonString(json->GetString("newData"));
1007 manager->extraInfo_ = newData->GetString("customDragInfo");
1008 };
1009 getDataCallback_ = callback;
1010 }
1011
1012 if (getDataCallback_ && clipboard_) {
1013 clipboard_->GetData(getDataCallback_, true);
1014 }
1015
1016 extraInfo = extraInfo_;
1017 }
1018
RestoreClipboardData()1019 void DragDropManager::RestoreClipboardData()
1020 {
1021 auto pipeline = PipelineContext::GetCurrentContext();
1022 CHECK_NULL_VOID(pipeline);
1023
1024 if (!clipboard_) {
1025 clipboard_ = ClipboardProxy::GetInstance()->GetClipboard(pipeline->GetTaskExecutor());
1026 }
1027
1028 if (!deleteDataCallback_) {
1029 auto callback = [weakManager = WeakClaim(this)](const std::string& data) {
1030 auto dragDropManager = weakManager.Upgrade();
1031 CHECK_NULL_VOID(dragDropManager);
1032 auto json = JsonUtil::ParseJsonString(data);
1033 if (json->Contains("preData")) {
1034 dragDropManager->clipboard_->SetData(json->GetString("preData"));
1035 }
1036 };
1037 deleteDataCallback_ = callback;
1038 }
1039 if (clipboard_) {
1040 clipboard_->GetData(deleteDataCallback_, true);
1041 }
1042 }
1043
DestroyDragWindow()1044 void DragDropManager::DestroyDragWindow()
1045 {
1046 if (dragWindow_ != nullptr) {
1047 dragWindow_->Destroy();
1048 dragWindow_ = nullptr;
1049 }
1050 ResetRecordSize();
1051 if (dragWindowRootNode_) {
1052 dragWindowRootNode_ = nullptr;
1053 }
1054 SetIsDragged(false);
1055 SetIsDragWindowShow(false);
1056 previewRect_ = Rect(-1, -1, -1, -1);
1057 isMouseDragged_ = false;
1058 currentId_ = -1;
1059 }
1060
CancelItemDrag()1061 void DragDropManager::CancelItemDrag()
1062 {
1063 if (draggedGridFrameNode_) {
1064 auto listEventHub = draggedGridFrameNode_->GetEventHub<ListEventHub>();
1065 if (listEventHub) {
1066 listEventHub->HandleOnItemDragCancel();
1067 return;
1068 }
1069 auto gridEventHub = draggedGridFrameNode_->GetEventHub<GridEventHub>();
1070 if (gridEventHub) {
1071 gridEventHub->HandleOnItemDragCancel();
1072 return;
1073 }
1074 }
1075 }
1076
CreateFrameworkDragDropProxy()1077 RefPtr<DragDropProxy> DragDropManager::CreateFrameworkDragDropProxy()
1078 {
1079 SetIsDragged(true);
1080 isDragCancel_ = false;
1081 currentId_ = ++g_proxyId;
1082 return MakeRefPtr<DragDropProxy>(currentId_);
1083 }
1084
UpdateNotifyDragEvent(RefPtr<NotifyDragEvent> & notifyEvent,const Point & point,const DragEventType dragEventType)1085 void DragDropManager::UpdateNotifyDragEvent(
1086 RefPtr<NotifyDragEvent>& notifyEvent, const Point& point, const DragEventType dragEventType)
1087 {
1088 notifyEvent->SetX((double)point.GetX());
1089 notifyEvent->SetY((double)point.GetY());
1090 notifyEvent->SetScreenX((double)point.GetScreenX());
1091 notifyEvent->SetScreenY((double)point.GetScreenY());
1092 if (dragEventType != DragEventType::START) {
1093 if (dragEventType != DragEventType::DROP) {
1094 notifyEvent->SetVelocity(velocityTracker_.GetVelocity());
1095 }
1096 notifyEvent->SetSummary(summaryMap_);
1097 notifyEvent->SetPreviewRect(GetDragWindowRect(point));
1098 }
1099 }
1100
UpdateDragEvent(RefPtr<OHOS::Ace::DragEvent> & event,const Point & point)1101 void DragDropManager::UpdateDragEvent(RefPtr<OHOS::Ace::DragEvent>& event, const Point& point)
1102 {
1103 auto pipeline = PipelineContext::GetCurrentContext();
1104 CHECK_NULL_VOID(pipeline);
1105 event->SetX(point.GetX());
1106 event->SetY(point.GetY());
1107 event->SetScreenX(point.GetScreenX());
1108 event->SetScreenY(point.GetScreenY());
1109 event->SetVelocity(velocityTracker_.GetVelocity());
1110 std::string udKey;
1111 InteractionInterface::GetInstance()->GetUdKey(udKey);
1112 if (udKey.empty()) {
1113 event->SetIsGetDataSuccess(false);
1114 } else {
1115 event->SetUdKey(udKey);
1116 }
1117 int ret = InteractionInterface::GetInstance()->AddPrivilege();
1118 if (ret != 0 && SystemProperties::GetDebugEnabled()) {
1119 TAG_LOGI(AceLogTag::ACE_DRAG, "Interaction AddPrivilege in DragEnd with code:%{public}d", ret);
1120 }
1121 RefPtr<UnifiedData> udData = UdmfClient::GetInstance()->CreateUnifiedData();
1122 ret = UdmfClient::GetInstance()->GetData(udData, udKey);
1123 if (ret != 0) {
1124 event->SetIsGetDataSuccess(false);
1125 } else {
1126 event->SetIsGetDataSuccess(true);
1127 }
1128 auto unifiedData = udData;
1129 event->SetData(unifiedData);
1130 RequireSummary();
1131 event->SetSummary(summaryMap_);
1132 ShadowOffsetData shadowOffsetData { -1, -1, -1, -1 };
1133 ret = InteractionInterface::GetInstance()->GetShadowOffset(shadowOffsetData);
1134 if (ret == 0) {
1135 previewRect_ = Rect(
1136 point.GetX() + shadowOffsetData.offsetX,
1137 point.GetY() + shadowOffsetData.offsetY,
1138 shadowOffsetData.width,
1139 shadowOffsetData.height);
1140 event->SetPreviewRect(previewRect_);
1141 } else {
1142 TAG_LOGD(AceLogTag::ACE_DRAG, "Interaction GetShadowOffset in DragEnd with code:%{public}d", ret);
1143 event->SetPreviewRect(previewRect_ + Offset(point.GetX(), point.GetY()));
1144 }
1145 }
1146
GetExtraInfo()1147 std::string DragDropManager::GetExtraInfo()
1148 {
1149 return extraInfo_;
1150 }
1151
SetExtraInfo(const std::string & extraInfo)1152 void DragDropManager::SetExtraInfo(const std::string& extraInfo)
1153 {
1154 extraInfo_ = extraInfo;
1155 }
1156
ClearExtraInfo()1157 void DragDropManager::ClearExtraInfo()
1158 {
1159 extraInfo_.clear();
1160 }
1161
IsMsdpDragging() const1162 bool DragDropManager::IsMsdpDragging() const
1163 {
1164 DragState dragState;
1165 InteractionInterface::GetInstance()->GetDragState(dragState);
1166 return dragState == DragState::START;
1167 }
1168
ClearVelocityInfo()1169 void DragDropManager::ClearVelocityInfo()
1170 {
1171 velocityTracker_.Reset();
1172 }
1173
UpdateVelocityTrackerPoint(const Point & point,bool isEnd)1174 void DragDropManager::UpdateVelocityTrackerPoint(const Point& point, bool isEnd)
1175 {
1176 std::chrono::microseconds microseconds(GetMicroTickCount());
1177 TimeStamp curTime(microseconds);
1178 velocityTracker_.UpdateTrackerPoint(point.GetX(), point.GetY(), curTime, isEnd);
1179 }
1180
GetDragPreviewInfo(const RefPtr<OverlayManager> & overlayManager,DragPreviewInfo & dragPreviewInfo)1181 bool DragDropManager::GetDragPreviewInfo(const RefPtr<OverlayManager>& overlayManager,
1182 DragPreviewInfo& dragPreviewInfo)
1183 {
1184 if (!overlayManager->GetHasPixelMap()) {
1185 return false;
1186 }
1187 auto imageNode = overlayManager->GetPixelMapContentNode();
1188 if (!imageNode) {
1189 return false;
1190 }
1191 double maxWidth = GridSystemManager::GetInstance().GetMaxWidthWithColumnType(GridColumnType::DRAG_PANEL);
1192 auto width = imageNode->GetGeometryNode()->GetFrameRect().Width();
1193 dragPreviewInfo.scale = static_cast<float>(imageNode->GetPreviewScaleVal());
1194 dragPreviewInfo.height = imageNode->GetGeometryNode()->GetFrameRect().Height();
1195 dragPreviewInfo.width = static_cast<double>(width);
1196 dragPreviewInfo.maxWidth = maxWidth;
1197 dragPreviewInfo.imageNode = imageNode;
1198 return true;
1199 }
1200
IsNeedScaleDragPreview()1201 bool DragDropManager::IsNeedScaleDragPreview()
1202 {
1203 return info_.scale > 0 && info_.scale < 1.0f;
1204 }
1205
CalcDragPreviewDistanceWithPoint(const OHOS::Ace::Dimension & preserverHeight,int32_t x,int32_t y,const DragPreviewInfo & info)1206 double DragDropManager::CalcDragPreviewDistanceWithPoint(
1207 const OHOS::Ace::Dimension& preserverHeight, int32_t x, int32_t y, const DragPreviewInfo& info)
1208 {
1209 CHECK_NULL_RETURN(info.imageNode, 0.0);
1210 auto nodeOffset = info.imageNode->GetTransformRelativeOffset();
1211 auto renderContext = info.imageNode->GetRenderContext();
1212 CHECK_NULL_RETURN(renderContext, 0.0);
1213 auto width = renderContext->GetPaintRectWithTransform().Width();
1214 nodeOffset.SetX(nodeOffset.GetX() + width / 2);
1215 nodeOffset.SetY(nodeOffset.GetY() + preserverHeight.ConvertToPx());
1216 auto pipeline = PipelineContext::GetCurrentContext();
1217 if (pipeline) {
1218 auto windowOffset = pipeline->GetWindow()->GetCurrentWindowRect().GetOffset();
1219 x += windowOffset.GetX();
1220 y += windowOffset.GetY();
1221 }
1222 return sqrt(pow(nodeOffset.GetX() - x, 2) + pow(nodeOffset.GetY() - y, 2));
1223 }
1224
CalcDragMoveOffset(const OHOS::Ace::Dimension & preserverHeight,int32_t x,int32_t y,const DragPreviewInfo & info)1225 Offset DragDropManager::CalcDragMoveOffset(
1226 const OHOS::Ace::Dimension& preserverHeight, int32_t x, int32_t y, const DragPreviewInfo& info)
1227 {
1228 CHECK_NULL_RETURN(info.imageNode, Offset(0.0f, 0.0f));
1229 auto originPoint = info.imageNode->GetOffsetRelativeToWindow();
1230 if (IsNeedScaleDragPreview()) {
1231 originPoint.SetX(originPoint.GetX() + 0.5 * (1 - info.scale) * info.width + info.maxWidth / 2);
1232 originPoint.SetY(originPoint.GetY() + 0.5 * (1 - info.scale) * info.height + preserverHeight.ConvertToPx());
1233 }
1234 Offset newOffset { x - originPoint.GetX(), y - originPoint.GetY() };
1235 auto pipeline = PipelineContext::GetCurrentContext();
1236 if (pipeline) {
1237 auto windowOffset = pipeline->GetWindow()->GetCurrentWindowRect().GetOffset();
1238 newOffset.SetX(newOffset.GetX() + windowOffset.GetX());
1239 newOffset.SetY(newOffset.GetY() + windowOffset.GetY());
1240 }
1241 return newOffset;
1242 }
1243
DoDragMoveAnimate(const PointerEvent & pointerEvent)1244 void DragDropManager::DoDragMoveAnimate(const PointerEvent& pointerEvent)
1245 {
1246 if (!IsNeedScaleDragPreview()) {
1247 return;
1248 }
1249 auto pipeline = PipelineContext::GetCurrentContext();
1250 auto containerId = Container::CurrentId();
1251 auto subwindow = SubwindowManager::GetInstance()->GetSubwindow(containerId);
1252 CHECK_NULL_VOID(subwindow);
1253 auto overlayManager = subwindow->GetOverlayManager();
1254 CHECK_NULL_VOID(overlayManager);
1255 Dimension preserveHeight = 8.0_vp;
1256 auto x = pointerEvent.GetPoint().GetX();
1257 auto y = pointerEvent.GetPoint().GetY();
1258 Offset newOffset = CalcDragMoveOffset(preserveHeight, x, y, info_);
1259 AnimationOption option;
1260 const RefPtr<Curve> curve = AceType::MakeRefPtr<ResponsiveSpringMotion>(0.347f, 0.99f, 0.0f);
1261 constexpr int32_t animateDuration = 30;
1262 option.SetCurve(curve);
1263 option.SetDuration(animateDuration);
1264 auto distance = CalcDragPreviewDistanceWithPoint(preserveHeight, x, y, info_);
1265 option.SetOnFinishEvent([distance, weakManager = WeakClaim(this), containerId]() {
1266 constexpr decltype(distance) MAX_DIS = 5.0;
1267 if (distance < MAX_DIS) {
1268 auto dragDropManager = weakManager.Upgrade();
1269 if (dragDropManager) {
1270 dragDropManager->TransDragWindowToDragFwk(containerId);
1271 }
1272 }
1273 });
1274 auto renderContext = info_.imageNode->GetRenderContext();
1275 CHECK_NULL_VOID(renderContext);
1276 AnimationUtils::Animate(
1277 option,
1278 [renderContext, localPoint = newOffset]() {
1279 renderContext->UpdateTransformTranslate({ localPoint.GetX(), localPoint.GetY(), 0.0f });
1280 },
1281 option.GetOnFinishEvent());
1282 }
1283
DoDragStartAnimation(const RefPtr<OverlayManager> & overlayManager,const GestureEvent & event)1284 void DragDropManager::DoDragStartAnimation(const RefPtr<OverlayManager>& overlayManager, const GestureEvent& event)
1285 {
1286 CHECK_NULL_VOID(overlayManager);
1287 if (!(GetDragPreviewInfo(overlayManager, info_)) || !IsNeedScaleDragPreview()) {
1288 return;
1289 }
1290 isDragFwkShow_ = false;
1291 Dimension preserveHeight = 8.0_vp;
1292 Offset newOffset = CalcDragMoveOffset(preserveHeight,
1293 static_cast<int32_t>(event.GetGlobalLocation().GetX()), static_cast<int32_t>(event.GetGlobalLocation().GetY()),
1294 info_);
1295 AnimationOption option;
1296 const RefPtr<Curve> curve = AceType::MakeRefPtr<ResponsiveSpringMotion>(0.347f, 0.99f, 0.0f);
1297 constexpr int32_t animateDuration = 30;
1298 option.SetCurve(curve);
1299 option.SetDuration(animateDuration);
1300 auto renderContext = info_.imageNode->GetRenderContext();
1301 AnimationUtils::Animate(
1302 option,
1303 [renderContext, scale = info_.scale, newOffset]() {
1304 renderContext->UpdateTransformScale({ scale, scale });
1305 renderContext->UpdateTransformTranslate({ newOffset.GetX(), newOffset.GetY(), 0.0f });
1306 },
1307 option.GetOnFinishEvent());
1308 }
1309
FireOnEditableTextComponent(const RefPtr<FrameNode> & frameNode,DragEventType type)1310 void DragDropManager::FireOnEditableTextComponent(const RefPtr<FrameNode>& frameNode,
1311 DragEventType type)
1312 {
1313 CHECK_NULL_VOID(frameNode);
1314 auto frameTag = frameNode->GetTag();
1315 if (!IsEditableTextComponent(frameTag)) {
1316 TAG_LOGD(AceLogTag::ACE_DRAG,
1317 "This frame node is not editable text component %{public}s", frameTag.c_str());
1318 return;
1319 }
1320
1321 if (type != DragEventType::ENTER && type != DragEventType::LEAVE) {
1322 TAG_LOGD(AceLogTag::ACE_DRAG, "It is an invalid drag type %{public}d", type);
1323 return;
1324 }
1325
1326 if (type == DragEventType::LEAVE) {
1327 TAG_LOGI(AceLogTag::ACE_DRAG, "The current control has been dragged away.");
1328 hasNotifiedTransformation_ = false;
1329 return;
1330 }
1331
1332 if (hasNotifiedTransformation_) {
1333 TAG_LOGI(AceLogTag::ACE_DRAG, "Coordinates have been transformed.");
1334 return;
1335 }
1336
1337 auto ret = InteractionInterface::GetInstance()->EnterTextEditorArea(true);
1338 if (ret != 0) {
1339 TAG_LOGI(AceLogTag::ACE_DRAG, "Fail to notify entering text editor erea.");
1340 return;
1341 }
1342
1343 hasNotifiedTransformation_ = true;
1344 }
1345
SetDragResult(const DragNotifyMsgCore & notifyMessage,const RefPtr<OHOS::Ace::DragEvent> & dragEvent)1346 void DragDropManager::SetDragResult(
1347 const DragNotifyMsgCore& notifyMessage, const RefPtr<OHOS::Ace::DragEvent>& dragEvent)
1348 {
1349 DragRet result = DragRet::DRAG_FAIL;
1350 switch (notifyMessage.result) {
1351 case DragRet::DRAG_SUCCESS:
1352 result = DragRet::DRAG_SUCCESS;
1353 break;
1354 case DragRet::DRAG_FAIL:
1355 result = DragRet::DRAG_FAIL;
1356 break;
1357 case DragRet::DRAG_CANCEL:
1358 result = DragRet::DRAG_CANCEL;
1359 break;
1360 default:
1361 break;
1362 }
1363 CHECK_NULL_VOID(dragEvent);
1364 dragEvent->SetResult(result);
1365 }
1366 } // namespace OHOS::Ace::NG
1367