• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "node_extened.h"
16 
17 
18 #include "node_model.h"
19 
20 #include "base/error/error_code.h"
21 #include "core/components_ng/base/ui_node.h"
22 
23 namespace OHOS::Ace::NodeModel {
24 
25 struct InnerCustomExtraParam  {
26     int32_t targetId;
27     void* userData;
28 };
29 
30 struct ExtraCustomData {
31     std::unordered_map<int64_t, InnerCustomExtraParam*> eventMap;
32 };
33 
NodeAddExtraData(ArkUI_NodeHandle node,ArkUI_NodeCustomEventType eventType,int32_t targetId,void * userData)34 void NodeAddExtraData(ArkUI_NodeHandle node, ArkUI_NodeCustomEventType eventType, int32_t targetId, void* userData)
35 {
36     if (!node->extraCustomData) {
37         node->extraCustomData = new ExtraCustomData();
38     }
39 
40     auto* extraCustomData = reinterpret_cast<ExtraCustomData*>(node->extraCustomData);
41     auto& eventMap = extraCustomData->eventMap;
42 
43     auto it = eventMap.find(eventType);
44     if (it != eventMap.end()) {
45         it->second->targetId = targetId;
46     } else {
47         auto eventExtraParam = new InnerCustomExtraParam({ targetId, userData });
48         eventMap.emplace(eventType, eventExtraParam);
49     }
50 }
51 
RegisterNodeCustomEvent(ArkUI_NodeHandle node,ArkUI_NodeCustomEventType eventType,int32_t targetId,void * userData)52 int32_t RegisterNodeCustomEvent(ArkUI_NodeHandle node, ArkUI_NodeCustomEventType eventType, int32_t targetId, void* userData)
53 {
54     if (!node || !CheckIsCNode(node)) {
55         return ERROR_CODE_PARAM_INVALID;
56     }
57     if (eventType <= 0) {
58         TAG_LOGE(AceLogTag::ACE_NATIVE_NODE, "Custom event is not supported %{public}d", eventType);
59         return ERROR_CODE_NATIVE_IMPL_TYPE_NOT_SUPPORTED;
60     }
61 
62     if (eventType & ARKUI_NODE_CUSTOM_EVENT_ON_MEASURE) {
63         if (node->type == ARKUI_NODE_CUSTOM || node->type == ARKUI_NODE_CUSTOM_SPAN) {
64             NodeAddExtraData(node, ARKUI_NODE_CUSTOM_EVENT_ON_MEASURE, targetId, userData);
65         } else {
66             return ERROR_CODE_NATIVE_IMPL_TYPE_NOT_SUPPORTED;
67         }
68     }
69 
70     if (eventType & ARKUI_NODE_CUSTOM_EVENT_ON_LAYOUT) {
71         if (node->type == ARKUI_NODE_CUSTOM) {
72             NodeAddExtraData(node, ARKUI_NODE_CUSTOM_EVENT_ON_LAYOUT, targetId, userData);
73         } else {
74             return ERROR_CODE_NATIVE_IMPL_TYPE_NOT_SUPPORTED;
75         }
76     }
77 
78     if (eventType & ARKUI_NODE_CUSTOM_EVENT_ON_DRAW) {
79         NodeAddExtraData(node, ARKUI_NODE_CUSTOM_EVENT_ON_DRAW, targetId, userData);
80     }
81 
82     if (eventType & ARKUI_NODE_CUSTOM_EVENT_ON_DRAW_FRONT) {
83         NodeAddExtraData(node, ARKUI_NODE_CUSTOM_EVENT_ON_DRAW_FRONT, targetId, userData);
84     }
85 
86     if (eventType & ARKUI_NODE_CUSTOM_EVENT_ON_DRAW_BEHIND) {
87         NodeAddExtraData(node, ARKUI_NODE_CUSTOM_EVENT_ON_DRAW_BEHIND, targetId, userData);
88     }
89 
90     if (eventType & ARKUI_NODE_CUSTOM_EVENT_ON_FOREGROUND_DRAW) {
91         NodeAddExtraData(node, ARKUI_NODE_CUSTOM_EVENT_ON_FOREGROUND_DRAW, targetId, userData);
92     }
93 
94     if (eventType & ARKUI_NODE_CUSTOM_EVENT_ON_OVERLAY_DRAW) {
95         NodeAddExtraData(node, ARKUI_NODE_CUSTOM_EVENT_ON_OVERLAY_DRAW, targetId, userData);
96     }
97     const auto* impl = GetFullImpl();
98     if (node->type == ARKUI_NODE_CUSTOM_SPAN) {
99         impl->getExtendedAPI()->registerCustomSpanAsyncEvent(
100             node->uiNodeHandle, eventType, reinterpret_cast<void*>(node));
101     } else {
102         impl->getExtendedAPI()->registerCustomNodeAsyncEvent(
103             node->uiNodeHandle, eventType, reinterpret_cast<void*>(node));
104     }
105     return ERROR_CODE_NO_ERROR;
106 }
107 
NodeRemoveExtraData(ArkUI_NodeHandle node,ArkUI_NodeCustomEventType eventType)108 void NodeRemoveExtraData(ArkUI_NodeHandle node, ArkUI_NodeCustomEventType eventType)
109 {
110     auto* extraCustomData = reinterpret_cast<ExtraCustomData*>(node->extraCustomData);
111     auto& eventMap = extraCustomData->eventMap;
112     auto innerEventExtraParam = eventMap.find(eventType);
113     if (innerEventExtraParam == eventMap.end()) {
114         return;
115     }
116     delete innerEventExtraParam->second;
117     eventMap.erase(innerEventExtraParam);
118     if (eventMap.empty()) {
119         delete extraCustomData;
120         node->extraCustomData = nullptr;
121     }
122 }
123 
UnregisterNodeCustomEvent(ArkUI_NodeHandle node,ArkUI_NodeCustomEventType eventType)124 void UnregisterNodeCustomEvent(ArkUI_NodeHandle node, ArkUI_NodeCustomEventType eventType)
125 {
126     if (node == nullptr || !node->extraCustomData || !CheckIsCNode(node)) {
127         return;
128     }
129     const auto* impl = GetFullImpl();
130 
131     auto resultValue = impl->getExtendedAPI()->unregisterCustomNodeAsyncEvent(node->uiNodeHandle, eventType);
132     if (resultValue == -1) {
133         TAG_LOGE(AceLogTag::ACE_NATIVE_NODE, "Custom event Unregister error %{public}d", eventType);
134         return;
135     }
136 
137     if (eventType & ARKUI_NODE_CUSTOM_EVENT_ON_MEASURE) {
138         NodeRemoveExtraData(node, ARKUI_NODE_CUSTOM_EVENT_ON_MEASURE);
139     }
140 
141     if (eventType & ARKUI_NODE_CUSTOM_EVENT_ON_LAYOUT) {
142         NodeRemoveExtraData(node, ARKUI_NODE_CUSTOM_EVENT_ON_LAYOUT);
143     }
144 
145     if (eventType & ARKUI_NODE_CUSTOM_EVENT_ON_DRAW) {
146         NodeRemoveExtraData(node, ARKUI_NODE_CUSTOM_EVENT_ON_DRAW);
147     }
148 
149     if (eventType & ARKUI_NODE_CUSTOM_EVENT_ON_DRAW_FRONT) {
150         NodeRemoveExtraData(node, ARKUI_NODE_CUSTOM_EVENT_ON_DRAW_FRONT);
151     }
152 
153     if (eventType & ARKUI_NODE_CUSTOM_EVENT_ON_DRAW_BEHIND) {
154         NodeRemoveExtraData(node, ARKUI_NODE_CUSTOM_EVENT_ON_DRAW_BEHIND);
155     }
156 
157     if (eventType & ARKUI_NODE_CUSTOM_EVENT_ON_FOREGROUND_DRAW) {
158         NodeRemoveExtraData(node, ARKUI_NODE_CUSTOM_EVENT_ON_FOREGROUND_DRAW);
159     }
160 
161     if (eventType & ARKUI_NODE_CUSTOM_EVENT_ON_OVERLAY_DRAW) {
162         NodeRemoveExtraData(node, ARKUI_NODE_CUSTOM_EVENT_ON_OVERLAY_DRAW);
163     }
164 }
165 
166 void (*g_customEventReceiver)(ArkUI_NodeCustomEvent* event) = nullptr;
RegisterNodeCustomReceiver(void (* eventReceiver)(ArkUI_NodeCustomEvent * event))167 void RegisterNodeCustomReceiver(void (*eventReceiver)(ArkUI_NodeCustomEvent* event))
168 {
169     g_customEventReceiver = eventReceiver;
170 }
171 
UnregisterNodeCustomEventReceiver()172 void UnregisterNodeCustomEventReceiver()
173 {
174     g_customEventReceiver = nullptr;
175 }
176 
HandleInnerCustomEvent(ArkUICustomNodeEvent * origin)177 void HandleInnerCustomEvent(ArkUICustomNodeEvent* origin)
178 {
179     if (!origin) {
180         return;
181     }
182     auto* nodePtr = reinterpret_cast<ArkUI_NodeHandle>(origin->extraParam);
183     if (!IsValidArkUINode(nodePtr) || !nodePtr->extraCustomData) {
184         return;
185     }
186 
187     auto* extraCustomData = reinterpret_cast<ExtraCustomData*>(nodePtr->extraCustomData);
188     ArkUI_NodeCustomEventType eventType = static_cast<ArkUI_NodeCustomEventType>(origin->kind);
189 
190     auto innerEventExtraParam = extraCustomData->eventMap.find(eventType);
191     if (innerEventExtraParam == extraCustomData->eventMap.end()) {
192         return;
193     }
194     ArkUI_NodeCustomEvent event;
195     event.event = origin;
196     event.node = nodePtr;
197     event.targetId = innerEventExtraParam->second->targetId;
198     event.userData = innerEventExtraParam->second->userData;
199     HandleCustomEvent(&event);
200 }
201 
HandleCustomEvent(ArkUI_NodeCustomEvent * event)202 void HandleCustomEvent(ArkUI_NodeCustomEvent* event)
203 {
204     if (!event) {
205         return;
206     }
207     if (event->node && event->node->customEventListeners) {
208         auto eventListenersSet = reinterpret_cast<std::set<void (*)(ArkUI_NodeCustomEvent*)>*>(
209             event->node->customEventListeners);
210         if (eventListenersSet) {
211             for (const auto& eventlistener : *eventListenersSet) {
212                 (*eventlistener)(event);
213             }
214         }
215     }
216     if (g_customEventReceiver) {
217         g_customEventReceiver(event);
218     }
219 }
220 
AddNodeCustomEventReceiver(ArkUI_NodeHandle nodePtr,void (* eventReceiver)(ArkUI_NodeCustomEvent * event))221 int32_t AddNodeCustomEventReceiver(ArkUI_NodeHandle nodePtr, void (*eventReceiver)(ArkUI_NodeCustomEvent* event))
222 {
223     if (!nodePtr || !eventReceiver || !CheckIsCNode(nodePtr)) {
224         return ERROR_CODE_PARAM_INVALID;
225     }
226     if (!nodePtr->customEventListeners) {
227         nodePtr->customEventListeners = new std::set<void (*)(ArkUI_NodeCustomEvent*)>();
228     }
229     auto eventListenersSet = reinterpret_cast<std::set<void (*)(ArkUI_NodeCustomEvent*)>*>(
230         nodePtr->customEventListeners);
231     if (!eventListenersSet) {
232         return ERROR_CODE_PARAM_INVALID;
233     }
234     eventListenersSet->emplace(eventReceiver);
235     return ERROR_CODE_NO_ERROR;
236 }
237 
RemoveNodeCustomEventReceiver(ArkUI_NodeHandle nodePtr,void (* eventReceiver)(ArkUI_NodeCustomEvent * event))238 int32_t RemoveNodeCustomEventReceiver(ArkUI_NodeHandle nodePtr,
239     void (*eventReceiver)(ArkUI_NodeCustomEvent* event))
240 {
241     if (!nodePtr || !eventReceiver || !nodePtr->customEventListeners || !CheckIsCNode(nodePtr)) {
242         return ERROR_CODE_PARAM_INVALID;
243     }
244     auto eventListenersSet = reinterpret_cast<std::set<void (*)(ArkUI_NodeCustomEvent*)>*>(
245         nodePtr->customEventListeners);
246     if (!eventListenersSet) {
247         return ERROR_CODE_PARAM_INVALID;
248     }
249     eventListenersSet->erase(eventReceiver);
250     if (eventListenersSet->empty()) {
251         delete eventListenersSet;
252         nodePtr->customEventListeners = nullptr;
253     }
254     return ERROR_CODE_NO_ERROR;
255 }
256 
SetMeasuredSize(ArkUI_NodeHandle node,int32_t width,int32_t height)257 int32_t SetMeasuredSize(ArkUI_NodeHandle node, int32_t width, int32_t height)
258 {
259     if (node == nullptr || !CheckIsCNode(node)) {
260         return ERROR_CODE_PARAM_INVALID;
261     }
262     const auto* impl = GetFullImpl();
263     impl->getExtendedAPI()->setMeasureWidth(node->uiNodeHandle, width > 0 ? width : 0);
264     impl->getExtendedAPI()->setMeasureHeight(node->uiNodeHandle, height > 0 ? height : 0);
265     return ERROR_CODE_NO_ERROR;
266 }
267 
SetLayoutPosition(ArkUI_NodeHandle node,int32_t positionX,int32_t positionY)268 int32_t SetLayoutPosition(ArkUI_NodeHandle node, int32_t positionX, int32_t positionY)
269 {
270     if (node == nullptr || !CheckIsCNode(node)) {
271         return ERROR_CODE_PARAM_INVALID;
272     }
273     const auto* impl = GetFullImpl();
274     impl->getExtendedAPI()->setX(node->uiNodeHandle, positionX);
275     impl->getExtendedAPI()->setY(node->uiNodeHandle, positionY);
276     return ERROR_CODE_NO_ERROR;
277 }
278 
GetLayoutConstraint(ArkUI_NodeHandle node,ArkUI_LayoutConstraint * layoutConstraint)279 int32_t GetLayoutConstraint(ArkUI_NodeHandle node, ArkUI_LayoutConstraint* layoutConstraint)
280 {
281     if (node == nullptr || layoutConstraint == nullptr || !CheckIsCNode(node)) {
282         return ERROR_CODE_PARAM_INVALID;
283     }
284     const auto* impl = GetFullImpl();
285     // data size
286     ArkUI_Int32 data[6];
287     impl->getExtendedAPI()->getLayoutConstraint(node->uiNodeHandle, data);
288     //minWidth
289     layoutConstraint->minWidth = data[0];
290     //minHeight
291     layoutConstraint->minHeight = data[1];
292     //maxWidth
293     layoutConstraint->maxWidth = data[2];
294     //maxHeight
295     layoutConstraint->maxHeight = data[3];
296     //percentReferWidth
297     layoutConstraint->percentReferWidth = data[4];
298     //percentReferHeight
299     layoutConstraint->percentReferHeight = data[5];
300     return ERROR_CODE_NO_ERROR;
301 }
302 
GetMeasuredSize(ArkUI_NodeHandle node)303 ArkUI_IntSize GetMeasuredSize(ArkUI_NodeHandle node)
304 {
305     ArkUI_IntSize size;
306     if (node == nullptr) {
307         return size;
308     }
309     const auto* impl = GetFullImpl();
310     size.width = impl->getExtendedAPI()->getMeasureWidth(node->uiNodeHandle);
311     size.height = impl->getExtendedAPI()->getMeasureHeight(node->uiNodeHandle);
312     return size;
313 }
314 
GetLayoutPosition(ArkUI_NodeHandle node)315 ArkUI_IntOffset GetLayoutPosition(ArkUI_NodeHandle node)
316 {
317     ArkUI_IntOffset offset;
318     if (node == nullptr) {
319         return offset;
320     }
321     const auto* impl = GetFullImpl();
322     offset.x = impl->getExtendedAPI()->getX(node->uiNodeHandle);
323     offset.y = impl->getExtendedAPI()->getY(node->uiNodeHandle);
324     return offset;
325 }
326 
MeasureNode(ArkUI_NodeHandle node,ArkUI_LayoutConstraint * constraint)327 int32_t MeasureNode(ArkUI_NodeHandle node, ArkUI_LayoutConstraint* constraint)
328 {
329     if (node == nullptr || constraint == nullptr || !CheckIsCNode(node)) {
330         return ERROR_CODE_PARAM_INVALID;
331     }
332     const auto* impl = GetFullImpl();
333     // data size
334     ArkUI_Float32 data[6];
335     //minWidth
336     data[0] = static_cast<ArkUI_Float32>(constraint->minWidth);
337     //minHeight
338     data[1] = static_cast<ArkUI_Float32>(constraint->minHeight);
339     //maxWidth
340     data[2] = static_cast<ArkUI_Float32>(constraint->maxWidth);
341     //maxHeight
342     data[3] = static_cast<ArkUI_Float32>(constraint->maxHeight);
343     //percentReferWidth
344     data[4] = static_cast<ArkUI_Float32>(constraint->percentReferWidth);
345     //percentReferHeight
346     data[5] = static_cast<ArkUI_Float32>(constraint->percentReferHeight);
347     impl->getExtendedAPI()->measureNode(nullptr, node->uiNodeHandle, data);
348     return ERROR_CODE_NO_ERROR;
349 }
350 
LayoutNode(ArkUI_NodeHandle node,int32_t positionX,int32_t positionY)351 int32_t LayoutNode(ArkUI_NodeHandle node, int32_t positionX, int32_t positionY)
352 {
353     if (node == nullptr || !CheckIsCNode(node)) {
354         return ERROR_CODE_PARAM_INVALID;
355     }
356     const auto* impl = GetFullImpl();
357     //layout data size
358     float data[2];
359     //positionX
360     data[0] = positionX;
361     //positionY
362     data[1] = positionY;
363     impl->getExtendedAPI()->layoutNode(nullptr, node->uiNodeHandle, &data);
364     return ERROR_CODE_NO_ERROR;
365 }
366 
GetTotalChildCount(ArkUI_NodeHandle node)367 uint32_t GetTotalChildCount(ArkUI_NodeHandle node)
368 {
369     if (node == nullptr) {
370         return 0;
371     }
372     const auto* impl = GetFullImpl();
373     return impl->getNodeModifiers()->getFrameNodeModifier()->getChildrenCount(node->uiNodeHandle, true);
374 }
375 
GetChildAt(ArkUI_NodeHandle node,int32_t position)376 ArkUI_NodeHandle GetChildAt(ArkUI_NodeHandle node, int32_t position)
377 {
378     if (node == nullptr) {
379         return nullptr;
380     }
381     const auto* impl = GetFullImpl();
382     auto* attachNode = impl->getNodeModifiers()->getFrameNodeModifier()->getChild(node->uiNodeHandle, position, true);
383     return GetArkUINode(attachNode);
384 }
385 
GetFirstChild(ArkUI_NodeHandle node)386 ArkUI_NodeHandle GetFirstChild(ArkUI_NodeHandle node)
387 {
388     if (node == nullptr) {
389         return nullptr;
390     }
391     const auto* impl = GetFullImpl();
392     auto* attachNode = impl->getNodeModifiers()->getFrameNodeModifier()->getFirst(node->uiNodeHandle, true);
393     return GetArkUINode(attachNode);
394 }
395 
GetLastChild(ArkUI_NodeHandle node)396 ArkUI_NodeHandle GetLastChild(ArkUI_NodeHandle node)
397 {
398     if (node == nullptr) {
399         return nullptr;
400     }
401     const auto* impl = GetFullImpl();
402     auto* attachNode = impl->getNodeModifiers()->getFrameNodeModifier()->getLast(node->uiNodeHandle, true);
403     return GetArkUINode(attachNode);
404 }
405 
GetPreviousSibling(ArkUI_NodeHandle node)406 ArkUI_NodeHandle GetPreviousSibling(ArkUI_NodeHandle node)
407 {
408     if (node == nullptr) {
409         return nullptr;
410     }
411     const auto* impl = GetFullImpl();
412     auto* attachNode = impl->getNodeModifiers()->getFrameNodeModifier()->getPreviousSibling(node->uiNodeHandle, true);
413     return GetArkUINode(attachNode);
414 }
415 
GetNextSibling(ArkUI_NodeHandle node)416 ArkUI_NodeHandle GetNextSibling(ArkUI_NodeHandle node)
417 {
418     if (node == nullptr) {
419         return nullptr;
420     }
421     const auto* impl = GetFullImpl();
422     auto* attachNode = impl->getNodeModifiers()->getFrameNodeModifier()->getNextSibling(node->uiNodeHandle, true);
423     return GetArkUINode(attachNode);
424 }
425 
GetParent(ArkUI_NodeHandle node)426 ArkUI_NodeHandle GetParent(ArkUI_NodeHandle node)
427 {
428     if (node == nullptr) {
429         return nullptr;
430     }
431     const auto* impl = GetFullImpl();
432     auto* value = impl->getNodeModifiers()->getFrameNodeModifier()->getParent(node->uiNodeHandle);
433     void* attachNode = impl->getExtendedAPI()->getAttachNodePtr(value);
434     if (attachNode) {
435         return reinterpret_cast<ArkUI_NodeHandle>(attachNode);
436     }
437     return nullptr;
438 }
439 
RemoveAllChildren(ArkUI_NodeHandle parentNode)440 int32_t RemoveAllChildren(ArkUI_NodeHandle parentNode)
441 {
442     CHECK_NULL_RETURN(parentNode, ERROR_CODE_PARAM_INVALID);
443     const auto* impl = GetFullImpl();
444     impl->getNodeModifiers()->getFrameNodeModifier()->clearChildren(parentNode->uiNodeHandle);
445     return ERROR_CODE_NO_ERROR;
446 }
447 } // namespace OHOS::Ace::NodeModel
448