* Copyright (c) 2025 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef MYAPPLICATION_ARKUIBASENODE_H
#define MYAPPLICATION_ARKUIBASENODE_H
#include <arkui/native_type.h>
#include <list>
#include <memory>
#include <hilog/log.h>
#include "NativeModule.h"
namespace NativeModule {
class ArkUIBaseNode {
public:
explicit ArkUIBaseNode(ArkUI_NodeHandle handle)
: handle_(handle), nativeModule_(NativeModuleInstance::GetInstance()->GetNativeNodeAPI()) {}
virtual ~ArkUIBaseNode()
{
if (!children_.empty()) {
for (const auto &child : children_) {
nativeModule_->removeChild(handle_, child->GetHandle());
}
children_.clear();
}
nativeModule_->disposeNode(handle_);
}
void AddChild(const std::shared_ptr<ArkUIBaseNode> &child)
{
children_.emplace_back(child);
OnAddChild(child);
}
void RemoveChild(const std::shared_ptr<ArkUIBaseNode> &child)
{
children_.remove(child);
OnRemoveChild(child);
}
void InsertChild(const std::shared_ptr<ArkUIBaseNode> &child, int32_t index)
{
if (index >= children_.size()) {
AddChild(child);
} else {
auto iter = children_.begin();
std::advance(iter, index);
children_.insert(iter, child);
OnInsertChild(child, index);
}
}
void InsertChildBefore(const std::shared_ptr<ArkUIBaseNode> &child,
const std::shared_ptr<ArkUIBaseNode> &slibing)
{
auto it = std::find(children_.begin(), children_.end(), slibing);
if (it != children_.end()) {
children_.insert(it, child);
}
OnInsertChildBefore(child, slibing);
}
void InsertChildAfter(const std::shared_ptr<ArkUIBaseNode> &child,
const std::shared_ptr<ArkUIBaseNode> &slibing)
{
auto it = std::find(children_.begin(), children_.end(), slibing);
if (it != children_.end()) {
children_.insert(std::next(it), child);
}
OnInsertChildAfter(child, slibing);
}
void RemoveAllChild()
{
for (auto it = children_.begin(); it != children_.end();) {
RemoveChild(*it);
}
OnRemoveAllChild();
}
ArkUI_NodeHandle (*getChildAt)(ArkUI_NodeHandle node, int32_t position);
ArkUI_NodeHandle (*getFirstChild)(ArkUI_NodeHandle node);
ArkUI_NodeHandle (*getLastChild)(ArkUI_NodeHandle node);
ArkUI_NodeHandle (*getPreviousSibling)(ArkUI_NodeHandle node);
ArkUI_NodeHandle (*getNextSibling)(ArkUI_NodeHandle node);
ArkUI_NodeHandle GetParent() const { return nativeModule_->getParent(handle_); }
ArkUI_NodeHandle GetChildAt(uint32_t index) const { return nativeModule_->getChildAt(handle_, index); }
ArkUI_NodeHandle GetFirstChild() const { return nativeModule_->getFirstChild(handle_); }
ArkUI_NodeHandle GetLastChild() const { return nativeModule_->getLastChild(handle_); }
ArkUI_NodeHandle GetPreviousSibling() const { return nativeModule_->getPreviousSibling(handle_); }
ArkUI_NodeHandle GetNextSibling() const { return nativeModule_->getNextSibling(handle_); }
ArkUI_NodeHandle GetParentInPageTree() const { return OH_ArkUI_NodeUtils_GetParentInPageTree(handle_); }
ArkUI_NodeHandle GetCurrentPageRootNode() const
{
auto rootNode = OH_ArkUI_NodeUtils_GetCurrentPageRootNode(handle_);
int32_t uniqueId = -1;
OH_ArkUI_NodeUtils_GetNodeUniqueId(handle_, &uniqueId);
auto nodeType = OH_ArkUI_NodeUtils_GetNodeType(handle_);
OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00, "BaseNode",
"Print base node info, uniqueId%{public}d, type:%{public}d, ", uniqueId, nodeType);
return rootNode;
}
ArkUI_NodeHandle GetActiveChildrenByIndex(uint32_t index) const
{
ArkUI_ActiveChildrenInfo *childrenInfo;
OH_ArkUI_NodeUtils_GetActiveChildrenInfo(handle_, &childrenInfo);
auto count = OH_ArkUI_ActiveChildrenInfo_GetCount(childrenInfo);
ArkUI_NodeHandle child;
if (index < count) {
child = OH_ArkUI_ActiveChildrenInfo_GetNodeByIndex(childrenInfo, index);
int32_t uniqueId = -1;
OH_ArkUI_NodeUtils_GetNodeUniqueId(child, &uniqueId);
auto nodeType = OH_ArkUI_NodeUtils_GetNodeType(child);
OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00, "BaseNode",
"Print child info, uniqueId%{public}d, type:%{public}d, ", uniqueId, nodeType);
}
OH_ArkUI_ActiveChildrenInfo_Destroy(childrenInfo);
return child;
}
uint32_t GetFirstChildIndexWithoutExpand() const
{
uint32_t index = -1;
OH_ArkUI_NodeUtils_GetFirstChildIndexWithoutExpand(handle_, &index);
return index;
}
uint32_t GetLastChildIndexWithoutExpand() const
{
uint32_t index = -1;
OH_ArkUI_NodeUtils_GetLastChildIndexWithoutExpand(handle_, &index);
return index;
}
ArkUI_NodeHandle GetChildWithExpandMode(uint32_t index) const
{
ArkUI_NodeHandle subNode;
auto result = OH_ArkUI_NodeUtils_GetChildWithExpandMode(handle_, index, &subNode, ARKUI_LAZY_EXPAND);
if (result == ARKUI_ERROR_CODE_NO_ERROR) {
return subNode;
}
return nullptr;
}
void MarkDirty()
{
nativeModule_->markDirty(handle_, NODE_NEED_MEASURE);
nativeModule_->markDirty(handle_, NODE_NEED_LAYOUT);
nativeModule_->markDirty(handle_, NODE_NEED_RENDER);
}
void SetLengthMetricUnit(ArkUI_LengthMetricUnit unit) { nativeModule_->setLengthMetricUnit(handle_, unit); }
void AddCustomProperty(const char *name, const char *value)
{
OH_ArkUI_NodeUtils_AddCustomProperty(handle_, name, value);
}
void RemoveCustomProperty(const char *name) { OH_ArkUI_NodeUtils_RemoveCustomProperty(handle_, name); }
const char* GetCustomProperty(const char *name)
{
ArkUI_CustomProperty *property;
OH_ArkUI_NodeUtils_GetCustomProperty(handle_, name, &property);
auto value = OH_ArkUI_CustomProperty_GetStringValue(property);
OH_LOG_Print(LOG_APP, LOG_INFO, 0xFF00, "BaseNode", "Get CP name-value: %{public}s - %{public}s",
name, value);
OH_ArkUI_CustomProperty_Destroy(property);
return value;
}
void MoveTo(const std::shared_ptr<ArkUIBaseNode> &anotherParent)
{
OH_ArkUI_NodeUtils_MoveTo(handle_, anotherParent->GetHandle(), -1);
}
ArkUI_NodeHandle GetHandle() const { return handle_; }
protected:
virtual void OnAddChild(const std::shared_ptr<ArkUIBaseNode> &child) {}
virtual void OnRemoveChild(const std::shared_ptr<ArkUIBaseNode> &child) {}
virtual void OnRemoveAllChild() {}
virtual void OnInsertChild(const std::shared_ptr<ArkUIBaseNode> &child, int32_t index) {}
virtual void OnInsertChildBefore(const std::shared_ptr<ArkUIBaseNode> &child,
const std::shared_ptr<ArkUIBaseNode> &slibing) {}
virtual void OnInsertChildAfter(const std::shared_ptr<ArkUIBaseNode> &child,
const std::shared_ptr<ArkUIBaseNode> &slibing) {}
ArkUI_NodeHandle handle_;
ArkUI_NativeNodeAPI_1 *nativeModule_ = nullptr;
private:
std::list<std::shared_ptr<ArkUIBaseNode>> children_;
};
}
#endif