Fetch the repository succeeded.
This action will force synchronization from OpenHarmony/docs, which will overwrite any changes that you have made since you forked the repository, and can not be recovered!!!
Synchronous operation will process in the background and will refresh the page when finishing processing. Please be patient.
import {
FrameNode,
NodeController,
RenderNode,
DrawContext,
BuilderNode,
RenderOptions,
Position
} from '@ohos.arkui.node';
import { UIContext } from '@ohos.arkui.UIContext';
import { Size } from '@ohos/hypium/src/main/Constant';
class CommonStyleModifier implements AttributeModifier<CommonAttribute> {
_size: SizeOptions = { width: 0, height: 0 };
_backgroundColor: ResourceColor = Color.Transparent;
applyNormalAttribute(instance: CommonAttribute): void {
instance.size(this._size);
instance.backgroundColor(this._backgroundColor);
}
size(size: SizeOptions): CommonStyleModifier {
this._size = size
return this
}
backgroundColor(color: ResourceColor): CommonStyleModifier {
this._backgroundColor = color
return this
}
}
class ImageStyleModifier implements AttributeModifier<ImageAttribute> {
_imageFit: ImageFit = ImageFit.None;
applyNormalAttribute(instance: ImageAttribute): void {
instance.objectFit(this._imageFit);
}
imageFit(imageFit: ImageFit): ImageStyleModifier {
this._imageFit = imageFit
return this
}
}
class BuilderParams {
}
class DivBuilderParams extends BuilderParams {
commonModifier: CommonStyleModifier;
constructor(commonModifier: CommonStyleModifier) {
super()
this.commonModifier = commonModifier;
}
}
class ImageBuilderParams extends BuilderParams {
commonModifier: CommonStyleModifier;
imageModifier: ImageStyleModifier;
src: string;
constructor(commonModifier: CommonStyleModifier, imageModifier: ImageStyleModifier, src: string) {
super()
this.commonModifier = commonModifier;
this.imageModifier = imageModifier;
this.src = src;
}
}
@Builder
function divBuilder(param: Object) {
Stack() {
}.attributeModifier((param as DivBuilderParams).commonModifier);
// Stack() {
// }
// .width((param as DivBuilderParams).commonModifier._size.width)
// .height((param as DivBuilderParams).commonModifier._size.height)
// .backgroundColor((param as DivBuilderParams).commonModifier._backgroundColor);
}
@Builder
function imageBuilder(param: Object) {
// Image($r((param as ImageBuilderParams).src))
// .attributeModifier((param as ImageBuilderParams).commonModifier)
// .attributeModifier((param as ImageBuilderParams).imageModifier);
Image($r((param as ImageBuilderParams).src))
.width((param as ImageBuilderParams).commonModifier._size.width)
.height((param as ImageBuilderParams).commonModifier._size.height)
.backgroundColor((param as ImageBuilderParams).commonModifier._backgroundColor)
.objectFit((param as ImageBuilderParams).imageModifier._imageFit);
}
class CKRenderNode {
protected _renderNode: RenderNode | null = null;
protected _id: number = 0;
protected _tag: string = '';
protected _pos: Position = { x: 0, y: 0 };
protected _size: Size = { width: 0, height: 0 };
constructor(renderNode: RenderNode | null, pos: Position, size: Size,) {
this._renderNode = renderNode;
this._pos = pos;
this._size = size;
if (renderNode) {
renderNode.position = pos;
renderNode.size = size;
}
}
getRenderNode(): RenderNode | null {
return this._renderNode;
}
}
@Builder
function DivBuilder(param: Object) {
// TODO: @zhaojie.szj 会 crash, 已反馈给华为侧
// Stack() {
// }.attributeModifier((param as CKBuilderNode).getCommonStyleModifier());
Stack() {
}
// size 100% 100% ? 如果用 100% 调用 update 大小会不对 ??
.size((param as CKBuilderNode).getCommonStyleModifier()._size)
.backgroundColor((param as CKBuilderNode).getCommonStyleModifier()._backgroundColor);
}
@Builder
function ImageBuilder(param: Object) {
// TODO: @zhaojie.szj 会 crash, 已反馈给华为侧
// Image((param as CKImageBuilderNode).src)
// .size({ width: "100%", height: "100%" })
// .attributeModifier((param as CKImageBuilderNode).getImageStyleModifier())
// .attributeModifier((param as CKImageBuilderNode).getCommonStyleModifier());
Image($r((param as CKImageBuilderNode).src))
// size 100% 100% ? 如果用 100% 调用 update 大小会不对 ??
.size((param as CKBuilderNode).getCommonStyleModifier()._size)
.backgroundColor((param as CKImageBuilderNode).getCommonStyleModifier()._backgroundColor)
.objectFit((param as CKImageBuilderNode).getImageStyleModifier()._imageFit);
}
class CKBuilderNode extends CKRenderNode {
private _builderNode: BuilderNode<CKBuilderNode[]>;
private _commonModifier: CommonStyleModifier = new CommonStyleModifier();
private _styles: Record<string, Object> = {};
private _attrs: Record<string, Object> = {};
private _events: Record<string, Object> = {};
constructor(builderNode: BuilderNode<CKBuilderNode[]>, pos: Position, size: Size, styles: Record<string, Object>) {
super(builderNode?.getFrameNode()?.getRenderNode() ?? null, pos, size);
this._builderNode = builderNode;
this._styles = styles;
}
build(builder: WrappedBuilder<CKBuilderNode[]>) {
this._builderNode.build(builder, this);
this._renderNode = this._builderNode.getFrameNode()?.getRenderNode() ?? null;
this._renderNode!.position = this._pos;
this._renderNode!.size = this._size;
}
static makeDivNode(uiContext: UIContext, pos: Position, size: Size,
styles: Record<string, Object>): CKBuilderNode {
// // 不指定 selfIdealSize RenderNode 为空??
// let options: RenderOptions = {
// selfIdealSize: size
// }
let builderNode = new BuilderNode(uiContext);
let divNode = new CKBuilderNode(builderNode, pos, size, styles);
divNode.build(new WrappedBuilder(DivBuilder));
// 要 build 后才能获取到 RenderNode
// builderNode.build(new WrappedBuilder(DivBuilder), divNode);
return divNode;
}
getCommonStyleModifier(): CommonStyleModifier {
return new CommonStyleModifier().size(this._size)
.backgroundColor(this._styles.backgroundColor as ResourceColor);
}
add(node: CKBuilderNode) {
this.getRenderNode()!.appendChild(node.getRenderNode()!);
}
updateStyle(styles: Record<string, Object>) {
this._styles = styles;
this._builderNode.update(this);
}
}
class CKImageBuilderNode extends CKBuilderNode {
private _imageModifier: ImageStyleModifier = new ImageStyleModifier();
private _src: string = '';
constructor(builderNode: BuilderNode<CKImageBuilderNode[]>, pos: Position, size: Size,
styles: Record<string, Object>, imageModifier: ImageStyleModifier, src: string) {
super(builderNode, pos, size, styles);
this._imageModifier = imageModifier;
this._src = src;
}
static makeImageNode(uiContext: UIContext, pos: Position, size: Size,
styles: Record<string, Object>, imageModifier: ImageStyleModifier, src: string): CKBuilderNode {
let builderNode = new BuilderNode(uiContext);
let imageNode = new CKImageBuilderNode(builderNode, pos, size, styles, imageModifier, src);
imageNode.build(new WrappedBuilder(ImageBuilder));
return imageNode;
}
getImageStyleModifier(): ImageStyleModifier {
return new ImageStyleModifier().imageFit(this._imageModifier._imageFit);
}
get src(): string {
return this._src;
}
}
class MyNodeController extends NodeController {
private _width: number = 0;
private _height: number = 0;
private _rootNode: FrameNode | null = null;
private _uiContext: UIContext | null = null;
constructor(width: number, height: number) {
super();
this._width = width;
this._height = height;
}
makeNode(uiContext: UIContext): FrameNode {
this._uiContext = uiContext;
this._rootNode = new FrameNode(uiContext);
const renderNode = this._rootNode.getRenderNode();
if (renderNode) {
renderNode.backgroundColor = Color.White;
renderNode.clipToFrame = true;
renderNode.frame = { x: 0, y: 0, width: this._width, height: this._height };
}
return this._rootNode;
}
appendChild(child: RenderNode): void {
const renderNode = this._rootNode?.getRenderNode();
if (renderNode) {
renderNode.appendChild(child);
}
}
get rootNode(): FrameNode | null {
return this._rootNode;
}
get uiContext(): UIContext | null {
return this._uiContext;
}
}
@Entry
@Component
struct XNodePage {
@State message: string = 'Hello World';
@State commonModifier: CommonStyleModifier = new CommonStyleModifier()
.size({ width: "80%", height: 300 })
.backgroundColor(Color.Red);
@State commonModifier1: CommonStyleModifier = new CommonStyleModifier()
.size({ width: "80%", height: 300 })
.backgroundColor(Color.Yellow);
@State imageModifier: ImageStyleModifier = new ImageStyleModifier()
.imageFit(ImageFit.Auto);
nodeController: MyNodeController = new MyNodeController(300, 300);
containerNode: BuilderNode<BuilderParams[]> | null = null;
createBuilderNode(uiContext: UIContext, w: number, h: number,
builder: WrappedBuilder<BuilderParams[]>,
arg: BuilderParams): BuilderNode<BuilderParams[]> {
let options: RenderOptions = {
selfIdealSize: { width: w, height: h }
}
let builderNode = new BuilderNode(uiContext, options);
builderNode.build(builder, arg);
return builderNode;
}
build() {
Column() {
NodeContainer(this.nodeController)
.width('100%')
.height('50%')
.backgroundColor(Color.Black)
Blank()
.height(50)
Row() {
Button('Init').onClick(() => {
let uiContext = this.nodeController.uiContext;
if (!uiContext) {
return;
}
// let divNode = CKBuilderNode.makeDivNode(uiContext, { x: 0, y: 0 }, { width: 100, height: 100 },
// { "backgroundColor": Color.Red });
// this.nodeController.appendChild(divNode.getRenderNode()!);
//
// let imgNode = CKImageBuilderNode.makeImageNode(uiContext, { x: 0, y: 0 }, { width: 50, height: 50 },
// { "backgroundColor": Color.Blue }, new ImageStyleModifier().imageFit(ImageFit.Auto), 'app.media.icon');
// divNode.add(imgNode);
//
// setTimeout(() => {
// divNode.updateStyle({ "backgroundColor": Color.Green });
// }, 5000);
this.containerNode = this.createBuilderNode(uiContext, 100, 100, new WrappedBuilder(divBuilder), new DivBuilderParams(
new CommonStyleModifier()
.size({
width: 100,
height: 100
})
.backgroundColor(Color.Red)));
this.containerNode.getFrameNode()!.getRenderNode()!.position = { x: 0, y: 0 };
this.containerNode.getFrameNode()!.getRenderNode()!.clipToFrame = true;
this.nodeController.appendChild(this.containerNode.getFrameNode()!.getRenderNode()!);
let img = this.createBuilderNode(uiContext, 50, 50, new WrappedBuilder(imageBuilder), new ImageBuilderParams(
new CommonStyleModifier()
.size({
width: 50,
height: 50
})
.backgroundColor(Color.Blue),
new ImageStyleModifier()
.imageFit(ImageFit.Auto),
'app.media.icon'));
img.getFrameNode()!.getRenderNode()!.position = { x: 0, y: 0 };
this.containerNode.getFrameNode()!.getRenderNode()!.appendChild(img.getFrameNode()!.getRenderNode()!);
// this.nodeController.appendChild(img.getFrameNode()!.getRenderNode()!);
})
Button('Add').onClick(() => {
let div = this.createBuilderNode(this.nodeController.uiContext!, 200, 30, new WrappedBuilder(divBuilder), new DivBuilderParams(
new CommonStyleModifier()
.size({
width: 200,
height: 30
})
.backgroundColor(Color.Yellow)));
div.getFrameNode()!.getRenderNode()!.position = { x: 0, y: 0 };
this.containerNode!.getFrameNode()!.getRenderNode()!.insertChildAfter(div.getFrameNode()!.getRenderNode()!, null);
// div.getFrameNode()!.getRenderNode()!.invalidate();
})
Button('Remove').onClick(() => {
this.containerNode!.getFrameNode()!.getRenderNode()!.removeChild(this.containerNode!.getFrameNode()!.getRenderNode()!.getFirstChild()!);
})
Button('Update').onClick(() => {
this.containerNode!.update(new DivBuilderParams(
new CommonStyleModifier()
.size({
width: 150,
height: 100
})
.backgroundColor(Color.Green)));
this.containerNode!.getFrameNode()!.getRenderNode()!.position = { x: 100, y: 100 };
this.containerNode!.getFrameNode()!.getRenderNode()!.clipToFrame = false;
})
}
.width('100%')
.justifyContent(FlexAlign.SpaceBetween)
}
}
// build() {
// Row() {
// Column() {
// Image($r('app.media.icon'))
// .attributeModifier(this.imageModifier)
// .attributeModifier(this.commonModifier)
// .onClick(() => {
// this.commonModifier.backgroundColor(Color.Yellow)
// })
//
// Stack() {
// }.attributeModifier(this.commonModifier1)
// }
// .width('100%')
// }
// .height('100%')
// }
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。