• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16interface Frame {
17  x: number;
18  y: number;
19  width: number;
20  height: number;
21}
22
23interface Vector2 {
24  x: number
25  y: number
26}
27
28interface Vector3 {
29  x: number;
30  y: number;
31  z: number;
32}
33
34type Transform = [
35  number,
36  number,
37  number,
38  number,
39  number,
40  number,
41  number,
42  number,
43  number,
44  number,
45  number,
46  number,
47  number,
48  number,
49  number,
50  number
51];
52
53enum BorderStyle {
54  SOLID = 0,
55  DASHED,
56  DOTTED,
57  NONE
58}
59
60type EdgeStyles = {
61  top?: BorderStyle;
62  right?: BorderStyle;
63  bottom?: BorderStyle;
64  left?: BorderStyle;
65};
66
67interface EdgesT<T> {
68  left: T,
69  right: T,
70  top: T,
71  bottom: T,
72}
73interface SizeT<T> {
74  width: T;
75  height: T;
76}
77
78enum LengthUnit {
79  PX = 0,
80  VP = 1,
81  FP = 2,
82  PERCENT = 3,
83  LPX = 4,
84}
85
86enum LengthMetricsUnit {
87  DEFAULT = 0,
88  PX = 1,
89}
90
91type EdgeWidths = EdgesT<Number>;
92
93type EdgeColors = EdgesT<Number>;
94
95interface Corners {
96  topLeft: number,
97  topRight: number,
98  bottomLeft: number,
99  bottomRight: number
100}
101
102type BorderRadiuses = Corners;
103
104interface Rect {
105  left: number,
106  right: number,
107  top: number,
108  bottom: number
109}
110
111interface CornerRadius {
112  topLeft: Vector2,
113  topRight: Vector2,
114  bottomLeft: Vector2,
115  bottomRight: Vector2
116}
117
118interface RoundRect {
119  rect: Rect,
120  corners: CornerRadius
121}
122
123interface Circle {
124  centerX: number,
125  centerY: number,
126  radius: number
127}
128
129interface CommandPath {
130  commands: string
131}
132
133class LengthMetrics {
134  public unit: LengthUnit;
135  public value: number;
136  constructor(value: number, unit?: LengthUnit) {
137    if (unit in LengthUnit) {
138      this.unit = unit;
139      this.value = value;
140    } else {
141      this.unit = LengthUnit.VP;
142          this.value = unit === undefined ? value : 0;
143    }
144  }
145  static px(value: number) {
146    return new LengthMetrics(value, LengthUnit.PX);
147  }
148  static vp(value: number) {
149    return new LengthMetrics(value, LengthUnit.VP);
150  }
151  static fp(value: number) {
152    return new LengthMetrics(value, LengthUnit.FP);
153  }
154  static percent(value: number) {
155    return new LengthMetrics(value, LengthUnit.PERCENT);
156  }
157  static lpx(value: number) {
158    return new LengthMetrics(value, LengthUnit.LPX);
159  }
160  static resource(res: Resource) {
161    let length:Array<number> = getUINativeModule().nativeUtils.resoureToLengthMetrics(res);
162    return new LengthMetrics(length[0], length[1]);
163  }
164}
165
166declare interface Resource {}
167declare type BusinessError = any
168
169declare enum Color {
170  White,
171  Black,
172  Blue,
173  Brown,
174  Gray,
175  Green,
176  Grey,
177  Orange,
178  Pink,
179  Red,
180  Yellow,
181  Transparent,
182}
183
184declare type ResourceColor = Color | number | string | Resource;
185
186const MAX_CHANNEL_VALUE = 0xFF;
187const MAX_ALPHA_VALUE = 1;
188const ERROR_CODE_RESOURCE_GET_FAILED = 180003;
189const ERROR_CODE_COLOR_PARAMETER_INCORRECT = 401;
190
191class ColorMetrics {
192  private red_: number;
193  private green_: number;
194  private blue_: number;
195  private alpha_: number;
196  private static clamp(value: number): number {
197    return Math.min(Math.max(value, 0), MAX_CHANNEL_VALUE);
198  }
199  private constructor(red: number, green: number, blue: number, alpha: number = MAX_CHANNEL_VALUE) {
200    this.red_ = ColorMetrics.clamp(red);
201    this.green_ = ColorMetrics.clamp(green);
202    this.blue_ = ColorMetrics.clamp(blue);
203    this.alpha_ = ColorMetrics.clamp(alpha);
204  }
205  private toNumeric(): number {
206    return (this.alpha_ << 24) + (this.red_ << 16) + (this.green_ << 8) + this.blue_;
207  }
208  static numeric(value: number): ColorMetrics {
209    const red = (value >> 16) & 0x000000FF;
210    const green = (value >> 8) & 0x000000FF;
211    const blue = value & 0x000000FF;
212    const alpha = (value >> 24) & 0x000000FF;
213    if (alpha === 0) {
214      return new ColorMetrics(red, green, blue);
215    }
216    return new ColorMetrics(red, green, blue, alpha);
217  }
218  static rgba(red: number, green: number, blue: number, alpha: number = MAX_ALPHA_VALUE): ColorMetrics {
219    return new ColorMetrics(red, green, blue, alpha * MAX_CHANNEL_VALUE);
220  }
221
222  private static rgbOrRGBA(format: string): ColorMetrics {
223    const rgbPattern = /^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i;
224    const rgbaPattern = /^rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+(\.\d+)?)\s*\)$/i;
225
226    const rgbMatch = rgbPattern.exec(format);
227    const rgbaMatch = rgbaPattern.exec(format);
228
229    if (rgbMatch) {
230      const [, red, green, blue] = rgbMatch;
231      return new ColorMetrics(Number.parseInt(red, 10), Number.parseInt(green, 10), Number.parseInt(blue, 10));
232    } else if (rgbaMatch) {
233      const [, red, green, blue, alpha] = rgbaMatch;
234      return new ColorMetrics(Number.parseInt(red, 10), Number.parseInt(green, 10), Number.parseInt(blue, 10), Number.parseFloat(alpha) * MAX_CHANNEL_VALUE);
235    } else {
236      const error = new Error('Parameter error. The format of the input color string is not RGB or RGBA.') as BusinessError;
237      error.code = ERROR_CODE_COLOR_PARAMETER_INCORRECT;
238      throw error;
239    }
240  }
241
242  static resourceColor(color: ResourceColor): ColorMetrics {
243    if (color === undefined || color === null) {
244      const error = new Error('Parameter error. The type of the input color parameter is not ResourceColor.') as BusinessError;
245      error.code = ERROR_CODE_COLOR_PARAMETER_INCORRECT;
246      throw error;
247    }
248    let chanels: Array<number> = [];
249    if (typeof color === 'object') {
250      chanels = getUINativeModule().nativeUtils.parseResourceColor(color);
251      if (chanels === undefined) {
252        const error = new Error('Failed to obtain the color resource.') as BusinessError;
253        error.code = ERROR_CODE_RESOURCE_GET_FAILED;
254        throw error;
255      }
256      const red = chanels[0];
257      const green = chanels[1];
258      const blue = chanels[2];
259      const alpha = chanels[3];
260      return new ColorMetrics(red, green, blue, alpha);
261    } else if (typeof color === 'number') {
262      return ColorMetrics.numeric(color);
263    } else if (typeof color === 'string') {
264      if (ColorMetrics.isHexFormat(color)) {
265        return ColorMetrics.hex(color);
266      } else {
267        return ColorMetrics.rgbOrRGBA(color);
268      }
269    } else {
270      const error = new Error('Parameter error. The type of the input color parameter is not ResourceColor.') as BusinessError;
271      error.code = ERROR_CODE_COLOR_PARAMETER_INCORRECT;
272      throw error;
273    }
274  }
275  private static isHexFormat(format: string): boolean {
276    return /#(([0-9A-Fa-f]{3})|([0-9A-Fa-f]{6})|([0-9A-Fa-f]{4})|([0-9A-Fa-f]{8}))/.test(format);
277  }
278
279  private static hex(hexFormat: string): ColorMetrics {
280    let r: number = 0;
281    let g: number = 0;
282    let b: number = 0;
283    let a: number = 255;
284    if (hexFormat.length === 4) {
285      r = parseInt(hexFormat.slice(1, 2).repeat(2), 16);
286      g = parseInt(hexFormat.slice(2, 3).repeat(2), 16);
287      b = parseInt(hexFormat.slice(3).repeat(2), 16);
288    } else if (hexFormat.length === 7) {
289      r = parseInt(hexFormat.slice(1, 3), 16);
290      g = parseInt(hexFormat.slice(3, 5), 16);
291      b = parseInt(hexFormat.slice(5), 16);
292    } else if (hexFormat.length === 5) {
293      a = parseInt(hexFormat.slice(1, 2).repeat(2), 16);
294      r = parseInt(hexFormat.slice(2, 3).repeat(2), 16);
295      g = parseInt(hexFormat.slice(3, 4).repeat(2), 16);
296      b = parseInt(hexFormat.slice(4).repeat(2), 16);
297    } else if (hexFormat.length === 9) {
298      a = parseInt(hexFormat.slice(1, 3), 16);
299      r = parseInt(hexFormat.slice(3, 5), 16);
300      g = parseInt(hexFormat.slice(5, 7), 16);
301      b = parseInt(hexFormat.slice(7), 16);
302    }
303    return new ColorMetrics(r, g, b, a);
304  }
305  blendColor(overlayColor: ColorMetrics): ColorMetrics {
306    if (overlayColor === undefined || overlayColor === null) {
307      const error = new Error('Parameter error. The type of the input parameter is not ColorMetrics.') as BusinessError;
308      error.code = ERROR_CODE_COLOR_PARAMETER_INCORRECT;
309      throw error;
310    }
311    const chanels = getUINativeModule().nativeUtils.blendColor(this.toNumeric(), overlayColor.toNumeric());
312    if (chanels === undefined) {
313      const error = new Error('Parameter error. The type of the input parameter is not ColorMetrics.') as BusinessError;
314      error.code = ERROR_CODE_COLOR_PARAMETER_INCORRECT;
315      throw error;
316    }
317    const red = chanels[0];
318    const green = chanels[1];
319    const blue = chanels[2];
320    const alpha = chanels[3];
321    return new ColorMetrics(red, green, blue, alpha);
322  }
323  get color(): string {
324    return `rgba(${this.red_}, ${this.green_}, ${this.blue_}, ${this.alpha_ / MAX_CHANNEL_VALUE})`;
325  }
326  get red(): number {
327    return this.red_;
328  }
329  get green(): number {
330    return this.green_;
331  }
332  get blue(): number {
333    return this.blue_;
334  }
335  get alpha(): number {
336    return this.alpha_;
337  }
338}
339
340class BaseShape {
341  public rect: Rect | null = null;
342  public roundRect: RoundRect | null = null;
343  public circle: Circle | null = null;
344  public oval: Rect | null = null;
345  public path: CommandPath | null = null;
346  setRectShape(rect: Rect) {
347    this.rect = rect;
348    this.roundRect = null;
349    this.circle = null;
350    this.oval = null;
351    this.path = null;
352  }
353  setRoundRectShape(roundRect: RoundRect) {
354    this.roundRect = roundRect;
355    this.rect = null;
356    this.circle = null;
357    this.oval = null;
358    this.path = null;
359  }
360  setCircleShape(circle: Circle) {
361    this.circle = circle;
362    this.rect = null;
363    this.roundRect = null;
364    this.oval = null;
365    this.path = null;
366  }
367  setOvalShape(oval: Rect) {
368    this.oval = oval;
369    this.rect = null;
370    this.circle = null;
371    this.roundRect = null;
372    this.path = null;
373  }
374  setCommandPath(path: CommandPath) {
375    this.path = path;
376    this.oval = null;
377    this.rect = null;
378    this.circle = null;
379    this.roundRect = null;
380  }
381}
382
383class ShapeClip extends BaseShape { }
384
385class ShapeMask extends BaseShape {
386  public fillColor: number = 0XFF000000;
387  public strokeColor: number = 0XFF000000;
388  public strokeWidth: number = 0;
389}
390
391class RenderNode {
392  private childrenList: Array<RenderNode>;
393  private nodePtr: NodePtr;
394  private parentRenderNode: WeakRef<RenderNode> | null;
395  private backgroundColorValue: number;
396  private clipToFrameValue: boolean;
397  private frameValue: Frame;
398  private opacityValue: number;
399  private pivotValue: Vector2;
400  private rotationValue: Vector3;
401  private scaleValue: Vector2;
402  private shadowColorValue: number;
403  private shadowOffsetValue: Vector2;
404  private labelValue: string;
405  private shadowAlphaValue: number;
406  private shadowElevationValue: number;
407  private shadowRadiusValue: number;
408  private transformValue: Transform;
409  private translationValue: Vector2;
410  private baseNode_: __JSBaseNode__;
411  private borderStyleValue: EdgeStyles;
412  private borderWidthValue: EdgeWidths;
413  private borderColorValue: EdgeColors;
414  private borderRadiusValue: BorderRadiuses;
415  private shapeMaskValue: ShapeMask;
416  private shapeClipValue: ShapeClip;
417  private _nativeRef: NativeStrongRef;
418  private _frameNode: WeakRef<FrameNode>;
419  private lengthMetricsUnitValue: LengthMetricsUnit;
420  private markNodeGroupValue: boolean;
421  private apiTargetVersion: number;
422
423  constructor(type: string) {
424    this.nodePtr = null;
425    this.childrenList = [];
426    this.parentRenderNode = null;
427    this.backgroundColorValue = 0;
428    this.apiTargetVersion = getUINativeModule().common.getApiTargetVersion();
429    this.clipToFrameValue = true;
430    if (this.apiTargetVersion && this.apiTargetVersion < 12) {
431        this.clipToFrameValue = false;
432    }
433    this.frameValue = { x: 0, y: 0, width: 0, height: 0 };
434    this.opacityValue = 1.0;
435    this.pivotValue = { x: 0.5, y: 0.5 };
436    this.rotationValue = { x: 0, y: 0, z: 0 };
437    this.scaleValue = { x: 1.0, y: 1.0 };
438    this.shadowColorValue = 0;
439    this.shadowOffsetValue = { x: 0, y: 0 };
440    this.labelValue = '';
441    this.shadowAlphaValue = 0;
442    this.shadowElevationValue = 0;
443    this.shadowRadiusValue = 0;
444    this.transformValue = [1, 0, 0, 0,
445      0, 1, 0, 0,
446      0, 0, 1, 0,
447      0, 0, 0, 1];
448    this.translationValue = { x: 0, y: 0 };
449    this.lengthMetricsUnitValue = LengthMetricsUnit.DEFAULT;
450    this.markNodeGroupValue = false;
451    if (type === 'BuilderRootFrameNode' || type === 'CustomFrameNode') {
452      return;
453    }
454    this._nativeRef = getUINativeModule().renderNode.createRenderNode(this);
455    this.nodePtr = this._nativeRef?.getNativeHandle();
456    if (this.apiTargetVersion && this.apiTargetVersion < 12) {
457      this.clipToFrame = false;
458  } else {
459      this.clipToFrame = true;
460  }
461  }
462
463  set backgroundColor(color: number) {
464    this.backgroundColorValue = this.checkUndefinedOrNullWithDefaultValue<number>(color, 0);
465    getUINativeModule().renderNode.setBackgroundColor(this.nodePtr, this.backgroundColorValue);
466  }
467  set clipToFrame(useClip: boolean) {
468    this.clipToFrameValue = this.checkUndefinedOrNullWithDefaultValue<boolean>(useClip, true);
469    getUINativeModule().renderNode.setClipToFrame(this.nodePtr, this.clipToFrameValue);
470  }
471  set frame(frame: Frame) {
472    if (frame === undefined || frame === null) {
473      this.frameValue = { x: 0, y: 0, width: 0, height: 0 };
474    } else {
475      this.size = { width: frame.width, height: frame.height };
476      this.position = { x: frame.x, y: frame.y };
477    }
478  }
479  set opacity(value: number) {
480    this.opacityValue = this.checkUndefinedOrNullWithDefaultValue<number>(value, 1.0);
481    getUINativeModule().common.setOpacity(this.nodePtr, this.opacityValue);
482  }
483  set pivot(pivot: Vector2) {
484    if (pivot === undefined || pivot === null) {
485      this.pivotValue = { x: 0.5, y: 0.5 };
486    } else {
487      this.pivotValue.x = this.checkUndefinedOrNullWithDefaultValue<number>(pivot.x, 0.5);
488      this.pivotValue.y = this.checkUndefinedOrNullWithDefaultValue<number>(pivot.y, 0.5);
489    }
490    getUINativeModule().renderNode.setPivot(this.nodePtr, this.pivotValue.x, this.pivotValue.y);
491  }
492  set position(position: Vector2) {
493    if (position === undefined || position === null) {
494      this.frameValue.x = 0;
495      this.frameValue.y = 0;
496    } else {
497      this.frameValue.x = this.checkUndefinedOrNullWithDefaultValue<number>(position.x, 0);
498      this.frameValue.y = this.checkUndefinedOrNullWithDefaultValue<number>(position.y, 0);
499    }
500    getUINativeModule().renderNode.setPosition(this.nodePtr, this.frameValue.x, this.frameValue.y, this.lengthMetricsUnitValue);
501  }
502  set rotation(rotation: Vector3) {
503    if (rotation === undefined || rotation === null) {
504      this.rotationValue = { x: 0, y: 0, z: 0 };
505    } else {
506      this.rotationValue.x = this.checkUndefinedOrNullWithDefaultValue<number>(rotation.x, 0);
507      this.rotationValue.y = this.checkUndefinedOrNullWithDefaultValue<number>(rotation.y, 0);
508      this.rotationValue.z = this.checkUndefinedOrNullWithDefaultValue<number>(rotation.z, 0);
509    }
510    getUINativeModule().renderNode.setRotation(this.nodePtr, this.rotationValue.x, this.rotationValue.y, this.rotationValue.z, this.lengthMetricsUnitValue);
511  }
512  set scale(scale: Vector2) {
513    if (scale === undefined || scale === null) {
514      this.scaleValue = { x: 1.0, y: 1.0 };
515    } else {
516      this.scaleValue.x = this.checkUndefinedOrNullWithDefaultValue<number>(scale.x, 1.0);
517      this.scaleValue.y = this.checkUndefinedOrNullWithDefaultValue<number>(scale.y, 1.0);
518    }
519    getUINativeModule().renderNode.setScale(this.nodePtr, this.scaleValue.x, this.scaleValue.y);
520  }
521  set shadowColor(color: number) {
522    this.shadowColorValue = this.checkUndefinedOrNullWithDefaultValue<number>(color, 0);
523    getUINativeModule().renderNode.setShadowColor(this.nodePtr, this.shadowColorValue);
524  }
525  set shadowOffset(offset: Vector2) {
526    if (offset === undefined || offset === null) {
527      this.shadowOffsetValue = { x: 0, y: 0 };
528    } else {
529      this.shadowOffsetValue.x = this.checkUndefinedOrNullWithDefaultValue<number>(offset.x, 0);
530      this.shadowOffsetValue.y = this.checkUndefinedOrNullWithDefaultValue<number>(offset.y, 0);
531    }
532    getUINativeModule().renderNode.setShadowOffset(this.nodePtr, this.shadowOffsetValue.x, this.shadowOffsetValue.y, this.lengthMetricsUnitValue);
533  }
534  set label(label: string) {
535    this.labelValue = this.checkUndefinedOrNullWithDefaultValue<string>(label, '');
536    getUINativeModule().renderNode.setLabel(this.nodePtr, this.labelValue);
537  }
538  set shadowAlpha(alpha: number) {
539    this.shadowAlphaValue = this.checkUndefinedOrNullWithDefaultValue<number>(alpha, 0);
540    getUINativeModule().renderNode.setShadowAlpha(this.nodePtr, this.shadowAlphaValue);
541  }
542  set shadowElevation(elevation: number) {
543    this.shadowElevationValue = this.checkUndefinedOrNullWithDefaultValue<number>(elevation, 0);
544    getUINativeModule().renderNode.setShadowElevation(this.nodePtr, this.shadowElevationValue);
545  }
546  set shadowRadius(radius: number) {
547    this.shadowRadiusValue = this.checkUndefinedOrNullWithDefaultValue<number>(radius, 0);
548    getUINativeModule().renderNode.setShadowRadius(this.nodePtr, this.shadowRadiusValue);
549  }
550  set size(size: Size) {
551    if (size === undefined || size === null) {
552      this.frameValue.width = 0;
553      this.frameValue.height = 0;
554    } else {
555      this.frameValue.width = this.checkUndefinedOrNullWithDefaultValue<number>(size.width, 0);
556      this.frameValue.height = this.checkUndefinedOrNullWithDefaultValue<number>(size.height, 0);
557    }
558      getUINativeModule().renderNode.setSize(this.nodePtr, this.frameValue.width, this.frameValue.height, this.lengthMetricsUnitValue);
559  }
560  set transform(transform: Transform) {
561    if (transform === undefined || transform === null) {
562      this.transformValue = [1, 0, 0, 0,
563        0, 1, 0, 0,
564        0, 0, 1, 0,
565        0, 0, 0, 1];
566    } else {
567      let i: number = 0;
568      while (i < transform.length && i < 16) {
569        if (i % 5 === 0) {
570          this.transformValue[i] = this.checkUndefinedOrNullWithDefaultValue<number>(transform[i], 1);
571        } else {
572          this.transformValue[i] = this.checkUndefinedOrNullWithDefaultValue<number>(transform[i], 0);
573        }
574        i = i + 1;
575      }
576    }
577    getUINativeModule().common.setTransform(this.nodePtr, this.transformValue);
578  }
579  set translation(translation: Vector2) {
580    if (translation === undefined || translation === null) {
581      this.translationValue = { x: 0, y: 0 };
582    } else {
583      this.translationValue.x = this.checkUndefinedOrNullWithDefaultValue<number>(translation.x, 0);
584      this.translationValue.y = this.checkUndefinedOrNullWithDefaultValue<number>(translation.y, 0);
585    }
586    getUINativeModule().renderNode.setTranslate(this.nodePtr, this.translationValue.x, this.translationValue.y, 0);
587  }
588  set lengthMetricsUnit(unit: LengthMetricsUnit) {
589    if (unit === undefined || unit == null) {
590      this.lengthMetricsUnitValue = LengthMetricsUnit.DEFAULT;
591    } else {
592      this.lengthMetricsUnitValue = unit;
593    }
594  }
595  set markNodeGroup(isNodeGroup) {
596    if (isNodeGroup === undefined || isNodeGroup === null) {
597        this.markNodeGroupValue = false;
598    } else {
599        this.markNodeGroupValue = isNodeGroup;
600    }
601    getUINativeModule().renderNode.setMarkNodeGroup(this.nodePtr, this.markNodeGroupValue);
602  }
603  get backgroundColor(): number {
604    return this.backgroundColorValue;
605  }
606  get clipToFrame(): boolean {
607    return this.clipToFrameValue;
608  }
609  get opacity(): number {
610    return this.opacityValue;
611  }
612  get frame(): Frame {
613    return this.frameValue;
614  }
615  get pivot(): Vector2 {
616    return this.pivotValue;
617  }
618  get position(): Vector2 {
619    return { x: this.frameValue.x, y: this.frameValue.y };
620  }
621  get rotation(): Vector3 {
622    return this.rotationValue;
623  }
624  get scale(): Vector2 {
625    return this.scaleValue;
626  }
627  get shadowColor(): number {
628    return this.shadowColorValue;
629  }
630  get shadowOffset(): Vector2 {
631    return this.shadowOffsetValue;
632  }
633  get label(): string {
634    return this.labelValue;
635  }
636  get shadowAlpha(): number {
637    return this.shadowAlphaValue;
638  }
639  get shadowElevation(): number {
640    return this.shadowElevationValue;
641  }
642  get shadowRadius(): number {
643    return this.shadowRadiusValue;
644  }
645  get size(): Size {
646    return { width: this.frameValue.width, height: this.frameValue.height };
647  }
648  get transform(): Transform {
649    return this.transformValue;
650  }
651  get translation(): Vector2 {
652    return this.translationValue;
653  }
654  get lengthMetricsUnit(): LengthMetricsUnit {
655    return this.lengthMetricsUnitValue;
656  }
657  get markNodeGroup() {
658    return this.markNodeGroupValue;
659  }
660  checkUndefinedOrNullWithDefaultValue<T>(arg: T, defaultValue: T): T {
661    if (arg === undefined || arg === null) {
662      return defaultValue;
663    } else {
664      return arg;
665    }
666  }
667  appendChild(node: RenderNode) {
668    if (node === undefined || node === null) {
669      return;
670    }
671    if (this.childrenList.findIndex(element => element === node) !== -1) {
672      return;
673    }
674    this.childrenList.push(node);
675    node.parentRenderNode = new WeakRef(this);
676    getUINativeModule().renderNode.appendChild(this.nodePtr, node.nodePtr);
677  }
678  insertChildAfter(child: RenderNode, sibling: RenderNode | null) {
679    if (child === undefined || child === null) {
680      return;
681    }
682    let indexOfNode: number = this.childrenList.findIndex(element => element === child);
683    if (indexOfNode !== -1) {
684      return;
685    }
686    child.parentRenderNode = new WeakRef(this);
687    let indexOfSibling = this.childrenList.findIndex(element => element === sibling);
688    if (indexOfSibling === -1) {
689      sibling === null;
690    }
691    if (sibling === undefined || sibling === null) {
692      this.childrenList.splice(0, 0, child);
693      getUINativeModule().renderNode.insertChildAfter(this.nodePtr, child.nodePtr, null);
694    } else {
695      this.childrenList.splice(indexOfSibling + 1, 0, child);
696      getUINativeModule().renderNode.insertChildAfter(this.nodePtr, child.nodePtr, sibling.nodePtr);
697    }
698  }
699  removeChild(node: RenderNode) {
700    if (node === undefined || node === null) {
701      return;
702    }
703    const index = this.childrenList.findIndex(element => element === node);
704    if (index === -1) {
705      return;
706    }
707    const child = this.childrenList[index];
708    child.parentRenderNode = null;
709    this.childrenList.splice(index, 1);
710    getUINativeModule().renderNode.removeChild(this.nodePtr, node.nodePtr);
711  }
712  clearChildren() {
713    this.childrenList = new Array<RenderNode>();
714    getUINativeModule().renderNode.clearChildren(this.nodePtr);
715  }
716  getChild(index: number): RenderNode | null {
717    if (this.childrenList.length > index && index >= 0) {
718      return this.childrenList[index];
719    }
720    return null;
721  }
722  getFirstChild(): RenderNode | null {
723    if (this.childrenList.length > 0) {
724      return this.childrenList[0];
725    }
726    return null;
727  }
728  getNextSibling(): RenderNode | null {
729    if (this.parentRenderNode === undefined || this.parentRenderNode === null) {
730      return null;
731    }
732    let parent = this.parentRenderNode.deref();
733    if (parent === undefined || parent === null) {
734      return null;
735    }
736    let siblingList = parent.childrenList;
737    const index = siblingList.findIndex(element => element === this);
738    if (index === -1) {
739      return null;
740    }
741    return parent.getChild(index + 1);
742  }
743  getPreviousSibling(): RenderNode | null {
744    if (this.parentRenderNode === undefined || this.parentRenderNode === null) {
745      return null;
746    }
747    let parent = this.parentRenderNode.deref();
748    if (parent === undefined || parent === null) {
749      return null;
750    }
751    let siblingList = parent.childrenList;
752    const index = siblingList.findIndex(element => element === this);
753    if (index === -1) {
754      return null;
755    }
756    return parent.getChild(index - 1);
757  }
758  setFrameNode(frameNode: WeakRef<FrameNode>) {
759    this._frameNode = frameNode;
760  }
761
762  setNodePtr(nativeRef: NativeStrongRef) {
763    this._nativeRef = nativeRef;
764    this.nodePtr = this._nativeRef?.getNativeHandle();
765  }
766
767  setBaseNode(baseNode: BaseNode | null) {
768    this.baseNode_ = baseNode;
769  }
770  resetNodePtr(): void {
771    this.nodePtr = null;
772    this._nativeRef = null;
773  }
774  dispose() {
775    this._nativeRef?.dispose();
776    this.baseNode_?.disposeNode();
777    this._frameNode?.deref()?.resetNodePtr();
778    this._nativeRef = null;
779    this.nodePtr = null;
780  }
781  getNodePtr(): NodePtr {
782    return this.nodePtr;
783  }
784
785  invalidate() {
786    getUINativeModule().renderNode.invalidate(this.nodePtr);
787  }
788  set borderStyle(style: EdgeStyles) {
789    if (style === undefined || style === null) {
790      this.borderStyleValue = { left: BorderStyle.NONE, top: BorderStyle.NONE, right: BorderStyle.NONE, bottom: BorderStyle.NONE };
791    } else {
792      this.borderStyleValue = style;
793    }
794    getUINativeModule().renderNode.setBorderStyle(
795      this.nodePtr, this.borderStyleValue.left, this.borderStyleValue.top, this.borderStyleValue.right, this.borderStyleValue.bottom);
796  }
797  get borderStyle(): EdgeStyles {
798    return this.borderStyleValue;
799  }
800  set borderWidth(width: EdgeWidths) {
801    if (width === undefined || width === null) {
802      this.borderWidthValue = { left: 0, top: 0, right: 0, bottom: 0 };
803    } else {
804      this.borderWidthValue = width;
805    }
806    getUINativeModule().renderNode.setBorderWidth(
807      this.nodePtr, this.borderWidthValue.left, this.borderWidthValue.top,
808      this.borderWidthValue.right, this.borderWidthValue.bottom, this.lengthMetricsUnitValue);
809  }
810  get borderWidth(): EdgeWidths {
811    return this.borderWidthValue;
812  }
813  set borderColor(color: EdgeColors) {
814    if (color === undefined || color === null) {
815      this.borderColorValue = { left: 0XFF000000, top: 0XFF000000, right: 0XFF000000, bottom: 0XFF000000 };
816    } else {
817      this.borderColorValue = color;
818    }
819    getUINativeModule().renderNode.setBorderColor(
820      this.nodePtr, this.borderColorValue.left, this.borderColorValue.top, this.borderColorValue.right, this.borderColorValue.bottom);
821  }
822  get borderColor(): EdgeColors {
823    return this.borderColorValue;
824  }
825  set borderRadius(radius: BorderRadiuses) {
826    if (radius === undefined || radius === null) {
827      this.borderRadiusValue = { topLeft: 0, topRight: 0, bottomLeft: 0, bottomRight: 0 };
828    } else {
829      this.borderRadiusValue = radius;
830    }
831    getUINativeModule().renderNode.setBorderRadius(
832      this.nodePtr, this.borderRadiusValue.topLeft, this.borderRadiusValue.topRight,
833      this.borderRadiusValue.bottomLeft, this.borderRadiusValue.bottomRight, this.lengthMetricsUnitValue);
834  }
835  get borderRadius(): BorderRadiuses {
836    return this.borderRadiusValue;
837  }
838  set shapeMask(shapeMask: ShapeMask) {
839    if (shapeMask === undefined || shapeMask === null) {
840      this.shapeMaskValue = new ShapeMask();
841    } else {
842      this.shapeMaskValue = shapeMask;
843    }
844    if (this.shapeMaskValue.rect !== null) {
845      const rectMask = this.shapeMaskValue.rect;
846      getUINativeModule().renderNode.setRectMask(
847        this.nodePtr, rectMask.left, rectMask.top, rectMask.right, rectMask.bottom,
848        this.shapeMaskValue.fillColor, this.shapeMaskValue.strokeColor, this.shapeMaskValue.strokeWidth);
849    } else if (this.shapeMaskValue.circle !== null) {
850      const circle = this.shapeMaskValue.circle;
851      getUINativeModule().renderNode.setCircleMask(
852        this.nodePtr, circle.centerX, circle.centerY, circle.radius,
853        this.shapeMaskValue.fillColor, this.shapeMaskValue.strokeColor, this.shapeMaskValue.strokeWidth);
854    } else if (this.shapeMaskValue.roundRect !== null) {
855      const roundRect = this.shapeMask.roundRect;
856      const corners = roundRect.corners;
857      const rect = roundRect.rect;
858      getUINativeModule().renderNode.setRoundRectMask(
859        this.nodePtr,
860        corners.topLeft.x,
861        corners.topLeft.y,
862        corners.topRight.x,
863        corners.topRight.y,
864        corners.bottomLeft.x,
865        corners.bottomLeft.y,
866        corners.bottomRight.x,
867        corners.bottomRight.y,
868        rect.left,
869        rect.top,
870        rect.right,
871        rect.bottom,
872        this.shapeMaskValue.fillColor,
873        this.shapeMaskValue.strokeColor,
874        this.shapeMaskValue.strokeWidth);
875    } else if (this.shapeMaskValue.oval !== null) {
876      const oval = this.shapeMaskValue.oval;
877      getUINativeModule().renderNode.setOvalMask(
878        this.nodePtr, oval.left, oval.top, oval.right, oval.bottom,
879        this.shapeMaskValue.fillColor, this.shapeMaskValue.strokeColor, this.shapeMaskValue.strokeWidth);
880    } else if (this.shapeMaskValue.path !== null) {
881      const path = this.shapeMaskValue.path;
882      getUINativeModule().renderNode.setPath(
883        this.nodePtr, path.commands, this.shapeMaskValue.fillColor, this.shapeMaskValue.strokeColor, this.shapeMaskValue.strokeWidth);
884    }
885  }
886  get shapeMask(): ShapeMask {
887    return this.shapeMaskValue;
888  }
889  set shapeClip(shapeClip: ShapeClip) {
890    if (shapeClip === undefined || shapeClip === null) {
891      this.shapeClipValue = new ShapeClip();
892    } else {
893      this.shapeClipValue = shapeClip;
894    }
895    if (this.shapeClipValue.rect !== null) {
896      const rectClip = this.shapeClipValue.rect;
897      getUINativeModule().renderNode.setRectClip(
898        this.nodePtr, rectClip.left, rectClip.top, rectClip.right, rectClip.bottom);
899    } else if (this.shapeClipValue.circle !== null) {
900      const circle = this.shapeClipValue.circle;
901      getUINativeModule().renderNode.setCircleClip(
902        this.nodePtr, circle.centerX, circle.centerY, circle.radius);
903    } else if (this.shapeClipValue.roundRect !== null) {
904      const roundRect = this.shapeClipValue.roundRect;
905      const corners = roundRect.corners;
906      const rect = roundRect.rect;
907      getUINativeModule().renderNode.setRoundRectClip(
908        this.nodePtr,
909        corners.topLeft.x,
910        corners.topLeft.y,
911        corners.topRight.x,
912        corners.topRight.y,
913        corners.bottomLeft.x,
914        corners.bottomLeft.y,
915        corners.bottomRight.x,
916        corners.bottomRight.y,
917        rect.left,
918        rect.top,
919        rect.right,
920        rect.bottom);
921    } else if (this.shapeClipValue.oval !== null) {
922      const oval = this.shapeClipValue.oval;
923      getUINativeModule().renderNode.setOvalClip(
924        this.nodePtr, oval.left, oval.top, oval.right, oval.bottom,
925      );
926    } else if (this.shapeClipValue.path !== null) {
927      const path = this.shapeClipValue.path;
928      getUINativeModule().renderNode.setPathClip(
929        this.nodePtr, path.commands);
930    }
931  }
932  get shapeClip(): ShapeClip {
933    this.shapeClipValue = this.shapeClipValue ? this.shapeClipValue : new ShapeClip();
934    return this.shapeClipValue;
935  }
936}
937
938function edgeColors(all: number): EdgeColors {
939  return { left: all, top: all, right: all, bottom: all };
940}
941
942function edgeWidths(all: number): EdgeWidths {
943  return { left: all, top: all, right: all, bottom: all };
944}
945
946function borderStyles(all: BorderStyle): EdgeStyles {
947  return { left: all, top: all, right: all, bottom: all };
948}
949
950function borderRadiuses(all: number): BorderRadiuses {
951  return { topLeft: all, topRight: all, bottomLeft: all, bottomRight: all };
952}
953