• 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/utils/utils.h"
21 #include "core/components_ng/pattern/grid/grid_event_hub.h"
22 #include "core/components_ng/pattern/list/list_event_hub.h"
23 #include "core/components_ng/pattern/root/root_pattern.h"
24 #include "core/components_ng/pattern/text_field/text_field_pattern.h"
25 #include "core/components_v2/inspector/inspector_constants.h"
26 #include "core/pipeline_ng/pipeline_context.h"
27 #include "base/utils/time_util.h"
28 
29 #ifdef ENABLE_DRAG_FRAMEWORK
30 #include "base/geometry/rect.h"
31 #include "base/msdp/device_status/interfaces/innerkits/interaction/include/interaction_manager.h"
32 #include "core/common/udmf/udmf_client.h"
33 #endif // ENABLE_DRAG_FRAMEWORK
34 
35 namespace OHOS::Ace::NG {
36 #ifdef ENABLE_DRAG_FRAMEWORK
37 using namespace Msdp::DeviceStatus;
38 #endif // ENABLE_DRAG_FRAMEWORK
39 namespace {
40 int64_t g_proxyId = 0;
41 #ifdef ENABLE_DRAG_FRAMEWORK
42 constexpr float PIXELMAP_POSITION_WIDTH = 0.5f;
43 constexpr float PIXELMAP_POSITION_HEIGHT = 0.2f;
44 #endif // ENABLE_DRAG_FRAMEWORK
45 } // namespace
46 
CreateAndShowDragWindow(const RefPtr<PixelMap> & pixelMap,const GestureEvent & info)47 RefPtr<DragDropProxy> DragDropManager::CreateAndShowDragWindow(
48     const RefPtr<PixelMap>& pixelMap, const GestureEvent& info)
49 {
50     CHECK_NULL_RETURN(pixelMap, nullptr);
51     SetIsDragged(true);
52     isDragCancel_ = false;
53 #if !defined(PREVIEW)
54     if (dragWindow_) {
55         LOGW("CreateAndShowDragWindow: There is a drag window, create drag window failed.");
56         return nullptr;
57     }
58 
59     CreateDragWindow(info, pixelMap->GetWidth(), pixelMap->GetHeight());
60     if (!dragWindow_) {
61         return nullptr;
62     }
63     dragWindow_->DrawPixelMap(pixelMap);
64 #endif
65     currentId_ = ++g_proxyId;
66     return MakeRefPtr<DragDropProxy>(currentId_);
67 }
68 
CreateAndShowDragWindow(const RefPtr<UINode> & customNode,const GestureEvent & info)69 RefPtr<DragDropProxy> DragDropManager::CreateAndShowDragWindow(
70     const RefPtr<UINode>& customNode, const GestureEvent& info)
71 {
72     dragWindowRootNode_ = CreateDragRootNode(customNode);
73     CHECK_NULL_RETURN(dragWindowRootNode_, nullptr);
74     SetIsDragged(true);
75     isDragCancel_ = false;
76 #if !defined(PREVIEW)
77     if (dragWindow_) {
78         LOGW("CreateAndShowDragWindow: There is a drag window, create drag window failed.");
79         return nullptr;
80     }
81 
82     auto geometryNode = dragWindowRootNode_->GetGeometryNode();
83     CHECK_NULL_RETURN(geometryNode, nullptr);
84 
85     auto frameRect = geometryNode->GetFrameSize();
86     CreateDragWindow(info, static_cast<uint32_t>(frameRect.Width()), static_cast<uint32_t>(frameRect.Height()));
87     if (!dragWindow_) {
88         return nullptr;
89     }
90     dragWindow_->DrawFrameNode(dragWindowRootNode_);
91 #endif
92     currentId_ = ++g_proxyId;
93     return MakeRefPtr<DragDropProxy>(currentId_);
94 }
95 
CreateTextDragDropProxy()96 RefPtr<DragDropProxy> DragDropManager::CreateTextDragDropProxy()
97 {
98     SetIsDragged(true);
99     isDragCancel_ = false;
100     currentId_ = ++g_proxyId;
101     return MakeRefPtr<DragDropProxy>(currentId_);
102 }
103 
CreateDragWindow(const GestureEvent & info,uint32_t width,uint32_t height)104 void DragDropManager::CreateDragWindow(const GestureEvent& info, uint32_t width, uint32_t height)
105 {
106     LOGI("CreateDragWindow");
107 #if !defined(PREVIEW)
108     auto pipeline = PipelineContext::GetCurrentContext();
109     CHECK_NULL_VOID(pipeline);
110     auto rect = pipeline->GetCurrentWindowRect();
111     dragWindow_ = DragWindow::CreateDragWindow("APP_DRAG_WINDOW",
112         static_cast<int32_t>(info.GetGlobalPoint().GetX()) + rect.Left(),
113         static_cast<int32_t>(info.GetGlobalPoint().GetY()) + rect.Top(), width, height);
114     if (dragWindow_) {
115         dragWindow_->SetOffset(rect.Left(), rect.Top());
116     } else {
117         LOGE("dragWindow create failed!");
118     }
119 #endif
120 }
121 
CreateDragRootNode(const RefPtr<UINode> & customNode)122 RefPtr<FrameNode> DragDropManager::CreateDragRootNode(const RefPtr<UINode>& customNode)
123 {
124     auto pipeline = PipelineContext::GetCurrentContext();
125     CHECK_NULL_RETURN(pipeline, nullptr);
126 
127     auto rootNode = FrameNode::CreateFrameNodeWithTree(
128         V2::ROOT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), MakeRefPtr<RootPattern>());
129     rootNode->SetActive(true);
130     rootNode->SetHostRootId(pipeline->GetInstanceId());
131     rootNode->SetHostPageId(-1);
132     rootNode->AddChild(customNode);
133     rootNode->AttachToMainTree();
134     rootNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
135     pipeline->FlushUITasks();
136     return rootNode;
137 }
138 
UpdateDragWindowPosition(int32_t globalX,int32_t globalY)139 void DragDropManager::UpdateDragWindowPosition(int32_t globalX, int32_t globalY)
140 {
141 #if !defined(PREVIEW)
142     CHECK_NULL_VOID(dragWindow_);
143     dragWindow_->MoveTo(globalX, globalY);
144 #endif
145 }
146 
147 #ifdef ENABLE_DRAG_FRAMEWORK
UpdatePixelMapPosition(int32_t globalX,int32_t globalY)148 void DragDropManager::UpdatePixelMapPosition(int32_t globalX, int32_t globalY)
149 {
150     auto pipeline = NG::PipelineContext::GetCurrentContext();
151     CHECK_NULL_VOID(pipeline);
152     auto manager = pipeline->GetOverlayManager();
153     CHECK_NULL_VOID(manager);
154     auto rootNode = pipeline->GetRootElement();
155     CHECK_NULL_VOID(rootNode);
156     if (manager->GetHasPixelMap()) {
157         auto columnNode = AceType::DynamicCast<NG::FrameNode>(rootNode->GetLastChild());
158         CHECK_NULL_VOID(columnNode);
159         auto imageNode = AceType::DynamicCast<NG::FrameNode>(columnNode->GetLastChild());
160         CHECK_NULL_VOID(imageNode);
161         auto geometryNode = imageNode->GetGeometryNode();
162         CHECK_NULL_VOID(geometryNode);
163         auto width = geometryNode->GetFrameSize().Width();
164         auto height = geometryNode->GetFrameSize().Height();
165         auto imageContext = imageNode->GetRenderContext();
166         CHECK_NULL_VOID(imageContext);
167         CHECK_NULL_VOID(draggedFrameNode_);
168         auto hub = draggedFrameNode_->GetOrCreateGestureEventHub();
169         CHECK_NULL_VOID(hub);
170         if (!hub->GetTextDraggable()) {
171             hub = columnNode->GetOrCreateGestureEventHub();
172             CHECK_NULL_VOID(hub);
173         }
174         RefPtr<PixelMap> pixelMap = hub->GetPixelMap();
175         CHECK_NULL_VOID(pixelMap);
176         float scale = NearZero(width) ? 1.0f : pixelMap->GetWidth() / width;
177         imageContext->UpdatePosition(NG::OffsetT<Dimension>(
178             Dimension(globalX - width * PIXELMAP_POSITION_WIDTH * scale - width / 2.0f + width * scale / 2.0f),
179             Dimension(globalY - height * PIXELMAP_POSITION_HEIGHT * scale - height / 2.0f + height * scale / 2.0f)));
180         imageContext->OnModifyDone();
181     }
182 }
183 #endif // ENABLE_DRAG_FRAMEWORK
184 
FindTargetInChildNodes(const RefPtr<UINode> parentNode,std::vector<RefPtr<FrameNode>> hitFrameNodes,bool findDrop)185 RefPtr<FrameNode> DragDropManager::FindTargetInChildNodes(
186     const RefPtr<UINode> parentNode, std::vector<RefPtr<FrameNode>> hitFrameNodes, bool findDrop)
187 {
188     CHECK_NULL_RETURN(parentNode, nullptr);
189     auto parentFrameNode = AceType::DynamicCast<FrameNode>(parentNode);
190     if (parentFrameNode && (!parentFrameNode->IsActive() || !parentFrameNode->IsVisible())) {
191         return nullptr;
192     }
193     auto children = parentNode->GetChildren();
194 
195     for (auto iter = children.rbegin(); iter != children.rend(); iter++) {
196         auto child = *iter;
197         if (child == nullptr) {
198             LOGW("when findding target in child nodes, find child is nullptr");
199             continue;
200         }
201         auto childFindResult = FindTargetInChildNodes(child, hitFrameNodes, findDrop);
202         if (childFindResult) {
203             return childFindResult;
204         }
205     }
206 
207     CHECK_NULL_RETURN_NOLOG(parentFrameNode, nullptr);
208     for (auto iter : hitFrameNodes) {
209         if (parentFrameNode == iter) {
210             auto eventHub = parentFrameNode->GetEventHub<EventHub>();
211             if (!eventHub) {
212                 continue;
213             }
214             if ((findDrop && (eventHub->HasOnDrop() || eventHub->HasOnItemDrop()))
215                 || (!findDrop && (eventHub->HasOnDrop() || eventHub->HasOnItemDrop()))) {
216                 return parentFrameNode;
217             }
218             if (SystemProperties::GetDebugEnabled()) {
219                 LOGW("Iter is in hitFrameNodes, but findDrop not suit with bind function.");
220             }
221         }
222     }
223     return nullptr;
224 }
225 
FindDragFrameNodeByPosition(float globalX,float globalY,DragType dragType,bool findDrop)226 RefPtr<FrameNode> DragDropManager::FindDragFrameNodeByPosition(
227     float globalX, float globalY, DragType dragType, bool findDrop)
228 {
229     std::map<int32_t, WeakPtr<FrameNode>> frameNodes;
230     switch (dragType) {
231         case DragType::COMMON:
232             frameNodes = dragFrameNodes_;
233             break;
234         case DragType::GRID:
235             frameNodes = gridDragFrameNodes_;
236             break;
237         case DragType::LIST:
238             frameNodes = listDragFrameNodes_;
239             break;
240         case DragType::TEXT:
241             frameNodes = textFieldDragFrameNodes_;
242             break;
243         default:
244             break;
245     }
246 
247     if (frameNodes.empty()) {
248         if (SystemProperties::GetDebugEnabled()) {
249             LOGW("FrameNodes which have onDragMove or onDrop set is empty, cannot find targetNode.");
250         }
251         return nullptr;
252     }
253 
254     PointF point(globalX, globalY);
255     std::vector<RefPtr<FrameNode>> hitFrameNodes;
256     for (auto iterOfFrameNode = frameNodes.begin(); iterOfFrameNode != frameNodes.end(); iterOfFrameNode++) {
257         auto frameNode = iterOfFrameNode->second.Upgrade();
258         if (!frameNode || !frameNode->IsVisible()) {
259             continue;
260         }
261         auto geometryNode = frameNode->GetGeometryNode();
262         if (!geometryNode) {
263             continue;
264         }
265         auto globalFrameRect = geometryNode->GetFrameRect();
266         globalFrameRect.SetOffset(frameNode->GetTransformRelativeOffset());
267         if (globalFrameRect.IsInRegion(point)) {
268             hitFrameNodes.push_back(frameNode);
269         }
270     }
271 
272     if (hitFrameNodes.empty()) {
273         if (SystemProperties::GetDebugEnabled()) {
274             LOGW("HitFrameNodes vector is empty, cannot find targetNode.");
275         }
276         return nullptr;
277     }
278     auto pipeline = NG::PipelineContext::GetCurrentContext();
279     CHECK_NULL_RETURN(pipeline, nullptr);
280     auto manager = pipeline->GetOverlayManager();
281     CHECK_NULL_RETURN(manager, nullptr);
282     auto rootNode = pipeline->GetRootElement();
283 
284     auto result = FindTargetInChildNodes(rootNode, hitFrameNodes, findDrop);
285     if (result) {
286         return result;
287     }
288     if (SystemProperties::GetDebugEnabled()) {
289         LOGW("Don't find targetNode by position in rootNode, return nullptr.");
290     }
291     return nullptr;
292 }
293 
CheckDragDropProxy(int64_t id) const294 bool DragDropManager::CheckDragDropProxy(int64_t id) const
295 {
296     return currentId_ == id;
297 }
298 
299 #ifdef ENABLE_DRAG_FRAMEWORK
UpdateDragAllowDrop(const RefPtr<FrameNode> & dragFrameNode,const bool isCopy)300 void DragDropManager::UpdateDragAllowDrop(const RefPtr<FrameNode>& dragFrameNode, const bool isCopy)
301 {
302     const auto& dragFrameNodeAllowDrop = dragFrameNode->GetAllowDrop();
303     if (dragFrameNodeAllowDrop.empty() || summaryMap_.empty()) {
304         auto recordSize = summaryMap_.size();
305         if (recordSize > 1) {
306             InteractionManager::GetInstance()->UpdateDragStyle(DragCursorStyle::MOVE);
307         } else {
308             InteractionManager::GetInstance()->UpdateDragStyle(DragCursorStyle::DEFAULT);
309         }
310         return;
311     }
312     for (const auto& it : summaryMap_) {
313         if (dragFrameNodeAllowDrop.find(it.first) == dragFrameNodeAllowDrop.end()) {
314             InteractionManager::GetInstance()->UpdateDragStyle(DragCursorStyle::FORBIDDEN);
315             return;
316         }
317     }
318     InteractionManager::GetInstance()->UpdateDragStyle(isCopy ? DragCursorStyle::COPY : DragCursorStyle::MOVE);
319 }
320 #endif // ENABLE_DRAG_FRAMEWORK
321 
OnDragStart(const Point & point,const RefPtr<FrameNode> & frameNode)322 void DragDropManager::OnDragStart(const Point& point, const RefPtr<FrameNode>& frameNode)
323 {
324     CHECK_NULL_VOID(frameNode);
325     preTargetFrameNode_ = frameNode;
326     draggedFrameNode_ = preTargetFrameNode_;
327     if (SystemProperties::GetDebugEnabled()) {
328         LOGI("DragDropManager onDragStart. Dragged frameNode is %{public}s, depth is %{public}d.",
329             frameNode->GetTag().c_str(), frameNode->GetDepth());
330     }
331 }
332 
PrintDragFrameNode(const Point & point,const RefPtr<FrameNode> & dragFrameNode)333 void DragDropManager::PrintDragFrameNode(const Point& point, const RefPtr<FrameNode>& dragFrameNode)
334 {
335     CHECK_NULL_VOID(dragFrameNode);
336     if (SystemProperties::GetDebugEnabled()) {
337         if (preTargetFrameNode_) {
338             LOGI("Position is %{public}f and %{public}f.",
339                 static_cast<float>(point.GetX()), static_cast<float>(point.GetY()));
340             LOGI("PreTargetFrameNode is %{public}s, depth is %{public}d.",
341                 preTargetFrameNode_->GetTag().c_str(), preTargetFrameNode_->GetDepth());
342             LOGI("New find targetNode is %{public}s, depth is %{public}d.",
343                 dragFrameNode->GetTag().c_str(), dragFrameNode->GetDepth());
344         } else {
345             LOGI("Position is %{public}f and %{public}f.",
346                 static_cast<float>(point.GetX()), static_cast<float>(point.GetY()));
347             LOGI("PreTargetFrameNode is nullptr.");
348             LOGI("New find targetNode is %{public}s, depth is %{public}d.",
349                 dragFrameNode->GetTag().c_str(), dragFrameNode->GetDepth());
350         }
351     }
352 }
353 
OnDragMove(const Point & point,const std::string & extraInfo)354 void DragDropManager::OnDragMove(const Point& point, const std::string& extraInfo)
355 {
356 #ifdef ENABLE_DRAG_FRAMEWORK
357     auto container = Container::Current();
358     if (container && container->IsScenceBoardWindow()) {
359         if (IsDragged() && IsWindowConsumed()) {
360             LOGD("The event does not need to be handled");
361             SetIsWindowConsumed(false);
362             return;
363         }
364     }
365     SetIsWindowConsumed(false);
366 #endif // ENABLE_DRAG_FRAMEWORK
367     UpdateVelocityTrackerPoint(point, false);
368     auto dragFrameNode = FindDragFrameNodeByPosition(
369         static_cast<float>(point.GetX()), static_cast<float>(point.GetY()), DragType::COMMON, false);
370     PrintDragFrameNode(point, dragFrameNode);
371     if (!dragFrameNode) {
372         if (preTargetFrameNode_) {
373             FireOnDragEvent(preTargetFrameNode_, point, DragEventType::LEAVE, extraInfo);
374             preTargetFrameNode_ = nullptr;
375         }
376 
377 #ifdef ENABLE_DRAG_FRAMEWORK
378         if (!isMouseDragged_ || isDragWindowShow_) {
379             InteractionManager::GetInstance()->UpdateDragStyle(
380                 summaryMap_.size() > 1 ? DragCursorStyle::MOVE : DragCursorStyle::DEFAULT);
381         }
382 #endif // ENABLE_DRAG_FRAMEWORK
383         return;
384     }
385 
386     if (dragFrameNode == preTargetFrameNode_) {
387         FireOnDragEvent(dragFrameNode, point, DragEventType::MOVE, extraInfo);
388         return;
389     }
390 
391     if (preTargetFrameNode_) {
392         auto preRect = preTargetFrameNode_->GetTransformRectRelativeToWindow();
393         if (!preRect.IsInRegion(PointF(static_cast<float>(point.GetX()), static_cast<float>(point.GetY())))) {
394             FireOnDragEvent(preTargetFrameNode_, point, DragEventType::LEAVE, extraInfo);
395         }
396     }
397     FireOnDragEvent(dragFrameNode, point, DragEventType::ENTER, extraInfo);
398     preTargetFrameNode_ = dragFrameNode;
399 }
400 
401 #ifdef ENABLE_DRAG_FRAMEWORK
TranslateDragResult(DragRet dragResult)402 DragResult TranslateDragResult(DragRet dragResult)
403 {
404     switch (dragResult) {
405         case DragRet::DRAG_SUCCESS:
406             return DragResult::DRAG_SUCCESS;
407         case DragRet::DRAG_FAIL:
408             return DragResult::DRAG_FAIL;
409         case DragRet::DRAG_CANCEL:
410             return DragResult::DRAG_CANCEL;
411         default:
412             return DragResult::DRAG_SUCCESS;
413     }
414 }
415 #endif // ENABLE_DRAG_FRAMEWORK
416 
OnDragEnd(const Point & point,const std::string & extraInfo)417 void DragDropManager::OnDragEnd(const Point& point, const std::string& extraInfo)
418 {
419     preTargetFrameNode_ = nullptr;
420 #ifdef ENABLE_DRAG_FRAMEWORK
421     auto container = Container::Current();
422     if (container && container->IsScenceBoardWindow()) {
423         if (IsDragged() && IsWindowConsumed()) {
424             LOGD("The event does not need to be handled");
425             return;
426         }
427     }
428     if (isDragCancel_) {
429         if (SystemProperties::GetDebugEnabled()) {
430             LOGI("DragDropManager is dragCancel, finish drag.");
431         }
432         InteractionManager::GetInstance()->SetDragWindowVisible(false);
433         InteractionManager::GetInstance()->StopDrag(DragResult::DRAG_CANCEL, false);
434         summaryMap_.clear();
435         ClearVelocityInfo();
436         return;
437     }
438 #endif // ENABLE_DRAG_FRAMEWORK
439     UpdateVelocityTrackerPoint(point, true);
440     auto dragFrameNode = FindDragFrameNodeByPosition(
441         static_cast<float>(point.GetX()), static_cast<float>(point.GetY()), DragType::COMMON, true);
442     if (SystemProperties::GetDebugEnabled()) {
443         if (dragFrameNode) {
444             LOGI("Position is %{public}f and %{public}f. TargetNode is %{public}s.",
445                 static_cast<float>(point.GetX()), static_cast<float>(point.GetY()),
446                 dragFrameNode->GetTag().c_str());
447         } else {
448             LOGI("Position is %{public}f and %{public}f. TargetNode is nullptr.",
449                 static_cast<float>(point.GetX()), static_cast<float>(point.GetY()));
450         }
451     }
452 #ifdef ENABLE_DRAG_FRAMEWORK
453     if (!dragFrameNode) {
454         if (SystemProperties::GetDebugEnabled()) {
455             LOGW("DragDropManager onDragEnd, not find drop target, stop drag.");
456         }
457         InteractionManager::GetInstance()->StopDrag(DragResult::DRAG_FAIL, isMouseDragged_);
458         summaryMap_.clear();
459         return;
460     }
461 #endif // ENABLE_DRAG_FRAMEWORK
462     CHECK_NULL_VOID_NOLOG(dragFrameNode);
463     auto eventHub = dragFrameNode->GetEventHub<EventHub>();
464     CHECK_NULL_VOID(eventHub);
465     RefPtr<OHOS::Ace::DragEvent> event = AceType::MakeRefPtr<OHOS::Ace::DragEvent>();
466     auto extraParams = eventHub->GetDragExtraParams(extraInfo_, point, DragEventType::DROP);
467     UpdateDragEvent(event, point);
468     eventHub->FireOnDrop(event, extraParams);
469     ClearVelocityInfo();
470 #ifdef ENABLE_DRAG_FRAMEWORK
471     SetIsDragged(false);
472     if (SystemProperties::GetDebugEnabled()) {
473         LOGI("DragDropManager finish drop, start do drop animation. UseCustomAnimation is %{public}d.",
474             event->IsUseCustomAnimation());
475     }
476     auto pipeline = PipelineContext::GetCurrentContext();
477     CHECK_NULL_VOID(pipeline);
478     auto dragResult = TranslateDragResult(event->GetResult());
479     auto useCustomAnimation = event->IsUseCustomAnimation();
480     pipeline->SetDragCleanTask([dragResult, useCustomAnimation, isMouseDragged = isMouseDragged_]() {
481         InteractionManager::GetInstance()->SetDragWindowVisible(
482             isMouseDragged ? !isMouseDragged : !useCustomAnimation);
483         InteractionManager::GetInstance()->StopDrag(dragResult, isMouseDragged ? isMouseDragged : useCustomAnimation);
484     });
485     dragFrameNode->MarkDirtyNode();
486     summaryMap_.clear();
487 #endif // ENABLE_DRAG_FRAMEWORK
488 }
489 
490 #ifdef ENABLE_DRAG_FRAMEWORK
RequireSummary()491 void DragDropManager::RequireSummary()
492 {
493     std::string udKey;
494     InteractionManager::GetInstance()->GetUdKey(udKey);
495     if (SystemProperties::GetDebugEnabled()) {
496         if (udKey.empty()) {
497             LOGW("Requiry summary get empty udKey.");
498         } else {
499             LOGI("Requiry summary get udKey %{public}s", udKey.c_str());
500         }
501     }
502     std::map<std::string, int64_t> summary;
503     int32_t ret = UdmfClient::GetInstance()->GetSummary(udKey, summary);
504     if (ret != 0) {
505         LOGW("OnDragStart: UDMF GetSummary failed: %{public}d", ret);
506     }
507     summaryMap_ = summary;
508 }
509 
ClearSummary()510 void DragDropManager::ClearSummary()
511 {
512     summaryMap_.clear();
513 }
514 #endif // ENABLE_DRAG_FRAMEWORK
515 
OnTextDragEnd(float globalX,float globalY,const std::string & extraInfo)516 void DragDropManager::OnTextDragEnd(float globalX, float globalY, const std::string& extraInfo)
517 {
518     auto dragFrameNode = FindDragFrameNodeByPosition(globalX, globalY, DragType::TEXT, true);
519     if (dragFrameNode) {
520         auto textFieldPattern = dragFrameNode->GetPattern<TextFieldPattern>();
521         if (textFieldPattern) {
522             textFieldPattern->InsertValue(extraInfo);
523         }
524     }
525     LOGI("OnTextDragEnd");
526     SetIsDragged(false);
527     currentId_ = -1;
528 }
529 
onDragCancel()530 void DragDropManager::onDragCancel()
531 {
532     preTargetFrameNode_ = nullptr;
533     draggedFrameNode_ = nullptr;
534 }
535 
FireOnDragEvent(const RefPtr<FrameNode> & frameNode,const Point & point,DragEventType type,const std::string & extraInfo)536 void DragDropManager::FireOnDragEvent(
537     const RefPtr<FrameNode>& frameNode, const Point& point, DragEventType type, const std::string& extraInfo)
538 {
539     auto eventHub = frameNode->GetEventHub<EventHub>();
540     CHECK_NULL_VOID(eventHub);
541     auto pipeline = PipelineContext::GetCurrentContext();
542     CHECK_NULL_VOID(pipeline);
543 
544     auto extraParams = eventHub->GetDragExtraParams(extraInfo_.empty() ? extraInfo : extraInfo_, point, type);
545     RefPtr<OHOS::Ace::DragEvent> event = AceType::MakeRefPtr<OHOS::Ace::DragEvent>();
546     event->SetX((double)point.GetX());
547     event->SetY((double)point.GetY());
548     event->SetScreenX((double)point.GetScreenX());
549     event->SetScreenY((double)point.GetScreenY());
550     event->SetVelocity(velocityTracker_.GetVelocity());
551 
552     switch (type) {
553         case DragEventType::ENTER:
554             eventHub->FireOnDragEnter(event, extraParams);
555             break;
556         case DragEventType::MOVE:
557             eventHub->FireOnDragMove(event, extraParams);
558             break;
559         case DragEventType::LEAVE:
560             eventHub->FireOnDragLeave(event, extraParams);
561             break;
562         case DragEventType::DROP:
563             eventHub->FireOnDrop(event, extraParams);
564             break;
565         default:
566             break;
567     }
568 
569 #ifdef ENABLE_DRAG_FRAMEWORK
570     if (isMouseDragged_ && !isDragWindowShow_) {
571         return;
572     }
573     if (event->GetResult() == DragRet::ENABLE_DROP) {
574         if (event->IsCopy()) {
575             InteractionManager::GetInstance()->UpdateDragStyle(DragCursorStyle::COPY);
576         } else {
577             InteractionManager::GetInstance()->UpdateDragStyle(DragCursorStyle::MOVE);
578         }
579     } else if (event->GetResult() == DragRet::DISABLE_DROP) {
580         InteractionManager::GetInstance()->UpdateDragStyle(DragCursorStyle::FORBIDDEN);
581     } else {
582         UpdateDragAllowDrop(frameNode, event->IsCopy());
583     }
584 #endif // ENABLE_DRAG_FRAMEWORK
585 }
586 
OnItemDragStart(float globalX,float globalY,const RefPtr<FrameNode> & frameNode)587 void DragDropManager::OnItemDragStart(float globalX, float globalY, const RefPtr<FrameNode>& frameNode)
588 {
589     preGridTargetFrameNode_ = frameNode;
590     draggedGridFrameNode_ = frameNode;
591 }
592 
OnItemDragMove(float globalX,float globalY,int32_t draggedIndex,DragType dragType)593 void DragDropManager::OnItemDragMove(float globalX, float globalY, int32_t draggedIndex, DragType dragType)
594 {
595     auto pipeline = PipelineContext::GetCurrentContext();
596     CHECK_NULL_VOID(pipeline);
597 
598     UpdateDragWindowPosition(static_cast<int32_t>(globalX), static_cast<int32_t>(globalY));
599 
600     OHOS::Ace::ItemDragInfo itemDragInfo;
601     itemDragInfo.SetX(pipeline->ConvertPxToVp(Dimension(globalX, DimensionUnit::PX)));
602     itemDragInfo.SetY(pipeline->ConvertPxToVp(Dimension(globalY, DimensionUnit::PX)));
603 
604     // use -1 for grid item not in eventGrid
605     auto getDraggedIndex = [draggedGrid = draggedGridFrameNode_, draggedIndex, dragType](
606                                const RefPtr<FrameNode>& eventGrid) {
607         return (dragType == DragType::GRID) ? (eventGrid == draggedGrid ? draggedIndex : -1) : draggedIndex;
608     };
609 
610     auto dragFrameNode = FindDragFrameNodeByPosition(globalX, globalY, dragType, false);
611     if (!dragFrameNode) {
612         if (preGridTargetFrameNode_) {
613             FireOnItemDragEvent(preGridTargetFrameNode_, dragType, itemDragInfo, DragEventType::LEAVE,
614                 getDraggedIndex(preGridTargetFrameNode_));
615             preGridTargetFrameNode_ = nullptr;
616         }
617         return;
618     }
619 
620     if (dragFrameNode == preGridTargetFrameNode_) {
621         int32_t insertIndex = GetItemIndex(dragFrameNode, dragType, globalX, globalY);
622         FireOnItemDragEvent(
623             dragFrameNode, dragType, itemDragInfo, DragEventType::MOVE, getDraggedIndex(dragFrameNode), insertIndex);
624         return;
625     }
626 
627     if (preGridTargetFrameNode_) {
628         FireOnItemDragEvent(preGridTargetFrameNode_, dragType, itemDragInfo, DragEventType::LEAVE,
629             getDraggedIndex(preGridTargetFrameNode_));
630     }
631 
632     FireOnItemDragEvent(dragFrameNode, dragType, itemDragInfo, DragEventType::ENTER, getDraggedIndex(dragFrameNode));
633     preGridTargetFrameNode_ = dragFrameNode;
634 }
635 
OnItemDragEnd(float globalX,float globalY,int32_t draggedIndex,DragType dragType)636 void DragDropManager::OnItemDragEnd(float globalX, float globalY, int32_t draggedIndex, DragType dragType)
637 {
638     auto pipeline = PipelineContext::GetCurrentContext();
639     CHECK_NULL_VOID(pipeline);
640 
641     OHOS::Ace::ItemDragInfo itemDragInfo;
642     itemDragInfo.SetX(pipeline->ConvertPxToVp(Dimension(globalX, DimensionUnit::PX)));
643     itemDragInfo.SetY(pipeline->ConvertPxToVp(Dimension(globalY, DimensionUnit::PX)));
644 
645     auto dragFrameNode = FindDragFrameNodeByPosition(globalX, globalY, dragType, true);
646     if (!dragFrameNode) {
647         // drag on one grid and drop on other area
648         if (draggedGridFrameNode_) {
649             if (dragType == DragType::GRID) {
650                 auto eventHub = draggedGridFrameNode_->GetEventHub<GridEventHub>();
651                 CHECK_NULL_VOID(eventHub);
652                 eventHub->FireOnItemDrop(itemDragInfo, draggedIndex, -1, false);
653             } else {
654                 auto eventHub = draggedGridFrameNode_->GetEventHub<ListEventHub>();
655                 CHECK_NULL_VOID(eventHub);
656                 eventHub->FireOnItemDrop(itemDragInfo, draggedIndex, -1, false);
657             }
658         }
659     } else {
660         int32_t insertIndex = GetItemIndex(dragFrameNode, dragType, globalX, globalY);
661         // drag and drop on the same grid
662         if (dragFrameNode == draggedGridFrameNode_) {
663             FireOnItemDropEvent(dragFrameNode, dragType, itemDragInfo, draggedIndex, insertIndex, true);
664         } else {
665             // drag and drop on different grid
666             bool isSuccess = FireOnItemDropEvent(dragFrameNode, dragType, itemDragInfo, -1, insertIndex, true);
667             if (draggedGridFrameNode_) {
668                 FireOnItemDropEvent(draggedGridFrameNode_, dragType, itemDragInfo, draggedIndex, -1, isSuccess);
669             }
670         }
671     }
672 
673     preGridTargetFrameNode_ = nullptr;
674     draggedGridFrameNode_ = nullptr;
675 }
676 
onItemDragCancel()677 void DragDropManager::onItemDragCancel()
678 {
679     preGridTargetFrameNode_ = nullptr;
680     draggedGridFrameNode_ = nullptr;
681 }
682 
FireOnItemDragEvent(const RefPtr<FrameNode> & frameNode,DragType dragType,const OHOS::Ace::ItemDragInfo & itemDragInfo,DragEventType type,int32_t draggedIndex,int32_t insertIndex)683 void DragDropManager::FireOnItemDragEvent(const RefPtr<FrameNode>& frameNode, DragType dragType,
684     const OHOS::Ace::ItemDragInfo& itemDragInfo, DragEventType type, int32_t draggedIndex, int32_t insertIndex)
685 {
686     if (dragType == DragType::GRID) {
687         auto eventHub = frameNode->GetEventHub<GridEventHub>();
688         CHECK_NULL_VOID(eventHub);
689         switch (type) {
690             case DragEventType::ENTER:
691                 eventHub->FireOnItemDragEnter(itemDragInfo);
692                 break;
693             case DragEventType::MOVE:
694                 eventHub->FireOnItemDragMove(itemDragInfo, draggedIndex, insertIndex);
695                 break;
696             case DragEventType::LEAVE:
697                 eventHub->FireOnItemDragLeave(itemDragInfo, draggedIndex);
698                 break;
699             default:
700                 break;
701         }
702     } else if (dragType == DragType::LIST) {
703         auto eventHub = frameNode->GetEventHub<ListEventHub>();
704         CHECK_NULL_VOID(eventHub);
705         switch (type) {
706             case DragEventType::ENTER:
707                 eventHub->FireOnItemDragEnter(itemDragInfo);
708                 break;
709             case DragEventType::MOVE:
710                 eventHub->FireOnItemDragMove(itemDragInfo, draggedIndex, insertIndex);
711                 break;
712             case DragEventType::LEAVE:
713                 eventHub->FireOnItemDragLeave(itemDragInfo, draggedIndex);
714                 break;
715             default:
716                 break;
717         }
718     }
719 }
720 
FireOnItemDropEvent(const RefPtr<FrameNode> & frameNode,DragType dragType,const OHOS::Ace::ItemDragInfo & itemDragInfo,int32_t draggedIndex,int32_t insertIndex,bool isSuccess)721 bool DragDropManager::FireOnItemDropEvent(const RefPtr<FrameNode>& frameNode, DragType dragType,
722     const OHOS::Ace::ItemDragInfo& itemDragInfo, int32_t draggedIndex, int32_t insertIndex, bool isSuccess)
723 {
724     if (dragType == DragType::GRID) {
725         auto eventHub = frameNode->GetEventHub<GridEventHub>();
726         CHECK_NULL_RETURN(eventHub, false);
727         return eventHub->FireOnItemDrop(itemDragInfo, draggedIndex, insertIndex, isSuccess);
728     } else if (dragType == DragType::LIST) {
729         auto eventHub = frameNode->GetEventHub<ListEventHub>();
730         CHECK_NULL_RETURN(eventHub, false);
731         return eventHub->FireOnItemDrop(itemDragInfo, draggedIndex, insertIndex, isSuccess);
732     }
733     return false;
734 }
735 
GetItemIndex(const RefPtr<FrameNode> & frameNode,DragType dragType,float globalX,float globalY)736 int32_t DragDropManager::GetItemIndex(
737     const RefPtr<FrameNode>& frameNode, DragType dragType, float globalX, float globalY)
738 {
739     CHECK_NULL_RETURN(frameNode, -1);
740     if (dragType == DragType::GRID) {
741         auto eventHub = frameNode->GetEventHub<GridEventHub>();
742         CHECK_NULL_RETURN(eventHub, -1);
743         if (frameNode != draggedGridFrameNode_) {
744             return eventHub->GetInsertPosition(globalX, globalY);
745         }
746         auto itemFrameNode = frameNode->FindChildByPosition(globalX, globalY);
747         if (!itemFrameNode) {
748             if (eventHub->CheckPostionInGrid(globalX, globalY)) {
749                 return eventHub->GetFrameNodeChildSize();
750             }
751         } else {
752             return eventHub->GetGridItemIndex(itemFrameNode);
753         }
754     } else if (dragType == DragType::LIST) {
755         auto eventHub = frameNode->GetEventHub<ListEventHub>();
756         CHECK_NULL_RETURN(eventHub, -1);
757         return eventHub->GetListItemIndexByPosition(globalX, globalY);
758     }
759     return -1;
760 }
761 
AddDataToClipboard(const std::string & extraInfo)762 void DragDropManager::AddDataToClipboard(const std::string& extraInfo)
763 {
764     auto pipeline = PipelineContext::GetCurrentContext();
765     CHECK_NULL_VOID(pipeline);
766     if (!extraInfo.empty()) {
767         if (!newData_) {
768             newData_ = JsonUtil::Create(true);
769             newData_->Put("customDragInfo", extraInfo.c_str());
770         } else {
771             newData_->Replace("customDragInfo", extraInfo.c_str());
772         }
773     } else {
774         return;
775     }
776     if (!clipboard_) {
777         clipboard_ = ClipboardProxy::GetInstance()->GetClipboard(pipeline->GetTaskExecutor());
778     }
779     if (!addDataCallback_) {
780         auto callback = [weakManager = WeakClaim(this)](const std::string& data) {
781             auto dragDropManager = weakManager.Upgrade();
782             auto addData = dragDropManager->newData_->ToString();
783             CHECK_NULL_VOID_NOLOG(dragDropManager);
784             auto clipboardAllData = JsonUtil::Create(true);
785             clipboardAllData->Put("preData", data.c_str());
786             clipboardAllData->Put("newData", addData.c_str());
787             dragDropManager->clipboard_->SetData(clipboardAllData->ToString(), CopyOptions::Local, true);
788         };
789         addDataCallback_ = callback;
790     }
791     if (clipboard_) {
792         clipboard_->GetData(addDataCallback_, true);
793     }
794 #ifdef ENABLE_DRAG_FRAMEWORK
795     extraInfo_ = extraInfo;
796 #endif // ENABLE_DRAG_FRAMEWORK
797 }
798 
GetExtraInfoFromClipboard(std::string & extraInfo)799 void DragDropManager::GetExtraInfoFromClipboard(std::string& extraInfo)
800 {
801     auto pipeline = PipelineContext::GetCurrentContext();
802     CHECK_NULL_VOID(pipeline);
803 
804     if (!clipboard_) {
805         clipboard_ = ClipboardProxy::GetInstance()->GetClipboard(pipeline->GetTaskExecutor());
806     }
807 
808     if (!getDataCallback_) {
809         auto callback = [weak = WeakClaim(this)](const std::string& data) {
810             auto manager = weak.Upgrade();
811             CHECK_NULL_VOID_NOLOG(manager);
812             auto json = JsonUtil::ParseJsonString(data);
813             auto newData = JsonUtil::ParseJsonString(json->GetString("newData"));
814             manager->extraInfo_ = newData->GetString("customDragInfo");
815         };
816         getDataCallback_ = callback;
817     }
818 
819     if (getDataCallback_ && clipboard_) {
820         clipboard_->GetData(getDataCallback_, true);
821     }
822 
823     extraInfo = extraInfo_;
824     if (SystemProperties::GetDebugEnabled()) {
825         LOGI("DragDropManager get extra info from clipBoard, extraInfo is %{public}s",
826             extraInfo_.c_str());
827     }
828 }
829 
RestoreClipboardData()830 void DragDropManager::RestoreClipboardData()
831 {
832     auto pipeline = PipelineContext::GetCurrentContext();
833     CHECK_NULL_VOID(pipeline);
834 
835     if (!clipboard_) {
836         clipboard_ = ClipboardProxy::GetInstance()->GetClipboard(pipeline->GetTaskExecutor());
837     }
838 
839     if (!deleteDataCallback_) {
840         auto callback = [weakManager = WeakClaim(this)](const std::string& data) {
841             auto dragDropManager = weakManager.Upgrade();
842             CHECK_NULL_VOID_NOLOG(dragDropManager);
843             auto json = JsonUtil::ParseJsonString(data);
844             if (json->Contains("preData")) {
845                 dragDropManager->clipboard_->SetData(json->GetString("preData"));
846             }
847         };
848         deleteDataCallback_ = callback;
849     }
850     if (clipboard_) {
851         clipboard_->GetData(deleteDataCallback_, true);
852     }
853 }
854 
DestroyDragWindow()855 void DragDropManager::DestroyDragWindow()
856 {
857 #if !defined(PREVIEW) && !defined(ENABLE_DRAG_FRAMEWORK)
858     CHECK_NULL_VOID(dragWindow_);
859     dragWindow_->Destroy();
860     dragWindow_ = nullptr;
861 #elif defined(ENABLE_DRAG_FRAMEWORK)
862     if (dragWindow_ != nullptr) {
863         dragWindow_->Destroy();
864         dragWindow_ = nullptr;
865     }
866 #endif // ENABLE_DRAG_FRAMEWORK
867     if (dragWindowRootNode_) {
868         dragWindowRootNode_ = nullptr;
869     }
870     LOGI("DestroyDragWindow");
871     SetIsDragged(false);
872     SetIsDragWindowShow(false);
873     isMouseDragged_ = false;
874     currentId_ = -1;
875 }
876 
877 #ifdef ENABLE_DRAG_FRAMEWORK
CreateFrameworkDragDropProxy()878 RefPtr<DragDropProxy> DragDropManager::CreateFrameworkDragDropProxy()
879 {
880     SetIsDragged(true);
881     isDragCancel_ = false;
882     currentId_ = ++g_proxyId;
883     return MakeRefPtr<DragDropProxy>(currentId_);
884 }
885 #endif // ENABLE_DRAG_FRAMEWORK
886 
UpdateDragEvent(RefPtr<OHOS::Ace::DragEvent> & event,const Point & point)887 void DragDropManager::UpdateDragEvent(RefPtr<OHOS::Ace::DragEvent>& event, const Point& point)
888 {
889     auto pipeline = PipelineContext::GetCurrentContext();
890     CHECK_NULL_VOID(pipeline);
891     event->SetX(point.GetX());
892     event->SetY(point.GetY());
893     event->SetScreenX(point.GetScreenX());
894     event->SetScreenY(point.GetScreenY());
895 #ifdef ENABLE_DRAG_FRAMEWORK
896     std::string udKey;
897     InteractionManager::GetInstance()->GetUdKey(udKey);
898     if (udKey.empty()) {
899         LOGW("InteractionManager GetUdkey is null");
900         event->SetIsGetDataSuccess(false);
901     } else {
902         event->SetUdKey(udKey);
903     }
904     RefPtr<UnifiedData> udData = UdmfClient::GetInstance()->CreateUnifiedData();
905     int ret = UdmfClient::GetInstance()->GetData(udData, udKey);
906     if (ret != 0) {
907         LOGW("UDMF GetData failed: %{public}d", ret);
908         event->SetIsGetDataSuccess(false);
909     } else {
910         event->SetIsGetDataSuccess(true);
911     }
912     auto unifiedData = udData;
913     event->SetData(unifiedData);
914     int x = -1;
915     int y = -1;
916     int width = -1;
917     int height = -1;
918     int retOffset = InteractionManager::GetInstance()->GetShadowOffset(x, y, width, height);
919     if (retOffset == 0) {
920         Rect rect(point.GetX() + x, point.GetY() + y, width, height);
921         event->SetPreviewRect(rect);
922     } else {
923         Rect rect(x, y, width, height);
924         event->SetPreviewRect(rect);
925         LOGW("InteractionManager GetShadowOffset is failed:%{public}d", retOffset);
926     }
927 #endif // ENABLE_DRAG_FRAMEWORK
928 }
929 
930 #ifdef ENABLE_DRAG_FRAMEWORK
GetExtraInfo()931 std::string DragDropManager::GetExtraInfo()
932 {
933     return extraInfo_;
934 }
935 
SetExtraInfo(const std::string & extraInfo)936 void DragDropManager::SetExtraInfo(const std::string& extraInfo)
937 {
938     extraInfo_ = extraInfo;
939 }
940 
ClearExtraInfo()941 void DragDropManager::ClearExtraInfo()
942 {
943     extraInfo_.clear();
944 }
945 #endif // ENABLE_DRAG_FRAMEWORK
946 
ClearVelocityInfo()947 void DragDropManager::ClearVelocityInfo()
948 {
949     velocityTracker_.Reset();
950 }
951 
UpdateVelocityTrackerPoint(const Point & point,bool isEnd)952 void DragDropManager::UpdateVelocityTrackerPoint(const Point& point, bool isEnd)
953 {
954     std::chrono::microseconds microseconds(GetMicroTickCount());
955     TimeStamp curTime(microseconds);
956     velocityTracker_.UpdateTrackerPoint(point.GetX(), point.GetY(), curTime, isEnd);
957 }
958 
959 } // namespace OHOS::Ace::NG
960