Skip to content

Commit

Permalink
feat(ohos): custom component solution modification
Browse files Browse the repository at this point in the history
  • Loading branch information
sohotz authored and etkmao committed Mar 6, 2025
1 parent 2ea1d1e commit 382d395
Show file tree
Hide file tree
Showing 11 changed files with 68 additions and 66 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,8 @@ export struct ExampleComponentA {
ForEach(this.children, (item: HippyRenderBaseView) => {
buildHippyRenderView(item, null)
}, (item: HippyRenderBaseView) => item.tag + '')
// 该自定义组件有Hippy子组件或其它自定义子组件时,必须加Slot来衔接子组件
ContentSlot(this.renderView.childSlot)
}
.applyRenderViewBaseAttr(this.renderView)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,8 @@ export struct ExampleComponentB {
build() {
Stack() {
Text("This is a custom component B.")
// 该自定义组件有Hippy子组件或其它自定义子组件时,必须加Slot来衔接子组件
ContentSlot(this.renderView.childSlot)
}
.applyRenderViewBaseAttr(this.renderView)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,10 @@ inline namespace native {

class CustomTsView : public BaseView {
public:
CustomTsView(std::shared_ptr<NativeRenderContext> &ctx, ArkUI_NodeHandle nodeHandle);
CustomTsView(std::shared_ptr<NativeRenderContext> &ctx, ArkUI_NodeHandle nodeHandle, ArkUI_NodeContentHandle contentHandle);
~CustomTsView();

StackNode *GetLocalRootArkUINode() override;
CustomTsNode *GetLocalRootArkUINode() override;
void CreateArkUINodeImpl() override;
void DestroyArkUINodeImpl() override;
bool SetPropImpl(const std::string &propKey, const HippyValue &propValue) override;
Expand All @@ -50,11 +50,11 @@ class CustomTsView : public BaseView {
void OnCustomTsViewChildInserted(uint32_t tag, std::shared_ptr<BaseView> const &childView, int32_t index);
void OnCustomTsViewChildRemoved(uint32_t tag, std::shared_ptr<BaseView> const &childView, int32_t index);

std::shared_ptr<StackNode> containerNode_;
std::shared_ptr<CustomTsNode> tsNode_;
std::shared_ptr<StackNode> subContainerNode_;
std::shared_ptr<StackNode> contentNode_;

ArkUI_NodeHandle customNodeHandle_ = nullptr;
ArkUI_NodeContentHandle contentHandle_ = nullptr;
};

} // namespace native
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,51 +32,50 @@ namespace hippy {
inline namespace render {
inline namespace native {

CustomTsView::CustomTsView(std::shared_ptr<NativeRenderContext> &ctx, ArkUI_NodeHandle nodeHandle) : BaseView(ctx), customNodeHandle_(nodeHandle) {
CustomTsView::CustomTsView(std::shared_ptr<NativeRenderContext> &ctx, ArkUI_NodeHandle nodeHandle,
ArkUI_NodeContentHandle contentHandle) : BaseView(ctx), customNodeHandle_(nodeHandle), contentHandle_(contentHandle) {

}

CustomTsView::~CustomTsView() {
if (!children_.empty()) {
if (subContainerNode_) {
if (contentNode_) {
for (const auto &child : children_) {
subContainerNode_->RemoveChild(child->GetLocalRootArkUINode());
contentNode_->RemoveChild(child->GetLocalRootArkUINode());
}
}
children_.clear();
}
if (containerNode_) {
containerNode_->RemoveChild(tsNode_.get());
containerNode_->RemoveChild(subContainerNode_.get());
}
if (customNodeHandle_) {
NativeNodeApi::GetInstance()->disposeNode(customNodeHandle_);
customNodeHandle_ = nullptr;
}
contentHandle_ = nullptr;
}

StackNode *CustomTsView::GetLocalRootArkUINode() {
return containerNode_.get();
CustomTsNode *CustomTsView::GetLocalRootArkUINode() {
return tsNode_.get();
}

void CustomTsView::CreateArkUINodeImpl() {
containerNode_ = std::make_shared<StackNode>();
tsNode_ = std::make_shared<CustomTsNode>(customNodeHandle_);
tsNode_->MarkReleaseHandle(false);
subContainerNode_ = std::make_shared<StackNode>();

containerNode_->AddChild(tsNode_.get());
containerNode_->AddChild(subContainerNode_.get());
containerNode_->SetClip(true);
subContainerNode_->SetWidthPercent(1.f);
subContainerNode_->SetHeightPercent(1.f);
subContainerNode_->SetHitTestMode(ARKUI_HIT_TEST_MODE_NONE);
contentNode_ = std::make_shared<StackNode>();
contentNode_->SetWidthPercent(1.f);
contentNode_->SetHeightPercent(1.f);
contentNode_->SetHitTestMode(ARKUI_HIT_TEST_MODE_NONE);
if (contentHandle_) {
OH_ArkUI_NodeContent_RegisterCallback(contentHandle_, nullptr);
OH_ArkUI_NodeContent_AddNode(contentHandle_, contentNode_->GetArkUINodeHandle());
}
}

void CustomTsView::DestroyArkUINodeImpl() {
containerNode_ = nullptr;
if (contentHandle_) {
OH_ArkUI_NodeContent_RemoveNode(contentHandle_, contentNode_->GetArkUINodeHandle());
}
tsNode_ = nullptr;
subContainerNode_ = nullptr;
contentNode_ = nullptr;
}

bool CustomTsView::SetPropImpl(const std::string &propKey, const HippyValue &propValue) {
Expand All @@ -99,12 +98,12 @@ void CustomTsView::OnChildRemoved(std::shared_ptr<BaseView> const &childView, in

void CustomTsView::OnChildInsertedImpl(std::shared_ptr<BaseView> const &childView, int32_t index) {
BaseView::OnChildInsertedImpl(childView, index);
subContainerNode_->InsertChild(childView->GetLocalRootArkUINode(), index);
contentNode_->InsertChild(childView->GetLocalRootArkUINode(), index);
}

void CustomTsView::OnChildRemovedImpl(std::shared_ptr<BaseView> const &childView, int32_t index) {
BaseView::OnChildRemovedImpl(childView, index);
subContainerNode_->RemoveChild(childView->GetLocalRootArkUINode());
contentNode_->RemoveChild(childView->GetLocalRootArkUINode());
}

void CustomTsView::OnCustomTsViewChildInserted(uint32_t tag, std::shared_ptr<BaseView> const &childView, int32_t index) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -545,7 +545,7 @@ HRRect HRViewManager::GetViewFrameInRoot(uint32_t node_id) {
}

void HRViewManager::AddBizViewInRoot(uint32_t biz_view_id, ArkUI_NodeHandle node_handle, const HRPosition &position) {
auto view = std::make_shared<CustomTsView>(ctx_, node_handle);
auto view = std::make_shared<CustomTsView>(ctx_, node_handle, nullptr);
view->Init();
view->SetTag(biz_view_id);
view->SetViewType("BizView");
Expand Down Expand Up @@ -589,24 +589,33 @@ std::shared_ptr<BaseView> HRViewManager::CreateCustomTsRenderView(uint32_t tag,
};

auto delegateObject = arkTs.GetObject(ts_render_provider_ref_);
napi_value tsNode = delegateObject.Call("createRenderViewForCApi", args);
napi_value nodeResult = delegateObject.Call("createRenderViewForCApi", args);

napi_valuetype type = arkTs.GetType(tsNode);
if (type == napi_null) {
FOOTSTONE_LOG(ERROR) << "create ts view error, tsNode null";
napi_valuetype type = arkTs.GetType(nodeResult);
if (type != napi_object) {
FOOTSTONE_LOG(ERROR) << "create ts view error, nodeResult not object";
return nullptr;
}


napi_value frameNode = arkTs.GetObjectProperty(nodeResult, "frameNode");
ArkUI_NodeHandle nodeHandle = nullptr;
auto status = OH_ArkUI_GetNodeHandleFromNapiValue(ts_env_, tsNode, &nodeHandle);
auto status = OH_ArkUI_GetNodeHandleFromNapiValue(ts_env_, frameNode, &nodeHandle);
if (status != ARKUI_ERROR_CODE_NO_ERROR) {
FOOTSTONE_LOG(ERROR) << "create ts view error, nodeHandle fail, status: " << status << ", nodeHandle: " << nodeHandle;
return nullptr;
}

napi_value childSlot = arkTs.GetObjectProperty(nodeResult, "childSlot");
ArkUI_NodeContentHandle contentHandle = nullptr;
status = OH_ArkUI_GetNodeContentFromNapiValue(ts_env_, childSlot, &contentHandle);
if (status != ARKUI_ERROR_CODE_NO_ERROR) {
FOOTSTONE_LOG(ERROR) << "create ts view error, contentHandle fail, status: " << status << ", contentHandle: " << contentHandle;
return nullptr;
}

napi_close_handle_scope(ts_env_, scope);

auto view = std::make_shared<CustomTsView>(ctx_, nodeHandle);
auto view = std::make_shared<CustomTsView>(ctx_, nodeHandle, contentHandle);
view->Init();
view->SetTag(tag);
view->SetViewType(view_name);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,19 @@
import { HippyAny, HippyMap } from '../support/common/HippyTypes'
import HippyRenderBaseView from './components/base/HippyRenderBaseView'
import { HRWeb, HRWebView } from './components/web/HRWebView'
import { NodeContent } from '@kit.ArkUI'

export interface CreateRenderViewParamsForCApi {
rootTag: number
tag: number
viewName: string
}

export interface CreateRenderViewResultForCApi {
frameNode?: FrameNode
childSlot?: NodeContent
}

export interface RemoveRenderViewParamsForCApi {
rootTag: number
tag: number
Expand Down
10 changes: 6 additions & 4 deletions framework/ohos/src/main/ets/renderer_native/NativeRenderImpl.ets
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import {
buildHippyRenderViewForCApi,
CallRenderViewMethodParamsForCApi,
CreateRenderViewParamsForCApi,
CreateRenderViewResultForCApi,
OnChildInsertedParamsForCApi,
OnChildRemovedParamsForCApi,
RemoveRenderViewParamsForCApi,
Expand Down Expand Up @@ -65,7 +66,7 @@ import { HRDisplaySyncUtils } from './utils/HRDisplaySyncUtils'
import { HRMeasureResult } from './utils/HRMeasure'
import { HRPosition, HRRect, HRSize } from './utils/HRTypes'
import { HRValueUtils } from './utils/HRValueUtils'
import { BuilderNode, FrameNode } from '@kit.ArkUI'
import { BuilderNode, FrameNode, NodeContent } from '@kit.ArkUI'
import HippyRenderBaseView from './components/base/HippyRenderBaseView'
import { HippyRootView } from '.'
import {
Expand Down Expand Up @@ -642,7 +643,7 @@ key1 value1
}

// for c-api
createRenderViewForCApi(params: CreateRenderViewParamsForCApi): FrameNode | null {
createRenderViewForCApi(params: CreateRenderViewParamsForCApi): CreateRenderViewResultForCApi | null {
let viewManager = this.renderManager.getViewManager(params.rootTag)
if (!viewManager) {
return null
Expand All @@ -655,7 +656,8 @@ key1 value1

let context = AppStorage.get<UIContext>('UIContextForHippy');

let view = viewManager.createRenderViewForCApi(params.tag, params.viewName)
let childSlot: NodeContent = new NodeContent()
let view = viewManager.createRenderViewForCApi(params.tag, params.viewName, childSlot)
if (!view) {
return null
}
Expand All @@ -666,7 +668,7 @@ key1 value1
let builderNodeManger = this.renderManager.getBuilerNodeManager(params.rootTag)
builderNodeManger?.addCustomViewBuilderNode(params.tag, builderNode)

return builderNode.getFrameNode()!;
return { frameNode: builderNode.getFrameNode()!, childSlot: childSlot }
}

// for c-api
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { HRRenderViewCreator } from './components/HippyRenderRegisterMap';
import {
CallRenderViewMethodParamsForCApi,
CreateRenderViewParamsForCApi,
CreateRenderViewResultForCApi,
OnChildInsertedParamsForCApi,
OnChildRemovedParamsForCApi,
RemoveRenderViewParamsForCApi,
Expand Down Expand Up @@ -301,7 +302,7 @@ export class NativeRenderProvider {
}

// for c-api
createRenderViewForCApi(params: CreateRenderViewParamsForCApi): FrameNode | null {
createRenderViewForCApi(params: CreateRenderViewParamsForCApi): CreateRenderViewResultForCApi | null {
return this.renderImpl.createRenderViewForCApi(params)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,11 @@ import { NativeRenderContext } from '../../NativeRenderContext'
import { HRMeasureMode, HRMeasureResult } from '../../utils/HRMeasure'
import { HRPadding, HRRect } from '../../utils/HRTypes'
import HippyRenderBaseView from '../base/HippyRenderBaseView'
import { NodeContent } from '@kit.ArkUI'

export class HippyCustomComponentView extends HippyRenderBaseView {
childSlot: NodeContent | null = null

constructor(ctx: NativeRenderContext) {
super(ctx)
}
Expand All @@ -32,19 +35,6 @@ export class HippyCustomComponentView extends HippyRenderBaseView {
return super.setProp(propKey, propValue)
}

updateRenderViewFrame(frame: HRRect, padding: HRPadding | null): void {
// For c api, the position is used by container node.
if (this.ctx.getNativeRender().isEnableArkCApi()) {
this.cssPositionX = 0
this.cssPositionY = 0
} else {
this.cssPositionX = frame.x
this.cssPositionY = frame.y
}
this.cssWidth = frame.width
this.cssHeight = frame.height
}

call(method: string, params: Array<HippyAny>, callback: HippyRenderCallback | null): void {

}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,19 +126,6 @@ export class HRWebView extends HippyRenderBaseView {
}
}

protected updateRenderViewFrame(frame: HRRect, padding: HRPadding | null): void {
// For c api, web view is a custom ts view, the position is used by container node.
if (this.ctx.getNativeRender().isEnableArkCApi()) {
this.cssPositionX = 0
this.cssPositionY = 0
} else {
this.cssPositionX = frame.x
this.cssPositionY = frame.y
}
this.cssWidth = frame.width
this.cssHeight = frame.height
}

call(method: string, params: Array<HippyAny>, callback: HippyRenderCallback | null): void {
switch (method) {
case "loadUrl":
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import { HRCreateMutation,
HRUpdateEventListenerMutation,
HRUpdateLayoutMutation,
HRUpdateMutation } from './HRMutation'
import { NodeContent } from '@kit.ArkUI'

export type HippyEndBatchCallback = () => void

Expand Down Expand Up @@ -292,7 +293,7 @@ export class HRViewManager {
}

// for c-api
createRenderViewForCApi(tag: number, viewName: string): HippyRenderBaseView | null {
createRenderViewForCApi(tag: number, viewName: string, childSlot: NodeContent): HippyRenderBaseView | null {
let renderView: HippyRenderBaseView | null = null
if (viewName == "WebView") {
renderView = new HRWebView(this.ctx);
Expand All @@ -302,6 +303,9 @@ export class HRViewManager {
let creator = customCreatorMap.get(viewName)
if (creator) {
renderView = creator(this.ctx)
if (renderView) {
(renderView as HippyCustomComponentView).childSlot = childSlot
}
}
}
}
Expand Down

0 comments on commit 382d395

Please sign in to comment.