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