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