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