1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "core/interfaces/native/node/drag_adapter_impl.h"
16 
17 #include "native_type.h"
18 
19 #include "base/image/pixel_map.h"
20 #include "base/utils/utils.h"
21 #include "core/common/ace_engine.h"
22 #include "core/common/udmf/udmf_client.h"
23 #include "core/components_ng/base/frame_node.h"
24 #include "core/components_ng/base/view_abstract.h"
25 #include "core/components_ng/event/gesture_event_hub.h"
26 #include "core/components_ng/manager/drag_drop/drag_drop_func_wrapper.h"
27 #include "core/components_ng/manager/drag_drop/utils/internal_drag_action.h"
28 #include "core/interfaces/arkoala/arkoala_api.h"
29 #include "core/pipeline_ng/pipeline_context.h"
30 
31 namespace OHOS::Ace::DragAdapter {
32 namespace {
DragActionConvert(ArkUIDragAction * dragAction,std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> internalDragAction)33 static void DragActionConvert(
34     ArkUIDragAction* dragAction, std::shared_ptr<OHOS::Ace::NG::ArkUIInteralDragAction> internalDragAction)
35 {
36     CHECK_NULL_VOID(dragAction);
37     CHECK_NULL_VOID(internalDragAction);
38     internalDragAction->pointer = dragAction->pointerId;
39     internalDragAction->size = dragAction->size;
40     auto* pixelMapTemp = reinterpret_cast<std::shared_ptr<void*>*>(dragAction->pixelmapArray);
41     for (int index = 0; index < dragAction->size; index++) {
42         auto pixelMap = PixelMap::CreatePixelMap(&pixelMapTemp[index]);
43         internalDragAction->pixelMapList.push_back(pixelMap);
44     }
45     internalDragAction->previewOption.isScaleEnabled = dragAction->dragPreviewOption.isScaleEnabled;
46     if (!internalDragAction->previewOption.isScaleEnabled) {
47         internalDragAction->previewOption.isDefaultShadowEnabled = dragAction->dragPreviewOption.isDefaultShadowEnabled;
48         internalDragAction->previewOption.isDefaultRadiusEnabled = dragAction->dragPreviewOption.isDefaultRadiusEnabled;
49     }
50     internalDragAction->previewOption.defaultAnimationBeforeLifting =
51         dragAction->dragPreviewOption.defaultAnimationBeforeLifting;
52     internalDragAction->previewOption.isMultiSelectionEnabled = dragAction->dragPreviewOption.isMultiSelectionEnabled;
53     internalDragAction->previewOption.isNumber = dragAction->dragPreviewOption.isNumberBadgeEnabled;
54     if (dragAction->dragPreviewOption.badgeNumber > 1) {
55         internalDragAction->previewOption.badgeNumber = dragAction->dragPreviewOption.badgeNumber;
56     } else {
57         internalDragAction->previewOption.isShowBadge = dragAction->dragPreviewOption.isShowBadge;
58     }
59     RefPtr<UnifiedData> udData = UdmfClient::GetInstance()->TransformUnifiedDataForNative(dragAction->unifiedData);
60     internalDragAction->unifiedData = udData;
61     internalDragAction->instanceId = dragAction->instanceId;
62     internalDragAction->touchPointX = dragAction->touchPointX;
63     internalDragAction->touchPointY = dragAction->touchPointY;
64     internalDragAction->hasTouchPoint = dragAction->hasTouchPoint;
65 }
66 
StartDrag(ArkUIDragAction * dragAction)67 ArkUI_Int32 StartDrag(ArkUIDragAction* dragAction)
68 {
69     CHECK_NULL_RETURN(dragAction, -1);
70     auto internalDragAction = std::make_shared<OHOS::Ace::NG::ArkUIInteralDragAction>();
71 
72     CHECK_NULL_RETURN(internalDragAction, -1);
73     auto callbacks = [listener = dragAction->listener, userData = dragAction->userData,
74                          instanceId = dragAction->instanceId](const DragNotifyMsg& dragNotifyMsg, int32_t status) {
75         auto pipelineContext = NG::PipelineContext::GetContextByContainerId(instanceId);
76         CHECK_NULL_VOID(pipelineContext);
77         auto manager = pipelineContext->GetDragDropManager();
78         CHECK_NULL_VOID(manager);
79         ArkUIDragEvent dragEvent;
80         dragEvent.dragResult = static_cast<int32_t>(dragNotifyMsg.result);
81         dragEvent.dragBehavior = static_cast<int32_t>(dragNotifyMsg.dragBehavior);
82 
83         auto action = manager->GetDragAction();
84         if (action != nullptr) {
85             action->hasHandle = false;
86         }
87         ArkUIDragAndDropInfo outInfo;
88         outInfo.status = status;
89         outInfo.dragEvent = &dragEvent;
90         CHECK_NULL_VOID(listener);
91         listener(&outInfo, userData);
92     };
93     internalDragAction->callback = callbacks;
94     DragActionConvert(dragAction, internalDragAction);
95     OHOS::Ace::NG::DragDropFuncWrapper::StartDragAction(internalDragAction);
96     return 0;
97 }
98 
RegisterStatusListener(ArkUIDragAction * dragAction,void * userData,DragStatusCallback listener)99 void RegisterStatusListener(ArkUIDragAction* dragAction, void* userData, DragStatusCallback listener)
100 {
101     CHECK_NULL_VOID(dragAction);
102     dragAction->listener = listener;
103     dragAction->userData = userData;
104 }
105 
UnRegisterStatusListener(ArkUIDragAction * dragAction)106 void UnRegisterStatusListener(ArkUIDragAction* dragAction)
107 {
108     CHECK_NULL_VOID(dragAction);
109     dragAction->listener = nullptr;
110     dragAction->userData = nullptr;
111 }
112 
CreateDragActionWithNode(ArkUINodeHandle node)113 ArkUIDragAction* CreateDragActionWithNode(ArkUINodeHandle node)
114 {
115     CHECK_NULL_RETURN(node, nullptr);
116     auto* frameNode = reinterpret_cast<NG::FrameNode*>(node);
117     CHECK_NULL_RETURN(frameNode, nullptr);
118     auto pipeline = frameNode->GetContext();
119     CHECK_NULL_RETURN(pipeline, nullptr);
120     auto* dragAction = new ArkUIDragAction();
121     CHECK_NULL_RETURN(dragAction, nullptr);
122     dragAction->instanceId = pipeline->GetInstanceId();
123     return dragAction;
124 }
125 
CreateDragActionWithContext(ArkUIContext * context)126 ArkUIDragAction* CreateDragActionWithContext(ArkUIContext* context)
127 {
128     CHECK_NULL_RETURN(context, nullptr);
129     auto* dragAction = new ArkUIDragAction();
130     CHECK_NULL_RETURN(dragAction, nullptr);
131     dragAction->instanceId = context->id;
132     return dragAction;
133 }
134 
SetDragPreview(ArkUINodeHandle node,void * dragPreview)135 void SetDragPreview(ArkUINodeHandle node, void* dragPreview)
136 {
137     auto* frameNode = reinterpret_cast<NG::FrameNode*>(node);
138     CHECK_NULL_VOID(frameNode);
139     NG::DragDropInfo dragPreviewInfo;
140     dragPreviewInfo.pixelMap = PixelMap::CreatePixelMap(dragPreview);
141     NG::ViewAbstract::SetDragPreview(frameNode, dragPreviewInfo);
142 }
143 
SetDragEventStrictReportingEnabledWithNode(bool enabled)144 void SetDragEventStrictReportingEnabledWithNode(bool enabled)
145 {
146     NG::ViewAbstract::SetDragEventStrictReportingEnabled(enabled);
147 }
148 
SetDragEventStrictReportingEnabledWithContext(ArkUI_Int32 instanceId,bool enabled)149 void SetDragEventStrictReportingEnabledWithContext(ArkUI_Int32 instanceId, bool enabled)
150 {
151     NG::ViewAbstract::SetDragEventStrictReportingEnabled(instanceId, enabled);
152 }
153 
154 } // namespace
GetDragAdapterAPI()155 const ArkUIDragAdapterAPI* GetDragAdapterAPI()
156 {
157     static const ArkUIDragAdapterAPI impl { StartDrag, RegisterStatusListener, UnRegisterStatusListener,
158         CreateDragActionWithNode, CreateDragActionWithContext, SetDragPreview,
159         SetDragEventStrictReportingEnabledWithNode, SetDragEventStrictReportingEnabledWithContext };
160     return &impl;
161 }
162 } // namespace OHOS::Ace::DragAdapter
163