• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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 #include "core/components_ng/pattern/dialog/dialog_pattern.h"
16 
17 #include <climits>
18 #include <cstdint>
19 #include <cstring>
20 
21 #include "base/log/dump_log.h"
22 #include "base/log/log.h"
23 #include "base/memory/ace_type.h"
24 #include "base/memory/referenced.h"
25 #include "base/subwindow/subwindow_manager.h"
26 #include "base/utils/measure_util.h"
27 #include "base/utils/utf_helper.h"
28 #include "core/common/ace_engine.h"
29 #include "core/common/container.h"
30 #include "core/common/recorder/event_recorder.h"
31 #include "core/components/button/button_theme.h"
32 #include "core/components/common/properties/alignment.h"
33 #include "core/components/theme/icon_theme.h"
34 #include "core/components/theme/shadow_theme.h"
35 #include "core/components_ng/base/frame_node.h"
36 #include "core/components_ng/base/inspector_filter.h"
37 #include "core/components_ng/base/ui_node.h"
38 #include "core/components_ng/base/view_stack_processor.h"
39 #include "core/components_ng/event/gesture_event_hub.h"
40 #include "core/components_ng/layout/layout_property.h"
41 #include "core/components_ng/pattern/button/button_layout_property.h"
42 #include "core/components_ng/pattern/button/button_pattern.h"
43 #include "core/components_ng/pattern/divider/divider_layout_property.h"
44 #include "core/components_ng/pattern/divider/divider_model_ng.h"
45 #include "core/components_ng/pattern/divider/divider_pattern.h"
46 #include "core/components_ng/pattern/flex/flex_layout_algorithm.h"
47 #include "core/components_ng/pattern/flex/flex_layout_property.h"
48 #include "core/components_ng/pattern/image/image_pattern.h"
49 #include "core/components_ng/pattern/linear_layout/linear_layout_pattern.h"
50 #include "core/components_ng/pattern/linear_layout/linear_layout_property.h"
51 #include "core/components_ng/pattern/list/list_pattern.h"
52 #include "core/components_ng/pattern/navrouter/navdestination_pattern.h"
53 #include "core/components_ng/pattern/overlay/dialog_manager.h"
54 #include "core/components_ng/pattern/overlay/overlay_manager.h"
55 #include "core/components_ng/pattern/relative_container/relative_container_model_ng.h"
56 #include "core/components_ng/pattern/relative_container/relative_container_pattern.h"
57 #include "core/components_ng/pattern/scroll/scroll_pattern.h"
58 #include "core/components_ng/pattern/stage/page_pattern.h"
59 #include "core/components_ng/pattern/text/text_layout_property.h"
60 #include "core/components_ng/pattern/text/text_pattern.h"
61 #include "core/components_ng/property/calc_length.h"
62 #include "core/components_ng/property/measure_property.h"
63 #include "core/components_v2/inspector/inspector_constants.h"
64 #include "core/event/key_event.h"
65 #include "core/event/touch_event.h"
66 #include "core/pipeline/base/element_register.h"
67 #include "core/pipeline_ng/pipeline_context.h"
68 
69 namespace OHOS::Ace::NG {
70 
71 namespace {
72 constexpr int32_t SHEET_INFO_IDX = -2;
73 constexpr Dimension SHEET_IMAGE_MARGIN = 16.0_vp;
74 constexpr Dimension SHEET_DIVIDER_WIDTH = 1.0_px;
75 constexpr Dimension SHEET_LIST_PADDING = 24.0_vp;
76 constexpr Color DEFAULT_BUTTON_COLOR = Color(0xff007dff);
77 const CalcLength SHEET_IMAGE_SIZE(40.0_vp);
78 constexpr int32_t THREE_BUTTON_MODE = 3;
79 constexpr int32_t TWO_BUTTON_MODE = 2;
80 constexpr int32_t ONE_BUTTON_MODE = 1;
81 constexpr int32_t START_CHILD_INDEX = 0;
82 constexpr uint32_t DIALOG_TITLE_MAXLINES = 1;
83 constexpr Dimension DIALOG_ONE_TITLE_ALL_HEIGHT = 56.0_vp;
84 constexpr Dimension DIALOG_TITLE_CONTENT_HEIGHT = 35.0_px;
85 constexpr int32_t DIALOG_TITLE_AVE_BY_2 = 2;
86 constexpr Dimension DIALOG_CONTENT_PADDING_TOP = 0.0_vp;
87 constexpr Dimension DIALOG_SUBTITLE_PADDING_LEFT = 24.0_vp;
88 constexpr Dimension DIALOG_SUBTITLE_PADDING_RIGHT = 24.0_vp;
89 constexpr Dimension DIALOG_TWO_TITLE_ZERO_SPACE = 0.0_vp;
90 constexpr Dimension ADAPT_TITLE_MIN_FONT_SIZE = 16.0_fp;
91 constexpr Dimension ADAPT_SUBTITLE_MIN_FONT_SIZE = 12.0_fp;
92 constexpr uint32_t ADAPT_TITLE_MAX_LINES = 2;
93 constexpr Dimension DIALOG_BUTTON_BORDER_RADIUS = 20.0_vp;
94 constexpr int32_t TEXT_ALIGN_TITLE_CENTER = 1;
95 constexpr int32_t BUTTON_TYPE_NORMAL = 1;
96 
GetBoolStr(bool isTure)97 std::string GetBoolStr(bool isTure)
98 {
99     return isTure ? "True" : "False";
100 }
101 } // namespace
102 
OnModifyDone()103 void DialogPattern::OnModifyDone()
104 {
105     Pattern::OnModifyDone();
106     auto host = GetHost();
107     CHECK_NULL_VOID(host);
108     auto gestureHub = host->GetOrCreateGestureEventHub();
109     CHECK_NULL_VOID(gestureHub);
110 
111     if (!onClick_) {
112         InitClickEvent(gestureHub);
113     }
114     auto focusHub = host->GetOrCreateFocusHub();
115     CHECK_NULL_VOID(focusHub);
116     RegisterOnKeyEvent(focusHub);
117     InitFocusEvent(focusHub);
118 }
119 
OnAttachToFrameNode()120 void DialogPattern::OnAttachToFrameNode()
121 {
122     auto host = GetHost();
123     CHECK_NULL_VOID(host);
124     auto pipelineContext = host->GetContext();
125     CHECK_NULL_VOID(pipelineContext);
126     pipelineContext->AddWindowSizeChangeCallback(host->GetId());
127     InitHostWindowRect();
128     auto foldModeChangeCallback = [weak = WeakClaim(this)](FoldDisplayMode foldDisplayMode) {
129         auto pattern = weak.Upgrade();
130         CHECK_NULL_VOID(pattern);
131         pattern->isFoldStatusChanged_ = true;
132     };
133     auto callbackId = pipelineContext->RegisterFoldDisplayModeChangedCallback(std::move(foldModeChangeCallback));
134     UpdateFoldDisplayModeChangedCallbackId(callbackId);
135     RegisterHoverModeChangeCallback();
136 }
137 
RegisterHoverModeChangeCallback()138 void DialogPattern::RegisterHoverModeChangeCallback()
139 {
140     auto hoverModeChangeCallback = [weak = WeakClaim(this)](bool isHalfFoldHover) {
141         auto pattern = weak.Upgrade();
142         CHECK_NULL_VOID(pattern);
143         auto host = pattern->GetHost();
144         CHECK_NULL_VOID(host);
145         auto context = host->GetContext();
146         CHECK_NULL_VOID(context);
147         AnimationOption optionPosition;
148         auto motion = AceType::MakeRefPtr<ResponsiveSpringMotion>(0.35f, 1.0f, 0.0f);
149         optionPosition.SetCurve(motion);
150         context->FlushUITasks();
151         context->Animate(optionPosition, motion, [host, context]() {
152             host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
153             context->FlushUITasks();
154         });
155     };
156     auto host = GetHost();
157     CHECK_NULL_VOID(host);
158     auto context = host->GetContext();
159     CHECK_NULL_VOID(context);
160     auto hoverModeCallId = context->RegisterHalfFoldHoverChangedCallback(std::move(hoverModeChangeCallback));
161     UpdateHoverModeChangedCallbackId(hoverModeCallId);
162 }
163 
OnDetachFromFrameNode(FrameNode * frameNode)164 void DialogPattern::OnDetachFromFrameNode(FrameNode* frameNode)
165 {
166     auto pipeline = PipelineContext::GetCurrentContext();
167     CHECK_NULL_VOID(pipeline);
168     pipeline->RemoveWindowSizeChangeCallback(frameNode->GetId());
169     if (HasFoldDisplayModeChangedCallbackId()) {
170         pipeline->UnRegisterFoldDisplayModeChangedCallback(foldDisplayModeChangedCallbackId_.value_or(-1));
171     }
172     if (HasHoverModeChangedCallbackId()) {
173         pipeline->UnRegisterHalfFoldHoverChangedCallback(hoverModeChangedCallbackId_.value_or(-1));
174     }
175 }
176 
OnFontConfigurationUpdate()177 void DialogPattern::OnFontConfigurationUpdate()
178 {
179     CHECK_NULL_VOID(buttonContainer_);
180     UpdatePropertyForElderly(dialogProperties_.buttons);
181     contentColumn_->RemoveChild(buttonContainer_);
182     auto buttonContainer = BuildButtons(dialogProperties_.buttons, dialogProperties_.buttonDirection);
183     CHECK_NULL_VOID(buttonContainer);
184     buttonContainer->MountToParent(contentColumn_);
185     UpdateTextFontScale();
186     if (isSuitableForElderly_ && NeedsButtonDirectionChange(dialogProperties_.buttons)) {
187         contentColumn_->RemoveChild(buttonContainer_);
188         auto buttonContainerNew = BuildButtons(dialogProperties_.buttons, DialogButtonDirection::VERTICAL);
189         CHECK_NULL_VOID(buttonContainerNew);
190         buttonContainerNew->MountToParent(contentColumn_);
191         buttonContainer_ = buttonContainerNew;
192         CheckScrollHeightIsNegative(contentColumn_, dialogProperties_);
193         UpdateTextFontScale();
194     }
195 }
196 
InitClickEvent(const RefPtr<GestureEventHub> & gestureHub)197 void DialogPattern::InitClickEvent(const RefPtr<GestureEventHub>& gestureHub)
198 {
199     GestureEventFunc task = [weak = WeakClaim(this)](const GestureEvent& info) {
200         auto pattern = weak.Upgrade();
201         CHECK_NULL_VOID(pattern);
202         pattern->HandleClick(info);
203     };
204     onClick_ = MakeRefPtr<ClickEvent>(std::move(task));
205     gestureHub->AddClickEvent(onClick_);
206 }
207 
GetContentRect(const RefPtr<FrameNode> & contentNode)208 RectF DialogPattern::GetContentRect(const RefPtr<FrameNode>& contentNode)
209 {
210     auto contentRect = contentNode->GetGeometryNode()->GetFrameRect();
211     if (!dialogProperties_.customStyle) {
212         return contentRect;
213     }
214 
215     RefPtr<FrameNode> customContent;
216     auto customNode = customNode_.Upgrade();
217     while (customNode) {
218         customContent = DynamicCast<FrameNode>(customNode);
219         if (customContent) {
220             break;
221         }
222         customNode = customNode->GetChildAtIndex(0);
223     }
224     CHECK_NULL_RETURN(customContent, contentRect);
225 
226     auto customContentRect = customContent->GetGeometryNode()->GetFrameRect();
227     auto customContentX = contentRect.GetX() + customContentRect.GetX();
228     auto customContentY = contentRect.GetY() + customContentRect.GetY();
229     contentRect.SetRect(customContentX, customContentY, customContentRect.Width(), customContentRect.Height());
230     return contentRect;
231 }
232 
HandleClick(const GestureEvent & info)233 void DialogPattern::HandleClick(const GestureEvent& info)
234 {
235     if (info.GetSourceDevice() == SourceType::KEYBOARD) {
236         return;
237     }
238     auto host = GetHost();
239     CHECK_NULL_VOID(host);
240     auto props = host->GetLayoutProperty<DialogLayoutProperty>();
241     CHECK_NULL_VOID(props);
242     auto globalOffset = host->GetPaintRectOffset(false, true);
243     auto autoCancel = props->GetAutoCancel().value_or(true);
244     if (autoCancel) {
245         auto content = DynamicCast<FrameNode>(host->GetChildAtIndex(0));
246         CHECK_NULL_VOID(content);
247         auto contentRect = GetContentRect(content);
248         // close dialog if clicked outside content rect
249         auto&& clickPosition = info.GetGlobalLocation();
250         if (!contentRect.IsInRegion(
251             PointF(clickPosition.GetX() - globalOffset.GetX(), clickPosition.GetY() - globalOffset.GetY()))) {
252             auto overlayManager = GetOverlayManager(nullptr);
253             CHECK_NULL_VOID(overlayManager);
254             if (this->CallDismissInNDK(static_cast<int32_t>(DialogDismissReason::DIALOG_TOUCH_OUTSIDE))) {
255                 return;
256             } else if (this->ShouldDismiss()) {
257                 overlayManager->SetDismissDialogId(host->GetId());
258                 DialogManager::GetInstance().SetDismissDialogInfo(host->GetId(), host->GetTag());
259                 auto currentId = Container::CurrentId();
260                 this->CallOnWillDismiss(static_cast<int32_t>(DialogDismissReason::DIALOG_TOUCH_OUTSIDE), currentId);
261                 TAG_LOGI(AceLogTag::ACE_DIALOG, "Dialog Should Dismiss, currentId: %{public}d", currentId);
262                 return;
263             }
264             PopDialog(-1);
265             if (overlayManager->isMaskNode(GetHost()->GetId())) {
266                 overlayManager->PopModalDialog(GetHost()->GetId());
267             }
268         }
269     }
270 }
271 
PopDialog(int32_t buttonIdx=-1)272 void DialogPattern::PopDialog(int32_t buttonIdx = -1)
273 {
274     auto host = GetHost();
275     CHECK_NULL_VOID(host);
276     auto overlayManager = GetOverlayManager(host);
277     CHECK_NULL_VOID(overlayManager);
278 
279     if (host->IsRemoving()) {
280         return;
281     }
282 
283     auto hub = host->GetEventHub<DialogEventHub>();
284     if (buttonIdx != -1) {
285         hub->FireSuccessEvent(buttonIdx);
286         RecordEvent(buttonIdx);
287     } else {
288         // trigger onCancel callback
289         hub->FireCancelEvent();
290         RecordEvent(buttonIdx);
291     }
292     if (dialogProperties_.isShowInSubWindow) {
293         auto pipeline = host->GetContextRefPtr();
294         auto currentId = pipeline ? pipeline->GetInstanceId() : Container::CurrentId();
295         SubwindowManager::GetInstance()->DeleteHotAreas(currentId, host->GetId(), SubwindowType::TYPE_DIALOG);
296         SubwindowManager::GetInstance()->HideDialogSubWindow(currentId);
297     }
298     overlayManager->CloseDialog(host);
299 }
300 
RecordEvent(int32_t btnIndex) const301 void DialogPattern::RecordEvent(int32_t btnIndex) const
302 {
303     if (!Recorder::EventRecorder::Get().IsComponentRecordEnable()) {
304         return;
305     }
306     std::string btnText;
307     if (btnIndex >= 0 && static_cast<size_t>(btnIndex) < dialogProperties_.buttons.size()) {
308         btnText = dialogProperties_.buttons.at(btnIndex).text;
309     }
310     Recorder::EventType eventType;
311     if (btnIndex == -1) {
312         eventType = Recorder::EventType::DIALOG_CANCEL;
313     } else {
314         eventType = Recorder::EventType::DIALOG_ACTION;
315     }
316     Recorder::EventParamsBuilder builder;
317     builder.SetEventType(eventType)
318         .SetText(btnText)
319         .SetExtra(Recorder::KEY_TITLE, title_)
320         .SetExtra(Recorder::KEY_SUB_TITLE, subtitle_);
321     Recorder::EventRecorder::Get().OnEvent(std::move(builder));
322 }
323 
324 // set render context properties of content frame
UpdateContentRenderContext(const RefPtr<FrameNode> & contentNode,const DialogProperties & props)325 void DialogPattern::UpdateContentRenderContext(const RefPtr<FrameNode>& contentNode, const DialogProperties& props)
326 {
327     auto contentRenderContext = contentNode->GetRenderContext();
328     CHECK_NULL_VOID(contentRenderContext);
329     contentRenderContext_ = contentRenderContext;
330     auto pipeLineContext = contentNode->GetContextWithCheck();
331     CHECK_NULL_VOID(pipeLineContext);
332     if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_ELEVEN) &&
333         contentRenderContext->IsUniRenderEnabled() && props.isSysBlurStyle) {
334         BlurStyleOption styleOption;
335         if (props.blurStyleOption.has_value()) {
336             styleOption = props.blurStyleOption.value();
337             if (styleOption.policy == BlurStyleActivePolicy::FOLLOWS_WINDOW_ACTIVE_STATE) {
338                 pipeLineContext->AddWindowFocusChangedCallback(contentNode->GetId());
339             } else {
340                 pipeLineContext->RemoveWindowFocusChangedCallback(contentNode->GetId());
341             }
342         }
343         styleOption.blurStyle = static_cast<BlurStyle>(
344             props.backgroundBlurStyle.value_or(dialogTheme_->GetDialogBackgroundBlurStyle()));
345         if (props.blurStyleOption.has_value() && contentRenderContext->GetBackgroundEffect().has_value()) {
346             contentRenderContext->UpdateBackgroundEffect(std::nullopt);
347         }
348         contentRenderContext->UpdateBackBlurStyle(styleOption);
349         if (props.effectOption.has_value()) {
350             if (props.effectOption->policy == BlurStyleActivePolicy::FOLLOWS_WINDOW_ACTIVE_STATE) {
351                 pipeLineContext->AddWindowFocusChangedCallback(contentNode->GetId());
352             } else {
353                 pipeLineContext->RemoveWindowFocusChangedCallback(contentNode->GetId());
354             }
355             if (contentRenderContext->GetBackBlurStyle().has_value()) {
356                 contentRenderContext->UpdateBackBlurStyle(std::nullopt);
357             }
358             contentRenderContext->UpdateBackgroundEffect(props.effectOption.value());
359         }
360         contentRenderContext->UpdateBackgroundColor(props.backgroundColor.value_or(dialogTheme_->GetColorBgWithBlur()));
361     } else {
362         contentRenderContext->UpdateBackgroundColor(props.backgroundColor.value_or(dialogTheme_->GetBackgroundColor()));
363     }
364     bool isCustomBorder = props.borderRadius.has_value() || props.borderWidth.has_value() ||
365         props.borderStyle.has_value() || props.borderColor.has_value();
366     BorderRadiusProperty radius;
367     if (props.borderRadius.has_value()) {
368         if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TWELVE)) {
369             radius = props.borderRadius.value();
370             ParseBorderRadius(radius);
371             contentRenderContext->UpdateBorderRadius(radius);
372         } else {
373             contentRenderContext->UpdateBorderRadius(props.borderRadius.value());
374         }
375     } else {
376         radius.SetRadius(dialogTheme_->GetRadius().GetX());
377         contentRenderContext->UpdateBorderRadius(radius);
378         if (!isCustomBorder && dialogTheme_->GetDialogDoubleBorderEnable()) {
379             contentRenderContext->UpdateOuterBorderRadius(radius);
380         }
381     }
382     if (props.borderWidth.has_value()) {
383         auto layoutProps = contentNode->GetLayoutProperty<LinearLayoutProperty>();
384         CHECK_NULL_VOID(layoutProps);
385         layoutProps->UpdateBorderWidth(props.borderWidth.value());
386         contentRenderContext->UpdateBorderWidth(props.borderWidth.value());
387     } else {
388         BorderWidthProperty borderWidth;
389         if (!isCustomBorder && dialogTheme_->GetDialogDoubleBorderEnable()) {
390             auto layoutProps = contentNode->GetLayoutProperty<LinearLayoutProperty>();
391             CHECK_NULL_VOID(layoutProps);
392             borderWidth.SetBorderWidth(Dimension(dialogTheme_->GetDialogInnerBorderWidth()));
393             layoutProps->UpdateBorderWidth(borderWidth);
394             BorderWidthProperty outerWidthProp;
395             outerWidthProp.SetBorderWidth(Dimension(dialogTheme_->GetDialogOuterBorderWidth()));
396             contentRenderContext->UpdateOuterBorderWidth(outerWidthProp);
397         } else {
398             borderWidth.SetBorderWidth(dialogTheme_->GetBackgroudBorderWidth());
399             auto layoutProps = contentNode->GetLayoutProperty<LinearLayoutProperty>();
400             if (layoutProps) {
401                 layoutProps->UpdateBorderWidth(borderWidth);
402             }
403         }
404         contentRenderContext->UpdateBorderWidth(borderWidth);
405     }
406     contentNodeMap_[DialogContentNode::BORDERWIDTH] = contentNode;
407     if (props.borderStyle.has_value()) {
408         contentRenderContext->UpdateBorderStyle(props.borderStyle.value());
409     }
410     auto contentPattern = contentNode->GetPattern();
411     CHECK_NULL_VOID(contentPattern);
412     if (props.borderColor.has_value()) {
413         contentRenderContext->UpdateBorderColor(props.borderColor.value());
414         contentPattern->CheckLocalized();
415     } else {
416         BorderColorProperty borderColor;
417         if (!isCustomBorder && dialogTheme_->GetDialogDoubleBorderEnable()) {
418             borderColor.SetColor(dialogTheme_->GetDialogInnerBorderColor());
419             BorderColorProperty outerColorProp;
420             outerColorProp.SetColor(dialogTheme_->GetDialogOuterBorderColor());
421             contentRenderContext->UpdateOuterBorderColor(outerColorProp);
422         } else {
423             borderColor.SetColor(dialogTheme_->GetBackgroudBorderColor());
424         }
425         contentRenderContext->UpdateBorderColor(borderColor);
426     }
427     if (props.shadow.has_value()) {
428         contentRenderContext->UpdateBackShadow(props.shadow.value());
429     } else {
430         Shadow shadow = Shadow::CreateShadow(static_cast<ShadowStyle>(dialogTheme_->GetShadowDialog()));
431         contentRenderContext->UpdateBackShadow(shadow);
432     }
433     contentRenderContext->SetClipToBounds(true);
434 }
435 
ParseBorderRadius(BorderRadiusProperty & raidus)436 void DialogPattern::ParseBorderRadius(BorderRadiusProperty& raidus)
437 {
438     if (!raidus.radiusTopLeft.has_value() || raidus.radiusTopLeft.value().Value() < 0) {
439         raidus.radiusTopLeft = dialogTheme_->GetRadius().GetX();
440     }
441     if (!raidus.radiusTopRight.has_value() || raidus.radiusTopRight.value().Value() < 0) {
442         raidus.radiusTopRight = dialogTheme_->GetRadius().GetX();
443     }
444     if (!raidus.radiusBottomLeft.has_value() || raidus.radiusBottomLeft.value().Value() < 0) {
445         raidus.radiusBottomLeft = dialogTheme_->GetRadius().GetX();
446     }
447     if (!raidus.radiusBottomRight.has_value() || raidus.radiusBottomRight.value().Value() < 0) {
448         raidus.radiusBottomRight = dialogTheme_->GetRadius().GetX();
449     }
450 }
451 
CreateDialogScroll(const DialogProperties & dialogProps)452 RefPtr<FrameNode> DialogPattern::CreateDialogScroll(const DialogProperties& dialogProps)
453 {
454     auto scroll = FrameNode::CreateFrameNode(
455         V2::SCROLL_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<ScrollPattern>());
456     CHECK_NULL_RETURN(scroll, nullptr);
457     auto props = scroll->GetLayoutProperty<ScrollLayoutProperty>();
458     props->UpdateAxis(Axis::VERTICAL);
459     props->UpdateAlignment(Alignment::CENTER_LEFT);
460     // If title not exist, set scroll align center so that text align center.
461     auto scrollFlexAlign = dialogTheme_->GetScrollFlexAlign();
462     if ((dialogProps.title.empty() && dialogProps.subtitle.empty())) {
463         scrollFlexAlign = FlexAlign::CENTER;
464     }
465     props->UpdateAlignSelf(scrollFlexAlign);
466     return scroll;
467 }
468 
BuildChild(const DialogProperties & props)469 void DialogPattern::BuildChild(const DialogProperties& props)
470 {
471     UpdatePropertyForElderly(props.buttons);
472     // append customNode
473     auto customNode = customNode_.Upgrade();
474     if (customNode) {
475         BuildCustomChild(props, customNode);
476         return;
477     }
478     // Make dialog Content Column
479     auto contentColumn = FrameNode::CreateFrameNode(V2::COLUMN_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
480         AceType::MakeRefPtr<LinearLayoutPattern>(true));
481     CHECK_NULL_VOID(contentColumn);
482     if (!props.title.empty() || !props.subtitle.empty()) {
483         auto title = BuildTitle(props);
484         CHECK_NULL_VOID(title);
485         titleContainer_ = title;
486         contentColumn->AddChild(title);
487     }
488 
489     if (!props.content.empty()) {
490         auto content = BuildContent(props);
491         CHECK_NULL_VOID(content);
492         // create a scroll
493         auto scroll = CreateDialogScroll(props);
494         CHECK_NULL_VOID(scroll);
495         content->MountToParent(scroll);
496         scroll->MountToParent(contentColumn);
497         scroll->MarkModifyDone();
498     }
499 
500     if (!props.customStyle) {
501         UpdateContentRenderContext(contentColumn, props);
502         if (props.height.has_value()) {
503             auto layoutProps = contentColumn->GetLayoutProperty<LinearLayoutProperty>();
504             CHECK_NULL_VOID(layoutProps);
505             layoutProps->UpdateMainAxisAlign(FlexAlign::SPACE_BETWEEN);
506             layoutProps->UpdateMeasureType(MeasureType::MATCH_PARENT_MAIN_AXIS);
507         }
508     }
509 
510     auto columnProp = AceType::DynamicCast<LinearLayoutProperty>(contentColumn->GetLayoutProperty());
511     CHECK_NULL_VOID(columnProp);
512     // content is full screen in Watch mode
513     auto measureType = dialogTheme_->GetColumnMeasureType();
514     columnProp->UpdateMeasureType(measureType);
515 
516     // build ActionSheet child
517     if (props.type == DialogType::ACTION_SHEET && !props.sheetsInfo.empty()) {
518         auto sheetContainer = BuildSheet(props.sheetsInfo);
519         contentNodeMap_[DialogContentNode::SHEET] = sheetContainer;
520         CHECK_NULL_VOID(sheetContainer);
521         sheetContainer->MountToParent(contentColumn);
522         // scrollable
523         sheetContainer->MarkModifyDone();
524     }
525 
526     // Make Menu node if hasMenu (actionMenu)
527     if (props.isMenu) {
528         bool hasTitle = !props.title.empty() || !props.subtitle.empty();
529         auto menu = BuildMenu(props.buttons, hasTitle);
530         CHECK_NULL_VOID(menu);
531         menu->MountToParent(contentColumn);
532     } else {
533         // build buttons
534         if (!props.buttons.empty()) {
535             auto buttonContainer = BuildButtons(props.buttons, props.buttonDirection);
536             CHECK_NULL_VOID(buttonContainer);
537             buttonContainer->MountToParent(contentColumn);
538         }
539     }
540 
541     auto dialog = GetHost();
542     contentColumn->MountToParent(dialog);
543     AddExtraMaskNode(props);
544     UpdateTextFontScale();
545     if (isSuitableForElderly_ && NeedsButtonDirectionChange(props.buttons)) {
546         //remove buttonContainer when Button text is too long
547         contentColumn->RemoveChild(buttonContainer_);
548         auto buttonContainerNew = BuildButtons(props.buttons, DialogButtonDirection::VERTICAL);
549         buttonContainerNew->MountToParent(contentColumn);
550         buttonContainer_ = buttonContainerNew;
551         CheckScrollHeightIsNegative(contentColumn, props);
552     }
553     contentColumn_ = contentColumn;
554     UpdateTextFontScale();
555 }
556 
AddExtraMaskNode(const DialogProperties & props)557 void DialogPattern::AddExtraMaskNode(const DialogProperties& props)
558 {
559     auto dialog = GetHost();
560     CHECK_NULL_VOID(dialog);
561     auto pipeline = dialog->GetContext();
562     CHECK_NULL_VOID(pipeline);
563     auto dialogTheme = pipeline->GetTheme<DialogTheme>();
564     CHECK_NULL_VOID(dialogTheme);
565     if (IsUIExtensionSubWindow() && props.isModal) {
566         auto extraMaskNode = FrameNode::CreateFrameNode(V2::COLUMN_ETS_TAG,
567             ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<LinearLayoutPattern>(true));
568         CHECK_NULL_VOID(extraMaskNode);
569         auto extraMaskNodeContext = extraMaskNode->GetRenderContext();
570         CHECK_NULL_VOID(extraMaskNodeContext);
571         auto maskLayoutProps = extraMaskNode->GetLayoutProperty<LinearLayoutProperty>();
572         CHECK_NULL_VOID(maskLayoutProps);
573         extraMaskNodeContext->UpdateBackgroundColor(props.maskColor.value_or(dialogTheme->GetMaskColorEnd()));
574         extraMaskNodeContext->UpdateZIndex(-1);
575         extraMaskNode->MountToParent(dialog);
576     }
577 }
578 
BuildCustomChild(const DialogProperties & props,const RefPtr<UINode> & customNode)579 void DialogPattern::BuildCustomChild(const DialogProperties& props, const RefPtr<UINode>& customNode)
580 {
581     auto contentWrapper = FrameNode::CreateFrameNode(V2::COLUMN_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
582         AceType::MakeRefPtr<LinearLayoutPattern>(true));
583     CHECK_NULL_VOID(contentWrapper);
584     if (!props.customStyle) {
585         UpdateContentRenderContext(contentWrapper, props);
586     }
587     customNode->MountToParent(contentWrapper);
588     auto dialog = GetHost();
589     contentWrapper->MountToParent(dialog);
590     AddExtraMaskNode(props);
591 }
592 
BuildMainTitle(const DialogProperties & dialogProperties)593 RefPtr<FrameNode> DialogPattern::BuildMainTitle(const DialogProperties& dialogProperties)
594 {
595     auto title = FrameNode::CreateFrameNode(
596         V2::TEXT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<TextPattern>());
597     auto titleProp = AceType::DynamicCast<TextLayoutProperty>(title->GetLayoutProperty());
598     CHECK_NULL_RETURN(titleProp, nullptr);
599     titleProp->UpdateMaxLines(DIALOG_TITLE_MAXLINES);
600     titleProp->UpdateTextOverflow(TextOverflow::ELLIPSIS);
601     std::string titleContent = dialogProperties.title.empty() ? dialogProperties.subtitle : dialogProperties.title;
602     titleProp->UpdateContent(titleContent);
603     auto titleStyle = dialogTheme_->GetTitleTextStyle();
604     titleProp->UpdateFontSize(titleStyle.GetFontSize());
605     titleProp->UpdateFontWeight(titleStyle.GetFontWeight());
606     titleProp->UpdateTextColor(titleStyle.GetTextColor());
607     if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
608         titleProp->UpdateAdaptMaxFontSize(dialogTheme_->GetTitleTextStyle().GetFontSize());
609         titleProp->UpdateAdaptMinFontSize(ADAPT_TITLE_MIN_FONT_SIZE);
610         titleProp->UpdateHeightAdaptivePolicy(TextHeightAdaptivePolicy::MIN_FONT_SIZE_FIRST);
611         titleProp->UpdateMaxLines(ADAPT_TITLE_MAX_LINES);
612     }
613     PaddingProperty titlePadding;
614     auto paddingInTheme = (dialogProperties.content.empty() && dialogProperties.buttons.empty())
615                               ? dialogTheme_->GetTitleDefaultPadding()
616                               : dialogTheme_->GetTitleAdjustPadding();
617     titlePadding.left = CalcLength(paddingInTheme.Left());
618     titlePadding.right = CalcLength(paddingInTheme.Right());
619     if (!dialogProperties.title.empty() && !dialogProperties.subtitle.empty()) {
620         titlePadding.top = CalcLength(dialogTheme_->GetPaddingTopTitle());
621         titlePadding.bottom = CalcLength(DIALOG_TWO_TITLE_ZERO_SPACE);
622     } else {
623         auto padding =
624             DIALOG_ONE_TITLE_ALL_HEIGHT - Dimension(DIALOG_TITLE_CONTENT_HEIGHT.ConvertToVp(), DimensionUnit::VP);
625         if (dialogTheme_->GetPaddingSingleTitle().ConvertToVp() > 0) {
626             padding = dialogTheme_->GetPaddingSingleTitle();
627         }
628         titlePadding.top = CalcLength(padding / DIALOG_TITLE_AVE_BY_2);
629         titlePadding.bottom = CalcLength(padding / DIALOG_TITLE_AVE_BY_2);
630     }
631     titleProp->UpdatePadding(titlePadding);
632     // XTS inspector value
633     title_ = dialogProperties.title;
634     subtitle_ = dialogProperties.subtitle;
635     auto titleRow = FrameNode::CreateFrameNode(V2::ROW_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
636         AceType::MakeRefPtr<LinearLayoutPattern>(false));
637     CHECK_NULL_RETURN(titleRow, nullptr);
638     auto titleRowProps = titleRow->GetLayoutProperty<LinearLayoutProperty>();
639     CHECK_NULL_RETURN(titleRowProps, nullptr);
640     titleRowProps->UpdateMainAxisAlign(
641         dialogTheme_->GetTextAlignTitle() == TEXT_ALIGN_TITLE_CENTER ? FlexAlign::CENTER : FlexAlign::FLEX_START);
642     titleRowProps->UpdateMeasureType(MeasureType::MATCH_PARENT_MAIN_AXIS);
643     title->MountToParent(titleRow);
644     title->MarkModifyDone();
645     contentNodeMap_[dialogProperties.title.empty() ? DialogContentNode::SUBTITLE : DialogContentNode::TITLE] = title;
646     auto focusHub = titleRow->GetFocusHub();
647     CHECK_NULL_RETURN(focusHub, titleRow);
648     focusHub->SetFocusable(false);
649     return titleRow;
650 }
651 
BuildSubTitle(const DialogProperties & dialogProperties)652 RefPtr<FrameNode> DialogPattern::BuildSubTitle(const DialogProperties& dialogProperties)
653 {
654     auto subtitle = FrameNode::CreateFrameNode(
655         V2::TEXT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<TextPattern>());
656     auto titleProp = AceType::DynamicCast<TextLayoutProperty>(subtitle->GetLayoutProperty());
657     CHECK_NULL_RETURN(titleProp, nullptr);
658     auto titleStyle = dialogTheme_->GetSubTitleTextStyle();
659     titleProp->UpdateMaxLines(DIALOG_TITLE_MAXLINES);
660     titleProp->UpdateTextOverflow(TextOverflow::ELLIPSIS);
661     titleProp->UpdateContent(dialogProperties.subtitle);
662     titleProp->UpdateFontSize(titleStyle.GetFontSize());
663     titleProp->UpdateTextColor(titleStyle.GetTextColor());
664     if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
665         titleProp->UpdateAdaptMaxFontSize(titleStyle.GetFontSize());
666         titleProp->UpdateAdaptMinFontSize(ADAPT_SUBTITLE_MIN_FONT_SIZE);
667         titleProp->UpdateHeightAdaptivePolicy(TextHeightAdaptivePolicy::MIN_FONT_SIZE_FIRST);
668         titleProp->UpdateMaxLines(ADAPT_TITLE_MAX_LINES);
669     }
670     PaddingProperty titlePadding;
671     titlePadding.left = CalcLength(DIALOG_SUBTITLE_PADDING_LEFT);
672     titlePadding.right = CalcLength(DIALOG_SUBTITLE_PADDING_RIGHT);
673     titlePadding.top = CalcLength(DIALOG_TWO_TITLE_ZERO_SPACE);
674     titlePadding.bottom = CalcLength(dialogTheme_->GetPaddingTopTitle());
675     titleProp->UpdatePadding(titlePadding);
676 
677     // XTS inspector value
678     subtitle_ = dialogProperties.subtitle;
679 
680     auto subtitleRow = FrameNode::CreateFrameNode(V2::ROW_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
681         AceType::MakeRefPtr<LinearLayoutPattern>(false));
682     CHECK_NULL_RETURN(subtitleRow, nullptr);
683     auto subtitleRowProps = subtitleRow->GetLayoutProperty<LinearLayoutProperty>();
684     CHECK_NULL_RETURN(subtitleRowProps, nullptr);
685     subtitleRowProps->UpdateMainAxisAlign(
686         dialogTheme_->GetTextAlignTitle() == TEXT_ALIGN_TITLE_CENTER ? FlexAlign::CENTER : FlexAlign::FLEX_START);
687     subtitleRowProps->UpdateMeasureType(MeasureType::MATCH_PARENT_MAIN_AXIS);
688     subtitle->MountToParent(subtitleRow);
689     subtitle->MarkModifyDone();
690     contentNodeMap_[DialogContentNode::SUBTITLE] = subtitle;
691     return subtitleRow;
692 }
693 
BuildTitle(const DialogProperties & dialogProperties)694 RefPtr<FrameNode> DialogPattern::BuildTitle(const DialogProperties& dialogProperties)
695 {
696     auto titleRow = BuildMainTitle(dialogProperties);
697     if (!dialogProperties.title.empty() && !dialogProperties.subtitle.empty()) {
698         auto titleColumn = FrameNode::CreateFrameNode(V2::COLUMN_ETS_TAG,
699             ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<LinearLayoutPattern>(true));
700         CHECK_NULL_RETURN(titleColumn, nullptr);
701         auto columnProps = titleColumn->GetLayoutProperty<LinearLayoutProperty>();
702         CHECK_NULL_RETURN(columnProps, nullptr);
703         columnProps->UpdateMainAxisAlign(FlexAlign::FLEX_START);
704         columnProps->UpdateMeasureType(MeasureType::MATCH_CONTENT);
705         auto subtitleRow = BuildSubTitle(dialogProperties);
706         titleColumn->AddChild(titleRow);
707         titleColumn->AddChild(subtitleRow);
708         return titleColumn;
709     }
710     return titleRow;
711 }
712 
BuildContent(const DialogProperties & props)713 RefPtr<FrameNode> DialogPattern::BuildContent(const DialogProperties& props)
714 {
715     // Make Content node
716     auto contentNode = FrameNode::CreateFrameNode(
717         V2::TEXT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<TextPattern>());
718     auto contentProp = AceType::DynamicCast<TextLayoutProperty>(contentNode->GetLayoutProperty());
719     CHECK_NULL_RETURN(contentProp, nullptr);
720     // textAlign always align start. When text line count 1 and title doesn't exist, set text center position.
721     contentProp->UpdateTextAlign(TextAlign::START);
722     contentProp->UpdateContent(props.content);
723     auto contentStyle = dialogTheme_->GetContentTextStyle();
724     contentProp->UpdateFontSize(contentStyle.GetFontSize());
725     contentProp->UpdateTextColor(contentStyle.GetTextColor());
726     // update padding
727     Edge contentPaddingInTheme;
728     PaddingProperty contentPadding;
729     if (!props.title.empty() || !props.subtitle.empty()) {
730         contentPaddingInTheme =
731             props.buttons.empty() ? dialogTheme_->GetDefaultPadding() : dialogTheme_->GetAdjustPadding();
732         contentPadding.top = CalcLength(DIALOG_CONTENT_PADDING_TOP);
733     } else {
734         contentPaddingInTheme =
735             props.buttons.empty() ? dialogTheme_->GetContentDefaultPadding() : dialogTheme_->GetContentAdjustPadding();
736         contentPadding.top = CalcLength(contentPaddingInTheme.Top());
737     }
738     contentPadding.left = CalcLength(contentPaddingInTheme.Left());
739     contentPadding.right = CalcLength(contentPaddingInTheme.Right());
740     contentPadding.bottom = CalcLength(contentPaddingInTheme.Bottom());
741     contentProp->UpdatePadding(contentPadding);
742 
743     // XTS inspector value
744     message_ = props.content;
745     contentNode->MarkModifyDone();
746     contentNodeMap_[DialogContentNode::MESSAGE] = contentNode;
747     return contentNode;
748 }
749 
750 // to close dialog when clicked, use button index in Prompt to trigger success callback
BindCloseCallBack(const RefPtr<GestureEventHub> & hub,int32_t buttonIdx)751 void DialogPattern::BindCloseCallBack(const RefPtr<GestureEventHub>& hub, int32_t buttonIdx)
752 {
753     auto host = GetHost();
754     auto closeCallback = [weak = WeakClaim(RawPtr(host)), buttonIdx](GestureEvent& /*info*/) {
755         auto dialog = weak.Upgrade();
756         CHECK_NULL_VOID(dialog);
757         dialog->GetPattern<DialogPattern>()->PopDialog(buttonIdx);
758     };
759 
760     hub->AddClickEvent(AceType::MakeRefPtr<ClickEvent>(closeCallback));
761 }
762 
ParseButtonFontColorAndBgColor(const ButtonInfo & params,std::string & textColor,std::optional<Color> & bgColor)763 void DialogPattern::ParseButtonFontColorAndBgColor(
764     const ButtonInfo& params, std::string& textColor, std::optional<Color>& bgColor)
765 {
766     // Parse Button Style
767     if (params.dlgButtonStyle.has_value()) {
768         switch (params.dlgButtonStyle.value()) {
769             case DialogButtonStyle::DEFAULT:
770                 textColor = dialogTheme_->GetButtonDefaultFontColor().ColorToString();
771                 bgColor = dialogTheme_->GetButtonDefaultBgColor();
772                 break;
773             case DialogButtonStyle::HIGHTLIGHT:
774                 textColor = dialogTheme_->GetButtonHighlightFontColor().ColorToString();
775                 bgColor = dialogTheme_->GetButtonHighlightBgColor();
776                 break;
777             default:
778                 break;
779         }
780     }
781 
782     // font color and background color
783     if (!params.textColor.empty()) {
784         textColor = params.textColor;
785     }
786     if (params.isBgColorSetted) {
787         bgColor = params.bgColor;
788     }
789 
790     // Parse default focus
791     bool isNormalButton = dialogTheme_->GetButtonType() == BUTTON_TYPE_NORMAL;
792     if (textColor.empty()) {
793         if (params.defaultFocus && isFirstDefaultFocus_ && !isNormalButton) {
794             textColor = dialogTheme_->GetButtonHighlightFontColor().ColorToString();
795         } else {
796             textColor = dialogTheme_->GetButtonDefaultFontColor().ColorToString();
797         }
798     }
799     if (!bgColor.has_value()) {
800         if (params.defaultFocus && isFirstDefaultFocus_ && !isNormalButton) {
801             bgColor = dialogTheme_->GetButtonHighlightBgColor();
802             isFirstDefaultFocus_ = false;
803         } else {
804             bgColor = dialogTheme_->GetButtonDefaultBgColor();
805         }
806     }
807 }
808 
CreateButton(const ButtonInfo & params,int32_t index,bool isCancel,bool isVertical,int32_t length)809 RefPtr<FrameNode> DialogPattern::CreateButton(
810     const ButtonInfo& params, int32_t index, bool isCancel, bool isVertical, int32_t length)
811 {
812     auto buttonNode = FrameNode::CreateFrameNode(
813         V2::BUTTON_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), MakeRefPtr<ButtonPattern>());
814     CHECK_NULL_RETURN(buttonNode, nullptr);
815     UpdateDialogButtonProperty(buttonNode, index, isVertical, length);
816     // parse button text color and background color
817     std::string textColor;
818     std::optional<Color> bgColor;
819     isFirstDefaultFocus_ = true;
820     ParseButtonFontColorAndBgColor(params, textColor, bgColor);
821     if ((dialogTheme_->GetButtonType() == BUTTON_TYPE_NORMAL) && params.dlgButtonStyle.has_value()) {
822         auto buttonStyle = params.dlgButtonStyle.value() == DialogButtonStyle::HIGHTLIGHT ? ButtonStyleMode::EMPHASIZE
823                                                                                           : ButtonStyleMode::NORMAL;
824         auto buttonProp = AceType::DynamicCast<ButtonLayoutProperty>(buttonNode->GetLayoutProperty());
825         CHECK_NULL_RETURN(buttonProp, nullptr);
826         buttonProp->UpdateButtonStyle(buttonStyle);
827     }
828 
829     // append text inside button
830     auto textNode = CreateButtonText(params.text, textColor);
831     CHECK_NULL_RETURN(textNode, nullptr);
832     textNode->MountToParent(buttonNode);
833     textNode->MarkModifyDone();
834     SetButtonEnabled(buttonNode, params.enabled);
835     auto hub = buttonNode->GetOrCreateGestureEventHub();
836     CHECK_NULL_RETURN(hub, nullptr);
837     // bind click event
838     if (params.action) {
839         hub->AddClickEvent(params.action);
840     }
841 
842     if (params.isPrimary) {
843         auto focusHub = buttonNode->GetFocusHub();
844         CHECK_NULL_RETURN(focusHub, nullptr);
845         focusHub->SetIsDefaultFocus(params.isPrimary);
846     }
847 
848     // to close dialog when clicked inside button rect
849     if (!isCancel) {
850         BindCloseCallBack(hub, index);
851     } else {
852         BindCloseCallBack(hub, -1);
853     }
854 
855     // add scale animation
856     auto inputHub = buttonNode->GetOrCreateInputEventHub();
857     CHECK_NULL_RETURN(inputHub, nullptr);
858     inputHub->SetHoverEffect(HoverEffectType::AUTO);
859 
860     // update background color
861     auto renderContext = buttonNode->GetRenderContext();
862     CHECK_NULL_RETURN(renderContext, nullptr);
863     renderContext->UpdateBackgroundColor(bgColor.value());
864 
865     // set button default height
866     auto layoutProps = buttonNode->GetLayoutProperty();
867     CHECK_NULL_RETURN(layoutProps, nullptr);
868     auto pipeline = PipelineContext::GetCurrentContext();
869     CHECK_NULL_RETURN(pipeline, nullptr);
870     auto theme = pipeline->GetTheme<ButtonTheme>();
871     CHECK_NULL_RETURN(theme, nullptr);
872     if (!isSuitableForElderly_) {
873         layoutProps->UpdateUserDefinedIdealSize(CalcSize(std::nullopt, CalcLength(theme->GetHeight())));
874     }
875     return buttonNode;
876 }
877 
UpdateDialogButtonProperty(RefPtr<FrameNode> & buttonNode,int32_t index,bool isVertical,int32_t length)878 void DialogPattern::UpdateDialogButtonProperty(
879     RefPtr<FrameNode>& buttonNode, int32_t index, bool isVertical, int32_t length)
880 {
881     // update button padding
882     auto buttonProp = AceType::DynamicCast<ButtonLayoutProperty>(buttonNode->GetLayoutProperty());
883     buttonProp->UpdateType(ButtonType::NORMAL);
884     if (dialogTheme_->GetButtonType() == BUTTON_TYPE_NORMAL) {
885         buttonProp->UpdateButtonStyle(ButtonStyleMode::NORMAL);
886     }
887     buttonProp->UpdateBorderRadius(BorderRadiusProperty(DIALOG_BUTTON_BORDER_RADIUS));
888     PaddingProperty buttonPadding;
889     buttonPadding.left = CalcLength(SHEET_LIST_PADDING);
890     buttonPadding.right = CalcLength(SHEET_LIST_PADDING);
891     buttonProp->UpdatePadding(buttonPadding);
892     if (!isVertical) {
893         // set flex grow to fill horizontal space
894         buttonProp->UpdateLayoutWeight(1);
895         buttonProp->UpdateFlexGrow(1.0);
896         buttonProp->UpdateFlexShrink(1.0);
897         if (isSuitableForElderly_ && index != 0) {
898             MarginProperty margin = {
899                 .left = CalcLength(dialogTheme_->GetMarginLeft()),
900             };
901             buttonProp->UpdateMargin(margin);
902         }
903     } else if (isVertical && index != (length - 1)) {
904         // update button space in vertical
905         auto buttonSpace = dialogTheme_->GetMutiButtonPaddingVertical();
906         MarginProperty margin = {
907             .bottom = CalcLength(buttonSpace),
908         };
909         buttonProp->UpdateMargin(margin);
910     }
911 }
912 
CreateDivider(const Dimension & dividerLength,const Dimension & dividerWidth,const Color & color,const Dimension & space)913 RefPtr<FrameNode> DialogPattern::CreateDivider(
914     const Dimension& dividerLength, const Dimension& dividerWidth, const Color& color, const Dimension& space)
915 {
916     auto dividerNode = FrameNode::CreateFrameNode(
917         V2::DIVIDER_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<DividerPattern>());
918     CHECK_NULL_RETURN(dividerNode, nullptr);
919     auto dividerProps = dividerNode->GetLayoutProperty<DividerLayoutProperty>();
920     CHECK_NULL_RETURN(dividerProps, nullptr);
921     dividerProps->UpdateVertical(true);
922     dividerProps->UpdateStrokeWidth(dividerWidth);
923     dividerProps->UpdateUserDefinedIdealSize(CalcSize(std::nullopt, CalcLength(dividerLength)));
924     auto dividerPaintProps = dividerNode->GetPaintProperty<DividerRenderProperty>();
925     CHECK_NULL_RETURN(dividerPaintProps, nullptr);
926     dividerPaintProps->UpdateDividerColor(color);
927     // add divider margin
928     MarginProperty margin = {
929         .left = CalcLength((space - dividerWidth) / 2),
930         .right = CalcLength((space - dividerWidth) / 2),
931     };
932     dividerProps->UpdateMargin(margin);
933     return dividerNode;
934 }
935 
936 // alert dialog buttons
BuildButtons(const std::vector<ButtonInfo> & buttons,const DialogButtonDirection & direction)937 RefPtr<FrameNode> DialogPattern::BuildButtons(
938     const std::vector<ButtonInfo>& buttons, const DialogButtonDirection& direction)
939 {
940     auto Id = ElementRegister::GetInstance()->MakeUniqueId();
941     RefPtr<FrameNode> container;
942     bool isVertical;
943     if (direction == DialogButtonDirection::HORIZONTAL ||
944         (direction == DialogButtonDirection::AUTO && buttons.size() == TWO_BUTTON_MODE)) {
945         // use horizontal layout
946         isVertical = false;
947         container = FrameNode::CreateFrameNode(V2::ROW_ETS_TAG, Id, AceType::MakeRefPtr<LinearLayoutPattern>(false));
948         CHECK_NULL_RETURN(container, nullptr);
949         auto layoutProps = container->GetLayoutProperty<LinearLayoutProperty>();
950         layoutProps->UpdateMainAxisAlign(FlexAlign::SPACE_BETWEEN);
951         layoutProps->UpdateMeasureType(MeasureType::MATCH_PARENT_MAIN_AXIS);
952     } else {
953         // use vertical layout
954         isVertical = true;
955         container = FrameNode::CreateFrameNode(V2::COLUMN_ETS_TAG, Id, AceType::MakeRefPtr<LinearLayoutPattern>(true));
956         auto layoutProps = container->GetLayoutProperty<LinearLayoutProperty>();
957         layoutProps->UpdateCrossAxisAlign(FlexAlign::STRETCH);
958         layoutProps->UpdateMeasureType(MeasureType::MATCH_PARENT_CROSS_AXIS);
959     }
960     CHECK_NULL_RETURN(container, nullptr);
961     // set action's padding
962     PaddingProperty actionPadding;
963     if (buttons.size() == ONE_BUTTON_MODE || isVertical) {
964         actionPadding.left = CalcLength(dialogTheme_->GetSingleButtonPaddingStart());
965         actionPadding.right = CalcLength(dialogTheme_->GetSingleButtonPaddingEnd());
966     } else {
967         actionPadding.left = CalcLength(dialogTheme_->GetMutiButtonPaddingStart());
968         actionPadding.right = CalcLength(dialogTheme_->GetMutiButtonPaddingEnd());
969     }
970     auto padding = dialogTheme_->GetActionsPadding();
971     actionPadding.top = CalcLength(dialogTheme_->GetButtonWithContentPadding());
972     actionPadding.bottom = CalcLength(dialogTheme_->GetButtonPaddingBottom());
973     container->GetLayoutProperty()->UpdatePadding(actionPadding);
974     AddButtonAndDivider(buttons, container, isVertical);
975     container->MarkModifyDone();
976     buttonContainer_ = container;
977     return container;
978 }
979 
AddButtonAndDivider(const std::vector<ButtonInfo> & buttons,const RefPtr<NG::FrameNode> & container,bool isVertical)980 void DialogPattern::AddButtonAndDivider(
981     const std::vector<ButtonInfo>& buttons, const RefPtr<NG::FrameNode>& container, bool isVertical)
982 {
983     auto dividerLength = dialogTheme_->GetDividerLength();
984     auto dividerWidth = dialogTheme_->GetDividerBetweenButtonWidth_();
985     auto dividerColor = dialogTheme_->GetDividerColor();
986     auto buttonSpace = dialogTheme_->GetMutiButtonPaddingHorizontal();
987     auto length = buttons.size();
988     for (size_t i = 0; i < length; ++i) {
989         if (i != 0 && !isVertical && !isSuitableForElderly_) {
990             auto dividerNode = CreateDivider(dividerLength, dividerWidth, dividerColor, buttonSpace);
991             CHECK_NULL_VOID(dividerNode);
992             container->AddChild(dividerNode);
993         }
994         auto buttonNode = CreateButton(buttons[i], i, false, isVertical, length);
995         CHECK_NULL_VOID(buttonNode);
996         auto buttonPattern = buttonNode->GetPattern<ButtonPattern>();
997         CHECK_NULL_VOID(buttonPattern);
998         buttonPattern->SetSkipColorConfigurationUpdate();
999         buttonNode->MountToParent(container);
1000         buttonNode->MarkModifyDone();
1001     }
1002 }
1003 
CreateButtonText(const std::string & text,const std::string & colorStr)1004 RefPtr<FrameNode> DialogPattern::CreateButtonText(const std::string& text, const std::string& colorStr)
1005 {
1006     auto textNode = FrameNode::CreateFrameNode(
1007         V2::TEXT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<TextPattern>());
1008     CHECK_NULL_RETURN(textNode, nullptr);
1009     textNode->GetOrCreateFocusHub()->SetFocusable(true);
1010     auto textProps = textNode->GetLayoutProperty<TextLayoutProperty>();
1011     CHECK_NULL_RETURN(textProps, nullptr);
1012     textProps->UpdateContent(text);
1013     textProps->UpdateFontWeight(FontWeight::MEDIUM);
1014     textProps->UpdateMaxLines(1);
1015     textProps->UpdateTextOverflow(TextOverflow::ELLIPSIS);
1016     Dimension buttonTextSize = dialogTheme_->GetButtonTextSize().IsValid() ? dialogTheme_->GetButtonTextSize()
1017                                                                            : dialogTheme_->GetNormalButtonFontSize();
1018     textProps->UpdateFontSize(buttonTextSize);
1019 
1020     // update text color
1021     Color color;
1022     if (Color::ParseColorString(colorStr, color)) {
1023         textProps->UpdateTextColor(color);
1024     } else {
1025         textProps->UpdateTextColor(DEFAULT_BUTTON_COLOR);
1026     }
1027     auto host = GetHost();
1028     CHECK_NULL_RETURN(host, textNode);
1029     auto context = host->GetContext();
1030     CHECK_NULL_RETURN(context, textNode);
1031     auto textTheme = context->GetTheme<TextTheme>();
1032     CHECK_NULL_RETURN(textTheme, textNode);
1033     if (textTheme->GetIsTextFadeout()) {
1034         textProps->UpdateTextOverflow(TextOverflow::MARQUEE);
1035         textProps->UpdateTextMarqueeStartPolicy(MarqueeStartPolicy::ON_FOCUS);
1036         textProps->UpdateTextMarqueeFadeout(true);
1037     }
1038     return textNode;
1039 }
1040 
BuildSheetItem(const ActionSheetInfo & item)1041 RefPtr<FrameNode> DialogPattern::BuildSheetItem(const ActionSheetInfo& item)
1042 {
1043     // ListItem -> Row -> title + icon
1044     auto Id = ElementRegister::GetInstance()->MakeUniqueId();
1045     RefPtr<FrameNode> itemNode = FrameNode::CreateFrameNode(
1046         V2::LIST_ITEM_ETS_TAG, Id, AceType::MakeRefPtr<ListItemPattern>(nullptr, V2::ListItemStyle::NONE));
1047     CHECK_NULL_RETURN(itemNode, nullptr);
1048 
1049     // update sheet row flex align
1050     auto rowId = ElementRegister::GetInstance()->MakeUniqueId();
1051     auto itemRow = FrameNode::CreateFrameNode(V2::ROW_ETS_TAG, rowId, AceType::MakeRefPtr<LinearLayoutPattern>(false));
1052     CHECK_NULL_RETURN(itemRow, nullptr);
1053     auto layoutProps = itemRow->GetLayoutProperty<LinearLayoutProperty>();
1054     layoutProps->UpdateMainAxisAlign(FlexAlign::FLEX_START);
1055     layoutProps->UpdateMeasureType(MeasureType::MATCH_PARENT_MAIN_AXIS);
1056 
1057     // mount icon
1058     if (!item.icon.empty()) {
1059         auto iconNode = BuildSheetInfoIcon(item.icon);
1060         iconNode->MountToParent(itemRow);
1061         iconNode->MarkModifyDone();
1062     }
1063 
1064     // mount title
1065     if (!item.title.empty()) {
1066         auto titleNode = BuildSheetInfoTitle(item.title);
1067         titleNode->MountToParent(itemRow);
1068         titleNode->MarkModifyDone();
1069     }
1070 
1071     // set sheetItem action
1072     auto hub = itemRow->GetOrCreateGestureEventHub();
1073     if (item.action) {
1074         hub->AddClickEvent(item.action);
1075         auto recordEvent = [weak = WeakClaim(this), title = item.title](GestureEvent& info) {
1076             if (!Recorder::EventRecorder::Get().IsComponentRecordEnable()) {
1077                 return;
1078             }
1079             auto pattern = weak.Upgrade();
1080             CHECK_NULL_VOID(pattern);
1081             Recorder::EventParamsBuilder builder;
1082             builder.SetEventType(Recorder::EventType::DIALOG_SELECT)
1083                 .SetText(title)
1084                 .SetExtra(Recorder::KEY_TITLE, pattern->title_)
1085                 .SetExtra(Recorder::KEY_SUB_TITLE, pattern->subtitle_);
1086             Recorder::EventRecorder::Get().OnEvent(std::move(builder));
1087         };
1088         auto recordEventPtr = MakeRefPtr<ClickEvent>(std::move(recordEvent));
1089         hub->AddClickEvent(recordEventPtr);
1090     }
1091 
1092     // close dialog when clicked
1093     BindCloseCallBack(hub, SHEET_INFO_IDX);
1094     itemRow->MountToParent(itemNode);
1095     return itemNode;
1096 }
1097 
BuildSheetInfoTitle(const std::string & title)1098 RefPtr<FrameNode> DialogPattern::BuildSheetInfoTitle(const std::string& title)
1099 {
1100     auto titleId = ElementRegister::GetInstance()->MakeUniqueId();
1101     auto titleNode = FrameNode::CreateFrameNode(V2::TEXT_ETS_TAG, titleId, AceType::MakeRefPtr<TextPattern>());
1102     CHECK_NULL_RETURN(titleNode, nullptr);
1103     // update text style
1104     auto style = dialogTheme_->GetContentTextStyle();
1105     auto props = titleNode->GetLayoutProperty<TextLayoutProperty>();
1106     props->UpdateContent(title);
1107     props->UpdateTextOverflow(TextOverflow::ELLIPSIS);
1108     props->UpdateAdaptMaxFontSize(style.GetFontSize());
1109     props->UpdateAdaptMinFontSize(dialogTheme_->GetTitleMinFontSize());
1110     props->UpdateMaxLines(style.GetMaxLines());
1111     props->UpdateFlexGrow(1.0f);
1112     props->UpdateFlexShrink(1.0f);
1113     return titleNode;
1114 }
1115 
BuildSheetInfoIcon(const std::string & icon)1116 RefPtr<FrameNode> DialogPattern::BuildSheetInfoIcon(const std::string& icon)
1117 {
1118     auto iconId = ElementRegister::GetInstance()->MakeUniqueId();
1119     auto iconNode = FrameNode::CreateFrameNode(V2::IMAGE_ETS_TAG, iconId, AceType::MakeRefPtr<ImagePattern>());
1120     CHECK_NULL_RETURN(iconNode, nullptr);
1121     // add image margin
1122     MarginProperty margin = {
1123         .left = CalcLength(SHEET_IMAGE_MARGIN),
1124         .right = CalcLength(SHEET_IMAGE_MARGIN),
1125         .top = CalcLength(SHEET_IMAGE_MARGIN),
1126         .bottom = CalcLength(SHEET_IMAGE_MARGIN),
1127     };
1128     auto iconProps = iconNode->GetLayoutProperty<ImageLayoutProperty>();
1129     iconProps->UpdateMargin(margin);
1130     auto imageSrc = ImageSourceInfo(icon);
1131     iconProps->UpdateImageSourceInfo(imageSrc);
1132     iconProps->UpdateUserDefinedIdealSize(CalcSize(SHEET_IMAGE_SIZE, SHEET_IMAGE_SIZE));
1133     return iconNode;
1134 }
1135 
BuildSheet(const std::vector<ActionSheetInfo> & sheets)1136 RefPtr<FrameNode> DialogPattern::BuildSheet(const std::vector<ActionSheetInfo>& sheets)
1137 {
1138     auto listId = ElementRegister::GetInstance()->MakeUniqueId();
1139     auto list = FrameNode::CreateFrameNode(V2::LIST_ETS_TAG, listId, AceType::MakeRefPtr<ListPattern>());
1140     CHECK_NULL_RETURN(list, nullptr);
1141 
1142     // set sheet padding
1143     CalcLength padding(SHEET_LIST_PADDING.ConvertToPx());
1144     PaddingProperty sheetPadding = {
1145         .left = padding,
1146         .right = padding,
1147         .top = padding,
1148         .bottom = padding,
1149     };
1150     list->GetLayoutProperty()->UpdatePadding(sheetPadding);
1151     list->GetPaintProperty<ScrollablePaintProperty>()->UpdateScrollBarMode(DisplayMode::OFF);
1152 
1153     for (auto&& item : sheets) {
1154         auto itemNode = BuildSheetItem(item);
1155         CHECK_NULL_RETURN(itemNode, nullptr);
1156         list->AddChild(itemNode);
1157     }
1158 
1159     // set list divider
1160     auto divider = V2::ItemDivider {
1161         .strokeWidth = SHEET_DIVIDER_WIDTH,
1162         .color = Color::GRAY,
1163     };
1164     auto props = list->GetLayoutProperty<ListLayoutProperty>();
1165     props->UpdateDivider(divider);
1166     props->UpdateListDirection(Axis::VERTICAL);
1167     return list;
1168 }
1169 
BuildMenu(const std::vector<ButtonInfo> & buttons,bool hasTitle)1170 RefPtr<FrameNode> DialogPattern::BuildMenu(const std::vector<ButtonInfo>& buttons, bool hasTitle)
1171 {
1172     auto menu = FrameNode::CreateFrameNode(
1173         V2::COLUMN_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), MakeRefPtr<LinearLayoutPattern>(true));
1174     menuNode_ = menu;
1175     // column -> button
1176     const size_t size = buttons.size();
1177     for (size_t i = 0; i < size; ++i) {
1178         RefPtr<FrameNode> button;
1179         uint32_t val = size > 0 ? size - 1 : 0;
1180         if (i != val) {
1181             button = CreateButton(buttons[i], i, false, isSuitableForElderly_, size);
1182         } else {
1183             button = CreateButton(buttons[i], i, true, isSuitableForElderly_, size);
1184         }
1185         CHECK_NULL_RETURN(button, nullptr);
1186         auto props = DynamicCast<FrameNode>(button)->GetLayoutProperty();
1187         auto buttonRow = FrameNode::CreateFrameNode(V2::ROW_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
1188             AceType::MakeRefPtr<LinearLayoutPattern>(isSuitableForElderly_));
1189         CHECK_NULL_RETURN(buttonRow, nullptr);
1190         auto buttonRowProps = buttonRow->GetLayoutProperty<LinearLayoutProperty>();
1191         CHECK_NULL_RETURN(buttonRowProps, nullptr);
1192         if (isSuitableForElderly_) {
1193             buttonRowProps->UpdateCrossAxisAlign(FlexAlign::STRETCH);
1194             buttonRowProps->UpdateMeasureType(MeasureType::MATCH_PARENT_CROSS_AXIS);
1195         } else {
1196             buttonRowProps->UpdateMainAxisAlign(FlexAlign::FLEX_START);
1197             buttonRowProps->UpdateMeasureType(MeasureType::MATCH_PARENT_MAIN_AXIS);
1198         }
1199 
1200         button->MountToParent(buttonRow);
1201         button->MarkModifyDone();
1202         menu->AddChild(buttonRow);
1203     }
1204     auto menuProps = menu->GetLayoutProperty<LinearLayoutProperty>();
1205     CHECK_NULL_RETURN(menuProps, nullptr);
1206     PaddingProperty menuPadding;
1207     if (!hasTitle) {
1208         menuPadding.top = CalcLength(dialogTheme_->GetContentAdjustPadding().Top());
1209     }
1210     menuPadding.left = CalcLength(dialogTheme_->GetDefaultPadding().Left());
1211     menuPadding.right = CalcLength(dialogTheme_->GetDefaultPadding().Right());
1212     menuPadding.bottom = CalcLength(dialogTheme_->GetButtonPaddingBottom());
1213     menuProps->UpdatePadding(menuPadding);
1214     return menu;
1215 }
1216 
RegisterOnKeyEvent(const RefPtr<FocusHub> & focusHub)1217 void DialogPattern::RegisterOnKeyEvent(const RefPtr<FocusHub>& focusHub)
1218 {
1219     auto onKeyEvent = [wp = WeakClaim(this)](const KeyEvent& event) -> bool {
1220         auto pattern = wp.Upgrade();
1221         CHECK_NULL_RETURN(pattern, false);
1222         return pattern->OnKeyEvent(event);
1223     };
1224     focusHub->SetOnKeyEventInternal(std::move(onKeyEvent));
1225 }
1226 
OnKeyEvent(const KeyEvent & event)1227 bool DialogPattern::OnKeyEvent(const KeyEvent& event)
1228 {
1229     if (event.action != KeyAction::DOWN) {
1230         return false;
1231     }
1232     return false;
1233 }
1234 
InitFocusEvent(const RefPtr<FocusHub> & focusHub)1235 void DialogPattern::InitFocusEvent(const RefPtr<FocusHub>& focusHub)
1236 {
1237     auto onFocus = [wp = WeakClaim(this)]() {
1238         auto pattern = wp.Upgrade();
1239         CHECK_NULL_VOID(pattern);
1240         pattern->HandleFocusEvent();
1241     };
1242     focusHub->SetOnFocusInternal(std::move(onFocus));
1243 
1244     auto onBlur = [wp = WeakClaim(this)]() {
1245         auto pattern = wp.Upgrade();
1246         CHECK_NULL_VOID(pattern);
1247         pattern->HandleBlurEvent();
1248     };
1249     focusHub->SetOnBlurInternal(std::move(onBlur));
1250 }
1251 
GetDefaultShadow(ShadowStyle style)1252 Shadow GetDefaultShadow(ShadowStyle style)
1253 {
1254     Shadow shadow = Shadow::CreateShadow(ShadowStyle::None);
1255     auto pipeline = PipelineContext::GetCurrentContext();
1256     CHECK_NULL_RETURN(pipeline, shadow);
1257     auto shadowTheme = pipeline->GetTheme<ShadowTheme>();
1258     CHECK_NULL_RETURN(shadowTheme, shadow);
1259     auto colorMode = pipeline->GetColorMode();
1260     shadow = shadowTheme->GetShadow(style, colorMode);
1261     return shadow;
1262 }
1263 
HandleBlurEvent()1264 void DialogPattern::HandleBlurEvent()
1265 {
1266     CHECK_NULL_VOID(contentRenderContext_ && Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TWELVE));
1267     auto defaultShadowOff = static_cast<ShadowStyle>(dialogTheme_->GetDefaultShadowOff());
1268     contentRenderContext_->UpdateBackShadow(dialogProperties_.shadow.value_or(GetDefaultShadow(defaultShadowOff)));
1269 }
1270 
HandleFocusEvent()1271 void DialogPattern::HandleFocusEvent()
1272 {
1273     CHECK_NULL_VOID(contentRenderContext_ && Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_TWELVE));
1274     auto defaultShadowOn = static_cast<ShadowStyle>(dialogTheme_->GetDefaultShadowOn());
1275     contentRenderContext_->UpdateBackShadow(dialogProperties_.shadow.value_or(GetDefaultShadow(defaultShadowOn)));
1276 }
1277 
1278 // XTS inspector
ToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter) const1279 void DialogPattern::ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
1280 {
1281     /* no fixed attr below, just return */
1282     if (filter.IsFastFilter()) {
1283         return;
1284     }
1285     auto host = GetHost();
1286     CHECK_NULL_VOID(host);
1287     if (host->GetTag() == V2::ALERT_DIALOG_ETS_TAG || host->GetTag() == V2::ACTION_SHEET_DIALOG_ETS_TAG) {
1288         json->PutExtAttr("title", title_.c_str(), filter);
1289         json->PutExtAttr("subtitle", subtitle_.c_str(), filter);
1290         json->PutExtAttr("message", message_.c_str(), filter);
1291     }
1292     auto context = host->GetRenderContext();
1293     CHECK_NULL_VOID(context);
1294     json->PutExtAttr("uniRender", context->IsUniRenderEnabled() ? "true" : "false", filter);
1295 }
1296 
OnColorConfigurationUpdate()1297 void DialogPattern::OnColorConfigurationUpdate()
1298 {
1299     auto host = GetHost();
1300     CHECK_NULL_VOID(host);
1301     auto context = host->GetContext();
1302     CHECK_NULL_VOID(context);
1303     auto dialogTheme = context->GetTheme<DialogTheme>();
1304     CHECK_NULL_VOID(dialogTheme);
1305     dialogTheme_ = dialogTheme;
1306     UpdateTitleAndContentColor();
1307     UpdateWrapperBackgroundStyle(host, dialogTheme);
1308     UpdateButtonsProperty();
1309     OnModifyDone();
1310     host->MarkDirtyNode();
1311 }
1312 
UpdateTitleAndContentColor()1313 void DialogPattern::UpdateTitleAndContentColor()
1314 {
1315     CHECK_NULL_VOID(dialogTheme_);
1316     if (!dialogProperties_.title.empty() && contentNodeMap_.find(DialogContentNode::TITLE) != contentNodeMap_.end()) {
1317         UpdateDialogTextColor(contentNodeMap_[DialogContentNode::TITLE], dialogTheme_->GetTitleTextStyle());
1318     }
1319     if (!dialogProperties_.subtitle.empty() &&
1320         contentNodeMap_.find(DialogContentNode::SUBTITLE) != contentNodeMap_.end()) {
1321         UpdateDialogTextColor(contentNodeMap_[DialogContentNode::SUBTITLE],
1322             dialogProperties_.title.empty() ? dialogTheme_->GetTitleTextStyle() : dialogTheme_->GetSubTitleTextStyle());
1323     }
1324     if (!dialogProperties_.content.empty() &&
1325         contentNodeMap_.find(DialogContentNode::MESSAGE) != contentNodeMap_.end()) {
1326         UpdateDialogTextColor(contentNodeMap_[DialogContentNode::MESSAGE], dialogTheme_->GetContentTextStyle());
1327     }
1328 }
1329 
UpdateDialogTextColor(const RefPtr<FrameNode> & textNode,const TextStyle & textStyle)1330 void DialogPattern::UpdateDialogTextColor(const RefPtr<FrameNode>& textNode, const TextStyle& textStyle)
1331 {
1332     CHECK_NULL_VOID(textNode);
1333     auto textProps = AceType::DynamicCast<TextLayoutProperty>(textNode->GetLayoutProperty());
1334     CHECK_NULL_VOID(textProps);
1335     textProps->UpdateTextColor(textStyle.GetTextColor());
1336     textNode->MarkModifyDone();
1337 }
1338 
UpdateAlignmentAndOffset()1339 void DialogPattern::UpdateAlignmentAndOffset()
1340 {
1341     auto host = GetHost();
1342     CHECK_NULL_VOID(host);
1343     auto props = host->GetLayoutProperty<DialogLayoutProperty>();
1344     CHECK_NULL_VOID(props);
1345     auto dialogProp = GetDialogProperties();
1346     props->UpdateDialogAlignment(dialogProp.alignment);
1347     props->UpdateDialogOffset(dialogProp.offset);
1348 }
1349 
OnLanguageConfigurationUpdate()1350 void DialogPattern::OnLanguageConfigurationUpdate()
1351 {
1352     CHECK_NULL_VOID(dialogProperties_.onLanguageChange);
1353     dialogProperties_.onLanguageChange(dialogProperties_);
1354     UpdateAlignmentAndOffset();
1355     if (!dialogProperties_.title.empty() && contentNodeMap_.find(DialogContentNode::TITLE) != contentNodeMap_.end()) {
1356         UpdateNodeContent(contentNodeMap_[DialogContentNode::TITLE], dialogProperties_.title);
1357         title_ = dialogProperties_.title;
1358     }
1359 
1360     if (!dialogProperties_.subtitle.empty() &&
1361         contentNodeMap_.find(DialogContentNode::SUBTITLE) != contentNodeMap_.end()) {
1362         UpdateNodeContent(contentNodeMap_[DialogContentNode::SUBTITLE], dialogProperties_.subtitle);
1363         subtitle_ = dialogProperties_.subtitle;
1364     }
1365 
1366     if (!dialogProperties_.content.empty() &&
1367         contentNodeMap_.find(DialogContentNode::MESSAGE) != contentNodeMap_.end()) {
1368         UpdateNodeContent(contentNodeMap_[DialogContentNode::MESSAGE], dialogProperties_.content);
1369         message_ = dialogProperties_.content;
1370     }
1371 
1372     if (!dialogProperties_.buttons.empty()) {
1373         UpdateButtonsProperty();
1374     }
1375 
1376     if (dialogProperties_.type == DialogType::ACTION_SHEET) {
1377         UpdateSheetIconAndText();
1378     }
1379 
1380     if (dialogProperties_.shadow.has_value()) {
1381         contentRenderContext_->UpdateBackShadow(dialogProperties_.shadow.value());
1382     }
1383 
1384     if (dialogProperties_.borderWidth.has_value() &&
1385         contentNodeMap_.find(DialogContentNode::BORDERWIDTH) != contentNodeMap_.end()) {
1386         auto layoutProps = contentNodeMap_[DialogContentNode::BORDERWIDTH]->GetLayoutProperty<LinearLayoutProperty>();
1387         layoutProps->UpdateBorderWidth(dialogProperties_.borderWidth.value());
1388         contentRenderContext_->UpdateBorderWidth(dialogProperties_.borderWidth.value());
1389     }
1390 
1391     if (dialogProperties_.borderColor.has_value()) {
1392         auto contentNode = contentRenderContext_->GetHost();
1393         CHECK_NULL_VOID(contentNode);
1394         auto contentPattern = contentNode->GetPattern();
1395         CHECK_NULL_VOID(contentPattern);
1396         contentRenderContext_->UpdateBorderColor(dialogProperties_.borderColor.value());
1397         contentPattern->CheckLocalized();
1398     }
1399 
1400     if (dialogProperties_.borderRadius.has_value()) {
1401         contentRenderContext_->UpdateBorderRadius(dialogProperties_.borderRadius.value());
1402     }
1403 }
1404 
UpdateNodeContent(const RefPtr<FrameNode> & node,std::string & text)1405 void DialogPattern::UpdateNodeContent(const RefPtr<FrameNode>& node, std::string& text)
1406 {
1407     CHECK_NULL_VOID(node);
1408     auto layoutProps = AceType::DynamicCast<TextLayoutProperty>(node->GetLayoutProperty());
1409     CHECK_NULL_VOID(layoutProps);
1410     layoutProps->UpdateContent(text);
1411     node->MarkModifyDone();
1412 }
1413 
UpdateSheetIconAndText()1414 void DialogPattern::UpdateSheetIconAndText()
1415 {
1416     if (dialogProperties_.sheetsInfo.empty()) {
1417         return;
1418     }
1419 
1420     auto sheetContainer = contentNodeMap_[DialogContentNode::SHEET];
1421     CHECK_NULL_VOID(sheetContainer);
1422     int32_t sheetIndex = 0;
1423     for (const auto& sheet : sheetContainer->GetChildren()) {
1424         auto itemRow = DynamicCast<FrameNode>(sheet->GetFirstChild());
1425         CHECK_NULL_VOID(itemRow);
1426 
1427         auto sheetInfo = dialogProperties_.sheetsInfo.at(sheetIndex);
1428         if (!sheetInfo.icon.empty()) {
1429             auto iconNode = DynamicCast<FrameNode>(itemRow->GetFirstChild());
1430             CHECK_NULL_VOID(iconNode);
1431             auto iconProps = iconNode->GetLayoutProperty<ImageLayoutProperty>();
1432             CHECK_NULL_VOID(iconProps);
1433             iconProps->UpdateImageSourceInfo(ImageSourceInfo(sheetInfo.icon));
1434             iconNode->MarkModifyDone();
1435         }
1436         if (!sheetInfo.title.empty()) {
1437             auto titleNode = DynamicCast<FrameNode>(itemRow->GetLastChild());
1438             CHECK_NULL_VOID(titleNode);
1439             auto titleProps = titleNode->GetLayoutProperty<TextLayoutProperty>();
1440             CHECK_NULL_VOID(titleProps);
1441             titleProps->UpdateContent(sheetInfo.title);
1442             titleNode->MarkModifyDone();
1443         }
1444         ++sheetIndex;
1445     }
1446 }
1447 
UpdateButtonsPropertyForEachButton(RefPtr<FrameNode> buttonFrameNode,int32_t btnIndex)1448 void DialogPattern::UpdateButtonsPropertyForEachButton(RefPtr<FrameNode> buttonFrameNode, int32_t btnIndex)
1449 {
1450     CHECK_NULL_VOID(buttonFrameNode);
1451     auto pattern = buttonFrameNode->GetPattern<ButtonPattern>();
1452     CHECK_NULL_VOID(pattern);
1453     pattern->SetSkipColorConfigurationUpdate();
1454     // parse button text color and background color
1455     std::string textColorStr;
1456     std::optional<Color> bgColor;
1457     ParseButtonFontColorAndBgColor(dialogProperties_.buttons[btnIndex], textColorStr, bgColor);
1458     // update background color
1459     auto renderContext = buttonFrameNode->GetRenderContext();
1460     CHECK_NULL_VOID(renderContext);
1461     renderContext->UpdateBackgroundColor(bgColor.value());
1462     auto buttonTextNode = DynamicCast<FrameNode>(buttonFrameNode->GetFirstChild());
1463     CHECK_NULL_VOID(buttonTextNode);
1464     auto buttonTextLayoutProperty = buttonTextNode->GetLayoutProperty<TextLayoutProperty>();
1465     CHECK_NULL_VOID(buttonTextLayoutProperty);
1466     Color textColor;
1467     Color::ParseColorString(textColorStr, textColor);
1468     buttonTextLayoutProperty->UpdateContent(dialogProperties_.buttons[btnIndex].text);
1469     buttonTextLayoutProperty->UpdateTextColor(textColor);
1470     buttonTextNode->MarkModifyDone();
1471     buttonTextNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF);
1472 }
1473 
UpdateButtonsProperty()1474 void DialogPattern::UpdateButtonsProperty()
1475 {
1476     int32_t btnIndex = 0;
1477     if (buttonContainer_) {
1478         isFirstDefaultFocus_ = true;
1479         for (const auto& buttonNode : buttonContainer_->GetChildren()) {
1480             if (buttonNode->GetTag() != V2::BUTTON_ETS_TAG) {
1481                 continue;
1482             }
1483             auto buttonFrameNode = DynamicCast<FrameNode>(buttonNode);
1484             UpdateButtonsPropertyForEachButton(buttonFrameNode, btnIndex);
1485             ++btnIndex;
1486         }
1487     } else {
1488         auto upgradedMenuNode = menuNode_.Upgrade();
1489         CHECK_NULL_VOID(upgradedMenuNode);
1490         for (const auto& rowNode : upgradedMenuNode->GetChildren()) {
1491             if (rowNode->GetTag() != V2::ROW_ETS_TAG) {
1492                 continue;
1493             }
1494             auto buttonFrameNode = DynamicCast<FrameNode>(rowNode->GetFirstChild());
1495             if (buttonFrameNode && buttonFrameNode->GetTag() == V2::BUTTON_ETS_TAG) {
1496                 UpdateButtonsPropertyForEachButton(buttonFrameNode, btnIndex);
1497             }
1498             ++btnIndex;
1499         }
1500     }
1501 }
1502 
UpdatePropertyForElderly(const std::vector<ButtonInfo> & buttons)1503 void DialogPattern::UpdatePropertyForElderly(const std::vector<ButtonInfo>& buttons)
1504 {
1505     isSuitableForElderly_ = false;
1506     notAdapationAging_ = false;
1507     auto pipeline = PipelineContext::GetCurrentContext();
1508     CHECK_NULL_VOID(pipeline);
1509     auto windowManager = pipeline->GetWindowManager();
1510     CHECK_NULL_VOID(windowManager);
1511     auto dialogContext = GetContext();
1512     CHECK_NULL_VOID(dialogContext);
1513     TAG_LOGI(AceLogTag::ACE_DIALOG, "dialog GetContext fontScale : %{public}f", dialogContext->GetFontScale());
1514     if (GreatOrEqual(dialogContext->GetFontScale(), dialogTheme_->GetMinFontScaleForElderly())) {
1515         if (pipeline->GetRootHeight() < dialogTheme_->GetDialogLandscapeHeightBoundary().ConvertToPx() &&
1516             windowManager->GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_PRIMARY) {
1517             notAdapationAging_ = true;
1518             return;
1519         }
1520         deviceOrientation_ = SystemProperties::GetDeviceOrientation();
1521         if (buttons.size() >= THREE_BUTTON_MODE && deviceOrientation_ == DeviceOrientation::LANDSCAPE) {
1522             notAdapationAging_ = true;
1523             return;
1524         }
1525         fontScaleForElderly_ = dialogContext->GetFontScale();
1526         isSuitableForElderly_ = true;
1527         notAdapationAging_ = false;
1528     }
1529 }
1530 
NeedsButtonDirectionChange(const std::vector<ButtonInfo> & buttons)1531 bool DialogPattern::NeedsButtonDirectionChange(const std::vector<ButtonInfo>& buttons)
1532 {
1533     CHECK_NULL_RETURN(buttonContainer_, false);
1534     if (buttons.size() == ONE_BUTTON_MODE || buttonContainer_->GetTag() != V2::ROW_ETS_TAG) {
1535         return false;
1536     }
1537     auto host = GetHost();
1538     CHECK_NULL_RETURN(host, false);
1539     auto props = host->GetLayoutProperty<DialogLayoutProperty>();
1540     CHECK_NULL_RETURN(props, false);
1541     auto buttonLayoutConstraint = props->GetLayoutConstraint();
1542     isSuitOldMeasure_ = true;
1543     host->Measure(buttonLayoutConstraint);
1544     isSuitOldMeasure_ = false;
1545     const auto& children = buttonContainer_->GetChildren();
1546     for (const auto& child : children) {
1547         if (child->GetTag() == V2::BUTTON_ETS_TAG) {
1548             auto buttonNode = AceType::DynamicCast<FrameNode>(child);
1549             CHECK_NULL_RETURN(buttonNode, false);
1550             auto buttonTextNode = DynamicCast<FrameNode>(buttonNode->GetFirstChild());
1551             CHECK_NULL_RETURN(buttonTextNode, false);
1552             auto textGeometryNode = buttonTextNode->GetGeometryNode();
1553             CHECK_NULL_RETURN(textGeometryNode, false);
1554             auto textFarmeSize = textGeometryNode->GetFrameSize();
1555             auto textPattern = buttonTextNode->GetPattern<TextPattern>();
1556             CHECK_NULL_RETURN(textPattern, false);
1557             auto textDisplay = UtfUtils::Str16ToStr8(textPattern->GetTextForDisplay());
1558             auto textProps = buttonTextNode->GetLayoutProperty<TextLayoutProperty>();
1559             CHECK_NULL_RETURN(textProps, false);
1560             Dimension buttonTextSize = textProps->GetFontSize().value_or(dialogTheme_->GetButtonTextSize());
1561             MeasureContext measureContext;
1562             measureContext.textContent = textDisplay;
1563             measureContext.fontSize = buttonTextSize;
1564             auto dialogContext = GetContext();
1565             CHECK_NULL_RETURN(dialogContext, false);
1566             if (isSuitableForElderly_ && dialogContext->GetFontScale() >= dialogTheme_->GetTitleMaxFontScale() &&
1567                 SystemProperties::GetDeviceOrientation() == DeviceOrientation::LANDSCAPE) {
1568                 measureContext.fontSize =
1569                     Dimension(buttonTextSize.Value() * dialogTheme_->GetTitleMaxFontScale(), DimensionUnit::VP);
1570             }
1571             auto fontweight = StringUtils::FontWeightToString(FontWeight::MEDIUM);
1572             measureContext.fontWeight = fontweight;
1573             Size measureSize = MeasureUtil::MeasureTextSize(measureContext);
1574             if (measureSize.Width() != textFarmeSize.Width()) {
1575                 return true;
1576             }
1577         }
1578     }
1579     return false;
1580 }
1581 
CheckScrollHeightIsNegative(const RefPtr<UINode> & contentColumn,const DialogProperties & Dialogprops)1582 void DialogPattern::CheckScrollHeightIsNegative(
1583     const RefPtr<UINode>& contentColumn, const DialogProperties& Dialogprops)
1584 {
1585     CHECK_NULL_VOID(buttonContainer_);
1586     if (Dialogprops.buttons.size() == ONE_BUTTON_MODE || buttonContainer_->GetTag() == V2::ROW_ETS_TAG) {
1587         return;
1588     }
1589     auto host = GetHost();
1590     CHECK_NULL_VOID(host);
1591     auto props = host->GetLayoutProperty<DialogLayoutProperty>();
1592     CHECK_NULL_VOID(props);
1593     auto buttonLayoutConstraint = props->GetLayoutConstraint();
1594     isSuitOldMeasure_ = true;
1595     host->Measure(buttonLayoutConstraint);
1596     isSuitOldMeasure_ = false;
1597     if (isScrollHeightNegative_) {
1598         isSuitableForElderly_ = false;
1599         notAdapationAging_ = true;
1600         contentColumn->RemoveChild(buttonContainer_);
1601         auto buttonContainerNew = BuildButtons(Dialogprops.buttons, Dialogprops.buttonDirection);
1602         buttonContainerNew->MountToParent(contentColumn);
1603         buttonContainer_ = buttonContainerNew;
1604     }
1605 }
1606 
UpdateDeviceOrientation(const DeviceOrientation & deviceOrientation)1607 void DialogPattern::UpdateDeviceOrientation(const DeviceOrientation& deviceOrientation)
1608 {
1609     if (deviceOrientation_ != deviceOrientation) {
1610         CHECK_NULL_VOID(buttonContainer_);
1611         OnFontConfigurationUpdate();
1612         auto host = GetHost();
1613         CHECK_NULL_VOID(host);
1614         host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
1615         deviceOrientation_ = deviceOrientation;
1616     }
1617 }
1618 
UpdateTitleTextFontScale()1619 void DialogPattern::UpdateTitleTextFontScale()
1620 {
1621     CHECK_NULL_VOID(titleContainer_);
1622     auto scale = dialogTheme_->GetMinFontScaleForElderly();
1623     if (isSuitableForElderly_) {
1624         scale = dialogTheme_->GetTitleMaxFontScale();
1625     }
1626     if (titleContainer_->GetTag() == V2::COLUMN_ETS_TAG) {
1627         auto children = titleContainer_->GetChildren();
1628         for (const auto& child : children) {
1629             auto textNode = AceType::DynamicCast<FrameNode>(child->GetChildAtIndex(START_CHILD_INDEX));
1630             CHECK_NULL_VOID(textNode);
1631             auto titleProp = AceType::DynamicCast<TextLayoutProperty>(textNode->GetLayoutProperty());
1632             CHECK_NULL_VOID(titleProp);
1633             if (notAdapationAging_) {
1634                 titleProp->UpdateMaxFontScale(dialogTheme_->GetDialogDefaultScale());
1635             } else {
1636                 titleProp->UpdateMaxFontScale(scale);
1637                 titleProp->UpdateMaxLines(ADAPT_TITLE_MAX_LINES);
1638             }
1639         }
1640     } else {
1641         auto textNode = AceType::DynamicCast<FrameNode>(titleContainer_->GetChildAtIndex(START_CHILD_INDEX));
1642         CHECK_NULL_VOID(textNode);
1643         auto titleProp = AceType::DynamicCast<TextLayoutProperty>(textNode->GetLayoutProperty());
1644         CHECK_NULL_VOID(titleProp);
1645         if (notAdapationAging_) {
1646             titleProp->UpdateMaxFontScale(dialogTheme_->GetDialogDefaultScale());
1647         } else {
1648             titleProp->UpdateMaxFontScale(scale);
1649             titleProp->UpdateMaxLines(ADAPT_TITLE_MAX_LINES);
1650         }
1651     }
1652 }
1653 
UpdateTextFontScale()1654 void DialogPattern::UpdateTextFontScale()
1655 {
1656     UpdateTitleTextFontScale();
1657     CHECK_NULL_VOID(contentNodeMap_[DialogContentNode::MESSAGE]);
1658     auto scale = dialogTheme_->GetMinFontScaleForElderly();
1659     auto contentProp =
1660         AceType::DynamicCast<TextLayoutProperty>(contentNodeMap_[DialogContentNode::MESSAGE]->GetLayoutProperty());
1661     CHECK_NULL_VOID(contentProp);
1662     if (isSuitableForElderly_) {
1663         scale = SystemProperties::GetDeviceOrientation() == DeviceOrientation::LANDSCAPE
1664                     ? dialogTheme_->GetContentLandscapeMaxFontScale()
1665                     : dialogTheme_->GetContentMaxFontScale();
1666     }
1667     if (notAdapationAging_) {
1668         contentProp->UpdateMaxFontScale(dialogTheme_->GetDialogDefaultScale());
1669     } else {
1670         contentProp->UpdateMaxFontScale(scale);
1671     }
1672     CHECK_NULL_VOID(buttonContainer_);
1673     MarginProperty margin;
1674     if (isSuitableForElderly_) {
1675         scale = SystemProperties::GetDeviceOrientation() == DeviceOrientation::LANDSCAPE
1676                     ? dialogTheme_->GetButtonLandscapeMaxFontScale()
1677                     : dialogTheme_->GetButtonMaxFontScale();
1678         margin.top = CalcLength(8.0_vp);
1679         margin.bottom = CalcLength(8.0_vp);
1680     }
1681     const auto& children = buttonContainer_->GetChildren();
1682     for (const auto& child : children) {
1683         if (child->GetTag() == V2::BUTTON_ETS_TAG) {
1684             auto buttonNode = AceType::DynamicCast<FrameNode>(child);
1685             CHECK_NULL_VOID(buttonNode);
1686             auto buttonTextNode = DynamicCast<FrameNode>(buttonNode->GetFirstChild());
1687             CHECK_NULL_VOID(buttonTextNode);
1688             auto textProp = AceType::DynamicCast<TextLayoutProperty>(buttonTextNode->GetLayoutProperty());
1689             CHECK_NULL_VOID(textProp);
1690             if (notAdapationAging_) {
1691                 textProp->UpdateMaxFontScale(dialogTheme_->GetDialogDefaultScale());
1692             } else {
1693                 textProp->UpdateMaxFontScale(scale);
1694             }
1695             if (isSuitableForElderly_) {
1696                 textProp->UpdateMargin(margin);
1697             }
1698         }
1699     }
1700 }
1701 
UpdateFontScale()1702 void DialogPattern::UpdateFontScale()
1703 {
1704     auto dialogContext = GetContext();
1705     CHECK_NULL_VOID(dialogContext);
1706     if (dialogContext->GetFontScale() != fontScaleForElderly_) {
1707         OnFontConfigurationUpdate();
1708         auto host = GetHost();
1709         CHECK_NULL_VOID(host);
1710         host->MarkModifyDone();
1711         host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
1712         fontScaleForElderly_ = dialogContext->GetFontScale();
1713     }
1714 }
1715 
SetButtonEnabled(const RefPtr<FrameNode> & buttonNode,bool enabled)1716 void DialogPattern::SetButtonEnabled(const RefPtr<FrameNode>& buttonNode, bool enabled)
1717 {
1718     // set Enabled and Focusable
1719     auto buttonButtonEvent = buttonNode->GetEventHub<ButtonEventHub>();
1720     CHECK_NULL_VOID(buttonButtonEvent);
1721     buttonButtonEvent->SetEnabled(enabled);
1722     buttonNode->GetOrCreateFocusHub()->SetFocusable(enabled);
1723 }
1724 
UpdateWrapperBackgroundStyle(const RefPtr<FrameNode> & host,const RefPtr<DialogTheme> & dialogTheme)1725 void DialogPattern::UpdateWrapperBackgroundStyle(const RefPtr<FrameNode>& host, const RefPtr<DialogTheme>& dialogTheme)
1726 {
1727     auto col = DynamicCast<FrameNode>(host->GetChildAtIndex(START_CHILD_INDEX));
1728     CHECK_NULL_VOID(col);
1729     auto colRenderContext = col->GetRenderContext();
1730     CHECK_NULL_VOID(colRenderContext);
1731     if (!dialogProperties_.customStyle && !dialogProperties_.backgroundColor.has_value() &&
1732         (Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN) || !colRenderContext->IsUniRenderEnabled() ||
1733             !dialogProperties_.isSysBlurStyle)) {
1734         colRenderContext->UpdateBackgroundColor(dialogTheme->GetBackgroundColor());
1735     }
1736     if (colRenderContext->GetBackBlurStyle().has_value()) {
1737         colRenderContext->UpdateBackBlurStyle(colRenderContext->GetBackBlurStyle());
1738     }
1739 }
1740 
DumpInfo()1741 void DialogPattern::DumpInfo()
1742 {
1743     DumpLog::GetInstance().AddDesc("Type: " + DialogTypeUtils::ConvertDialogTypeToString(dialogProperties_.type));
1744     if (!dialogProperties_.title.empty()) {
1745         DumpLog::GetInstance().AddDesc("Title: " + dialogProperties_.title);
1746     }
1747     if (!dialogProperties_.subtitle.empty()) {
1748         DumpLog::GetInstance().AddDesc("Subtitle: " + dialogProperties_.subtitle);
1749     }
1750     if (!dialogProperties_.content.empty()) {
1751         DumpLog::GetInstance().AddDesc("Content: " + dialogProperties_.content);
1752     }
1753     DumpLog::GetInstance().AddDesc(
1754         "DialogButtonDirection: " +
1755         DialogButtonDirectionUtils::ConvertDialogButtonDirectionToString(dialogProperties_.buttonDirection));
1756     if (dialogProperties_.width.has_value()) {
1757         DumpLog::GetInstance().AddDesc("Width: " + dialogProperties_.width.value().ToString());
1758     }
1759     if (dialogProperties_.height.has_value()) {
1760         DumpLog::GetInstance().AddDesc("Height: " + dialogProperties_.height.value().ToString());
1761     }
1762     if (dialogProperties_.backgroundBlurStyle.has_value()) {
1763         DumpLog::GetInstance().AddDesc(
1764             "BackgroundBlurStyle: " + std::to_string(dialogProperties_.backgroundBlurStyle.value()));
1765     }
1766     if (dialogProperties_.borderWidth.has_value()) {
1767         DumpLog::GetInstance().AddDesc("BorderWidth: " + dialogProperties_.borderWidth.value().ToString());
1768     }
1769     if (dialogProperties_.borderColor.has_value()) {
1770         DumpLog::GetInstance().AddDesc("BorderColor: " + dialogProperties_.borderColor.value().ToString());
1771     }
1772     if (dialogProperties_.backgroundColor.has_value()) {
1773         DumpLog::GetInstance().AddDesc("BackgroundColor: " + dialogProperties_.backgroundColor.value().ToString());
1774     }
1775     if (dialogProperties_.borderRadius.has_value()) {
1776         DumpLog::GetInstance().AddDesc("BorderRadius: " + dialogProperties_.borderRadius.value().ToString());
1777     }
1778     DumpBoolProperty();
1779     DumpObjectProperty();
1780 }
1781 
DumpBoolProperty()1782 void DialogPattern::DumpBoolProperty()
1783 {
1784     DumpLog::GetInstance().AddDesc("AutoCancel: " + GetBoolStr(dialogProperties_.autoCancel));
1785     DumpLog::GetInstance().AddDesc("CustomStyle: " + GetBoolStr(dialogProperties_.customStyle));
1786     DumpLog::GetInstance().AddDesc("IsMenu: " + GetBoolStr(dialogProperties_.isMenu));
1787     DumpLog::GetInstance().AddDesc("IsMask: " + GetBoolStr(dialogProperties_.isMask));
1788     DumpLog::GetInstance().AddDesc("IsModal: " + GetBoolStr(dialogProperties_.isModal));
1789     DumpLog::GetInstance().AddDesc("IsScenceBoardDialog: " + GetBoolStr(dialogProperties_.isScenceBoardDialog));
1790     DumpLog::GetInstance().AddDesc("IsSysBlurStyle: " + GetBoolStr(dialogProperties_.isSysBlurStyle));
1791     DumpLog::GetInstance().AddDesc("IsShowInSubWindow: " + GetBoolStr(dialogProperties_.isShowInSubWindow));
1792 }
1793 
DumpObjectProperty()1794 void DialogPattern::DumpObjectProperty()
1795 {
1796     DumpLog::GetInstance().AddDesc(
1797         "Alignment: " + DialogAlignmentUtils::ConvertDialogAlignmentToString(dialogProperties_.alignment));
1798     DumpLog::GetInstance().AddDesc("Offset: { dx: " + dialogProperties_.offset.GetX().ToString() +
1799                                    " dy: " + dialogProperties_.offset.GetY().ToString() + " }");
1800     if (dialogProperties_.buttons.size() > 0) {
1801         std::stringstream butonInfoSteam;
1802         butonInfoSteam << "Buttons: [";
1803         for (auto buttonInfo : dialogProperties_.buttons) {
1804             butonInfoSteam << "{ text: " << buttonInfo.text << " , color: " << buttonInfo.textColor << " }, ";
1805         }
1806         butonInfoSteam << "]";
1807         DumpLog::GetInstance().AddDesc(butonInfoSteam.str());
1808     }
1809     if (dialogProperties_.shadow.has_value()) {
1810         auto shadow = dialogProperties_.shadow.value();
1811         std::stringstream butonInfoSteam;
1812         static const int32_t precision = 2;
1813         butonInfoSteam << "Shadow: {";
1814         butonInfoSteam << " radius:" << std::fixed << std::setprecision(precision) << shadow.GetBlurRadius();
1815         butonInfoSteam << " style:" << std::to_string(static_cast<int32_t>(shadow.GetStyle()));
1816         butonInfoSteam << " type:" << std::to_string(static_cast<int32_t>(shadow.GetShadowType()));
1817         butonInfoSteam << " fill:" << GetBoolStr(shadow.GetIsFilled());
1818         butonInfoSteam << " offset:" << shadow.GetOffset().ToString();
1819         butonInfoSteam << " }";
1820         DumpLog::GetInstance().AddDesc(butonInfoSteam.str());
1821     }
1822     if (dialogProperties_.maskColor.has_value()) {
1823         DumpLog::GetInstance().AddDesc("MaskColor: " + dialogProperties_.maskColor.value().ToString());
1824     }
1825     if (dialogProperties_.maskRect.has_value()) {
1826         DumpLog::GetInstance().AddDesc("MaskRect: " + dialogProperties_.maskRect.value().ToString());
1827     }
1828 }
1829 
NeedUpdateHostWindowRect()1830 bool DialogPattern::NeedUpdateHostWindowRect()
1831 {
1832     CHECK_NULL_RETURN(isUIExtensionSubWindow_, false);
1833     if (!SystemProperties::IsSuperFoldDisplayDevice()) {
1834         return false;
1835     }
1836 
1837     auto host = GetHost();
1838     CHECK_NULL_RETURN(host, false);
1839     auto pipeline = host->GetContextRefPtr();
1840     CHECK_NULL_RETURN(pipeline, false);
1841     auto currentId = pipeline->GetInstanceId();
1842     if (currentId < MIN_SUBCONTAINER_ID) {
1843         return false;
1844     }
1845 
1846     auto container = AceEngine::Get().GetContainer(currentId);
1847     CHECK_NULL_RETURN(container, false);
1848     if (container->GetCurrentFoldStatus() == FoldStatus::HALF_FOLD) {
1849         auto subwindow = SubwindowManager::GetInstance()->GetSubwindowById(currentId);
1850         CHECK_NULL_RETURN(subwindow, false);
1851         return subwindow->IsSameDisplayWithParentWindow();
1852     }
1853 
1854     return false;
1855 }
1856 
OnWindowSizeChanged(int32_t width,int32_t height,WindowSizeChangeReason type)1857 void DialogPattern::OnWindowSizeChanged(int32_t width, int32_t height, WindowSizeChangeReason type)
1858 {
1859     auto forceUpdate = NeedUpdateHostWindowRect();
1860     auto isWindowChanged = type == WindowSizeChangeReason::ROTATION || type == WindowSizeChangeReason::RESIZE;
1861 
1862     TAG_LOGI(AceLogTag::ACE_DIALOG,
1863         "WindowSize is changed, type: %{public}d isFoldStatusChanged_: %{public}d forceUpdate: %{public}d", type,
1864         isFoldStatusChanged_, forceUpdate);
1865 
1866     if (isFoldStatusChanged_ || isWindowChanged || forceUpdate) {
1867         auto host = GetHost();
1868         CHECK_NULL_VOID(host);
1869         InitHostWindowRect();
1870         host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
1871         isFoldStatusChanged_ = false;
1872     }
1873 }
1874 
UpdateHostWindowRect()1875 void DialogPattern::UpdateHostWindowRect()
1876 {
1877     CHECK_NULL_VOID(isUIExtensionSubWindow_);
1878 
1879     auto host = GetHost();
1880     CHECK_NULL_VOID(host);
1881     auto pipeline = host->GetContextRefPtr();
1882     CHECK_NULL_VOID(pipeline);
1883     auto currentId = pipeline->GetInstanceId();
1884     if (currentId < MIN_SUBCONTAINER_ID) {
1885         return;
1886     }
1887 
1888     auto needUpdate = true;
1889     if (SystemProperties::IsSuperFoldDisplayDevice()) {
1890         auto container = AceEngine::Get().GetContainer(currentId);
1891         auto isHalfFold = container && container->GetCurrentFoldStatus() == FoldStatus::HALF_FOLD;
1892         auto subwindow = SubwindowManager::GetInstance()->GetSubwindowById(currentId);
1893         needUpdate = isHalfFold && subwindow && subwindow->IsSameDisplayWithParentWindow();
1894     }
1895 
1896     if (needUpdate) {
1897         InitHostWindowRect();
1898         host->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
1899     }
1900 }
1901 
InitHostWindowRect()1902 void DialogPattern::InitHostWindowRect()
1903 {
1904     if (!dialogProperties_.isShowInSubWindow) {
1905         isUIExtensionSubWindow_ = false;
1906         hostWindowRect_.Reset();
1907         return;
1908     }
1909 
1910     auto currentId = Container::CurrentId();
1911     auto container = Container::Current();
1912     CHECK_NULL_VOID(container);
1913     if (container->IsSubContainer()) {
1914         auto parentContainerId = SubwindowManager::GetInstance()->GetParentContainerId(currentId);
1915         container = AceEngine::Get().GetContainer(parentContainerId);
1916         CHECK_NULL_VOID(container);
1917     }
1918 
1919     if (container->IsUIExtensionWindow()) {
1920         isUIExtensionSubWindow_ = true;
1921         auto subwindow = SubwindowManager::GetInstance()->GetSubwindowByType(currentId, SubwindowType::TYPE_DIALOG);
1922         CHECK_NULL_VOID(subwindow);
1923         auto rect = subwindow->GetUIExtensionHostWindowRect();
1924         hostWindowRect_ = RectF(rect.Left(), rect.Top(), rect.Width(), rect.Height());
1925     }
1926     TAG_LOGI(AceLogTag::ACE_DIALOG, "InitHostWindowRect: %{public}s", hostWindowRect_.ToString().c_str());
1927 }
1928 
DumpInfo(std::unique_ptr<JsonValue> & json)1929 void DialogPattern::DumpInfo(std::unique_ptr<JsonValue>& json)
1930 {
1931     json->Put("Type", DialogTypeUtils::ConvertDialogTypeToString(dialogProperties_.type).c_str());
1932     if (!dialogProperties_.title.empty()) {
1933         json->Put("Title", dialogProperties_.title.c_str());
1934     }
1935     if (!dialogProperties_.subtitle.empty()) {
1936         json->Put("Subtitle", dialogProperties_.subtitle.c_str());
1937     }
1938     if (!dialogProperties_.content.empty()) {
1939         json->Put("Content", dialogProperties_.content.c_str());
1940     }
1941     json->Put("DialogButtonDirection",
1942         DialogButtonDirectionUtils::ConvertDialogButtonDirectionToString(dialogProperties_.buttonDirection).c_str());
1943     if (dialogProperties_.width.has_value()) {
1944         json->Put("Width", dialogProperties_.width.value().ToString().c_str());
1945     }
1946     if (dialogProperties_.height.has_value()) {
1947         json->Put("Height", dialogProperties_.height.value().ToString().c_str());
1948     }
1949     if (dialogProperties_.backgroundBlurStyle.has_value()) {
1950         json->Put("BackgroundBlurStyle", std::to_string(dialogProperties_.backgroundBlurStyle.value()).c_str());
1951     }
1952     if (dialogProperties_.borderWidth.has_value()) {
1953         json->Put("BorderWidth", dialogProperties_.borderWidth.value().ToString().c_str());
1954     }
1955     if (dialogProperties_.borderColor.has_value()) {
1956         json->Put("BorderColor", dialogProperties_.borderColor.value().ToString().c_str());
1957     }
1958     if (dialogProperties_.backgroundColor.has_value()) {
1959         json->Put("BackgroundColor", dialogProperties_.backgroundColor.value().ToString().c_str());
1960     }
1961     if (dialogProperties_.borderRadius.has_value()) {
1962         json->Put("BorderRadius", dialogProperties_.borderRadius.value().ToString().c_str());
1963     }
1964     DumpBoolProperty(json);
1965     DumpObjectProperty(json);
1966 }
1967 
DumpBoolProperty(std::unique_ptr<JsonValue> & json)1968 void DialogPattern::DumpBoolProperty(std::unique_ptr<JsonValue>& json)
1969 {
1970     json->Put("AutoCancel", GetBoolStr(dialogProperties_.autoCancel).c_str());
1971     json->Put("CustomStyle", GetBoolStr(dialogProperties_.customStyle).c_str());
1972     json->Put("IsMenu", GetBoolStr(dialogProperties_.isMenu).c_str());
1973     json->Put("IsMask", GetBoolStr(dialogProperties_.isMask).c_str());
1974     json->Put("IsModal", GetBoolStr(dialogProperties_.isModal).c_str());
1975     json->Put("IsScenceBoardDialog", GetBoolStr(dialogProperties_.isScenceBoardDialog).c_str());
1976     json->Put("IsSysBlurStyle", GetBoolStr(dialogProperties_.isSysBlurStyle).c_str());
1977     json->Put("IsShowInSubWindow", GetBoolStr(dialogProperties_.isShowInSubWindow).c_str());
1978 }
1979 
DumpObjectProperty(std::unique_ptr<JsonValue> & json)1980 void DialogPattern::DumpObjectProperty(std::unique_ptr<JsonValue>& json)
1981 {
1982     json->Put("Alignment", DialogAlignmentUtils::ConvertDialogAlignmentToString(dialogProperties_.alignment).c_str());
1983     std::unique_ptr<JsonValue> children = JsonUtil::Create(true);
1984     children->Put("dx", dialogProperties_.offset.GetX().ToString().c_str());
1985     children->Put("dy", dialogProperties_.offset.GetY().ToString().c_str());
1986     json->Put("Offset", children);
1987     if (dialogProperties_.buttons.size() > 0) {
1988         std::unique_ptr<JsonValue> buttons = JsonUtil::Create(true);
1989         int32_t inx = -1;
1990         for (auto buttonInfo : dialogProperties_.buttons) {
1991             std::unique_ptr<JsonValue> child = JsonUtil::Create(true);
1992             child->Put("text", buttonInfo.text.c_str());
1993             child->Put("color", buttonInfo.textColor.c_str());
1994             inx++;
1995             std::string key = "button_" + std::to_string(inx);
1996             buttons->Put(key.c_str(), child);
1997         }
1998         json->Put("buttons", buttons);
1999     }
2000     if (dialogProperties_.shadow.has_value()) {
2001         auto shadow = dialogProperties_.shadow.value();
2002         std::unique_ptr<JsonValue> child = JsonUtil::Create(true);
2003 
2004         child->Put("radius", shadow.GetBlurRadius());
2005         child->Put("style", static_cast<int32_t>(shadow.GetStyle()));
2006         child->Put("type", static_cast<int32_t>(shadow.GetShadowType()));
2007         child->Put("fill", GetBoolStr(shadow.GetIsFilled()).c_str());
2008         child->Put("offset", shadow.GetOffset().ToString().c_str());
2009         json->Put("shadow", child);
2010     }
2011     if (dialogProperties_.maskColor.has_value()) {
2012         json->Put("MaskColor", dialogProperties_.maskColor.value().ToString().c_str());
2013     }
2014     if (dialogProperties_.maskRect.has_value()) {
2015         json->Put("MaskRect", dialogProperties_.maskRect.value().ToString().c_str());
2016     }
2017 }
2018 
IsShowInFreeMultiWindow()2019 bool DialogPattern::IsShowInFreeMultiWindow()
2020 {
2021     auto currentId = Container::CurrentId();
2022     auto container = Container::Current();
2023     if (!container) {
2024         TAG_LOGW(AceLogTag::ACE_DIALOG, "container is null");
2025         return false;
2026     }
2027     if (container->IsSubContainer()) {
2028         currentId = SubwindowManager::GetInstance()->GetParentContainerId(currentId);
2029         container = AceEngine::Get().GetContainer(currentId);
2030         if (!container) {
2031             TAG_LOGW(AceLogTag::ACE_DIALOG, "parent container is null");
2032             return false;
2033         }
2034     }
2035     return container->IsFreeMultiWindow();
2036 }
2037 
IsShowInFloatingWindow()2038 bool DialogPattern::IsShowInFloatingWindow()
2039 {
2040     auto currentId = Container::CurrentId();
2041     auto container = Container::Current();
2042     if (!container) {
2043         TAG_LOGW(AceLogTag::ACE_DIALOG, "container is null");
2044         return false;
2045     }
2046     if (container->IsSubContainer()) {
2047         currentId = SubwindowManager::GetInstance()->GetParentContainerId(currentId);
2048         container = AceEngine::Get().GetContainer(currentId);
2049         if (!container) {
2050             TAG_LOGW(AceLogTag::ACE_DIALOG, "parent container is null");
2051             return false;
2052         }
2053     }
2054     return container->IsFloatingWindow();
2055 }
2056 
DumpSimplifyInfo(std::unique_ptr<JsonValue> & json)2057 void DialogPattern::DumpSimplifyInfo(std::unique_ptr<JsonValue>& json)
2058 {
2059     json->Put("Type", DialogTypeUtils::ConvertDialogTypeToString(dialogProperties_.type).c_str());
2060     if (!dialogProperties_.title.empty()) {
2061         json->Put("Title", dialogProperties_.title.c_str());
2062     }
2063     if (!dialogProperties_.subtitle.empty()) {
2064         json->Put("Subtitle", dialogProperties_.subtitle.c_str());
2065     }
2066     if (!dialogProperties_.content.empty()) {
2067         json->Put("Content", dialogProperties_.content.c_str());
2068     }
2069     if (dialogProperties_.buttonDirection != DialogButtonDirection::AUTO) {
2070         json->Put("ButtonDirection",
2071             DialogButtonDirectionUtils::ConvertDialogButtonDirectionToString(
2072                 dialogProperties_.buttonDirection).c_str());
2073     }
2074     if (dialogProperties_.backgroundBlurStyle.has_value() && dialogProperties_.backgroundBlurStyle.value() != 0) {
2075         json->Put("BackgroundBlurStyle", std::to_string(dialogProperties_.backgroundBlurStyle.value()).c_str());
2076     }
2077     if (dialogProperties_.backgroundColor.value_or(Color::TRANSPARENT) != Color::TRANSPARENT) {
2078         json->Put("BackgroundColor", dialogProperties_.backgroundColor.value_or(Color::TRANSPARENT).ToString().c_str());
2079     }
2080     DumpSimplifySizeProperty(json);
2081     DumpSimplifyBorderProperty(json);
2082     DumpSimplifyBoolProperty(json);
2083     DumpSimplifyObjectProperty(json);
2084 }
2085 
DumpSimplifyBorderProperty(std::unique_ptr<JsonValue> & json)2086 void DialogPattern::DumpSimplifyBorderProperty(std::unique_ptr<JsonValue>& json)
2087 {
2088     if (dialogProperties_.borderWidth.has_value()) {
2089         auto border = dialogProperties_.borderWidth.value();
2090         DimensionUnit unit = border.leftDimen.value_or(
2091             border.topDimen.value_or(border.rightDimen.value_or(border.bottomDimen.value_or(Dimension())))).Unit();
2092         Dimension defaultValue(0, unit);
2093         BorderWidthProperty defaultBorder = { defaultValue, defaultValue, defaultValue, defaultValue, std::nullopt,
2094             std::nullopt };
2095         if (!(border == defaultBorder)) {
2096             json->Put("BorderWidth", border.ToString().c_str());
2097         }
2098     }
2099     if (dialogProperties_.borderColor.has_value()) {
2100         auto color = dialogProperties_.borderColor.value();
2101         BorderColorProperty defaultValue = { Color::BLACK, Color::BLACK, Color::BLACK, Color::BLACK, std::nullopt,
2102             std::nullopt };
2103         if (!(color == defaultValue)) {
2104             json->Put("BorderColor", color.ToString().c_str());
2105         }
2106     }
2107     if (dialogProperties_.borderRadius.has_value()) {
2108         auto radius = dialogProperties_.borderRadius.value();
2109         DimensionUnit unit = radius.radiusTopLeft.value_or(radius.radiusTopRight.value_or(
2110             radius.radiusTopLeft.value_or(radius.radiusBottomLeft.value_or(
2111                 radius.radiusBottomRight.value_or(radius.radiusTopStart.value_or(radius.radiusTopEnd.value_or(
2112                     radius.radiusBottomStart.value_or(radius.radiusBottomEnd.value_or(Dimension()))))))))).Unit();
2113         Dimension defaultValue(0, unit);
2114         BorderRadiusProperty defaultRadius(defaultValue);
2115         if (!(radius == defaultRadius)) {
2116             json->Put("BorderRadius", dialogProperties_.borderRadius.value().ToString().c_str());
2117         }
2118     }
2119 }
2120 
DumpSimplifySizeProperty(std::unique_ptr<JsonValue> & json)2121 void DialogPattern::DumpSimplifySizeProperty(std::unique_ptr<JsonValue>& json)
2122 {
2123     if (dialogProperties_.width.has_value() || dialogProperties_.height.has_value()) {
2124         DimensionUnit unit = dialogProperties_.width.has_value() ?
2125             dialogProperties_.width.value().Unit() : dialogProperties_.height.value().Unit();
2126         CalcDimension defaultCalcDimen(0, unit);
2127         if (dialogProperties_.width.value_or(defaultCalcDimen) != defaultCalcDimen &&
2128             dialogProperties_.height.value_or(defaultCalcDimen) != defaultCalcDimen) {
2129             json->Put("Width", dialogProperties_.width.value_or(defaultCalcDimen).ToString().c_str());
2130             json->Put("Height", dialogProperties_.height.value_or(defaultCalcDimen).ToString().c_str());
2131         }
2132     }
2133 }
2134 
DumpSimplifyBoolProperty(std::unique_ptr<JsonValue> & json)2135 void DialogPattern::DumpSimplifyBoolProperty(std::unique_ptr<JsonValue>& json)
2136 {
2137     if (dialogProperties_.autoCancel) {
2138         json->Put("AutoCancel", GetBoolStr(dialogProperties_.autoCancel).c_str());
2139     }
2140     if (dialogProperties_.customStyle) {
2141         json->Put("CustomStyle", GetBoolStr(dialogProperties_.customStyle).c_str());
2142     }
2143     if (dialogProperties_.isMenu) {
2144         json->Put("IsMenu", GetBoolStr(dialogProperties_.isMenu).c_str());
2145     }
2146     if (dialogProperties_.isMask) {
2147         json->Put("IsMask", GetBoolStr(dialogProperties_.isMask).c_str());
2148     }
2149     if (dialogProperties_.isModal) {
2150         json->Put("IsModal", GetBoolStr(dialogProperties_.isModal).c_str());
2151     }
2152     if (dialogProperties_.isScenceBoardDialog) {
2153         json->Put("IsScenceBoardDialog", GetBoolStr(dialogProperties_.isScenceBoardDialog).c_str());
2154     }
2155     if (dialogProperties_.isSysBlurStyle) {
2156         json->Put("IsSysBlurStyle", GetBoolStr(dialogProperties_.isSysBlurStyle).c_str());
2157     }
2158     if (dialogProperties_.isShowInSubWindow) {
2159         json->Put("IsShowInSubWindow", GetBoolStr(dialogProperties_.isShowInSubWindow).c_str());
2160     }
2161 }
2162 
DumpSimplifyObjectProperty(std::unique_ptr<JsonValue> & json)2163 void DialogPattern::DumpSimplifyObjectProperty(std::unique_ptr<JsonValue>& json)
2164 {
2165     json->Put("Alignment", DialogAlignmentUtils::ConvertDialogAlignmentToString(dialogProperties_.alignment).c_str());
2166     std::stringstream stream;
2167     stream << dialogProperties_.offset.GetX().ToString() << "," << dialogProperties_.offset.GetY().ToString();
2168     json->Put("Offset", stream.str().c_str());
2169     if (!dialogProperties_.buttons.empty()) {
2170         std::unique_ptr<JsonValue> buttons = JsonUtil::Create(true);
2171         int32_t index = -1;
2172         for (const auto& buttonInfo : dialogProperties_.buttons) {
2173             std::unique_ptr<JsonValue> child = JsonUtil::Create(true);
2174             child->Put("Text", buttonInfo.text.c_str());
2175             child->Put("Color", buttonInfo.textColor.c_str());
2176             index++;
2177             std::string key = "Button" + std::to_string(index);
2178             buttons->PutRef(key.c_str(), std::move(child));
2179         }
2180         json->PutRef("Buttons", std::move(buttons));
2181     }
2182     if (dialogProperties_.shadow.has_value()) {
2183         auto shadow = dialogProperties_.shadow.value();
2184         std::unique_ptr<JsonValue> child = JsonUtil::Create(true);
2185 
2186         child->Put("Radius", shadow.GetBlurRadius());
2187         child->Put("Style", static_cast<int32_t>(shadow.GetStyle()));
2188         child->Put("Type", static_cast<int32_t>(shadow.GetShadowType()));
2189         child->Put("Fill", GetBoolStr(shadow.GetIsFilled()).c_str());
2190         child->Put("Offset", shadow.GetOffset().ToString().c_str());
2191         json->PutRef("Shadow", std::move(child));
2192     }
2193     if (dialogProperties_.maskColor.has_value()) {
2194         json->Put("MaskColor", dialogProperties_.maskColor.value().ToString().c_str());
2195     }
2196     if (dialogProperties_.maskRect.has_value()) {
2197         json->Put("MaskRect", dialogProperties_.maskRect.value().ToString().c_str());
2198     }
2199 }
2200 
GetEmbeddedOverlay(const RefPtr<OverlayManager> & context)2201 RefPtr<OverlayManager> DialogPattern::GetEmbeddedOverlay(const RefPtr<OverlayManager>& context)
2202 {
2203     auto host = GetHost();
2204     auto overlayManager = DialogManager::GetInstance().GetEmbeddedOverlayWithNode(host);
2205     CHECK_NULL_RETURN(overlayManager, context);
2206     return overlayManager;
2207 }
2208 
OnAttachToMainTree()2209 void DialogPattern::OnAttachToMainTree()
2210 {
2211     auto host = GetHost();
2212     CHECK_NULL_VOID(host);
2213     auto parentNode = AceType::DynamicCast<FrameNode>(host->GetParent());
2214     CHECK_NULL_VOID(parentNode);
2215     if (parentNode->GetTag() != V2::NAVDESTINATION_VIEW_ETS_TAG) {
2216         return;
2217     }
2218     auto dialogRenderContext = host->GetRenderContext();
2219     CHECK_NULL_VOID(dialogRenderContext);
2220     auto navDestinationPattern = parentNode->GetPattern<NavDestinationPattern>();
2221     CHECK_NULL_VOID(navDestinationPattern);
2222     auto zIndex = navDestinationPattern->GetTitlebarZIndex();
2223     dialogRenderContext->UpdateZIndex(zIndex + 1);
2224 }
2225 
GetOverlayManager(const RefPtr<FrameNode> & host)2226 RefPtr<OverlayManager> DialogPattern::GetOverlayManager(const RefPtr<FrameNode>& host)
2227 {
2228     RefPtr<PipelineContext> pipeline;
2229     if (host) {
2230         pipeline = host->GetContext();
2231     } else {
2232         pipeline = PipelineContext::GetCurrentContext();
2233     }
2234     CHECK_NULL_RETURN(pipeline, nullptr);
2235     auto overlayManager = pipeline->GetOverlayManager();
2236     CHECK_NULL_RETURN(overlayManager, nullptr);
2237     return GetEmbeddedOverlay(overlayManager);
2238 }
2239 
OverlayDismissDialog(const RefPtr<FrameNode> & dialogNode)2240 void DialogPattern::OverlayDismissDialog(const RefPtr<FrameNode>& dialogNode)
2241 {
2242     auto overlayManager = GetOverlayManager(nullptr);
2243     CHECK_NULL_VOID(overlayManager);
2244     overlayManager->RemoveDialog(dialogNode, false);
2245     if (overlayManager->isMaskNode(GetHost()->GetId())) {
2246         overlayManager->PopModalDialog(GetHost()->GetId());
2247     }
2248 }
2249 } // namespace OHOS::Ace::NG
2250