• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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