• 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 resourceId_: number;
197  private static clamp(value: number): number {
198    return Math.min(Math.max(value, 0), MAX_CHANNEL_VALUE);
199  }
200  private constructor(red: number, green: number, blue: number, alpha: number = MAX_CHANNEL_VALUE) {
201    this.red_ = ColorMetrics.clamp(red);
202    this.green_ = ColorMetrics.clamp(green);
203    this.blue_ = ColorMetrics.clamp(blue);
204    this.alpha_ = ColorMetrics.clamp(alpha);
205  }
206  private toNumeric(): number {
207    return (this.alpha_ << 24) + (this.red_ << 16) + (this.green_ << 8) + this.blue_;
208  }
209  static numeric(value: number): ColorMetrics {
210    const red = (value >> 16) & 0x000000FF;
211    const green = (value >> 8) & 0x000000FF;
212    const blue = value & 0x000000FF;
213    const alpha = (value >> 24) & 0x000000FF;
214    if (alpha === 0) {
215      return new ColorMetrics(red, green, blue);
216    }
217    return new ColorMetrics(red, green, blue, alpha);
218  }
219  static rgba(red: number, green: number, blue: number, alpha: number = MAX_ALPHA_VALUE): ColorMetrics {
220    return new ColorMetrics(red, green, blue, alpha * MAX_CHANNEL_VALUE);
221  }
222
223  private static rgbOrRGBA(format: string): ColorMetrics {
224    const rgbPattern = /^rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\)$/i;
225    const rgbaPattern = /^rgba\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+(\.\d+)?)\s*\)$/i;
226
227    const rgbMatch = rgbPattern.exec(format);
228    const rgbaMatch = rgbaPattern.exec(format);
229
230    if (rgbMatch) {
231      const [, red, green, blue] = rgbMatch;
232      return new ColorMetrics(Number.parseInt(red, 10), Number.parseInt(green, 10), Number.parseInt(blue, 10));
233    } else if (rgbaMatch) {
234      const [, red, green, blue, alpha] = rgbaMatch;
235      return new ColorMetrics(Number.parseInt(red, 10), Number.parseInt(green, 10), Number.parseInt(blue, 10), Number.parseFloat(alpha) * MAX_CHANNEL_VALUE);
236    } else {
237      const error = new Error('Parameter error. The format of the input color string is not RGB or RGBA.') as BusinessError;
238      error.code = ERROR_CODE_COLOR_PARAMETER_INCORRECT;
239      throw error;
240    }
241  }
242
243  static resourceColor(color: ResourceColor): ColorMetrics {
244    if (color === undefined || color === null) {
245      const error = new Error('Parameter error. The type of the input color parameter is not ResourceColor.') as BusinessError;
246      error.code = ERROR_CODE_COLOR_PARAMETER_INCORRECT;
247      throw error;
248    }
249    let chanels: Array<number> = [];
250    if (typeof color === 'object') {
251      chanels = getUINativeModule().nativeUtils.parseResourceColor(color);
252      if (chanels === undefined) {
253        const error = new Error('Failed to obtain the color resource.') as BusinessError;
254        error.code = ERROR_CODE_RESOURCE_GET_FAILED;
255        throw error;
256      }
257      const red = chanels[0];
258      const green = chanels[1];
259      const blue = chanels[2];
260      const alpha = chanels[3];
261      const resourceId = chanels[4];
262      const colorMetrics = new ColorMetrics(red, green, blue, alpha);
263      colorMetrics.setResourceId(resourceId);
264      return colorMetrics;
265    } else if (typeof color === 'number') {
266      return ColorMetrics.numeric(color);
267    } else if (typeof color === 'string') {
268      if (ColorMetrics.isHexFormat(color)) {
269        return ColorMetrics.hex(color);
270      } else {
271        return ColorMetrics.rgbOrRGBA(color);
272      }
273    } else {
274      const error = new Error('Parameter error. The type of the input color parameter is not ResourceColor.') as BusinessError;
275      error.code = ERROR_CODE_COLOR_PARAMETER_INCORRECT;
276      throw error;
277    }
278  }
279  private static isHexFormat(format: string): boolean {
280    return /#(([0-9A-Fa-f]{3})|([0-9A-Fa-f]{6})|([0-9A-Fa-f]{4})|([0-9A-Fa-f]{8}))/.test(format);
281  }
282
283  private static hex(hexFormat: string): ColorMetrics {
284    let r: number = 0;
285    let g: number = 0;
286    let b: number = 0;
287    let a: number = 255;
288    if (hexFormat.length === 4) {
289      r = parseInt(hexFormat.slice(1, 2).repeat(2), 16);
290      g = parseInt(hexFormat.slice(2, 3).repeat(2), 16);
291      b = parseInt(hexFormat.slice(3).repeat(2), 16);
292    } else if (hexFormat.length === 7) {
293      r = parseInt(hexFormat.slice(1, 3), 16);
294      g = parseInt(hexFormat.slice(3, 5), 16);
295      b = parseInt(hexFormat.slice(5), 16);
296    } else if (hexFormat.length === 5) {
297      a = parseInt(hexFormat.slice(1, 2).repeat(2), 16);
298      r = parseInt(hexFormat.slice(2, 3).repeat(2), 16);
299      g = parseInt(hexFormat.slice(3, 4).repeat(2), 16);
300      b = parseInt(hexFormat.slice(4).repeat(2), 16);
301    } else if (hexFormat.length === 9) {
302      a = parseInt(hexFormat.slice(1, 3), 16);
303      r = parseInt(hexFormat.slice(3, 5), 16);
304      g = parseInt(hexFormat.slice(5, 7), 16);
305      b = parseInt(hexFormat.slice(7), 16);
306    }
307    return new ColorMetrics(r, g, b, a);
308  }
309  blendColor(overlayColor: ColorMetrics): ColorMetrics {
310    if (overlayColor === undefined || overlayColor === null) {
311      const error = new Error('Parameter error. The type of the input parameter is not ColorMetrics.') as BusinessError;
312      error.code = ERROR_CODE_COLOR_PARAMETER_INCORRECT;
313      throw error;
314    }
315    const chanels = getUINativeModule().nativeUtils.blendColor(this.toNumeric(), overlayColor.toNumeric());
316    if (chanels === undefined) {
317      const error = new Error('Parameter error. The type of the input parameter is not ColorMetrics.') as BusinessError;
318      error.code = ERROR_CODE_COLOR_PARAMETER_INCORRECT;
319      throw error;
320    }
321    const red = chanels[0];
322    const green = chanels[1];
323    const blue = chanels[2];
324    const alpha = chanels[3];
325    return new ColorMetrics(red, green, blue, alpha);
326  }
327  get color(): string {
328    return `rgba(${this.red_}, ${this.green_}, ${this.blue_}, ${this.alpha_ / MAX_CHANNEL_VALUE})`;
329  }
330  get red(): number {
331    return this.red_;
332  }
333  get green(): number {
334    return this.green_;
335  }
336  get blue(): number {
337    return this.blue_;
338  }
339  get alpha(): number {
340    return this.alpha_;
341  }
342  setResourceId(resourceId: number): void {
343    this.resourceId_ = resourceId;
344  }
345  getResourceId(): number {
346    return this.resourceId_;
347  }
348}
349
350class BaseShape {
351  public rect: Rect | null = null;
352  public roundRect: RoundRect | null = null;
353  public circle: Circle | null = null;
354  public oval: Rect | null = null;
355  public path: CommandPath | null = null;
356  setRectShape(rect: Rect) {
357    this.rect = rect;
358    this.roundRect = null;
359    this.circle = null;
360    this.oval = null;
361    this.path = null;
362  }
363  setRoundRectShape(roundRect: RoundRect) {
364    this.roundRect = roundRect;
365    this.rect = null;
366    this.circle = null;
367    this.oval = null;
368    this.path = null;
369  }
370  setCircleShape(circle: Circle) {
371    this.circle = circle;
372    this.rect = null;
373    this.roundRect = null;
374    this.oval = null;
375    this.path = null;
376  }
377  setOvalShape(oval: Rect) {
378    this.oval = oval;
379    this.rect = null;
380    this.circle = null;
381    this.roundRect = null;
382    this.path = null;
383  }
384  setCommandPath(path: CommandPath) {
385    this.path = path;
386    this.oval = null;
387    this.rect = null;
388    this.circle = null;
389    this.roundRect = null;
390  }
391}
392
393class ShapeClip extends BaseShape { }
394
395class ShapeMask extends BaseShape {
396  public fillColor: number = 0XFF000000;
397  public strokeColor: number = 0XFF000000;
398  public strokeWidth: number = 0;
399}
400
401class RenderNode {
402  private childrenList: Array<RenderNode>;
403  private nodePtr: NodePtr;
404  private parentRenderNode: WeakRef<RenderNode> | null;
405  private backgroundColorValue: number;
406  private clipToFrameValue: boolean;
407  private frameValue: Frame;
408  private opacityValue: number;
409  private pivotValue: Vector2;
410  private rotationValue: Vector3;
411  private scaleValue: Vector2;
412  private shadowColorValue: number;
413  private shadowOffsetValue: Vector2;
414  private labelValue: string;
415  private shadowAlphaValue: number;
416  private shadowElevationValue: number;
417  private shadowRadiusValue: number;
418  private transformValue: Transform;
419  private translationValue: Vector2;
420  private baseNode_: BaseNode;
421  private borderStyleValue: EdgeStyles;
422  private borderWidthValue: EdgeWidths;
423  private borderColorValue: EdgeColors;
424  private borderRadiusValue: BorderRadiuses;
425  private shapeMaskValue: ShapeMask;
426  private shapeClipValue: ShapeClip;
427  private _nativeRef: NativeStrongRef;
428  private _frameNode: WeakRef<FrameNode>;
429  private lengthMetricsUnitValue: LengthMetricsUnit;
430  private markNodeGroupValue: boolean;
431  private apiTargetVersion: number;
432
433  constructor(type: string) {
434    this.nodePtr = null;
435    this.childrenList = [];
436    this.parentRenderNode = null;
437    this.backgroundColorValue = 0;
438    this.apiTargetVersion = getUINativeModule().common.getApiTargetVersion();
439    this.clipToFrameValue = true;
440    if (this.apiTargetVersion && this.apiTargetVersion < 12) {
441        this.clipToFrameValue = false;
442    }
443    this.frameValue = { x: 0, y: 0, width: 0, height: 0 };
444    this.opacityValue = 1.0;
445    this.pivotValue = { x: 0.5, y: 0.5 };
446    this.rotationValue = { x: 0, y: 0, z: 0 };
447    this.scaleValue = { x: 1.0, y: 1.0 };
448    this.shadowColorValue = 0;
449    this.shadowOffsetValue = { x: 0, y: 0 };
450    this.labelValue = '';
451    this.shadowAlphaValue = 0;
452    this.shadowElevationValue = 0;
453    this.shadowRadiusValue = 0;
454    this.transformValue = [1, 0, 0, 0,
455      0, 1, 0, 0,
456      0, 0, 1, 0,
457      0, 0, 0, 1];
458    this.translationValue = { x: 0, y: 0 };
459    this.lengthMetricsUnitValue = LengthMetricsUnit.DEFAULT;
460    this.markNodeGroupValue = false;
461    if (type === 'BuilderRootFrameNode' || type === 'CustomFrameNode') {
462      return;
463    }
464    this._nativeRef = getUINativeModule().renderNode.createRenderNode(this);
465    this.nodePtr = this._nativeRef?.getNativeHandle();
466    if (this.apiTargetVersion && this.apiTargetVersion < 12) {
467      this.clipToFrame = false;
468  } else {
469      this.clipToFrame = true;
470  }
471  }
472
473  set backgroundColor(color: number) {
474    this.backgroundColorValue = this.checkUndefinedOrNullWithDefaultValue<number>(color, 0);
475    getUINativeModule().renderNode.setBackgroundColor(this.nodePtr, this.backgroundColorValue);
476  }
477  set clipToFrame(useClip: boolean) {
478    this.clipToFrameValue = this.checkUndefinedOrNullWithDefaultValue<boolean>(useClip, true);
479    getUINativeModule().renderNode.setClipToFrame(this.nodePtr, this.clipToFrameValue);
480  }
481  set frame(frame: Frame) {
482    if (frame === undefined || frame === null) {
483      this.frameValue = { x: 0, y: 0, width: 0, height: 0 };
484    } else {
485      this.size = { width: frame.width, height: frame.height };
486      this.position = { x: frame.x, y: frame.y };
487    }
488  }
489  set opacity(value: number) {
490    this.opacityValue = this.checkUndefinedOrNullWithDefaultValue<number>(value, 1.0);
491    getUINativeModule().common.setOpacity(this.nodePtr, this.opacityValue);
492  }
493  set pivot(pivot: Vector2) {
494    if (pivot === undefined || pivot === null) {
495      this.pivotValue = { x: 0.5, y: 0.5 };
496    } else {
497      this.pivotValue.x = this.checkUndefinedOrNullWithDefaultValue<number>(pivot.x, 0.5);
498      this.pivotValue.y = this.checkUndefinedOrNullWithDefaultValue<number>(pivot.y, 0.5);
499    }
500    getUINativeModule().renderNode.setPivot(this.nodePtr, this.pivotValue.x, this.pivotValue.y);
501  }
502  set position(position: Vector2) {
503    if (position === undefined || position === null) {
504      this.frameValue.x = 0;
505      this.frameValue.y = 0;
506    } else {
507      this.frameValue.x = this.checkUndefinedOrNullWithDefaultValue<number>(position.x, 0);
508      this.frameValue.y = this.checkUndefinedOrNullWithDefaultValue<number>(position.y, 0);
509    }
510    getUINativeModule().renderNode.setPosition(this.nodePtr, this.frameValue.x, this.frameValue.y, this.lengthMetricsUnitValue);
511  }
512  set rotation(rotation: Vector3) {
513    if (rotation === undefined || rotation === null) {
514      this.rotationValue = { x: 0, y: 0, z: 0 };
515    } else {
516      this.rotationValue.x = this.checkUndefinedOrNullWithDefaultValue<number>(rotation.x, 0);
517      this.rotationValue.y = this.checkUndefinedOrNullWithDefaultValue<number>(rotation.y, 0);
518      this.rotationValue.z = this.checkUndefinedOrNullWithDefaultValue<number>(rotation.z, 0);
519    }
520    getUINativeModule().renderNode.setRotation(this.nodePtr, this.rotationValue.x, this.rotationValue.y, this.rotationValue.z, this.lengthMetricsUnitValue);
521  }
522  set scale(scale: Vector2) {
523    if (scale === undefined || scale === null) {
524      this.scaleValue = { x: 1.0, y: 1.0 };
525    } else {
526      this.scaleValue.x = this.checkUndefinedOrNullWithDefaultValue<number>(scale.x, 1.0);
527      this.scaleValue.y = this.checkUndefinedOrNullWithDefaultValue<number>(scale.y, 1.0);
528    }
529    getUINativeModule().renderNode.setScale(this.nodePtr, this.scaleValue.x, this.scaleValue.y);
530  }
531  set shadowColor(color: number) {
532    this.shadowColorValue = this.checkUndefinedOrNullWithDefaultValue<number>(color, 0);
533    getUINativeModule().renderNode.setShadowColor(this.nodePtr, this.shadowColorValue);
534  }
535  set shadowOffset(offset: Vector2) {
536    if (offset === undefined || offset === null) {
537      this.shadowOffsetValue = { x: 0, y: 0 };
538    } else {
539      this.shadowOffsetValue.x = this.checkUndefinedOrNullWithDefaultValue<number>(offset.x, 0);
540      this.shadowOffsetValue.y = this.checkUndefinedOrNullWithDefaultValue<number>(offset.y, 0);
541    }
542    getUINativeModule().renderNode.setShadowOffset(this.nodePtr, this.shadowOffsetValue.x, this.shadowOffsetValue.y, this.lengthMetricsUnitValue);
543  }
544  set label(label: string) {
545    this.labelValue = this.checkUndefinedOrNullWithDefaultValue<string>(label, '');
546    getUINativeModule().renderNode.setLabel(this.nodePtr, this.labelValue);
547  }
548  set shadowAlpha(alpha: number) {
549    this.shadowAlphaValue = this.checkUndefinedOrNullWithDefaultValue<number>(alpha, 0);
550    getUINativeModule().renderNode.setShadowAlpha(this.nodePtr, this.shadowAlphaValue);
551  }
552  set shadowElevation(elevation: number) {
553    this.shadowElevationValue = this.checkUndefinedOrNullWithDefaultValue<number>(elevation, 0);
554    getUINativeModule().renderNode.setShadowElevation(this.nodePtr, this.shadowElevationValue);
555  }
556  set shadowRadius(radius: number) {
557    this.shadowRadiusValue = this.checkUndefinedOrNullWithDefaultValue<number>(radius, 0);
558    getUINativeModule().renderNode.setShadowRadius(this.nodePtr, this.shadowRadiusValue);
559  }
560  set size(size: Size) {
561    if (size === undefined || size === null) {
562      this.frameValue.width = 0;
563      this.frameValue.height = 0;
564    } else {
565      this.frameValue.width = this.checkUndefinedOrNullWithDefaultValue<number>(size.width, 0);
566      this.frameValue.height = this.checkUndefinedOrNullWithDefaultValue<number>(size.height, 0);
567    }
568      getUINativeModule().renderNode.setSize(this.nodePtr, this.frameValue.width, this.frameValue.height, this.lengthMetricsUnitValue);
569  }
570  set transform(transform: Transform) {
571    if (transform === undefined || transform === null) {
572      this.transformValue = [1, 0, 0, 0,
573        0, 1, 0, 0,
574        0, 0, 1, 0,
575        0, 0, 0, 1];
576    } else {
577      let i: number = 0;
578      while (i < transform.length && i < 16) {
579        if (i % 5 === 0) {
580          this.transformValue[i] = this.checkUndefinedOrNullWithDefaultValue<number>(transform[i], 1);
581        } else {
582          this.transformValue[i] = this.checkUndefinedOrNullWithDefaultValue<number>(transform[i], 0);
583        }
584        i = i + 1;
585      }
586    }
587    getUINativeModule().common.setTransform(this.nodePtr, this.transformValue);
588  }
589  set translation(translation: Vector2) {
590    if (translation === undefined || translation === null) {
591      this.translationValue = { x: 0, y: 0 };
592    } else {
593      this.translationValue.x = this.checkUndefinedOrNullWithDefaultValue<number>(translation.x, 0);
594      this.translationValue.y = this.checkUndefinedOrNullWithDefaultValue<number>(translation.y, 0);
595    }
596    getUINativeModule().renderNode.setTranslate(this.nodePtr, this.translationValue.x, this.translationValue.y, 0);
597  }
598  set lengthMetricsUnit(unit: LengthMetricsUnit) {
599    if (unit === undefined || unit == null) {
600      this.lengthMetricsUnitValue = LengthMetricsUnit.DEFAULT;
601    } else {
602      this.lengthMetricsUnitValue = unit;
603    }
604  }
605  set markNodeGroup(isNodeGroup) {
606    if (isNodeGroup === undefined || isNodeGroup === null) {
607        this.markNodeGroupValue = false;
608    } else {
609        this.markNodeGroupValue = isNodeGroup;
610    }
611    getUINativeModule().renderNode.setMarkNodeGroup(this.nodePtr, this.markNodeGroupValue);
612  }
613  get backgroundColor(): number {
614    return this.backgroundColorValue;
615  }
616  get clipToFrame(): boolean {
617    return this.clipToFrameValue;
618  }
619  get opacity(): number {
620    return this.opacityValue;
621  }
622  get frame(): Frame {
623    return this.frameValue;
624  }
625  get pivot(): Vector2 {
626    return this.pivotValue;
627  }
628  get position(): Vector2 {
629    return { x: this.frameValue.x, y: this.frameValue.y };
630  }
631  get rotation(): Vector3 {
632    return this.rotationValue;
633  }
634  get scale(): Vector2 {
635    return this.scaleValue;
636  }
637  get shadowColor(): number {
638    return this.shadowColorValue;
639  }
640  get shadowOffset(): Vector2 {
641    return this.shadowOffsetValue;
642  }
643  get label(): string {
644    return this.labelValue;
645  }
646  get shadowAlpha(): number {
647    return this.shadowAlphaValue;
648  }
649  get shadowElevation(): number {
650    return this.shadowElevationValue;
651  }
652  get shadowRadius(): number {
653    return this.shadowRadiusValue;
654  }
655  get size(): Size {
656    return { width: this.frameValue.width, height: this.frameValue.height };
657  }
658  get transform(): Transform {
659    return this.transformValue;
660  }
661  get translation(): Vector2 {
662    return this.translationValue;
663  }
664  get lengthMetricsUnit() {
665    return this.lengthMetricsUnitValue;
666  }
667  get markNodeGroup() {
668    return this.markNodeGroupValue;
669  }
670  checkUndefinedOrNullWithDefaultValue<T>(arg: T, defaultValue: T): T {
671    if (arg === undefined || arg === null) {
672      return defaultValue;
673    } else {
674      return arg;
675    }
676  }
677  appendChild(node: RenderNode) {
678    if (node === undefined || node === null) {
679      return;
680    }
681    if (this.childrenList.findIndex(element => element === node) !== -1) {
682      return;
683    }
684    this.childrenList.push(node);
685    node.parentRenderNode = new WeakRef(this);
686    getUINativeModule().renderNode.appendChild(this.nodePtr, node.nodePtr);
687  }
688  insertChildAfter(child: RenderNode, sibling: RenderNode | null) {
689    if (child === undefined || child === null) {
690      return;
691    }
692    let indexOfNode: number = this.childrenList.findIndex(element => element === child);
693    if (indexOfNode !== -1) {
694      return;
695    }
696    child.parentRenderNode = new WeakRef(this);
697    let indexOfSibling = this.childrenList.findIndex(element => element === sibling);
698    if (indexOfSibling === -1) {
699      sibling === null;
700    }
701    if (sibling === undefined || sibling === null) {
702      this.childrenList.splice(0, 0, child);
703      getUINativeModule().renderNode.insertChildAfter(this.nodePtr, child.nodePtr, null);
704    } else {
705      this.childrenList.splice(indexOfSibling + 1, 0, child);
706      getUINativeModule().renderNode.insertChildAfter(this.nodePtr, child.nodePtr, sibling.nodePtr);
707    }
708  }
709  removeChild(node: RenderNode) {
710    if (node === undefined || node === null) {
711      return;
712    }
713    const index = this.childrenList.findIndex(element => element === node);
714    if (index === -1) {
715      return;
716    }
717    const child = this.childrenList[index];
718    child.parentRenderNode = null;
719    this.childrenList.splice(index, 1);
720    getUINativeModule().renderNode.removeChild(this.nodePtr, node.nodePtr);
721  }
722  clearChildren() {
723    this.childrenList = new Array<RenderNode>();
724    getUINativeModule().renderNode.clearChildren(this.nodePtr);
725  }
726  getChild(index: number): RenderNode | null {
727    if (this.childrenList.length > index && index >= 0) {
728      return this.childrenList[index];
729    }
730    return null;
731  }
732  getFirstChild(): RenderNode | null {
733    if (this.childrenList.length > 0) {
734      return this.childrenList[0];
735    }
736    return null;
737  }
738  getNextSibling(): RenderNode | null {
739    if (this.parentRenderNode === undefined || this.parentRenderNode === null) {
740      return null;
741    }
742    let parent = this.parentRenderNode.deref();
743    if (parent === undefined || parent === null) {
744      return null;
745    }
746    let siblingList = parent.childrenList;
747    const index = siblingList.findIndex(element => element === this);
748    if (index === -1) {
749      return null;
750    }
751    return parent.getChild(index + 1);
752  }
753  getPreviousSibling(): RenderNode | null {
754    if (this.parentRenderNode === undefined || this.parentRenderNode === null) {
755      return null;
756    }
757    let parent = this.parentRenderNode.deref();
758    if (parent === undefined || parent === null) {
759      return null;
760    }
761    let siblingList = parent.childrenList;
762    const index = siblingList.findIndex(element => element === this);
763    if (index === -1) {
764      return null;
765    }
766    return parent.getChild(index - 1);
767  }
768  setFrameNode(frameNode: WeakRef<FrameNode>) {
769    this._frameNode = frameNode;
770  }
771
772  setNodePtr(nativeRef: NativeStrongRef) {
773    this._nativeRef = nativeRef;
774    this.nodePtr = this._nativeRef?.getNativeHandle();
775  }
776
777  setBaseNode(baseNode: BaseNode | null) {
778    this.baseNode_ = baseNode;
779  }
780  resetNodePtr(): void {
781    this.nodePtr = null;
782    this._nativeRef = null;
783  }
784  dispose() {
785    this._nativeRef?.dispose();
786    this.baseNode_?.disposeNode();
787    this._frameNode?.deref()?.resetNodePtr();
788    this._nativeRef = null;
789    this.nodePtr = null;
790  }
791  getNodePtr(): NodePtr {
792    return this.nodePtr;
793  }
794
795  invalidate() {
796    getUINativeModule().renderNode.invalidate(this.nodePtr);
797  }
798  set borderStyle(style: EdgeStyles) {
799    if (style === undefined || style === null) {
800      this.borderStyleValue = { left: BorderStyle.NONE, top: BorderStyle.NONE, right: BorderStyle.NONE, bottom: BorderStyle.NONE };
801    } else {
802      this.borderStyleValue = style;
803    }
804    getUINativeModule().renderNode.setBorderStyle(
805      this.nodePtr, this.borderStyleValue.left, this.borderStyleValue.top, this.borderStyleValue.right, this.borderStyleValue.bottom);
806  }
807  get borderStyle(): EdgeStyles {
808    return this.borderStyleValue;
809  }
810  set borderWidth(width: EdgeWidths) {
811    if (width === undefined || width === null) {
812      this.borderWidthValue = { left: 0, top: 0, right: 0, bottom: 0 };
813    } else {
814      this.borderWidthValue = width;
815    }
816    getUINativeModule().renderNode.setBorderWidth(
817      this.nodePtr, this.borderWidthValue.left, this.borderWidthValue.top,
818      this.borderWidthValue.right, this.borderWidthValue.bottom, this.lengthMetricsUnitValue);
819  }
820  get borderWidth(): EdgeWidths {
821    return this.borderWidthValue;
822  }
823  set borderColor(color: EdgeColors) {
824    if (color === undefined || color === null) {
825      this.borderColorValue = { left: 0XFF000000, top: 0XFF000000, right: 0XFF000000, bottom: 0XFF000000 };
826    } else {
827      this.borderColorValue = color;
828    }
829    getUINativeModule().renderNode.setBorderColor(
830      this.nodePtr, this.borderColorValue.left, this.borderColorValue.top, this.borderColorValue.right, this.borderColorValue.bottom);
831  }
832  get borderColor(): EdgeColors {
833    return this.borderColorValue;
834  }
835  set borderRadius(radius: BorderRadiuses) {
836    if (radius === undefined || radius === null) {
837      this.borderRadiusValue = { topLeft: 0, topRight: 0, bottomLeft: 0, bottomRight: 0 };
838    } else {
839      this.borderRadiusValue = radius;
840    }
841    getUINativeModule().renderNode.setBorderRadius(
842      this.nodePtr, this.borderRadiusValue.topLeft, this.borderRadiusValue.topRight,
843      this.borderRadiusValue.bottomLeft, this.borderRadiusValue.bottomRight, this.lengthMetricsUnitValue);
844  }
845  get borderRadius(): BorderRadiuses {
846    return this.borderRadiusValue;
847  }
848  set shapeMask(shapeMask: ShapeMask) {
849    if (shapeMask === undefined || shapeMask === null) {
850      this.shapeMaskValue = new ShapeMask();
851    } else {
852      this.shapeMaskValue = shapeMask;
853    }
854    if (this.shapeMaskValue.rect !== null) {
855      const rectMask = this.shapeMaskValue.rect;
856      getUINativeModule().renderNode.setRectMask(
857        this.nodePtr, rectMask.left, rectMask.top, rectMask.right, rectMask.bottom,
858        this.shapeMaskValue.fillColor, this.shapeMaskValue.strokeColor, this.shapeMaskValue.strokeWidth);
859    } else if (this.shapeMaskValue.circle !== null) {
860      const circle = this.shapeMaskValue.circle;
861      getUINativeModule().renderNode.setCircleMask(
862        this.nodePtr, circle.centerX, circle.centerY, circle.radius,
863        this.shapeMaskValue.fillColor, this.shapeMaskValue.strokeColor, this.shapeMaskValue.strokeWidth);
864    } else if (this.shapeMaskValue.roundRect !== null) {
865      const roundRect = this.shapeMask.roundRect;
866      const corners = roundRect.corners;
867      const rect = roundRect.rect;
868      getUINativeModule().renderNode.setRoundRectMask(
869        this.nodePtr,
870        corners.topLeft.x,
871        corners.topLeft.y,
872        corners.topRight.x,
873        corners.topRight.y,
874        corners.bottomLeft.x,
875        corners.bottomLeft.y,
876        corners.bottomRight.x,
877        corners.bottomRight.y,
878        rect.left,
879        rect.top,
880        rect.right,
881        rect.bottom,
882        this.shapeMaskValue.fillColor,
883        this.shapeMaskValue.strokeColor,
884        this.shapeMaskValue.strokeWidth);
885    } else if (this.shapeMaskValue.oval !== null) {
886      const oval = this.shapeMaskValue.oval;
887      getUINativeModule().renderNode.setOvalMask(
888        this.nodePtr, oval.left, oval.top, oval.right, oval.bottom,
889        this.shapeMaskValue.fillColor, this.shapeMaskValue.strokeColor, this.shapeMaskValue.strokeWidth);
890    } else if (this.shapeMaskValue.path !== null) {
891      const path = this.shapeMaskValue.path;
892      getUINativeModule().renderNode.setPath(
893        this.nodePtr, path.commands, this.shapeMaskValue.fillColor, this.shapeMaskValue.strokeColor, this.shapeMaskValue.strokeWidth);
894    }
895  }
896  get shapeMask(): ShapeMask {
897    return this.shapeMaskValue;
898  }
899  set shapeClip(shapeClip: ShapeClip) {
900    if (shapeClip === undefined || shapeClip === null) {
901      this.shapeClipValue = new ShapeClip();
902    } else {
903      this.shapeClipValue = shapeClip;
904    }
905    if (this.shapeClipValue.rect !== null) {
906      const rectClip = this.shapeClipValue.rect;
907      getUINativeModule().renderNode.setRectClip(
908        this.nodePtr, rectClip.left, rectClip.top, rectClip.right, rectClip.bottom);
909    } else if (this.shapeClipValue.circle !== null) {
910      const circle = this.shapeClipValue.circle;
911      getUINativeModule().renderNode.setCircleClip(
912        this.nodePtr, circle.centerX, circle.centerY, circle.radius);
913    } else if (this.shapeClipValue.roundRect !== null) {
914      const roundRect = this.shapeClipValue.roundRect;
915      const corners = roundRect.corners;
916      const rect = roundRect.rect;
917      getUINativeModule().renderNode.setRoundRectClip(
918        this.nodePtr,
919        corners.topLeft.x,
920        corners.topLeft.y,
921        corners.topRight.x,
922        corners.topRight.y,
923        corners.bottomLeft.x,
924        corners.bottomLeft.y,
925        corners.bottomRight.x,
926        corners.bottomRight.y,
927        rect.left,
928        rect.top,
929        rect.right,
930        rect.bottom);
931    } else if (this.shapeClipValue.oval !== null) {
932      const oval = this.shapeClipValue.oval;
933      getUINativeModule().renderNode.setOvalClip(
934        this.nodePtr, oval.left, oval.top, oval.right, oval.bottom,
935      );
936    } else if (this.shapeClipValue.path !== null) {
937      const path = this.shapeClipValue.path;
938      getUINativeModule().renderNode.setPathClip(
939        this.nodePtr, path.commands);
940    }
941  }
942  get shapeClip(): ShapeClip {
943    this.shapeClipValue = this.shapeClipValue ? this.shapeClipValue : new ShapeClip();
944    return this.shapeClipValue;
945  }
946}
947
948function edgeColors(all: number): EdgeColors {
949  return { left: all, top: all, right: all, bottom: all };
950}
951
952function edgeWidths(all: number): EdgeWidths {
953  return { left: all, top: all, right: all, bottom: all };
954}
955
956function borderStyles(all: BorderStyle): EdgeStyles {
957  return { left: all, top: all, right: all, bottom: all };
958}
959
960function borderRadiuses(all: number): BorderRadiuses {
961  return { topLeft: all, topRight: all, bottomLeft: all, bottomRight: all };
962}
963