4#include <qarkui/qnativenodeapi.h>
6#include <QtCore/private/qohoslogger_p.h>
7#include <arkui/native_interface.h>
8#include <arkui/native_node.h>
9#include <arkui/native_type.h>
10#include <qohosutils.h>
17const ::ArkUI_NativeNodeAPI_1 &nativeNodeApi()
19 static const ::ArkUI_NativeNodeAPI_1 api = []() {
23 auto *nativeNodeApi =
reinterpret_cast<::ArkUI_NativeNodeAPI_1 *>(
24 ::OH_ArkUI_QueryModuleInterfaceByName(::ARKUI_NATIVE_NODE,
"ArkUI_NativeNodeAPI_1"));
26 if (nativeNodeApi ==
nullptr)
27 qOhosReportFatalErrorAndAbort(
"::OH_ArkUI_QueryModuleInterface failed");
29 static constexpr auto requiredNonNullFunctionPointersMembers =
std::make_tuple(
30 &::ArkUI_NativeNodeAPI_1::addChild,
31 &::ArkUI_NativeNodeAPI_1::addNodeEventReceiver,
32 &::ArkUI_NativeNodeAPI_1::createNode,
33 &::ArkUI_NativeNodeAPI_1::disposeNode,
34 &::ArkUI_NativeNodeAPI_1::getAttribute,
35 &::ArkUI_NativeNodeAPI_1::getChildAt,
36 &::ArkUI_NativeNodeAPI_1::getParent,
37 &::ArkUI_NativeNodeAPI_1::getTotalChildCount,
38 &::ArkUI_NativeNodeAPI_1::registerNodeEvent,
39 &::ArkUI_NativeNodeAPI_1::removeChild,
40 &::ArkUI_NativeNodeAPI_1::removeNodeEventReceiver,
41 &::ArkUI_NativeNodeAPI_1::setAttribute,
42 &::ArkUI_NativeNodeAPI_1::unregisterNodeEvent);
44 QtOhos::tupleForEach(requiredNonNullFunctionPointersMembers, [&](
auto functionMemberPointer) {
45 if ((nativeNodeApi->*functionMemberPointer) ==
nullptr)
46 qOhosReportFatalErrorAndAbort(
"Required function is null");
49 return *nativeNodeApi;
55::ArkUI_NumberValue toArkUiNumberValue(
std::int32_t value)
57 return ::ArkUI_NumberValue {
62::ArkUI_NumberValue toArkUiNumberValue(
std::uint32_t value)
64 return ::ArkUI_NumberValue {
69::ArkUI_NumberValue toArkUiNumberValue(
float value)
71 return ::ArkUI_NumberValue {
76void setNodeAttributeOrFail(
77 ::ArkUI_NodeHandle node,
78 ::ArkUI_NodeAttributeType attribute,
79 std::initializer_list<::ArkUI_AttributeItem> values)
81 auto errorCode = nativeNodeApi().setAttribute(node, attribute, values.begin());
82 if (errorCode != ::ARKUI_ERROR_CODE_NO_ERROR) {
83 qOhosReportFatalErrorAndAbort(
84 "Failed to set attribute: %d on node: %p with error: %d",
91void setNodeAttributeOrFail(
92 ::ArkUI_NodeHandle node,
93 ::ArkUI_NodeAttributeType attribute,
94 std::initializer_list<::ArkUI_NumberValue> values)
96 ::ArkUI_AttributeItem item = {
97 .value = values.begin(),
98 .size =
static_cast<
std::int32_t>(values.size()),
100 setNodeAttributeOrFail(node, attribute, {item});
103std::shared_ptr<
void> registerNodeEvent(
104 ::ArkUI_NodeHandle node, ::ArkUI_NodeEventType eventType,
void *userData)
106 auto registerEventRes = nativeNodeApi().registerNodeEvent(
107 node, eventType,
static_cast<std::int32_t>(eventType), userData);
108 if (registerEventRes != ::ARKUI_ERROR_CODE_NO_ERROR) {
109 qOhosReportFatalErrorAndAbort(
110 "QArkUi: registerNodeEvent(%p, %d) failed with error: %d",
111 node, eventType, registerEventRes);
114 return QtOhos::makeDestroyNotifier(
115 [node, eventType]() {
116 nativeNodeApi().unregisterNodeEvent(node, eventType);
120std::shared_ptr<
void> addNodeEventReceiver(
121 ::ArkUI_NodeHandle node,
void (*eventReceiver)(::ArkUI_NodeEvent *event))
123 auto addEventReceiverRes = nativeNodeApi().addNodeEventReceiver(node, eventReceiver);
124 if (addEventReceiverRes != ::ARKUI_ERROR_CODE_NO_ERROR) {
125 qOhosReportFatalErrorAndAbort(
126 "QArkUi: addNodeEventReceiver(%p, ...) failed with error: %d",
127 node, addEventReceiverRes);
130 return QtOhos::makeDestroyNotifier(
131 [node, eventReceiver]() {
132 nativeNodeApi().removeNodeEventReceiver(node, eventReceiver);
138std::set<::ArkUI_NodeHandle>
Node::qtManagedNodes;
141 ::ArkUI_NodeAttributeType attributeType,
float value)
143 setNodeAttributeOrFail(handle(), attributeType, {toArkUiNumberValue(value)});
147 ::ArkUI_NodeAttributeType attributeType,
std::int32_t value)
149 setNodeAttributeOrFail(handle(), attributeType, {toArkUiNumberValue(value)});
153 ::ArkUI_NodeAttributeType attributeType,
std::uint32_t value)
155 setNodeAttributeOrFail(handle(), attributeType, {toArkUiNumberValue(value)});
159 ::ArkUI_NodeAttributeType attributeType,
bool value)
161 std::int32_t intValue = value ? 1 : 0;
162 setNodeAttributeOrFail(handle(), attributeType, {toArkUiNumberValue(intValue)});
166 ::ArkUI_NodeAttributeType attributeType,
const std::string &value)
168 ::ArkUI_AttributeItem item = {
169 .string = value.data(),
171 setNodeAttributeOrFail(handle(), attributeType, {item});
176 auto errorCode = nativeNodeApi().addChild(handle(), child.handle());
177 if (errorCode != ::ARKUI_ERROR_CODE_NO_ERROR) {
178 qOhosReportFatalErrorAndAbort(
179 "addChild failed for parent: %p, child: %p with error: %d",
200Node::Node(::ArkUI_NodeHandle handle)
204 auto *parentNode = nativeNodeApi().getParent(handle);
205 if (parentNode !=
nullptr)
206 nativeNodeApi().removeChild(parentNode, handle);
207 nativeNodeApi().disposeNode(handle);
208 std::ignore = qtManagedNodes.erase(handle);
212 std::tie(
std::ignore, added) = qtManagedNodes.insert(handle);
214 qOhosReportFatalErrorAndAbort(
"Attempted to take ownership of ::ArkUI_NodeHandle for a second time.");
219 auto errorCode = nativeNodeApi().removeChild(handle(), child.handle());
220 if (errorCode != ::ARKUI_ERROR_CODE_NO_ERROR)
221 qOhosReportFatalErrorAndAbort(
"removeChild failed with error: %d", errorCode);
225 ::ArkUI_NodeEventType eventType,
226 std::function<
void(::ArkUI_NodeEvent *)> eventHandler)
228 if (!m_eventReceiverHandle) {
229 m_eventReceiverHandle = addNodeEventReceiver(
231 [](ArkUI_NodeEvent *event) {
232 void *userData = ::OH_ArkUI_NodeEvent_GetUserData(event);
233 if (userData ==
nullptr) {
234 qOhosPrintfWarning(
"QArkUi: got node event with null userData, ignoring");
238 auto *self =
reinterpret_cast<Node *>(userData);
240 auto eventType = ::OH_ArkUI_NodeEvent_GetEventType(event);
242 auto eventHandlerIter = self->m_eventHandlers.find(eventType);
243 if (eventHandlerIter != self->m_eventHandlers.end())
244 eventHandlerIter->second(event);
246 qOhosPrintfWarning(
"QArkUi: got node event type %d with no handler set, ignoring", eventType);
250 m_eventHandlers.erase(eventType);
252 auto eventRegistrationHandle = registerNodeEvent(handle(), eventType,
this);
254 m_eventHandlers.emplace(
256 [eventRegistrationHandle, eventHandler = std::move(eventHandler)](ArkUI_NodeEvent *event) {
261void Node::setAttributeOrFail(
262 ::ArkUI_NodeAttributeType attributeType,
263 std::size_t numberCount,
const ::ArkUI_NumberValue *numbers)
265 ::ArkUI_AttributeItem item = {
267 .size =
static_cast<
std::int32_t>(numberCount),
270 setNodeAttributeOrFail(handle(), attributeType, {item});
273std::unique_ptr<Node>
Node::takeOwnershipOfExternalNode(::ArkUI_NodeHandle nodeHandle)
275 if (nodeHandle ==
nullptr)
276 qOhosReportFatalErrorAndAbort(
"nodeHandle must not be null");
278 return std::unique_ptr<Node>(
new Node(nodeHandle));
281bool Node::isQtManagedNode(::ArkUI_NodeHandle nodeHandle)
283 return qtManagedNodes.find(nodeHandle) != qtManagedNodes.end();
286::ArkUI_NumberValue
Node::getNumberValueAttributeOrFail(::ArkUI_NodeAttributeType attributeType)
const
288 const auto *item = nativeNodeApi().getAttribute(handle(), attributeType);
289 if (item ==
nullptr) {
290 qOhosReportFatalErrorAndAbort(
291 "QArkUi: Failed to retrieve node: %p attribute: %d", handle(), attributeType);
304 auto errorCode = nativeNodeApi().setLengthMetricUnit(handle(), unit);
305 if (errorCode != ::ARKUI_ERROR_CODE_NO_ERROR) {
306 qOhosReportFatalErrorAndAbort(
307 "setLengthMetricUnit failed for node: %p with error: %d", handle(), errorCode);
311QOhosOptional<::ArkUI_NodeHandle>
Node::tryfindChild(
312 ::ArkUI_NodeHandle nodeHandle,
const std::function<
bool(::ArkUI_NodeHandle)> predicate)
314 const auto childCount = nativeNodeApi().getTotalChildCount(nodeHandle);
315 for (
std::uint32_t i = 0; i < childCount; ++i) {
316 auto *childNodeHandle = nativeNodeApi().getChildAt(nodeHandle, i);
317 if (predicate(childNodeHandle))
318 return makeQOhosOptional(childNodeHandle);
void setAttributeOrFail(::ArkUI_NodeAttributeType attributeType, bool value)
void setAttributeOrFail(::ArkUI_NodeAttributeType attributeType, std::uint32_t value)
void setAttributeOrFail(::ArkUI_NodeAttributeType attributeType, std::int32_t value)
void setAttributeOrFail(::ArkUI_NodeAttributeType attributeType, const std::string &value)
void setEventHandler(::ArkUI_NodeEventType eventType, std::function< void(::ArkUI_NodeEvent *)> eventHandler)
::ArkUI_NodeHandle handle() const
void removeChildOrFail(Node &child)
void setLengthMetricUnitOrFail(::ArkUI_LengthMetricUnit unit)
void setAttributeOrFail(::ArkUI_NodeAttributeType attributeType, float value)
void addChildOrFail(Node &child)
std::int32_t Node::getAttributeOrFail< std::int32_t >(::ArkUI_NodeAttributeType attributeType) const
Combined button and popup list for selecting options.
QOhosOptional< void > makeEmptyQOhosOptional()