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 event.dragEvent.key = info->GetUdKey().c_str();
120 }
121
SetOnDragDrop(ArkUINodeHandle node,void * extraParam)122 void SetOnDragDrop(ArkUINodeHandle node, void* extraParam)
123 {
124 auto* frameNode = reinterpret_cast<FrameNode*>(node);
125 CHECK_NULL_VOID(frameNode);
126 int32_t nodeId = frameNode->GetId();
127 auto onDragDrop = [frameNode, nodeId, extraParam](
128 const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) -> void {
129 ArkUINodeEvent event;
130 event.kind = ArkUIEventCategory::DRAG_EVENT;
131 event.nodeId = nodeId;
132 event.extraParam = reinterpret_cast<intptr_t>(extraParam);
133 event.dragEvent.subKind = ON_DRAG_DROP;
134 auto summary = info->GetSummary();
135 std::vector<const char*> strList;
136 std::vector<std::string> keepStr(summary.size());
137
138 SetDragEventProperty(info, event, strList, keepStr);
139 event.dragEvent.isSuitGetData = true;
140
141 auto unifiedData = UdmfClient::GetInstance()->TransformUnifiedDataPtr(info->GetData());
142
143 event.dragEvent.unifiedData = unifiedData;
144 event.dragEvent.dragBehavior = static_cast<ArkUI_Int32>(DragBehavior::UNKNOWN);
145 PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
146 SendArkUIAsyncEvent(&event);
147 info->UseCustomAnimation(event.dragEvent.useCustomDropAnimation);
148 info->SetResult(static_cast<DragRet>(event.dragEvent.dragResult));
149 info->SetDragBehavior(static_cast<DragBehavior>(event.dragEvent.dragBehavior));
150 info->SetCapi(true);
151 };
152 ViewAbstract::SetOnDrop(frameNode, onDragDrop);
153 }
154
SetOnDragStart(ArkUINodeHandle node,void * extraParam)155 void SetOnDragStart(ArkUINodeHandle node, void* extraParam)
156 {
157 auto* frameNode = reinterpret_cast<FrameNode*>(node);
158 CHECK_NULL_VOID(frameNode);
159 int32_t nodeId = frameNode->GetId();
160 auto onDragStart = [frameNode, nodeId, extraParam](const RefPtr<OHOS::Ace::DragEvent>& info,
161 const std::string& extraParams) -> NG::DragDropBaseInfo {
162 ArkUINodeEvent event;
163 event.kind = ArkUIEventCategory::DRAG_EVENT;
164 event.nodeId = nodeId;
165 event.extraParam = reinterpret_cast<intptr_t>(extraParam);
166 event.dragEvent.subKind = ON_DRAG_START;
167 auto summary = info->GetSummary();
168 std::vector<const char*> strList;
169 std::vector<std::string> keepStr(summary.size());
170
171 SetDragEventProperty(info, event, strList, keepStr);
172 event.dragEvent.isSuitGetData = false;
173
174 PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
175 SendArkUIAsyncEvent(&event);
176 RefPtr<UnifiedData> udData =
177 UdmfClient::GetInstance()->TransformUnifiedDataForNative(event.dragEvent.unifiedData);
178
179 info->SetData(udData);
180 NG::DragDropBaseInfo dragDropInfo;
181 return dragDropInfo;
182 };
183 ViewAbstractModelNG::SetOnDragStart(frameNode, onDragStart);
184 }
185
SetOnDragEnter(ArkUINodeHandle node,void * extraParam)186 void SetOnDragEnter(ArkUINodeHandle node, void* extraParam)
187 {
188 auto* frameNode = reinterpret_cast<FrameNode*>(node);
189 CHECK_NULL_VOID(frameNode);
190 int32_t nodeId = frameNode->GetId();
191 auto onDragEnter = [frameNode, nodeId, extraParam](
192 const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
193 ArkUINodeEvent event;
194 event.kind = ArkUIEventCategory::DRAG_EVENT;
195 event.nodeId = nodeId;
196 event.extraParam = reinterpret_cast<intptr_t>(extraParam);
197 event.dragEvent.subKind = ON_DRAG_ENTER;
198
199 auto summary = info->GetSummary();
200 std::vector<const char*> strList;
201 std::vector<std::string> keepStr(summary.size());
202
203 SetDragEventProperty(info, event, strList, keepStr);
204 auto unifiedData = UdmfClient::GetInstance()->TransformUnifiedDataPtr(info->GetData());
205 event.dragEvent.dragBehavior = static_cast<ArkUI_Int32>(DragBehavior::UNKNOWN);
206 event.dragEvent.unifiedData = unifiedData;
207 event.dragEvent.isSuitGetData = false;
208
209 PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
210 SendArkUIAsyncEvent(&event);
211 info->SetResult(static_cast<DragRet>(event.dragEvent.dragResult));
212 info->SetDragBehavior(static_cast<DragBehavior>(event.dragEvent.dragBehavior));
213 info->SetCapi(true);
214 };
215 ViewAbstract::SetOnDragEnter(frameNode, onDragEnter);
216 }
217
SetOnDragMove(ArkUINodeHandle node,void * extraParam)218 void SetOnDragMove(ArkUINodeHandle node, void* extraParam)
219 {
220 auto* frameNode = reinterpret_cast<FrameNode*>(node);
221 CHECK_NULL_VOID(frameNode);
222 int32_t nodeId = frameNode->GetId();
223 auto onDragMove = [frameNode, nodeId, extraParam](
224 const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
225 ArkUINodeEvent event;
226 event.kind = ArkUIEventCategory::DRAG_EVENT;
227 event.nodeId = nodeId;
228 event.extraParam = reinterpret_cast<intptr_t>(extraParam);
229 event.dragEvent.subKind = ON_DRAG_MOVE;
230 auto summary = info->GetSummary();
231 std::vector<const char*> strList;
232 std::vector<std::string> keepStr(summary.size());
233
234 SetDragEventProperty(info, event, strList, keepStr);
235 auto unifiedData = UdmfClient::GetInstance()->TransformUnifiedDataPtr(info->GetData());
236 event.dragEvent.dragBehavior = static_cast<ArkUI_Int32>(DragBehavior::UNKNOWN);
237 event.dragEvent.unifiedData = unifiedData;
238 event.dragEvent.isSuitGetData = false;
239
240 PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
241 SendArkUIAsyncEvent(&event);
242 info->SetResult(static_cast<DragRet>(event.dragEvent.dragResult));
243 info->SetDragBehavior(static_cast<DragBehavior>(event.dragEvent.dragBehavior));
244 info->SetCapi(true);
245 };
246 ViewAbstract::SetOnDragMove(frameNode, onDragMove);
247 }
248
SetOnDragLeave(ArkUINodeHandle node,void * extraParam)249 void SetOnDragLeave(ArkUINodeHandle node, void* extraParam)
250 {
251 auto* frameNode = reinterpret_cast<FrameNode*>(node);
252 CHECK_NULL_VOID(frameNode);
253 int32_t nodeId = frameNode->GetId();
254 auto onDragLeave = [frameNode, nodeId, extraParam](
255 const RefPtr<OHOS::Ace::DragEvent>& info, const std::string& extraParams) {
256 ArkUINodeEvent event;
257 event.kind = ArkUIEventCategory::DRAG_EVENT;
258 event.nodeId = nodeId;
259 event.extraParam = reinterpret_cast<intptr_t>(extraParam);
260 event.dragEvent.subKind = ON_DRAG_LEAVE;
261
262 auto summary = info->GetSummary();
263 std::vector<const char*> strList;
264 std::vector<std::string> keepStr(summary.size());
265
266 SetDragEventProperty(info, event, strList, keepStr);
267 auto unifiedData = UdmfClient::GetInstance()->TransformUnifiedDataPtr(info->GetData());
268 event.dragEvent.dragBehavior = static_cast<ArkUI_Int32>(DragBehavior::UNKNOWN);
269 event.dragEvent.unifiedData = unifiedData;
270 event.dragEvent.isSuitGetData = false;
271
272 PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
273 SendArkUIAsyncEvent(&event);
274 info->SetResult(static_cast<DragRet>(event.dragEvent.dragResult));
275 info->SetDragBehavior(static_cast<DragBehavior>(event.dragEvent.dragBehavior));
276 info->SetCapi(true);
277 };
278 ViewAbstract::SetOnDragLeave(frameNode, onDragLeave);
279 }
280
SetOnDragEnd(ArkUINodeHandle node,void * extraParam)281 void SetOnDragEnd(ArkUINodeHandle node, void* extraParam)
282 {
283 auto* frameNode = reinterpret_cast<FrameNode*>(node);
284 CHECK_NULL_VOID(frameNode);
285 int32_t nodeId = frameNode->GetId();
286 auto onDragEnd = [frameNode, nodeId, extraParam](const RefPtr<OHOS::Ace::DragEvent>& info) -> void {
287 ArkUINodeEvent event;
288 event.kind = ArkUIEventCategory::DRAG_EVENT;
289 event.nodeId = nodeId;
290 event.extraParam = reinterpret_cast<intptr_t>(extraParam);
291 event.dragEvent.subKind = ON_DRAG_END;
292 auto summary = info->GetSummary();
293 event.dragEvent.dataTypesCount = static_cast<int32_t>(summary.size());
294
295 int32_t index = 0;
296 int32_t maxLength = 0;
297 std::vector<const char*> strList;
298 std::vector<std::string> keepStr(summary.size());
299 for (auto it = summary.begin(); it != summary.end(); it++) {
300 int32_t keyLength = static_cast<int32_t>(it->first.length());
301 maxLength = std::max(maxLength, keyLength);
302 keepStr[index] = it->first;
303 strList.push_back(keepStr[index].c_str());
304 ++index;
305 }
306 event.dragEvent.dataTypes = strList.data();
307 event.dragEvent.dataTypesMaxStrLength = maxLength + 1;
308
309 auto unifiedData = UdmfClient::GetInstance()->TransformUnifiedDataPtr(info->GetData());
310
311 event.dragEvent.unifiedData = unifiedData;
312 event.dragEvent.isSuitGetData = false;
313
314 // Did NOT define pressCode, so will NOT pass presscode to UI.
315 event.dragEvent.dragResult = static_cast<ArkUI_Int32>(info->GetResult());
316 event.dragEvent.dragBehavior = static_cast<ArkUI_Int32>(info->GetDragBehavior());
317
318 PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
319 SendArkUIAsyncEvent(&event);
320 };
321 ViewAbstract::SetOnDragEnd(frameNode, onDragEnd);
322 }
323
SetOnPreDrag(ArkUINodeHandle node,void * extraParam)324 void SetOnPreDrag(ArkUINodeHandle node, void* extraParam)
325 {
326 auto* frameNode = reinterpret_cast<FrameNode*>(node);
327 CHECK_NULL_VOID(frameNode);
328 int32_t nodeId = frameNode->GetId();
329 auto onPreDrag = [frameNode, nodeId, extraParam](const PreDragStatus preDragStatus) -> void {
330 ArkUINodeEvent event;
331 event.kind = ArkUIEventCategory::COMPONENT_ASYNC_EVENT;
332 event.nodeId = nodeId;
333 event.extraParam = reinterpret_cast<intptr_t>(extraParam);
334 event.componentAsyncEvent.subKind = ON_PRE_DRAG;
335
336 // Did NOT define pressCode, so will NOT pass presscode to UI.
337 event.componentAsyncEvent.data[0].i32 = static_cast<ArkUI_Int32>(preDragStatus);
338 event.dragEvent.isSuitGetData = false;
339
340 PipelineContext::SetCallBackNode(AceType::WeakClaim(frameNode));
341 SendArkUIAsyncEvent(&event);
342 };
343 ViewAbstract::SetOnPreDrag(frameNode, onPreDrag);
344 }
345 } // namespace NodeModifier
346 } // namespace OHOS::Ace::NG
347