• 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' />
17class ArkToggleComponent extends ArkComponent implements ToggleAttribute {
18  builder: WrappedBuilder<Object[]> | null = null;
19  toggleNode: BuilderNode<[ToggleConfiguration]> | null = null;
20  modifier: ContentModifier<ToggleConfiguration>;
21  needRebuild: boolean = false;
22  toggleType: ToggleType = ToggleType.Switch;
23  constructor(nativePtr: KNode, classType?: ModifierType) {
24    super(nativePtr, classType);
25  }
26  allowChildCount(): number {
27    if (this.toggleType === ToggleType.Button) {
28      return 1;
29    }
30    return 0;
31  }
32  initialize(value: Object[]): this {
33    if (!value.length) {
34      return this;
35    }
36    if (!isUndefined(value[0]) && !isNull(value[0]) && isObject(value[0])) {
37      this.toggleType = (value[0] as ToggleOptions).type;
38      modifierWithKey(this._modifiersWithKeys, ToggleOptionsModifier.identity, ToggleOptionsModifier, value[0]);
39    } else {
40      modifierWithKey(this._modifiersWithKeys, ToggleOptionsModifier.identity, ToggleOptionsModifier, undefined);
41    }
42    return this;
43  }
44  onChange(callback: (isOn: boolean) => void): this {
45    modifierWithKey(this._modifiersWithKeys, ToggleOnChangeModifier.identity, ToggleOnChangeModifier, callback);
46    return this;
47  }
48  selectedColor(value: ResourceColor): this {
49    modifierWithKey(this._modifiersWithKeys, ToggleSelectedColorModifier.identity, ToggleSelectedColorModifier, value);
50    return this;
51  }
52  switchPointColor(value: ResourceColor): this {
53    modifierWithKey(this._modifiersWithKeys, ToggleSwitchPointColorModifier.identity, ToggleSwitchPointColorModifier, value);
54    return this;
55  }
56  height(value: Length): this {
57    modifierWithKey(this._modifiersWithKeys, ToggleHeightModifier.identity, ToggleHeightModifier, value);
58    return this;
59  }
60  responseRegion(value: Rectangle | Rectangle[]): this {
61    modifierWithKey(this._modifiersWithKeys, ToggleResponseRegionModifier.identity, ToggleResponseRegionModifier, value);
62    return this;
63  }
64  padding(value: Padding | Length): this {
65    modifierWithKey(this._modifiersWithKeys, TogglePaddingModifier.identity, TogglePaddingModifier, value);
66    return this;
67  }
68  backgroundColor(value: ResourceColor): this {
69    modifierWithKey(this._modifiersWithKeys, ToggleBackgroundColorModifier.identity, ToggleBackgroundColorModifier, value);
70    return this;
71  }
72  hoverEffect(value: HoverEffect): this {
73    modifierWithKey(this._modifiersWithKeys, ToggleHoverEffectModifier.identity, ToggleHoverEffectModifier, value);
74    return this;
75  }
76  switchStyle(value: SwitchStyle): this {
77    modifierWithKey(this._modifiersWithKeys, ToggleSwitchStyleModifier.identity, ToggleSwitchStyleModifier, value);
78    return this;
79  }
80  contentModifier(value: ContentModifier<ToggleConfiguration>): this {
81    modifierWithKey(this._modifiersWithKeys, ToggleContentModifier.identity, ToggleContentModifier, value);
82    return this;
83  }
84  setContentModifier(modifier: ContentModifier<ToggleConfiguration>): this {
85    if (modifier === undefined || modifier === null) {
86      getUINativeModule().toggle.setContentModifierBuilder(this.nativePtr, false);
87      return;
88    }
89    this.needRebuild = false;
90    if (this.builder !== modifier.applyContent()) {
91      this.needRebuild = true;
92    }
93    this.builder = modifier.applyContent();
94    this.modifier = modifier;
95    getUINativeModule().toggle.setContentModifierBuilder(this.nativePtr, this);
96  }
97  makeContentModifierNode(context: UIContext, toggleConfiguration: ToggleConfiguration): FrameNode | null {
98    toggleConfiguration.contentModifier = this.modifier;
99    if (isUndefined(this.toggleNode) || this.needRebuild) {
100      const xNode = globalThis.requireNapi('arkui.node');
101      this.toggleNode = new xNode.BuilderNode(context);
102      this.toggleNode.build(this.builder, toggleConfiguration);
103      this.needRebuild = false;
104    } else {
105      this.toggleNode.update(toggleConfiguration);
106    }
107    return this.toggleNode.getFrameNode();
108  }
109}
110
111class ToggleOnChangeModifier extends ModifierWithKey<(isOn:boolean) => void> {
112  constructor(value: (isOn:boolean) => void) {
113    super(value);
114  }
115  static identity = Symbol('toggleOnChange');
116  applyPeer(node: KNode, reset: boolean): void {
117    if (reset) {
118      getUINativeModule().toggle.resetOnChange(node);
119    } else {
120      getUINativeModule().toggle.setOnChange(node, this.value);
121    }
122  }
123}
124
125class ToggleSelectedColorModifier extends ModifierWithKey<ResourceColor> {
126  constructor(value: ResourceColor) {
127    super(value);
128  }
129  static identity = Symbol('toggleSelectedColor');
130  applyPeer(node: KNode, reset: boolean): void {
131    if (reset) {
132      getUINativeModule().toggle.resetSelectedColor(node);
133    } else {
134      getUINativeModule().toggle.setSelectedColor(node, this.value);
135    }
136  }
137
138  checkObjectDiff(): boolean {
139    return !isBaseOrResourceEqual(this.stageValue, this.value);
140  }
141}
142class ToggleSwitchPointColorModifier extends ModifierWithKey<ResourceColor> {
143  constructor(value: ResourceColor) {
144    super(value);
145  }
146  static identity = Symbol('toggleSwitchPointColor');
147  applyPeer(node: KNode, reset: boolean): void {
148    if (reset) {
149      getUINativeModule().toggle.resetSwitchPointColor(node);
150    } else {
151      getUINativeModule().toggle.setSwitchPointColor(node, this.value);
152    }
153  }
154
155  checkObjectDiff(): boolean {
156    return !isBaseOrResourceEqual(this.stageValue, this.value);
157  }
158}
159class ToggleHeightModifier extends ModifierWithKey<Length> {
160  constructor(value: Length) {
161    super(value);
162  }
163  static identity = Symbol('toggleHeight');
164  applyPeer(node: KNode, reset: boolean): void {
165    if (reset) {
166      getUINativeModule().toggle.resetHeight(node);
167    } else {
168      getUINativeModule().toggle.setHeight(node, this.value);
169    }
170  }
171  checkObjectDiff(): boolean {
172    return !isBaseOrResourceEqual(this.stageValue, this.value);
173  }
174}
175class ToggleResponseRegionModifier extends ModifierWithKey<Rectangle | Array<Rectangle>> {
176  constructor(value: Rectangle | Array<Rectangle>) {
177    super(value);
178  }
179  static identity = Symbol('toggleResponseRegion');
180  applyPeer(node: KNode, reset: boolean): void {
181    if (reset) {
182      getUINativeModule().toggle.resetResponseRegion(node);
183    } else {
184      let responseRegion: (number | string | Resource)[] = [];
185      if (Array.isArray(this.value)) {
186        for (let i = 0; i < this.value.length; i++) {
187          responseRegion.push(this.value[i].x ?? 'PLACEHOLDER');
188          responseRegion.push(this.value[i].y ?? 'PLACEHOLDER');
189          responseRegion.push(this.value[i].width ?? 'PLACEHOLDER');
190          responseRegion.push(this.value[i].height ?? 'PLACEHOLDER');
191        }
192      } else {
193        responseRegion.push(this.value.x ?? 'PLACEHOLDER');
194        responseRegion.push(this.value.y ?? 'PLACEHOLDER');
195        responseRegion.push(this.value.width ?? 'PLACEHOLDER');
196        responseRegion.push(this.value.height ?? 'PLACEHOLDER');
197      }
198      getUINativeModule().toggle.setResponseRegion(node, responseRegion, responseRegion.length);
199    }
200  }
201  checkObjectDiff(): boolean {
202    if (Array.isArray(this.stageValue) && Array.isArray(this.value)) {
203      if (this.value.length !== this.stageValue.length) {
204        return true;
205      } else {
206        for (let i = 0; i < this.value.length; i++) {
207          if (!(isBaseOrResourceEqual(this.stageValue[i].x, this.value[i].x) &&
208            isBaseOrResourceEqual(this.stageValue[i].y, this.value[i].y) &&
209            isBaseOrResourceEqual(this.stageValue[i].width, this.value[i].width) &&
210            isBaseOrResourceEqual(this.stageValue[i].height, this.value[i].height)
211          )) {
212            return true;
213          }
214        }
215        return false;
216      }
217    } else if (typeof this.stageValue === 'object' && typeof this.value === 'object') {
218      return !((this.stageValue as Rectangle).x === (this.value as Rectangle).x &&
219        (this.stageValue as Rectangle).y === (this.value as Rectangle).y &&
220        (this.stageValue as Rectangle).height === (this.value as Rectangle).height &&
221        (this.stageValue as Rectangle).width === (this.value as Rectangle).width);
222    } else {
223      return true;
224    }
225  }
226}
227class TogglePaddingModifier extends ModifierWithKey<Padding | Length> {
228  constructor(value: Padding | Length) {
229    super(value);
230  }
231  static identity = Symbol('togglePadding');
232  applyPeer(node: KNode, reset: boolean): void {
233    if (reset) {
234      getUINativeModule().toggle.resetPadding(node);
235    } else {
236      let top = undefined;
237      let right = undefined;
238      let bottom = undefined;
239      let left = undefined;
240      if (isLengthType(this.value) || isResource(this.value)) {
241        top = this.value;
242        right = this.value;
243        bottom = this.value;
244        left = this.value;
245      } else if (typeof this.value === 'object') {
246        top = (this.value as Padding).top;
247        right = (this.value as Padding).right;
248        bottom = (this.value as Padding).bottom;
249        left = (this.value as Padding).left;
250      }
251      getUINativeModule().toggle.setPadding(node, top, right, bottom, left);
252    }
253  }
254  checkObjectDiff(): boolean {
255    if (isResource(this.stageValue) && isResource(this.value)) {
256      return !isResourceEqual(this.stageValue, this.value);
257    } else if (!isResource(this.stageValue) && !isResource(this.value)) {
258      if (typeof this.stageValue === 'object' && typeof this.value === 'object') {
259        return !((this.stageValue as Padding).left === (this.value as Padding).left &&
260        (this.stageValue as Padding).right === (this.value as Padding).right &&
261        (this.stageValue as Padding).top === (this.value as Padding).top &&
262        (this.stageValue as Padding).bottom === (this.value as Padding).bottom);
263      } else {
264        return !(this.stageValue === this.value);
265      }
266    }
267    return true;
268  }
269}
270class ToggleBackgroundColorModifier extends ModifierWithKey<ResourceColor> {
271  constructor(value: ResourceColor) {
272    super(value);
273  }
274  static identity = Symbol('toggleBackgroundColor');
275  applyPeer(node: KNode, reset: boolean): void {
276    if (reset) {
277      getUINativeModule().toggle.resetBackgroundColor(node);
278    } else {
279      getUINativeModule().toggle.setBackgroundColor(node, this.value);
280    }
281  }
282  checkObjectDiff(): boolean {
283    return !isBaseOrResourceEqual(this.stageValue, this.value);
284  }
285}
286class ToggleHoverEffectModifier extends ModifierWithKey<HoverEffect> {
287  constructor(value: HoverEffect) {
288    super(value);
289  }
290  static identity = Symbol('toggleHoverEffect');
291  applyPeer(node: KNode, reset: boolean): void {
292    if (reset) {
293      getUINativeModule().toggle.resetHoverEffect(node);
294    } else {
295      getUINativeModule().toggle.setHoverEffect(node, this.value);
296    }
297  }
298}
299
300class ToggleSwitchStyleModifier extends ModifierWithKey<SwitchStyle> {
301  constructor(value: SwitchStyle) {
302    super(value);
303  }
304  static identity = Symbol('toggleSwitchStyle');
305  applyPeer(node: KNode, reset: boolean): void {
306    if (reset) {
307      getUINativeModule().toggle.resetSwitchStyle(node);
308    } else {
309      getUINativeModule().toggle.setSwitchStyle(node, this.value.pointRadius, this.value.unselectedColor,
310        this.value.pointColor, this.value.trackBorderRadius);
311    }
312  }
313
314  checkObjectDiff(): boolean {
315    if (!isResource(this.stageValue) && !isResource(this.value)) {
316      return !(this.stageValue.pointRadius === this.value.pointRadius &&
317        this.stageValue.unselectedColor === this.value.unselectedColor &&
318        this.stageValue.pointColor === this.value.pointColor &&
319        this.stageValue.trackBorderRadius === this.value.trackBorderRadius);
320    } else if (isResource(this.stageValue) && isResource(this.value)) {
321      return !(isResourceEqual(this.stageValue.pointRadius, this.value.pointRadius) &&
322      isResourceEqual(this.stageValue.unselectedColor, this.value.unselectedColor) &&
323      isResourceEqual(this.stageValue.pointColor, this.value.pointColor) &&
324      isResourceEqual(this.stageValue.trackBorderRadius, this.value.trackBorderRadius));
325    } else {
326      return true;
327    }
328  }
329}
330
331class ToggleContentModifier extends ModifierWithKey<ContentModifier<ToggleConfiguration>> {
332  constructor(value: ContentModifier<ToggleConfiguration>) {
333    super(value);
334  }
335  static identity: Symbol = Symbol('toggleContentModifier');
336  applyPeer(node: KNode, reset: boolean, component: ArkComponent) {
337    let toggleComponent = component as ArkToggleComponent;
338    toggleComponent.setNodePtr(node);
339    toggleComponent.setContentModifier(this.value);
340  }
341}
342class ToggleOptionsModifier extends ModifierWithKey<object> {
343  constructor(value: object) {
344    super(value);
345  }
346  static identity: Symbol = Symbol('toggleOptions');
347  applyPeer(node: KNode, reset: boolean): void {
348    if (reset) {
349      getUINativeModule().toggle.setToggleOptions(node, undefined);
350    } else {
351      getUINativeModule().toggle.setToggleOptions(node, this.value?.isOn);
352    }
353  }
354
355  checkObjectDiff(): boolean {
356    return !isBaseOrResourceEqual(this.stageValue.isOn, this.value.isOn);
357  }
358}
359// @ts-ignore
360globalThis.Toggle.attributeModifier = function (modifier: ArkComponent): void {
361  attributeModifierFunc.call(this, modifier, (nativePtr: KNode) => {
362    return new ArkToggleComponent(nativePtr);
363  }, (nativePtr: KNode, classType: ModifierType, modifierJS: ModifierJS) => {
364    return new modifierJS.ToggleModifier(nativePtr, classType);
365  });
366};
367// @ts-ignore
368globalThis.Toggle.contentModifier = function (modifier): void {
369  const elmtId = ViewStackProcessor.GetElmtIdToAccountFor();
370  let nativeNode = getUINativeModule().getFrameNodeById(elmtId);
371  let component = this.createOrGetNode(elmtId, () => {
372    return new ArkToggleComponent(nativeNode);
373  });
374  component.setNodePtr(nativeNode);
375  component.setContentModifier(modifier);
376};