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