* 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 REFRESH_MAKER_H
#define REFRESH_MAKER_H
#include <functional>
#include <memory>
#include <arkui/native_node.h>
#include <arkui/native_type.h>
#include "ScrollableNode.h"
inline constexpr int32_t K_REFRESH_OFFSET_DATA_INDEX = 0;
inline constexpr int32_t K_REFRESH_STATE_DATA_INDEX = 0;
class RefreshMaker : public BaseNode {
public:
static ArkUI_NodeHandle CreateNativeNode();
RefreshMaker()
: BaseNode(NodeApiInstance::GetInstance()->GetNativeNodeAPI()->createNode(ARKUI_NODE_REFRESH)),
registrar_(nodeApi_, GetHandle())
{
nodeApi_->addNodeEventReceiver(GetHandle(), StaticEvent);
}
void SetRefreshing(bool refreshing)
{
ArkUI_NumberValue v[]{{.i32 = refreshing ? 1 : 0}};
ArkUI_AttributeItem item{v, 1};
nodeApi_->setAttribute(GetHandle(), NODE_REFRESH_REFRESHING, &item);
}
void SetHeaderContent(const std::shared_ptr<BaseNode> &header)
{
if (header == nullptr) {
nodeApi_->resetAttribute(GetHandle(), NODE_REFRESH_CONTENT);
header_.reset();
return;
}
ArkUI_AttributeItem item{nullptr, 0, nullptr, header->GetHandle()};
nodeApi_->setAttribute(GetHandle(), NODE_REFRESH_CONTENT, &item);
header_ = header;
}
void SetPullDownRatio(float ratio)
{
ArkUI_NumberValue v[]{{.f32 = ratio}};
ArkUI_AttributeItem item{v, 1};
nodeApi_->setAttribute(GetHandle(), NODE_REFRESH_PULL_DOWN_RATIO, &item);
}
void SetRefreshOffset(float vp)
{
ArkUI_NumberValue v[]{{.f32 = vp}};
ArkUI_AttributeItem item{v, 1};
nodeApi_->setAttribute(GetHandle(), NODE_REFRESH_OFFSET, &item);
}
void SetPullToRefresh(bool enable)
{
ArkUI_NumberValue v[]{{.i32 = enable ? 1 : 0}};
ArkUI_AttributeItem item{v, 1};
nodeApi_->setAttribute(GetHandle(), NODE_REFRESH_PULL_TO_REFRESH, &item);
}
void SetMaxPullDownDistance(float vp)
{
ArkUI_NumberValue v[]{{.f32 = vp}};
ArkUI_AttributeItem item{v, 1};
nodeApi_->setAttribute(GetHandle(), NODE_REFRESH_MAX_PULL_DOWN_DISTANCE, &item);
}
void AttachChild(const std::shared_ptr<BaseNode> &child)
{
if (child != nullptr) {
AddChild(child);
}
}
void RegisterOnRefresh(const std::function<void()> &cb)
{
onRefresh_ = cb;
registrar_.RegisterEvent(NODE_REFRESH_ON_REFRESH, this);
}
void RegisterOnOffsetChange(const std::function<void(float)> &cb)
{
onOffsetChange_ = cb;
registrar_.RegisterEvent(NODE_REFRESH_ON_OFFSET_CHANGE, this);
}
void RegisterOnStateChange(const std::function<void(int32_t)> &cb)
{
onStateChange_ = cb;
registrar_.RegisterEvent(NODE_REFRESH_STATE_CHANGE, this);
}
private:
static void StaticEvent(ArkUI_NodeEvent *ev)
{
if (ev == nullptr) {
return;
}
auto *self = reinterpret_cast<RefreshMaker *>(OH_ArkUI_NodeEvent_GetUserData(ev));
if (self == nullptr) {
return;
}
self->OnNodeEvent(ev);
}
void OnNodeEvent(ArkUI_NodeEvent *ev) override
{
const int32_t type = OH_ArkUI_NodeEvent_GetEventType(ev);
ArkUI_NodeComponentEvent *ce = OH_ArkUI_NodeEvent_GetNodeComponentEvent(ev);
switch (type) {
case NODE_REFRESH_ON_REFRESH:
if (onRefresh_) {
onRefresh_();
}
break;
case NODE_REFRESH_ON_OFFSET_CHANGE:
if (ce != nullptr && onOffsetChange_) {
onOffsetChange_(ce->data[K_REFRESH_OFFSET_DATA_INDEX].f32);
}
break;
case NODE_REFRESH_STATE_CHANGE:
if (ce != nullptr && onStateChange_) {
onStateChange_(ce->data[K_REFRESH_STATE_DATA_INDEX].i32);
}
break;
default:
break;
}
}
private:
std::shared_ptr<BaseNode> header_;
std::function<void()> onRefresh_;
std::function<void(float)> onOffsetChange_;
std::function<void(int32_t)> onStateChange_;
NodeEventRegistrar registrar_;
};
#endif