1/* 2 * Copyright (c) 2023-2024 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 16import display from '@ohos.display'; 17import mediaquery from '@ohos.mediaquery'; 18import { Theme } from '@ohos.arkui.theme'; 19import { LengthMetrics } from '@ohos.arkui.node' 20 21interface IconTheme { 22 size: SizeOptions; 23 margin: LocalizedMargin; 24 fillColor: ResourceColor; 25 borderRadius: Length; 26} 27 28interface TitleTheme { 29 margin: LocalizedMargin; 30 minFontSize: number; 31 fontWeight: FontWeight; 32 fontSize: Resource; 33 fontColor: ResourceColor; 34} 35 36interface ButtonTheme { 37 margin: LocalizedMargin; 38 padding: LocalizedPadding; 39 fontSize: Resource; 40 fontColor: ResourceColor; 41 textMargin: LocalizedMargin; 42 minFontSize: number; 43 fontWeight: FontWeight; 44 hoverColor: ResourceColor; 45 backgroundColor: ResourceColor; 46} 47 48interface MessageTheme { 49 fontSize: Resource; 50 fontColor: ResourceColor; 51 fontWeight: FontWeight; 52 plainFontColor: ResourceColor; 53} 54 55interface CloseButtonTheme { 56 size: SizeOptions; 57 image: ResourceStr; 58 imageSize: SizeOptions; 59 margin: LocalizedMargin; 60 padding: LocalizedPadding; 61 fillColor: ResourceColor; 62 hoverColor: ResourceColor; 63 backgroundColor: ResourceColor; 64} 65 66interface WindowsTheme { 67 padding: LocalizedPadding; 68} 69 70interface PopupTheme { 71 icon: IconTheme; 72 title: TitleTheme; 73 button: ButtonTheme; 74 message: MessageTheme; 75 windows: WindowsTheme; 76 closeButton: CloseButtonTheme; 77} 78 79export const defaultTheme: PopupTheme = { 80 icon: { 81 size: { width: 32, height: 32 }, 82 margin: { 83 top: LengthMetrics.vp(12), 84 bottom: LengthMetrics.vp(12), 85 start: LengthMetrics.vp(12), 86 end: LengthMetrics.vp(12) 87 }, 88 fillColor: '', 89 borderRadius: $r('sys.float.ohos_id_corner_radius_default_s') 90 91 }, 92 title: { 93 margin: { bottom: LengthMetrics.vp(2) }, 94 minFontSize: 12, 95 fontWeight: FontWeight.Medium, 96 fontSize: $r('sys.float.ohos_id_text_size_sub_title2'), 97 fontColor: $r('sys.color.font_primary') 98 }, 99 button: { 100 margin: { 101 top: LengthMetrics.vp(16), 102 bottom: LengthMetrics.vp(16), 103 start: LengthMetrics.vp(16), 104 end: LengthMetrics.vp(16) 105 }, 106 padding: { 107 top: LengthMetrics.vp(4), 108 bottom: LengthMetrics.vp(4), 109 start: LengthMetrics.vp(4), 110 end: LengthMetrics.vp(4) 111 }, 112 fontSize: $r('sys.float.ohos_id_text_size_button2'), 113 fontColor: $r('sys.color.font_emphasize'), 114 textMargin: { 115 top: LengthMetrics.vp(8), 116 bottom: LengthMetrics.vp(8), 117 start: LengthMetrics.vp(8), 118 end: LengthMetrics.vp(8) 119 }, 120 minFontSize: 9, 121 fontWeight: FontWeight.Medium, 122 hoverColor: $r('sys.color.ohos_id_color_hover'), 123 backgroundColor: $r('sys.color.ohos_id_color_background_transparent') 124 }, 125 message: { 126 fontSize: $r('sys.float.ohos_id_text_size_body2'), 127 fontColor: $r('sys.color.font_secondary'), 128 fontWeight: FontWeight.Regular, 129 plainFontColor: $r('sys.color.font_primary') 130 }, 131 windows: { 132 padding: { 133 top: LengthMetrics.vp(12), 134 bottom: LengthMetrics.vp(12), 135 start: LengthMetrics.vp(12), 136 end: LengthMetrics.vp(12) 137 }, 138 }, 139 closeButton: { 140 size: { width: 22, height: 22 }, 141 imageSize: { width: 18, height: 18 }, 142 padding: { 143 top: LengthMetrics.vp(2), 144 bottom: LengthMetrics.vp(2), 145 start: LengthMetrics.vp(2), 146 end: LengthMetrics.vp(2) 147 }, 148 margin: { 149 top: LengthMetrics.vp(12), 150 bottom: LengthMetrics.vp(12), 151 start: LengthMetrics.vp(12), 152 end: LengthMetrics.vp(12) 153 }, 154 image: $r('sys.media.ohos_ic_public_cancel'), 155 fillColor: $r('sys.color.icon_secondary'), 156 hoverColor: $r('sys.color.ohos_id_color_hover'), 157 backgroundColor: $r('sys.color.ohos_id_color_background_transparent') 158 }, 159}; 160 161export interface PopupTextOptions { 162 text: ResourceStr; 163 fontSize?: number | string | Resource; 164 fontColor?: ResourceColor; 165 fontWeight?: number | FontWeight | string; 166} 167 168export interface PopupButtonOptions { 169 text: ResourceStr; 170 action?: () => void; 171 fontSize?: number | string | Resource; 172 fontColor?: ResourceColor; 173} 174 175export interface PopupIconOptions { 176 image: ResourceStr; 177 width?: Dimension; 178 height?: Dimension; 179 fillColor?: ResourceColor; 180 borderRadius?: Length | BorderRadiuses; 181} 182 183export interface PopupOptions { 184 icon?: PopupIconOptions; 185 title?: PopupTextOptions; 186 message: PopupTextOptions; 187 direction?: Direction; 188 showClose?: boolean | Resource; 189 onClose?: () => void; 190 buttons?: [PopupButtonOptions?, PopupButtonOptions?]; 191} 192 193const noop = () => { 194}; 195 196@Builder 197export function Popup(options: PopupOptions) { 198 PopupComponent({ 199 icon: options.icon, 200 title: options.title, 201 message: options.message, 202 popupDirection: options.direction, 203 showClose: options.showClose, 204 onClose: options.onClose, 205 buttons: options.buttons 206 }) 207} 208 209@Component 210export struct PopupComponent { 211 private onClose: () => void = noop; 212 private theme: PopupTheme = defaultTheme; 213 @Prop icon: PopupIconOptions = { image: '' }; 214 @Prop title: PopupTextOptions = { text: '' }; 215 @Prop message: PopupTextOptions = { text: '' }; 216 @Prop popupDirection: Direction = Direction.Auto; 217 @Prop showClose: boolean | Resource = true; 218 @Prop buttons: [PopupButtonOptions?, PopupButtonOptions?] = [{ text: '' }, { text: '' }]; 219 textHeight: number = 0; 220 @State titleHeight: number = 0; 221 @State applyHeight: number = 0; 222 @State buttonHeight: number = 0; 223 @State messageMaxWeight: number | undefined = 0; 224 @State beforeScreenStatus: boolean | undefined = undefined; 225 @State currentScreenStatus: boolean = true; 226 @State applySizeOptions: ConstraintSizeOptions | undefined = undefined; 227 @State closeButtonBackgroundColor: ResourceColor = $r('sys.color.ohos_id_color_background_transparent'); 228 @State firstButtonBackgroundColor: ResourceColor = $r('sys.color.ohos_id_color_background_transparent'); 229 @State secondButtonBackgroundColor: ResourceColor = $r('sys.color.ohos_id_color_background_transparent'); 230 @State closeButtonFillColorWithTheme: ResourceColor = $r('sys.color.icon_secondary'); 231 private listener = mediaquery.matchMediaSync('(orientation: landscape)') 232 233 private getIconWidth(): Dimension { 234 return this.icon?.width ?? this.theme.icon.size.width as number 235 } 236 237 private getIconHeight(): Dimension { 238 return this.icon?.height ?? this.theme.icon.size.height as number 239 } 240 241 private getIconFillColor(): ResourceColor { 242 return this.icon?.fillColor ?? this.theme.icon.fillColor 243 } 244 245 private getIconBorderRadius(): Length | BorderRadiuses { 246 return this.icon?.borderRadius ?? this.theme.icon.borderRadius 247 } 248 249 private getIconMargin(): LocalizedMargin { 250 return { 251 start: new LengthMetrics(this.theme.button.margin.start.value / 2, this.theme.button.margin.start.unit), 252 end: new LengthMetrics(this.theme.icon.margin.start.value - (this.theme.button.margin.end.value / 2) 253 , this.theme.button.margin.start.unit) 254 } 255 } 256 257 private getIconImage(): ResourceStr | undefined { 258 return this.icon?.image 259 } 260 261 private getTitleText(): ResourceStr | undefined { 262 return this.title?.text 263 } 264 265 private getTitlePadding(): LocalizedPadding { 266 return { 267 start: new LengthMetrics(this.theme.button.margin.start.value / 2, this.theme.button.margin.start.unit), 268 end: this.theme.closeButton.margin.end 269 } 270 } 271 272 private getTitleMargin(): LocalizedMargin { 273 return this.theme.title.margin 274 } 275 276 private getTitleMinFontSize(): number | string | Resource { 277 return this.theme.title.minFontSize 278 } 279 280 private getTitleFontWeight(): number | FontWeight | string { 281 return this.title?.fontWeight ?? this.theme.title.fontWeight 282 } 283 284 private getTitleFontSize(): number | string | Resource { 285 return this.title?.fontSize ?? this.theme.title.fontSize 286 } 287 288 private getTitleFontColor(): ResourceColor { 289 return this.title?.fontColor ?? this.theme.title.fontColor 290 } 291 292 private getCloseButtonWidth(): Length | undefined { 293 return this.theme.closeButton.size.width 294 } 295 296 private getCloseButtonHeight(): Length | undefined { 297 return this.theme.closeButton.size.height 298 } 299 300 private getCloseButtonImage(): ResourceStr { 301 return this.theme.closeButton.image 302 } 303 304 private getCloseButtonFillColor(): ResourceColor { 305 return this.closeButtonFillColorWithTheme; 306 } 307 308 private getCloseButtonHoverColor(): ResourceColor { 309 return this.theme.closeButton.hoverColor 310 } 311 312 private getCloseButtonBackgroundColor(): ResourceColor { 313 return this.theme.closeButton.backgroundColor 314 } 315 316 private getCloseButtonPadding(): LocalizedPadding { 317 return this.theme.closeButton.padding 318 } 319 320 private getCloseButtonImageWidth(): Length | undefined { 321 return this.theme.closeButton.imageSize.width 322 } 323 324 private getCloseButtonImageHeight(): Length | undefined { 325 return this.theme.closeButton.imageSize.height 326 } 327 328 private getMessageText(): string | Resource { 329 return this.message.text 330 } 331 332 private getMessageFontSize(): number | string | Resource { 333 return this.message.fontSize ?? this.theme.message.fontSize 334 } 335 336 private getMessageFontColor(): ResourceColor { 337 let fontColor: ResourceColor 338 if (this.message.fontColor) { 339 fontColor = this.message.fontColor 340 } else { 341 if (this.title.text !== '' && this.title.text !== void (0)) { 342 fontColor = this.theme.message.fontColor 343 } else { 344 fontColor = this.theme.message.plainFontColor 345 } 346 } 347 return fontColor 348 } 349 350 private getMessagePadding(): LocalizedPadding { 351 let padding: LocalizedPadding 352 if (this.title.text !== '' && this.title.text !== void (0)) { 353 padding = { start: LengthMetrics.vp(this.theme.button.margin.start.value / 2) } 354 } else { 355 padding = { 356 start: LengthMetrics.vp(this.theme.button.margin.start.value / 2), 357 end: LengthMetrics.vp(this.theme.closeButton.margin.end.value) 358 } 359 } 360 return padding 361 } 362 363 private getMessageMaxWeight(): number | undefined { 364 let textMaxWeight: number | undefined = undefined; 365 let defaultDisplaySync: display.Display = display.getDefaultDisplaySync() 366 if (this.showClose || this.showClose === void (0)) { 367 if (px2vp(defaultDisplaySync.width) > 400) { 368 textMaxWeight = 400 369 } else { 370 textMaxWeight = px2vp(defaultDisplaySync.width) - 40 - 40 371 } 372 textMaxWeight -= (this.theme.windows.padding.start.value - (this.theme.button.margin.end.value / 2)) 373 textMaxWeight -= this.theme.windows.padding.end.value 374 textMaxWeight -= this.theme.button.margin.start.value / 2 375 textMaxWeight -= this.getCloseButtonWidth() as number 376 } 377 return textMaxWeight 378 } 379 380 private getMessageFontWeight(): number | FontWeight | string { 381 return this.theme.message.fontWeight 382 } 383 384 private getButtonMargin(): LocalizedMargin { 385 return { 386 top: LengthMetrics.vp(this.theme.button.textMargin.top.value / 2 - 4), 387 bottom: LengthMetrics.vp(this.theme.button.textMargin.bottom.value / 2 - 4), 388 start: LengthMetrics.vp(this.theme.button.margin.start.value / 2 - 4), 389 end: LengthMetrics.vp(this.theme.button.margin.end.value / 2 - 4) 390 } 391 } 392 393 private getButtonTextMargin(): LocalizedMargin { 394 return { top: LengthMetrics.vp(this.theme.button.textMargin.bottom.value) } 395 } 396 397 private getButtonTextPadding(): LocalizedPadding { 398 return this.theme.button.padding 399 } 400 401 private getButtonHoverColor(): ResourceColor { 402 return this.theme.button.hoverColor 403 } 404 405 private getButtonBackgroundColor(): ResourceColor { 406 return this.theme.button.backgroundColor 407 } 408 409 private getFirstButtonText(): string | Resource | undefined { 410 return this.buttons?.[0]?.text 411 } 412 413 private getSecondButtonText(): string | Resource | undefined { 414 return this.buttons?.[1]?.text 415 } 416 417 private getFirstButtonFontSize(): number | string | Resource { 418 return this.buttons?.[0]?.fontSize ?? this.theme.button.fontSize 419 } 420 421 private getSecondButtonFontSize(): number | string | Resource { 422 return this.buttons?.[1]?.fontSize ?? this.theme.button.fontSize 423 } 424 425 private getFirstButtonFontColor(): ResourceColor { 426 return this.buttons?.[0]?.fontColor ?? this.theme.button.fontColor 427 } 428 429 private getSecondButtonFontColor(): ResourceColor { 430 return this.buttons?.[1]?.fontColor ?? this.theme.button.fontColor 431 } 432 433 private getButtonMinFontSize(): Dimension { 434 return this.theme.button.minFontSize 435 } 436 437 private getButtonFontWeight(): number | FontWeight | string { 438 return this.theme.button.fontWeight 439 } 440 441 private getWindowsPadding(): LocalizedPadding { 442 return { 443 top: this.theme.windows.padding.top, 444 bottom: LengthMetrics.vp(this.theme.windows.padding.bottom.value - 445 (this.theme.button.textMargin.bottom.value / 2)), 446 start: LengthMetrics.vp(this.theme.windows.padding.start.value - 447 (this.theme.button.margin.end.value / 2)), 448 end: this.theme.windows.padding.end 449 } 450 } 451 452 onWillApplyTheme(theme: Theme): void { 453 this.theme.title.fontColor = theme.colors.fontPrimary; 454 this.theme.button.fontColor = theme.colors.fontEmphasize; 455 this.theme.message.fontColor = theme.colors.fontSecondary; 456 this.theme.message.plainFontColor = theme.colors.fontPrimary; 457 this.closeButtonFillColorWithTheme = theme.colors.iconSecondary; 458 } 459 460 aboutToAppear() { 461 this.listener.on("change", (mediaQueryResult: mediaquery.MediaQueryResult) => { 462 this.currentScreenStatus = mediaQueryResult.matches 463 }) 464 } 465 466 aboutToDisappear() { 467 this.listener.off("change") 468 } 469 470 getScrollMaxHeight(): number | undefined { 471 let scrollMaxHeight: number | undefined = undefined; 472 if (this.currentScreenStatus !== this.beforeScreenStatus) { 473 this.applySizeOptions = this.getApplyMaxSize(); 474 this.beforeScreenStatus = this.currentScreenStatus 475 return scrollMaxHeight; 476 } 477 scrollMaxHeight = this.applyHeight 478 scrollMaxHeight -= this.titleHeight 479 scrollMaxHeight -= this.buttonHeight 480 scrollMaxHeight -= this.theme.windows.padding.top.value 481 scrollMaxHeight -= (this.theme.button.textMargin.bottom.value / 2) 482 scrollMaxHeight -= this.theme.title.margin.bottom.value 483 scrollMaxHeight -= (this.theme.windows.padding.bottom.value - 484 (this.theme.button.textMargin.bottom.value / 2)) 485 if (Math.floor(this.textHeight) > Math.floor(scrollMaxHeight + 1)) { 486 return scrollMaxHeight 487 } else { 488 scrollMaxHeight = undefined 489 return scrollMaxHeight 490 } 491 } 492 493 private getLayoutWeight(): number { 494 let layoutWeight: number 495 if ((this.icon.image !== '' && this.icon.image !== void (0)) || 496 (this.title.text !== '' && this.title.text !== void (0)) || 497 (this.buttons?.[0]?.text !== '' && this.buttons?.[0]?.text !== void (0)) || 498 (this.buttons?.[1]?.text !== '' && this.buttons?.[1]?.text !== void (0))) { 499 layoutWeight = 1 500 } else { 501 layoutWeight = 0 502 } 503 return layoutWeight 504 } 505 506 private getApplyMaxSize(): ConstraintSizeOptions { 507 let applyMaxWidth: number | undefined = undefined; 508 let applyMaxHeight: number | undefined = undefined; 509 let applyMaxSize: ConstraintSizeOptions | undefined = undefined; 510 let defaultDisplaySync: display.Display = display.getDefaultDisplaySync() 511 if (px2vp(defaultDisplaySync.width) > 400) { 512 applyMaxWidth = 400 513 } else { 514 applyMaxWidth = px2vp(defaultDisplaySync.width) - 40 - 40 515 } 516 if (px2vp(defaultDisplaySync.height) > 480) { 517 applyMaxHeight = 480 518 } else { 519 applyMaxHeight = px2vp(defaultDisplaySync.height) - 40 - 40 520 } 521 applyMaxSize = { maxWidth: applyMaxWidth, maxHeight: applyMaxHeight } 522 this.messageMaxWeight = this.getMessageMaxWeight() 523 return applyMaxSize 524 } 525 526 build() { 527 Row() { 528 if (this.icon.image !== '' && this.icon.image !== void (0)) { 529 Image(this.getIconImage()) 530 .direction(this.popupDirection) 531 .width(this.getIconWidth()) 532 .height(this.getIconHeight()) 533 .margin(this.getIconMargin()) 534 .fillColor(this.getIconFillColor()) 535 .borderRadius(this.getIconBorderRadius()) 536 } 537 if (this.title.text !== '' && this.title.text !== void (0)) { 538 Column() { 539 Flex({ alignItems: ItemAlign.Start }) { 540 Text(this.getTitleText()) 541 .direction(this.popupDirection) 542 .flexGrow(1) 543 .maxLines(2) 544 .align(Alignment.Start) 545 .padding(this.getTitlePadding()) 546 .minFontSize(this.getTitleMinFontSize()) 547 .textOverflow({ overflow: TextOverflow.Ellipsis }) 548 .fontWeight(this.getTitleFontWeight()) 549 .fontSize(this.getTitleFontSize()) 550 .fontColor(this.getTitleFontColor()) 551 .constraintSize({ minHeight: this.getCloseButtonHeight() }) 552 if (this.showClose || this.showClose === void (0)) { 553 Button() { 554 Image(this.getCloseButtonImage()) 555 .direction(this.popupDirection) 556 .focusable(true) 557 .width(this.getCloseButtonImageWidth()) 558 .height(this.getCloseButtonImageHeight()) 559 .fillColor(this.getCloseButtonFillColor()) 560 } 561 .direction(this.popupDirection) 562 .width(this.getCloseButtonWidth()) 563 .height(this.getCloseButtonHeight()) 564 .padding(this.getCloseButtonPadding()) 565 .backgroundColor(this.closeButtonBackgroundColor) 566 .onHover((isHover: boolean) => { 567 if (isHover) { 568 this.closeButtonBackgroundColor = this.getCloseButtonHoverColor() 569 } else { 570 this.closeButtonBackgroundColor = this.getCloseButtonBackgroundColor() 571 } 572 }) 573 .onClick(() => { 574 if (this.onClose) { 575 this.onClose(); 576 } 577 }) 578 } 579 } 580 .direction(this.popupDirection) 581 .width("100%") 582 .margin(this.getTitleMargin()) 583 .onAreaChange((_, rect) => { 584 this.titleHeight = rect.height as number 585 }) 586 587 Scroll() { 588 Text(this.getMessageText()) 589 .direction(this.popupDirection) 590 .fontSize(this.getMessageFontSize()) 591 .fontColor(this.getMessageFontColor()) 592 .fontWeight(this.getMessageFontWeight()) 593 .constraintSize({ minHeight: this.getCloseButtonHeight() }) 594 .onAreaChange((_, rect) => { 595 this.textHeight = rect.height as number 596 }) 597 } 598 .direction(this.popupDirection) 599 .width("100%") 600 .align(Alignment.TopStart) 601 .padding(this.getMessagePadding()) 602 .scrollBar(BarState.Auto) 603 .scrollable(ScrollDirection.Vertical) 604 .constraintSize({ maxHeight: this.getScrollMaxHeight() }) 605 606 Flex({ wrap: FlexWrap.Wrap }) { 607 if (this.buttons?.[0]?.text !== '' && this.buttons?.[0]?.text !== void (0)) { 608 Button() { 609 Text(this.getFirstButtonText()) 610 .direction(this.popupDirection) 611 .maxLines(2) 612 .focusable(true) 613 .fontSize(this.getFirstButtonFontSize()) 614 .fontColor(this.getFirstButtonFontColor()) 615 .fontWeight(this.getButtonFontWeight()) 616 .minFontSize(this.getButtonMinFontSize()) 617 .textOverflow({ overflow: TextOverflow.Ellipsis }) 618 } 619 .direction(this.popupDirection) 620 .margin(this.getButtonMargin()) 621 .padding(this.getButtonTextPadding()) 622 .backgroundColor(this.firstButtonBackgroundColor) 623 .onHover((isHover: boolean) => { 624 if (isHover) { 625 this.firstButtonBackgroundColor = this.getButtonHoverColor() 626 } 627 else { 628 this.firstButtonBackgroundColor = this.getButtonBackgroundColor() 629 } 630 }) 631 .onClick(() => { 632 if (this.buttons?.[0]?.action) { 633 this.buttons?.[0]?.action(); 634 } 635 }) 636 } 637 if (this.buttons?.[1]?.text !== '' && this.buttons?.[1]?.text !== void (0)) { 638 Button() { 639 Text(this.getSecondButtonText()) 640 .direction(this.popupDirection) 641 .maxLines(2) 642 .focusable(true) 643 .fontSize(this.getSecondButtonFontSize()) 644 .fontColor(this.getSecondButtonFontColor()) 645 .fontWeight(this.getButtonFontWeight()) 646 .minFontSize(this.getButtonMinFontSize()) 647 .textOverflow({ overflow: TextOverflow.Ellipsis }) 648 } 649 .direction(this.popupDirection) 650 .margin(this.getButtonMargin()) 651 .padding(this.getButtonTextPadding()) 652 .backgroundColor(this.secondButtonBackgroundColor) 653 .onHover((isHover: boolean) => { 654 if (isHover) { 655 this.secondButtonBackgroundColor = this.getButtonHoverColor() 656 } 657 else { 658 this.secondButtonBackgroundColor = this.getButtonBackgroundColor() 659 } 660 }) 661 .onClick(() => { 662 if (this.buttons?.[1]?.action) { 663 this.buttons?.[1]?.action(); 664 } 665 }) 666 } 667 } 668 .direction(this.popupDirection) 669 .margin(this.getButtonTextMargin()) 670 .flexGrow(1) 671 .onAreaChange((_, rect) => { 672 this.buttonHeight = rect.height as number 673 }) 674 } 675 .direction(this.popupDirection) 676 .layoutWeight(this.getLayoutWeight()) 677 } 678 else { 679 Column() { 680 Row() { 681 Scroll() { 682 Text(this.getMessageText()) 683 .direction(this.popupDirection) 684 .fontSize(this.getMessageFontSize()) 685 .fontColor(this.getMessageFontColor()) 686 .fontWeight(this.getMessageFontWeight()) 687 .constraintSize({ maxWidth: this.messageMaxWeight, minHeight: this.getCloseButtonHeight() }) 688 .onAreaChange((_, rect) => { 689 this.textHeight = rect.height as number 690 }) 691 } 692 .direction(this.popupDirection) 693 .layoutWeight(this.getLayoutWeight()) 694 .align(Alignment.TopStart) 695 .padding(this.getMessagePadding()) 696 .scrollBar(BarState.Auto) 697 .scrollable(ScrollDirection.Vertical) 698 .constraintSize({ maxHeight: this.getScrollMaxHeight() }) 699 700 if (this.showClose || this.showClose === void (0)) { 701 Button() { 702 Image(this.getCloseButtonImage()) 703 .direction(this.popupDirection) 704 .focusable(true) 705 .width(this.getCloseButtonImageWidth()) 706 .height(this.getCloseButtonImageHeight()) 707 .fillColor(this.getCloseButtonFillColor()) 708 } 709 .direction(this.popupDirection) 710 .width(this.getCloseButtonWidth()) 711 .height(this.getCloseButtonHeight()) 712 .padding(this.getCloseButtonPadding()) 713 .backgroundColor(this.closeButtonBackgroundColor) 714 .onHover((isHover: boolean) => { 715 if (isHover) { 716 this.closeButtonBackgroundColor = this.getCloseButtonHoverColor() 717 } 718 else { 719 this.closeButtonBackgroundColor = this.getCloseButtonBackgroundColor() 720 } 721 }) 722 .onClick(() => { 723 if (this.onClose) { 724 this.onClose(); 725 } 726 }) 727 } 728 } 729 .direction(this.popupDirection) 730 .alignItems(VerticalAlign.Top) 731 732 Flex({ wrap: FlexWrap.Wrap }) { 733 if (this.buttons?.[0]?.text !== '' && this.buttons?.[0]?.text !== void (0)) { 734 Button() { 735 Text(this.getFirstButtonText()) 736 .direction(this.popupDirection) 737 .maxLines(2) 738 .focusable(true) 739 .fontSize(this.getFirstButtonFontSize()) 740 .fontColor(this.getFirstButtonFontColor()) 741 .fontWeight(this.getButtonFontWeight()) 742 .minFontSize(this.getButtonMinFontSize()) 743 .textOverflow({ overflow: TextOverflow.Ellipsis }) 744 } 745 .direction(this.popupDirection) 746 .margin(this.getButtonMargin()) 747 .padding(this.getButtonTextPadding()) 748 .backgroundColor(this.firstButtonBackgroundColor) 749 .onHover((isHover: boolean) => { 750 if (isHover) { 751 this.firstButtonBackgroundColor = this.getButtonHoverColor() 752 } 753 else { 754 this.firstButtonBackgroundColor = this.getButtonBackgroundColor() 755 } 756 }) 757 .onClick(() => { 758 if (this.buttons?.[0]?.action) { 759 this.buttons?.[0]?.action(); 760 } 761 }) 762 } 763 if (this.buttons?.[1]?.text !== '' && this.buttons?.[1]?.text !== void (0)) { 764 Button() { 765 Text(this.getSecondButtonText()) 766 .direction(this.popupDirection) 767 .maxLines(2) 768 .focusable(true) 769 .fontSize(this.getSecondButtonFontSize()) 770 .fontColor(this.getSecondButtonFontColor()) 771 .fontWeight(this.getButtonFontWeight()) 772 .minFontSize(this.getButtonMinFontSize()) 773 .textOverflow({ overflow: TextOverflow.Ellipsis }) 774 } 775 .direction(this.popupDirection) 776 .margin(this.getButtonMargin()) 777 .padding(this.getButtonTextPadding()) 778 .backgroundColor(this.secondButtonBackgroundColor) 779 .onHover((isHover: boolean) => { 780 if (isHover) { 781 this.secondButtonBackgroundColor = this.getButtonHoverColor() 782 } 783 else { 784 this.secondButtonBackgroundColor = this.getButtonBackgroundColor() 785 } 786 }) 787 .onClick(() => { 788 if (this.buttons?.[1]?.action) { 789 this.buttons?.[1]?.action(); 790 } 791 }) 792 } 793 } 794 .direction(this.popupDirection) 795 .margin(this.getButtonTextMargin()) 796 .flexGrow(1) 797 .onAreaChange((_, rect) => { 798 this.buttonHeight = rect.height as number 799 }) 800 } 801 .direction(this.popupDirection) 802 .layoutWeight(this.getLayoutWeight()) 803 } 804 } 805 .direction(this.popupDirection) 806 .alignItems(VerticalAlign.Top) 807 .padding(this.getWindowsPadding()) 808 .constraintSize(this.applySizeOptions) 809 .onAreaChange((_, rect) => { 810 this.applyHeight = rect.height as number 811 }) 812 } 813} 814