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