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/node_drag_modifier.h"
16 
17 #include <cstddef>
18 #include <cstdint>
19 #include <string>
20 #include <vector>
21 
22 #include "interfaces/native/native_type.h"
23 #include "interfaces/native/node/node_model.h"
24 #include "securec.h"
25 
26 #include "base/geometry/ng/vector.h"
27 #include "base/geometry/shape.h"
28 #include "base/image/pixel_map.h"
29 #include "base/log/log_wrapper.h"
30 #include "base/memory/ace_type.h"
31 #include "base/utils/system_properties.h"
32 #include "base/utils/utils.h"
33 #include "bridge/common/utils/utils.h"
34 #include "core/animation/animation_pub.h"
35 #include "core/animation/curves.h"
36 #include "core/common/ime/text_input_type.h"
37 #include "core/common/udmf/udmf_client.h"
38 #include "core/components/common/layout/constants.h"
39 #include "core/components/common/properties/animation_option.h"
40 #include "core/components/common/properties/color.h"
41 #include "core/components/common/properties/decoration.h"
42 #include "core/components/common/properties/shadow.h"
43 #include "core/components/theme/shadow_theme.h"
44 #include "core/components_ng/base/frame_node.h"
45 #include "core/components_ng/base/view_abstract.h"
46 #include "core/components_ng/base/view_abstract_model_ng.h"
47 #include "core/components_ng/pattern/shape/shape_abstract_model_ng.h"
48 #include "core/components_ng/pattern/text/span_model_ng.h"
49 #include "core/components_ng/property/transition_property.h"
50 #include "core/event/axis_event.h"
51 #include "core/gestures/drag_event.h"
52 #include "core/image/image_source_info.h"
53 #include "core/interfaces/arkoala/arkoala_api.h"
54 #include "core/interfaces/native/node/node_api.h"
55 #include "core/interfaces/native/node/touch_event_convertor.h"
56 #include "core/interfaces/native/node/view_model.h"
57 
58 namespace OHOS::Ace::NG {
59 namespace NodeModifier {
CalculateModifierKeyState(const std::vector<OHOS::Ace::KeyCode> & status)60 uint64_t CalculateModifierKeyState(const std::vector<OHOS::Ace::KeyCode>& status)
61 {
62     uint64_t modifierKeysState = 0;
63     // check ctrl
64     if ((std::find(status.begin(), status.end(), OHOS::Ace::KeyCode::KEY_CTRL_LEFT) != std::end(status)) ||
65         (std::find(status.begin(), status.end(), OHOS::Ace::KeyCode::KEY_CTRL_RIGHT) != std::end(status))) {
66         modifierKeysState |= ARKUI_MODIFIER_KEY_CTRL;
67     }
68     // check alt
69     if ((std::find(status.begin(), status.end(), OHOS::Ace::KeyCode::KEY_ALT_LEFT) != std::end(status)) ||
70         (std::find(status.begin(), status.end(), OHOS::Ace::KeyCode::KEY_ALT_RIGHT) != std::end(status))) {
71         modifierKeysState |= ARKUI_MODIFIER_KEY_ALT;
72     }
73     // check shift
74     if ((std::find(status.begin(), status.end(), OHOS::Ace::KeyCode::KEY_SHIFT_LEFT) != std::end(status)) ||
75         (std::find(status.begin(), status.end(), OHOS::Ace::KeyCode::KEY_SHIFT_RIGHT) != std::end(status))) {
76         modifierKeysState |= ARKUI_MODIFIER_KEY_SHIFT;
77     }
78     // check fn
79     if (std::find(status.begin(), status.end(), OHOS::Ace::KeyCode::KEY_FN) != std::end(status)) {
80         modifierKeysState |= ARKUI_MODIFIER_KEY_FN;
81     }
82 
83     return modifierKeysState;
84 }
85 
SetDragEventProperty(const RefPtr<OHOS::Ace::DragEvent> & info,ArkUINodeEvent & event,std::vector<const char * > & strList,std::vector<std::string> & keepStr)86 void SetDragEventProperty(const RefPtr<OHOS::Ace::DragEvent>& info, ArkUINodeEvent& event,
87     std::vector<const char*>& strList, std::vector<std::string>& keepStr)
88 {
89     event.dragEvent.touchPointX = info->GetPreviewRect().GetOffset().GetX();
90     event.dragEvent.touchPointY = info->GetPreviewRect().GetOffset().GetY();
91 
92     event.dragEvent.windowX = info->GetX();
93     event.dragEvent.windowY = info->GetY();
94     event.dragEvent.displayX = info->GetDisplayX();
95     event.dragEvent.displayY = info->GetDisplayY();
96     event.dragEvent.screenX = info->GetScreenX();
97     event.dragEvent.screenY = info->GetScreenY();
98 
99     event.dragEvent.previewRectWidth = info->GetPreviewRect().Width();
100     event.dragEvent.previewRectHeight = info->GetPreviewRect().Height();
101     event.dragEvent.velocityX = info->GetVelocity().GetVelocityX();
102     event.dragEvent.velocityY = info->GetVelocity().GetVelocityY();
103     event.dragEvent.velocity = info->GetVelocity().GetVelocityValue();
104     event.dragEvent.modifierKeyState = NodeModifier::CalculateModifierKeyState(info->GetPressedKeyCodes());
105     auto summary = info->GetSummary();
106     event.dragEvent.dataTypesCount = static_cast<int32_t>(summary.size());
107 
108     int32_t index = 0;
109     int32_t maxLength = 0;
110     for (auto it = summary.begin(); it != summary.end(); it++) {
111         int32_t keyLength = static_cast<int32_t>(it->first.length());
112         maxLength = std::max(maxLength, keyLength);
113         keepStr[index] = it->first;
114         strList.push_back(keepStr[index].c_str());
115         ++index;
116     }
117     event.dragEvent.dataTypes = strList.data();
118     event.dragEvent.dataTypesMaxStrLength = maxLength + 1;
119 }
120 
SetOnDragDrop(ArkUINodeHandle node,void * extraParam)121 void SetOnDragDrop(ArkUINodeHandle node, void* extraParam)
122 {
123     auto* frameNode = reinterpret_cast<FrameNode*>(node);
124     CHECK_NULL_VOID(frameNode);
125     int32_t nodeId = frameNode->GetId();
126     auto onDragDrop = [frameNode, nodeId, extraParam](
127                           const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) -> void {
128         ArkUINodeEvent event;
129         event.kind = ArkUIEventCategory::DRAG_EVENT;
130         event.nodeId = nodeId;
131         event.extraParam = reinterpret_cast<intptr_t>(extraParam);
132         event.dragEvent.subKind = ON_DRAG_DROP;
133         auto summary = info->GetSummary();
134         std::vector<const char*> strList;
135         std::vector<std::string> keepStr(summary.size());
136 
137         SetDragEventProperty(info, event, strList, keepStr);
138         event.dragEvent.isSuitGetData = true;
139 
140         auto unifiedData = UdmfClient::GetInstance()->TransformUnifiedDataPtr(info->GetData());
141 
142         event.dragEvent.unifiedData = unifiedData;
143         event.dragEvent.dragBehavior = static_cast<ArkUI_Int32>(DragBehavior::UNKNOWN);
144         PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
145         SendArkUIAsyncEvent(&event);
146         info->UseCustomAnimation(event.dragEvent.useCustomDropAnimation);
147         info->SetResult(static_cast<DragRet>(event.dragEvent.dragResult));
148         info->SetDragBehavior(static_cast<DragBehavior>(event.dragEvent.dragBehavior));
149         info->SetCapi(true);
150     };
151     ViewAbstract::SetOnDrop(frameNode, onDragDrop);
152 }
153 
SetOnDragStart(ArkUINodeHandle node,void * extraParam)154 void SetOnDragStart(ArkUINodeHandle node, void* extraParam)
155 {
156     auto* frameNode = reinterpret_cast<FrameNode*>(node);
157     CHECK_NULL_VOID(frameNode);
158     int32_t nodeId = frameNode->GetId();
159     auto onDragStart = [frameNode, nodeId, extraParam](const RefPtr<OHOS::Ace::DragEvent>& info,
160                            const std::string& extraParams) -> NG::DragDropBaseInfo {
161         ArkUINodeEvent event;
162         event.kind = ArkUIEventCategory::DRAG_EVENT;
163         event.nodeId = nodeId;
164         event.extraParam = reinterpret_cast<intptr_t>(extraParam);
165         event.dragEvent.subKind = ON_DRAG_START;
166         auto summary = info->GetSummary();
167         std::vector<const char*> strList;
168         std::vector<std::string> keepStr(summary.size());
169 
170         SetDragEventProperty(info, event, strList, keepStr);
171         event.dragEvent.isSuitGetData = false;
172 
173         PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
174         SendArkUIAsyncEvent(&event);
175         RefPtr<UnifiedData> udData =
176             UdmfClient::GetInstance()->TransformUnifiedDataForNative(event.dragEvent.unifiedData);
177 
178         info->SetData(udData);
179         NG::DragDropBaseInfo dragDropInfo;
180         return dragDropInfo;
181     };
182     ViewAbstractModelNG::SetOnDragStart(frameNode, onDragStart);
183 }
184 
SetOnDragEnter(ArkUINodeHandle node,void * extraParam)185 void SetOnDragEnter(ArkUINodeHandle node, void* extraParam)
186 {
187     auto* frameNode = reinterpret_cast<FrameNode*>(node);
188     CHECK_NULL_VOID(frameNode);
189     int32_t nodeId = frameNode->GetId();
190     auto onDragEnter = [frameNode, nodeId, extraParam](
191                            const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
192         ArkUINodeEvent event;
193         event.kind = ArkUIEventCategory::DRAG_EVENT;
194         event.nodeId = nodeId;
195         event.extraParam = reinterpret_cast<intptr_t>(extraParam);
196         event.dragEvent.subKind = ON_DRAG_ENTER;
197 
198         auto summary = info->GetSummary();
199         std::vector<const char*> strList;
200         std::vector<std::string> keepStr(summary.size());
201 
202         SetDragEventProperty(info, event, strList, keepStr);
203         auto unifiedData = UdmfClient::GetInstance()->TransformUnifiedDataPtr(info->GetData());
204         event.dragEvent.dragBehavior = static_cast<ArkUI_Int32>(DragBehavior::UNKNOWN);
205         event.dragEvent.unifiedData = unifiedData;
206         event.dragEvent.isSuitGetData = false;
207 
208         PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
209         SendArkUIAsyncEvent(&event);
210         info->SetResult(static_cast<DragRet>(event.dragEvent.dragResult));
211         info->SetDragBehavior(static_cast<DragBehavior>(event.dragEvent.dragBehavior));
212         info->SetCapi(true);
213     };
214     ViewAbstract::SetOnDragEnter(frameNode, onDragEnter);
215 }
216 
SetOnDragMove(ArkUINodeHandle node,void * extraParam)217 void SetOnDragMove(ArkUINodeHandle node, void* extraParam)
218 {
219     auto* frameNode = reinterpret_cast<FrameNode*>(node);
220     CHECK_NULL_VOID(frameNode);
221     int32_t nodeId = frameNode->GetId();
222     auto onDragMove = [frameNode, nodeId, extraParam](
223                           const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
224         ArkUINodeEvent event;
225         event.kind = ArkUIEventCategory::DRAG_EVENT;
226         event.nodeId = nodeId;
227         event.extraParam = reinterpret_cast<intptr_t>(extraParam);
228         event.dragEvent.subKind = ON_DRAG_MOVE;
229         auto summary = info->GetSummary();
230         std::vector<const char*> strList;
231         std::vector<std::string> keepStr(summary.size());
232 
233         SetDragEventProperty(info, event, strList, keepStr);
234         auto unifiedData = UdmfClient::GetInstance()->TransformUnifiedDataPtr(info->GetData());
235         event.dragEvent.dragBehavior = static_cast<ArkUI_Int32>(DragBehavior::UNKNOWN);
236         event.dragEvent.unifiedData = unifiedData;
237         event.dragEvent.isSuitGetData = false;
238 
239         PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
240         SendArkUIAsyncEvent(&event);
241         info->SetResult(static_cast<DragRet>(event.dragEvent.dragResult));
242         info->SetDragBehavior(static_cast<DragBehavior>(event.dragEvent.dragBehavior));
243         info->SetCapi(true);
244     };
245     ViewAbstract::SetOnDragMove(frameNode, onDragMove);
246 }
247 
SetOnDragLeave(ArkUINodeHandle node,void * extraParam)248 void SetOnDragLeave(ArkUINodeHandle node, void* extraParam)
249 {
250     auto* frameNode = reinterpret_cast<FrameNode*>(node);
251     CHECK_NULL_VOID(frameNode);
252     int32_t nodeId = frameNode->GetId();
253     auto onDragLeave = [frameNode, nodeId, extraParam](
254                            const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
255         ArkUINodeEvent event;
256         event.kind = ArkUIEventCategory::DRAG_EVENT;
257         event.nodeId = nodeId;
258         event.extraParam = reinterpret_cast<intptr_t>(extraParam);
259         event.dragEvent.subKind = ON_DRAG_LEAVE;
260 
261         auto summary = info->GetSummary();
262         std::vector<const char*> strList;
263         std::vector<std::string> keepStr(summary.size());
264 
265         SetDragEventProperty(info, event, strList, keepStr);
266         auto unifiedData = UdmfClient::GetInstance()->TransformUnifiedDataPtr(info->GetData());
267         event.dragEvent.dragBehavior = static_cast<ArkUI_Int32>(DragBehavior::UNKNOWN);
268         event.dragEvent.unifiedData = unifiedData;
269         event.dragEvent.isSuitGetData = false;
270 
271         PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
272         SendArkUIAsyncEvent(&event);
273         info->SetResult(static_cast<DragRet>(event.dragEvent.dragResult));
274         info->SetDragBehavior(static_cast<DragBehavior>(event.dragEvent.dragBehavior));
275         info->SetCapi(true);
276     };
277     ViewAbstract::SetOnDragLeave(frameNode, onDragLeave);
278 }
279 
SetOnDragEnd(ArkUINodeHandle node,void * extraParam)280 void SetOnDragEnd(ArkUINodeHandle node, void* extraParam)
281 {
282     auto* frameNode = reinterpret_cast<FrameNode*>(node);
283     CHECK_NULL_VOID(frameNode);
284     int32_t nodeId = frameNode->GetId();
285     auto onDragEnd = [frameNode, nodeId, extraParam](const RefPtr<OHOS::Ace::DragEvent>& info) -> void {
286         ArkUINodeEvent event;
287         event.kind = ArkUIEventCategory::DRAG_EVENT;
288         event.nodeId = nodeId;
289         event.extraParam = reinterpret_cast<intptr_t>(extraParam);
290         event.dragEvent.subKind = ON_DRAG_END;
291         auto summary = info->GetSummary();
292         event.dragEvent.dataTypesCount = static_cast<int32_t>(summary.size());
293 
294         int32_t index = 0;
295         int32_t maxLength = 0;
296         std::vector<const char*> strList;
297         std::vector<std::string> keepStr(summary.size());
298         for (auto it = summary.begin(); it != summary.end(); it++) {
299             int32_t keyLength = static_cast<int32_t>(it->first.length());
300             maxLength = std::max(maxLength, keyLength);
301             keepStr[index] = it->first;
302             strList.push_back(keepStr[index].c_str());
303             ++index;
304         }
305         event.dragEvent.dataTypes = strList.data();
306         event.dragEvent.dataTypesMaxStrLength = maxLength + 1;
307 
308         auto unifiedData = UdmfClient::GetInstance()->TransformUnifiedDataPtr(info->GetData());
309 
310         event.dragEvent.unifiedData = unifiedData;
311         event.dragEvent.isSuitGetData = false;
312 
313         // Did NOT define pressCode, so will NOT pass presscode to UI.
314         event.dragEvent.dragResult = static_cast<ArkUI_Int32>(info->GetResult());
315         event.dragEvent.dragBehavior = static_cast<ArkUI_Int32>(info->GetDragBehavior());
316 
317         PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
318         SendArkUIAsyncEvent(&event);
319     };
320     ViewAbstract::SetOnDragEnd(frameNode, onDragEnd);
321 }
322 
SetOnPreDrag(ArkUINodeHandle node,void * extraParam)323 void SetOnPreDrag(ArkUINodeHandle node, void* extraParam)
324 {
325     auto* frameNode = reinterpret_cast<FrameNode*>(node);
326     CHECK_NULL_VOID(frameNode);
327     int32_t nodeId = frameNode->GetId();
328     auto onPreDrag = [frameNode, nodeId, extraParam](const PreDragStatus preDragStatus) -> void {
329         ArkUINodeEvent event;
330         event.kind = ArkUIEventCategory::COMPONENT_ASYNC_EVENT;
331         event.nodeId = nodeId;
332         event.extraParam = reinterpret_cast<intptr_t>(extraParam);
333         event.componentAsyncEvent.subKind = ON_PRE_DRAG;
334 
335         // Did NOT define pressCode, so will NOT pass presscode to UI.
336         event.componentAsyncEvent.data[0].i32 = static_cast<ArkUI_Int32>(preDragStatus);
337         event.dragEvent.isSuitGetData = false;
338 
339         PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
340         SendArkUIAsyncEvent(&event);
341     };
342     ViewAbstract::SetOnPreDrag(frameNode, onPreDrag);
343 }
344 } // namespace NodeModifier
345 } // namespace OHOS::Ace::NG
346