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 ArkSelectComponent extends ArkComponent implements SelectAttribute { 18 builder: WrappedBuilder<Object[]> | null = null; 19 menuItemNodes: Array<BuilderNode<[MenuItemConfiguration]>> | null = null; 20 modifier: ContentModifier<MenuItemConfiguration>; 21 constructor(nativePtr: KNode, classType?: ModifierType) { 22 super(nativePtr, classType); 23 } 24 optionWidth(value: Dimension | OptionWidthMode): this { 25 modifierWithKey( 26 this._modifiersWithKeys, SelectOptionWidthModifier.identity, SelectOptionWidthModifier, value); 27 return this; 28 } 29 optionHeight(value: Dimension): this { 30 modifierWithKey( 31 this._modifiersWithKeys, SelectOptionHeightModifier.identity, SelectOptionHeightModifier, value); 32 return this; 33 } 34 width(value: Length): this { 35 modifierWithKey( 36 this._modifiersWithKeys, SelectWidthModifier.identity, SelectWidthModifier, value); 37 return this; 38 } 39 height(value: Length): this { 40 modifierWithKey( 41 this._modifiersWithKeys, SelectHeightModifier.identity, SelectHeightModifier, value); 42 return this; 43 } 44 size(value: SizeOptions): this { 45 modifierWithKey( 46 this._modifiersWithKeys, SelectSizeModifier.identity, SelectSizeModifier, value); 47 return this; 48 } 49 selected(value: number | Resource): this { 50 modifierWithKey( 51 this._modifiersWithKeys, SelectedModifier.identity, SelectedModifier, value); 52 return this; 53 } 54 value(value: ResourceStr): this { 55 modifierWithKey( 56 this._modifiersWithKeys, ValueModifier.identity, ValueModifier, value); 57 return this; 58 } 59 font(value: Font): this { 60 modifierWithKey( 61 this._modifiersWithKeys, FontModifier.identity, FontModifier, value); 62 return this; 63 } 64 fontColor(value: ResourceColor): this { 65 modifierWithKey( 66 this._modifiersWithKeys, SelectFontColorModifier.identity, SelectFontColorModifier, value); 67 return this; 68 } 69 selectedOptionBgColor(value: ResourceColor): this { 70 modifierWithKey( 71 this._modifiersWithKeys, SelectedOptionBgColorModifier.identity, SelectedOptionBgColorModifier, value); 72 return this; 73 } 74 selectedOptionFont(value: Font): this { 75 modifierWithKey( 76 this._modifiersWithKeys, SelectedOptionFontModifier.identity, SelectedOptionFontModifier, value); 77 return this; 78 } 79 selectedOptionFontColor(value: ResourceColor): this { 80 modifierWithKey( 81 this._modifiersWithKeys, SelectedOptionFontColorModifier.identity, SelectedOptionFontColorModifier, value); 82 return this; 83 } 84 optionBgColor(value: ResourceColor): this { 85 modifierWithKey( 86 this._modifiersWithKeys, OptionBgColorModifier.identity, OptionBgColorModifier, value); 87 return this; 88 } 89 optionFont(value: Font): this { 90 modifierWithKey( 91 this._modifiersWithKeys, OptionFontModifier.identity, OptionFontModifier, value); 92 return this; 93 } 94 optionFontColor(value: ResourceColor): this { 95 modifierWithKey( 96 this._modifiersWithKeys, OptionFontColorModifier.identity, OptionFontColorModifier, value); 97 return this; 98 } 99 onSelect(callback: (index: number, value: string) => void): this { 100 throw new Error('Method not implemented.'); 101 } 102 space(value: Length): this { 103 modifierWithKey( 104 this._modifiersWithKeys, SpaceModifier.identity, SpaceModifier, value); 105 return this; 106 } 107 arrowPosition(value: ArrowPosition): this { 108 modifierWithKey( 109 this._modifiersWithKeys, ArrowPositionModifier.identity, ArrowPositionModifier, value); 110 return this; 111 } 112 menuAlign(alignType: MenuAlignType, offset?: Offset): this { 113 let menuAlign = new ArkMenuAlignType(alignType, offset); 114 modifierWithKey( 115 this._modifiersWithKeys, MenuAlignModifier.identity, MenuAlignModifier, menuAlign); 116 return this; 117 } 118 menuBackgroundColor(value: ResourceColor): this { 119 modifierWithKey( 120 this._modifiersWithKeys, MenuBackgroundColorModifier.identity, MenuBackgroundColorModifier, value); 121 return this; 122 } 123 menuBackgroundBlurStyle(value: BlurStyle): this { 124 modifierWithKey( 125 this._modifiersWithKeys, MenuBackgroundBlurStyleModifier.identity, MenuBackgroundBlurStyleModifier, value); 126 return this; 127 } 128 controlSize(controlSize: ControlSize): this { 129 modifierWithKey( 130 this._modifiersWithKeys, ControlSizeModifier.identity, ControlSizeModifier, controlSize); 131 return this; 132 } 133 setContentModifier(modifier: ContentModifier<MenuItemConfiguration>): this { 134 if (modifier === undefined || modifier === null) { 135 getUINativeModule().select.setContentModifierBuilder(this.nativePtr, false); 136 return; 137 } 138 this.builder = modifier.applyContent(); 139 this.modifier = modifier; 140 getUINativeModule().select.setContentModifierBuilder(this.nativePtr, this); 141 } 142 makeContentModifierNode(context: UIContext, menuItemConfiguration: MenuItemConfiguration): FrameNode | null { 143 menuItemConfiguration.contentModifier = this.modifier; 144 const index = menuItemConfiguration.index; 145 const xNode = globalThis.requireNapi('arkui.node'); 146 this.menuItemNodes = new xNode.BuilderNode(context); 147 this.menuItemNodes.build(this.builder, menuItemConfiguration); 148 return this.menuItemNodes.getFrameNode(); 149 } 150 divider(value: DividerOptions | null): this { 151 modifierWithKey( 152 this._modifiersWithKeys, SelectDividerModifier.identity, SelectDividerModifier, value); 153 return this; 154 } 155} 156 157class MenuBackgroundColorModifier extends ModifierWithKey<ResourceColor> { 158 constructor(value: ResourceColor) { 159 super(value); 160 } 161 static identity: Symbol = Symbol('selectMenuBackgroundColor'); 162 applyPeer(node: KNode, reset: boolean): void { 163 if (reset) { 164 getUINativeModule().select.resetMenuBackgroundColor(node); 165 } else { 166 getUINativeModule().select.setMenuBackgroundColor(node, this.value); 167 } 168 } 169 170 checkObjectDiff(): boolean { 171 return !isBaseOrResourceEqual(this.stageValue, this.value); 172 } 173} 174 175class MenuBackgroundBlurStyleModifier extends ModifierWithKey<BlurStyle> { 176 constructor(value: BlurStyle) { 177 super(value); 178 } 179 static identity: Symbol = Symbol('selectMenuBackgroundBlurStyle'); 180 applyPeer(node: KNode, reset: boolean): void { 181 if (reset) { 182 getUINativeModule().select.resetMenuBackgroundBlurStyle(node); 183 } else { 184 getUINativeModule().select.setMenuBackgroundBlurStyle(node, this.value); 185 } 186 } 187 188 checkObjectDiff(): boolean { 189 return !isBaseOrResourceEqual(this.stageValue, this.value); 190 } 191} 192 193class FontModifier extends ModifierWithKey<Font> { 194 constructor(value: Font) { 195 super(value); 196 } 197 static identity: Symbol = Symbol('selectFont'); 198 applyPeer(node: KNode, reset: boolean): void { 199 if (reset) { 200 getUINativeModule().select.resetFont(node); 201 } else { 202 getUINativeModule().select.setFont(node, this.value.size, this.value.weight, this.value.family, this.value.style); 203 } 204 } 205 206 checkObjectDiff(): boolean { 207 let sizeEQ = isBaseOrResourceEqual(this.stageValue.size, this.value.size); 208 let weightEQ = this.stageValue.weight === this.value.weight; 209 let familyEQ = isBaseOrResourceEqual(this.stageValue.family, this.value.family); 210 let styleEQ = this.stageValue.style === this.value.style; 211 return !sizeEQ || !weightEQ || !familyEQ || !styleEQ; 212 } 213} 214 215class OptionFontModifier extends ModifierWithKey<Font> { 216 constructor(value: Font) { 217 super(value); 218 } 219 static identity: Symbol = Symbol('selectOptionFont'); 220 applyPeer(node: KNode, reset: boolean): void { 221 if (reset) { 222 getUINativeModule().select.resetOptionFont(node); 223 } else { 224 getUINativeModule().select.setOptionFont(node, this.value.size, this.value.weight, this.value.family, this.value.style); 225 } 226 } 227 228 checkObjectDiff(): boolean { 229 let sizeEQ = isBaseOrResourceEqual(this.stageValue.size, this.value.size); 230 let weightEQ = this.stageValue.weight === this.value.weight; 231 let familyEQ = isBaseOrResourceEqual(this.stageValue.family, this.value.family); 232 let styleEQ = this.stageValue.style === this.value.style; 233 return !sizeEQ || !weightEQ || !familyEQ || !styleEQ; 234 } 235} 236 237class SelectedOptionFontModifier extends ModifierWithKey<Font> { 238 constructor(value: Font) { 239 super(value); 240 } 241 static identity: Symbol = Symbol('selectSelectedOptionFont'); 242 applyPeer(node: KNode, reset: boolean): void { 243 if (reset) { 244 getUINativeModule().select.resetSelectedOptionFont(node); 245 } else { 246 getUINativeModule().select.setSelectedOptionFont(node, this.value.size, this.value.weight, this.value.family, this.value.style); 247 } 248 } 249 250 checkObjectDiff(): boolean { 251 let sizeEQ = isBaseOrResourceEqual(this.stageValue.size, this.value.size); 252 let weightEQ = this.stageValue.weight === this.value.weight; 253 let familyEQ = isBaseOrResourceEqual(this.stageValue.family, this.value.family); 254 let styleEQ = this.stageValue.style === this.value.style; 255 return !sizeEQ || !weightEQ || !familyEQ || !styleEQ; 256 } 257} 258 259class MenuAlignModifier extends ModifierWithKey<ArkMenuAlignType> { 260 constructor(value: ArkMenuAlignType) { 261 super(value); 262 } 263 static identity: Symbol = Symbol('selectMenuAlign'); 264 applyPeer(node: KNode, reset: boolean): void { 265 if (reset) { 266 getUINativeModule().select.resetMenuAlign(node); 267 } else { 268 getUINativeModule().select.setMenuAlign(node, this.value.alignType, this.value.dx, this.value.dy); 269 } 270 } 271 272 checkObjectDiff(): boolean { 273 let alignTypeEQ = this.stageValue.alignType === this.value.alignType; 274 let dxEQ = isBaseOrResourceEqual(this.stageValue, this.value); 275 let dyEQ = isBaseOrResourceEqual(this.stageValue, this.value); 276 277 return !alignTypeEQ || !dxEQ || !dyEQ; 278 } 279 280 private isEqual(stageValue: Length, value: Length): boolean { 281 if ((!isUndefined(stageValue) && isResource(stageValue)) && 282 (!isUndefined(value) && isResource(value))) { 283 return !isResourceEqual(stageValue, value); 284 } else { 285 return stageValue !== value; 286 } 287 } 288} 289 290 291class ControlSizeModifier extends ModifierWithKey<ControlSize> { 292 constructor(value: ControlSize) { 293 super(value); 294 } 295 static identity: Symbol = Symbol('controlSize'); 296 applyPeer(node: KNode, reset: boolean): void { 297 if (reset) { 298 getUINativeModule().select.resetControlSize(node); 299 } else { 300 getUINativeModule().select.setControlSize(node, this.value); 301 } 302 } 303 304 checkObjectDiff(): boolean { 305 return this.stageValue !== this.value; 306 } 307} 308 309class ArrowPositionModifier extends ModifierWithKey<ArrowPosition> { 310 constructor(value: ArrowPosition) { 311 super(value); 312 } 313 static identity: Symbol = Symbol('selectArrowPosition'); 314 applyPeer(node: KNode, reset: boolean): void { 315 if (reset) { 316 getUINativeModule().select.resetArrowPosition(node); 317 } else { 318 getUINativeModule().select.setArrowPosition(node, this.value); 319 } 320 } 321 322 checkObjectDiff(): boolean { 323 return this.stageValue !== this.value; 324 } 325} 326class SpaceModifier extends ModifierWithKey<Length> { 327 constructor(value: Length) { 328 super(value); 329 } 330 static identity: Symbol = Symbol('selectSpace'); 331 332 applyPeer(node: KNode, reset: boolean): void { 333 if (reset) { 334 getUINativeModule().select.resetSpace(node); 335 } else { 336 getUINativeModule().select.setSpace(node, this.value); 337 } 338 } 339 340 checkObjectDiff(): boolean { 341 return !isBaseOrResourceEqual(this.stageValue, this.value); 342 } 343} 344class ValueModifier extends ModifierWithKey<ResourceStr> { 345 constructor(value: ResourceStr) { 346 super(value); 347 } 348 static identity: Symbol = Symbol('selectValue'); 349 350 applyPeer(node: KNode, reset: boolean): void { 351 if (reset) { 352 getUINativeModule().select.resetValue(node); 353 } else { 354 getUINativeModule().select.setValue(node, this.value); 355 } 356 } 357 358 checkObjectDiff(): boolean { 359 return !isBaseOrResourceEqual(this.stageValue, this.value); 360 } 361} 362class SelectedModifier extends ModifierWithKey<number | Resource> { 363 constructor(value: number | Resource) { 364 super(value); 365 } 366 static identity: Symbol = Symbol('selectSelected'); 367 368 applyPeer(node: KNode, reset: boolean): void { 369 if (reset) { 370 getUINativeModule().select.resetSelected(node); 371 } else { 372 getUINativeModule().select.setSelected(node, this.value); 373 } 374 } 375 376 checkObjectDiff(): boolean { 377 return !isBaseOrResourceEqual(this.stageValue, this.value); 378 } 379} 380class SelectFontColorModifier extends ModifierWithKey<ResourceColor> { 381 constructor(value: ResourceColor) { 382 super(value); 383 } 384 static identity: Symbol = Symbol('selectFontColor'); 385 386 applyPeer(node: KNode, reset: boolean): void { 387 if (reset) { 388 getUINativeModule().select.resetFontColor(node); 389 } else { 390 getUINativeModule().select.setFontColor(node, this.value); 391 } 392 } 393 checkObjectDiff(): boolean { 394 return !isBaseOrResourceEqual(this.stageValue, this.value); 395 } 396} 397class SelectedOptionBgColorModifier extends ModifierWithKey<ResourceColor> { 398 constructor(value: ResourceColor) { 399 super(value); 400 } 401 static identity: Symbol = Symbol('selectSelectedOptionBgColor'); 402 403 applyPeer(node: KNode, reset: boolean): void { 404 if (reset) { 405 getUINativeModule().select.resetSelectedOptionBgColor(node); 406 } else { 407 getUINativeModule().select.setSelectedOptionBgColor(node, this.value); 408 } 409 } 410 checkObjectDiff(): boolean { 411 return !isBaseOrResourceEqual(this.stageValue, this.value); 412 } 413} 414class OptionBgColorModifier extends ModifierWithKey<ResourceColor> { 415 constructor(value: ResourceColor) { 416 super(value); 417 } 418 static identity: Symbol = Symbol('selectOptionBgColor'); 419 420 applyPeer(node: KNode, reset: boolean): void { 421 if (reset) { 422 getUINativeModule().select.resetOptionBgColor(node); 423 } else { 424 getUINativeModule().select.setOptionBgColor(node, this.value); 425 } 426 } 427 checkObjectDiff(): boolean { 428 return !isBaseOrResourceEqual(this.stageValue, this.value); 429 } 430} 431class OptionFontColorModifier extends ModifierWithKey<ResourceColor> { 432 constructor(value: ResourceColor) { 433 super(value); 434 } 435 static identity: Symbol = Symbol('selectOptionFontColor'); 436 437 applyPeer(node: KNode, reset: boolean): void { 438 if (reset) { 439 getUINativeModule().select.resetOptionFontColor(node); 440 } else { 441 getUINativeModule().select.setOptionFontColor(node, this.value); 442 } 443 } 444 checkObjectDiff(): boolean { 445 return !isBaseOrResourceEqual(this.stageValue, this.value); 446 } 447} 448class SelectedOptionFontColorModifier extends ModifierWithKey<ResourceColor> { 449 constructor(value: ResourceColor) { 450 super(value); 451 } 452 static identity: Symbol = Symbol('selectSelectedOptionFontColor'); 453 454 applyPeer(node: KNode, reset: boolean): void { 455 if (reset) { 456 getUINativeModule().select.resetSelectedOptionFontColor(node); 457 } else { 458 getUINativeModule().select.setSelectedOptionFontColor(node, this.value); 459 } 460 } 461 checkObjectDiff(): boolean { 462 return !isBaseOrResourceEqual(this.stageValue, this.value); 463 } 464} 465 466class SelectOptionWidthModifier extends ModifierWithKey<Dimension | OptionWidthMode> { 467 constructor(value: Dimension | OptionWidthMode) { 468 super(value); 469 } 470 static identity: Symbol = Symbol('selectOptionWidth'); 471 472 applyPeer(node: KNode, reset: boolean): void { 473 if (reset) { 474 getUINativeModule().select.resetOptionWidth(node); 475 } else { 476 getUINativeModule().select.setOptionWidth(node, this.value); 477 } 478 } 479 480 checkObjectDiff(): boolean { 481 return !isBaseOrResourceEqual(this.stageValue, this.value); 482 } 483} 484 485class SelectOptionHeightModifier extends ModifierWithKey<Dimension> { 486 constructor(value: Dimension) { 487 super(value); 488 } 489 static identity: Symbol = Symbol('selectOptionHeight'); 490 491 applyPeer(node: KNode, reset: boolean): void { 492 if (reset) { 493 getUINativeModule().select.resetOptionHeight(node); 494 } else { 495 getUINativeModule().select.setOptionHeight(node, this.value); 496 } 497 } 498 499 checkObjectDiff(): boolean { 500 return !isBaseOrResourceEqual(this.stageValue, this.value); 501 } 502} 503 504class SelectWidthModifier extends ModifierWithKey<Length> { 505 constructor(value: Length) { 506 super(value); 507 } 508 static identity: Symbol = Symbol('selectWidth'); 509 510 applyPeer(node: KNode, reset: boolean): void { 511 if (reset) { 512 getUINativeModule().select.resetWidth(node); 513 } else { 514 getUINativeModule().select.setWidth(node, this.value); 515 } 516 } 517 518 checkObjectDiff(): boolean { 519 return !isBaseOrResourceEqual(this.stageValue, this.value); 520 } 521} 522 523class SelectDividerModifier extends ModifierWithKey<DividerOptions | null> { 524 constructor(value: DividerOptions | null) { 525 super(value); 526 } 527 static identity: Symbol = Symbol('selectDivider'); 528 applyPeer(node: KNode, reset: boolean): void { 529 if (reset) { 530 getUINativeModule().select.resetDivider(node, this.value); 531 } else { 532 getUINativeModule().select.setDivider(node, this.value?.strokeWidth, this.value?.color, this.value?.startMargin, this.value?.endMargin); 533 } 534 } 535 536 checkObjectDiff(): boolean { 537 return !(this.stageValue?.strokeWidth === this.value?.strokeWidth && 538 this.stageValue?.color === this.value?.color && 539 this.stageValue?.startMargin === this.value?.startMargin && 540 this.stageValue?.endMargin === this.value?.endMargin); 541 } 542} 543 544class SelectHeightModifier extends ModifierWithKey<Length> { 545 constructor(value: Length) { 546 super(value); 547 } 548 static identity: Symbol = Symbol('selectHeight'); 549 550 applyPeer(node: KNode, reset: boolean): void { 551 if (reset) { 552 getUINativeModule().select.resetHeight(node); 553 } else { 554 getUINativeModule().select.setHeight(node, this.value); 555 } 556 } 557 558 checkObjectDiff(): boolean { 559 return !isBaseOrResourceEqual(this.stageValue, this.value); 560 } 561} 562 563class SelectSizeModifier extends ModifierWithKey<SizeOptions> { 564 constructor(value: SizeOptions) { 565 super(value); 566 } 567 static identity: Symbol = Symbol('selectSize'); 568 569 applyPeer(node: KNode, reset: boolean): void { 570 if (reset) { 571 getUINativeModule().select.resetSize(node); 572 } else { 573 getUINativeModule().select.setSize(node, this.value.width, this.value.height); 574 } 575 } 576 577 checkObjectDiff(): boolean { 578 return !isBaseOrResourceEqual(this.stageValue.width, this.value.width) || 579 !isBaseOrResourceEqual(this.stageValue.height, this.value.height); 580 } 581} 582 583// @ts-ignore 584globalThis.Select.attributeModifier = function (modifier: ArkComponent): void { 585 attributeModifierFunc.call(this, modifier, (nativePtr: KNode) => { 586 return new ArkSelectComponent(nativePtr); 587 }, (nativePtr: KNode, classType: ModifierType, modifierJS: ModifierJS) => { 588 return new modifierJS.SelectModifier(nativePtr, classType); 589 }); 590}; 591 592// @ts-ignore 593globalThis.Select.menuItemContentModifier = function (modifier): void { 594 const elmtId = ViewStackProcessor.GetElmtIdToAccountFor(); 595 let nativeNode = getUINativeModule().getFrameNodeById(elmtId); 596 let component = this.createOrGetNode(elmtId, () => { 597 return new ArkSelectComponent(nativeNode); 598 }); 599 component.setContentModifier(modifier); 600}; 601