• 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
16/// <reference path='./import.ts' />
17
18class ArkRadioComponent extends ArkComponent implements RadioAttribute {
19  builder: WrappedBuilder<Object[]> | null = null;
20  radioNode: BuilderNode<[RadioConfiguration]> | null = null;
21  modifier: ContentModifier<RadioConfiguration>;
22  needRebuild: boolean = false;
23  constructor(nativePtr: KNode, classType?: ModifierType) {
24    super(nativePtr, classType);
25  }
26  checked(value: boolean): this {
27    modifierWithKey(this._modifiersWithKeys, RadioCheckedModifier.identity, RadioCheckedModifier, value);
28    return this;
29  }
30  onChange(callback: (isChecked: boolean) => void): this {
31    throw new Error('Method not implemented.');
32  }
33  radioStyle(value: RadioStyle): this {
34    modifierWithKey(this._modifiersWithKeys, RadioStyleModifier.identity, RadioStyleModifier, value);
35    return this;
36  }
37  width(value: Length): this {
38    modifierWithKey(this._modifiersWithKeys, RadioWidthModifier.identity, RadioWidthModifier, value);
39    return this;
40  }
41  height(value: Length): this {
42    modifierWithKey(this._modifiersWithKeys, RadioHeightModifier.identity, RadioHeightModifier, value);
43    return this;
44  }
45  size(value: { width: Length; height: Length }): this {
46    modifierWithKey(this._modifiersWithKeys, RadioSizeModifier.identity, RadioSizeModifier, value);
47    return this;
48  }
49  hoverEffect(value: HoverEffect): this {
50    modifierWithKey(this._modifiersWithKeys, RadioHoverEffectModifier.identity, RadioHoverEffectModifier, value);
51    return this;
52  }
53  padding(value: Padding | Length): this {
54    modifierWithKey(this._modifiersWithKeys, RadioPaddingModifier.identity, RadioPaddingModifier, value);
55    return this;
56  }
57  responseRegion(value: Array<Rectangle> | Rectangle): this {
58    modifierWithKey(this._modifiersWithKeys, RadioResponseRegionModifier.identity,
59      RadioResponseRegionModifier, value);
60    return this;
61  }
62  contentModifier(value: ContentModifier<RadioConfiguration>): this {
63    modifierWithKey(this._modifiersWithKeys, RadioContentModifier.identity, RadioContentModifier, value);
64    return this;
65  }
66  setContentModifier(modifier: ContentModifier<RadioConfiguration>): this {
67    if (modifier === undefined || modifier === null) {
68      getUINativeModule().radio.setContentModifierBuilder(this.nativePtr, false);
69      return;
70    }
71    this.needRebuild = false;
72    if (this.builder !== modifier.applyContent()) {
73      this.needRebuild = true;
74    }
75    this.builder = modifier.applyContent();
76    this.modifier = modifier;
77    getUINativeModule().radio.setContentModifierBuilder(this.nativePtr, this);
78  }
79  makeContentModifierNode(context: UIContext, radioConfiguration: RadioConfiguration): FrameNode | null {
80    radioConfiguration.contentModifier = this.modifier;
81    if (isUndefined(this.radioNode) || this.needRebuild) {
82      const xNode = globalThis.requireNapi('arkui.node');
83      this.radioNode = new xNode.BuilderNode(context);
84      this.radioNode.build(this.builder, radioConfiguration);
85      this.needRebuild = false;
86    } else {
87      this.radioNode.update(radioConfiguration);
88    }
89    return this.radioNode.getFrameNode();
90  }
91}
92
93class RadioCheckedModifier extends ModifierWithKey<boolean> {
94  constructor(value: boolean) {
95    super(value);
96  }
97  static identity: Symbol = Symbol('radioChecked');
98  applyPeer(node: KNode, reset: boolean): void {
99    if (reset) {
100      getUINativeModule().radio.resetRadioChecked(node);
101    } else {
102      getUINativeModule().radio.setRadioChecked(node, this.value!);
103    }
104  }
105}
106
107class RadioStyleModifier extends ModifierWithKey<RadioStyle> {
108  constructor(value: RadioStyle) {
109    super(value);
110  }
111  static identity: Symbol = Symbol('radioStyle');
112  applyPeer(node: KNode, reset: boolean): void {
113    if (reset) {
114      getUINativeModule().radio.resetRadioStyle(node);
115    } else {
116      getUINativeModule().radio.setRadioStyle(
117        node, this.value.checkedBackgroundColor, this.value.uncheckedBorderColor, this.value.indicatorColor);
118    }
119  }
120
121  checkObjectDiff(): boolean {
122    let checkedBackgroundColorEQ =
123      isBaseOrResourceEqual(this.stageValue.checkedBackgroundColor,
124        this.value.checkedBackgroundColor);
125    let uncheckedBorderColorEQ =
126      isBaseOrResourceEqual(this.stageValue.uncheckedBorderColor,
127        this.value.uncheckedBorderColor);
128    let indicatorColorEQ =
129      isBaseOrResourceEqual(this.stageValue.indicatorColor,
130        this.value.indicatorColor);
131    return !checkedBackgroundColorEQ ||
132      !uncheckedBorderColorEQ ||
133      !indicatorColorEQ;
134  }
135}
136
137class RadioWidthModifier extends ModifierWithKey<Length> {
138  constructor(value: Length) {
139    super(value);
140  }
141  static identity: Symbol = Symbol('radioWidth');
142  applyPeer(node: KNode, reset: boolean): void {
143    if (reset) {
144      getUINativeModule().radio.resetRadioWidth(node);
145    } else {
146      getUINativeModule().radio.setRadioWidth(node, this.value);
147    }
148  }
149
150  checkObjectDiff(): boolean {
151    return !isBaseOrResourceEqual(this.stageValue, this.value);
152  }
153}
154
155class RadioHeightModifier extends ModifierWithKey<Length> {
156  constructor(value: Length) {
157    super(value);
158  }
159  static identity: Symbol = Symbol('radioHeight');
160  applyPeer(node: KNode, reset: boolean): void {
161    if (reset) {
162      getUINativeModule().radio.resetRadioHeight(node);
163    } else {
164      getUINativeModule().radio.setRadioHeight(node, this.value);
165    }
166  }
167
168  checkObjectDiff(): boolean {
169    return !isBaseOrResourceEqual(this.stageValue, this.value);
170  }
171}
172
173class RadioSizeModifier extends ModifierWithKey<{ width: Length; height: Length }> {
174  constructor(value: { width: Length; height: Length }) {
175    super(value);
176  }
177  static identity: Symbol = Symbol('radioSize');
178  applyPeer(node: KNode, reset: boolean): void {
179    if (reset) {
180      getUINativeModule().radio.resetRadioSize(node);
181    } else {
182      getUINativeModule().radio.setRadioSize(node, this.value.width, this.value.height);
183    }
184  }
185
186  checkObjectDiff(): boolean {
187    return !isBaseOrResourceEqual(this.stageValue.width, this.value.width) ||
188      !isBaseOrResourceEqual(this.stageValue.height, this.value.height);
189  }
190}
191
192class RadioHoverEffectModifier extends ModifierWithKey<HoverEffect> {
193  constructor(value: HoverEffect) {
194    super(value);
195  }
196  static identity: Symbol = Symbol('radioHoverEffect');
197  applyPeer(node: KNode, reset: boolean): void {
198    if (reset) {
199      getUINativeModule().radio.resetRadioHoverEffect(node);
200    } else {
201      getUINativeModule().radio.setRadioHoverEffect(node, this.value);
202    }
203  }
204
205  checkObjectDiff(): boolean {
206    return !isBaseOrResourceEqual(this.stageValue, this.value);
207  }
208}
209
210class RadioPaddingModifier extends ModifierWithKey<Padding | Length> {
211  constructor(value: Padding | Length) {
212    super(value);
213  }
214  static identity: Symbol = Symbol('radioPadding');
215  applyPeer(node: KNode, reset: boolean): void {
216    if (reset) {
217      getUINativeModule().radio.resetRadioPadding(node);
218    } else {
219      let paddingTop: Length;
220      let paddingRight: Length;
221      let paddingBottom: Length;
222      let paddingLeft: Length;
223      if (this.value !== null && this.value !== undefined) {
224        if (isLengthType(this.value) || isResource(this.value)) {
225          paddingTop = <Length> this.value;
226          paddingRight = <Length> this.value;
227          paddingBottom = <Length> this.value;
228          paddingLeft = <Length> this.value;
229        } else {
230          paddingTop = (<Padding> this.value).top;
231          paddingRight = (<Padding> this.value).right;
232          paddingBottom = (<Padding> this.value).bottom;
233          paddingLeft = (<Padding> this.value).left;
234        }
235      }
236      getUINativeModule().radio.setRadioPadding(node, paddingTop, paddingRight, paddingBottom, paddingLeft);
237    }
238  }
239
240  checkObjectDiff(): boolean {
241    if (isResource(this.stageValue) && isResource(this.value)) {
242      return !isResourceEqual(this.stageValue, this.value);
243    } else if (!isResource(this.stageValue) && !isResource(this.value)) {
244      return !((this.stageValue as Padding).left === (this.value as Padding).left &&
245        (this.stageValue as Padding).right === (this.value as Padding).right &&
246        (this.stageValue as Padding).top === (this.value as Padding).top &&
247        (this.stageValue as Padding).bottom === (this.value as Padding).bottom);
248    } else {
249      return true;
250    }
251  }
252}
253
254class RadioResponseRegionModifier extends ModifierWithKey<Array<Rectangle> | Rectangle> {
255  constructor(value: Array<Rectangle> | Rectangle) {
256    super(value);
257  }
258  static identity = Symbol('radioResponseRegion');
259  applyPeer(node: KNode, reset: boolean): void {
260    if (reset) {
261      getUINativeModule().radio.resetRadioResponseRegion(node);
262    } else {
263      let responseRegion: (number | string | Resource)[] = [];
264      if (Array.isArray(this.value)) {
265        for (let i = 0; i < this.value.length; i++) {
266          responseRegion.push(this.value[i].x ?? 'PLACEHOLDER');
267          responseRegion.push(this.value[i].y ?? 'PLACEHOLDER');
268          responseRegion.push(this.value[i].width ?? 'PLACEHOLDER');
269          responseRegion.push(this.value[i].height ?? 'PLACEHOLDER');
270        }
271      } else {
272        responseRegion.push(this.value.x ?? 'PLACEHOLDER');
273        responseRegion.push(this.value.y ?? 'PLACEHOLDER');
274        responseRegion.push(this.value.width ?? 'PLACEHOLDER');
275        responseRegion.push(this.value.height ?? 'PLACEHOLDER');
276      }
277      getUINativeModule().radio.setRadioResponseRegion(node, responseRegion, responseRegion.length);
278    }
279  }
280
281  checkObjectDiff(): boolean {
282    if (Array.isArray(this.value) && Array.isArray(this.stageValue)) {
283      if (this.value.length !== this.stageValue.length) {
284        return true;
285      } else {
286        for (let i = 0; i < this.value.length; i++) {
287          if (!(isBaseOrResourceEqual(this.stageValue[i].x, this.value[i].x) &&
288            isBaseOrResourceEqual(this.stageValue[i].y, this.value[i].y) &&
289            isBaseOrResourceEqual(this.stageValue[i].width, this.value[i].width) &&
290            isBaseOrResourceEqual(this.stageValue[i].height, this.value[i].height)
291          )) {
292            return true;
293          }
294        }
295        return false;
296      }
297    } else if (!Array.isArray(this.value) && !Array.isArray(this.stageValue)) {
298      return (!(isBaseOrResourceEqual(this.stageValue.x, this.value.x) &&
299        isBaseOrResourceEqual(this.stageValue.y, this.value.y) &&
300        isBaseOrResourceEqual(this.stageValue.width, this.value.width) &&
301        isBaseOrResourceEqual(this.stageValue.height, this.value.height)
302      ));
303    } else {
304      return true;
305    }
306  }
307}
308
309class RadioContentModifier extends ModifierWithKey<ContentModifier<RadioConfiguration>> {
310  constructor(value: ContentModifier<RadioConfiguration>) {
311    super(value);
312  }
313  static identity: Symbol = Symbol('radioContentModifier');
314  applyPeer(node: KNode, reset: boolean, component: ArkComponent): void {
315    let radioComponent = component as ArkRadioComponent;
316    radioComponent.setContentModifier(this.value);
317  }
318}
319// @ts-ignore
320globalThis.Radio.attributeModifier = function (modifier: ArkComponent): void {
321  attributeModifierFunc.call(this, modifier, (nativePtr: KNode) => {
322    return new ArkRadioComponent(nativePtr);
323  }, (nativePtr: KNode, classType: ModifierType, modifierJS: ModifierJS) => {
324    return new modifierJS.RadioModifier(nativePtr, classType);
325  });
326};
327
328// @ts-ignore
329globalThis.Radio.contentModifier = function (modifier): void {
330  const elmtId = ViewStackProcessor.GetElmtIdToAccountFor();
331  let nativeNode = getUINativeModule().getFrameNodeById(elmtId);
332  let component = this.createOrGetNode(elmtId, () => {
333    return new ArkRadioComponent(nativeNode);
334  });
335  component.setContentModifier(modifier);
336};
337