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/bubble/bubble_view.h"
16
17 #include "base/geometry/dimension.h"
18 #include "base/geometry/ng/offset_t.h"
19 #include "base/memory/ace_type.h"
20 #include "base/memory/referenced.h"
21 #include "base/utils/utils.h"
22 #include "core/common/container.h"
23 #include "core/components/button/button_theme.h"
24 #include "core/components/common/layout/constants.h"
25 #include "core/components/common/layout/grid_system_manager.h"
26 #include "core/components/common/properties/alignment.h"
27 #include "core/components/common/properties/color.h"
28 #include "core/components/popup/popup_theme.h"
29 #include "core/components_ng/base/frame_node.h"
30 #include "core/components_ng/pattern/bubble/bubble_pattern.h"
31 #include "core/components_ng/pattern/button/button_event_hub.h"
32 #include "core/components_ng/pattern/button/button_layout_property.h"
33 #include "core/components_ng/pattern/button/button_pattern.h"
34 #include "core/components_ng/pattern/flex/flex_layout_pattern.h"
35 #include "core/components_ng/pattern/linear_layout/linear_layout_pattern.h"
36 #include "core/components_ng/pattern/linear_layout/linear_layout_property.h"
37 #include "core/components_ng/pattern/scroll/scroll_pattern.h"
38 #include "core/components_ng/pattern/text/text_pattern.h"
39 #include "core/components_ng/property/calc_length.h"
40 #include "core/components_ng/render/paint_property.h"
41 #include "core/components_v2/inspector/inspector_constants.h"
42 #include "core/pipeline/base/element_register.h"
43 #include "core/pipeline/pipeline_base.h"
44 #include "core/pipeline_ng/pipeline_context.h"
45
46 namespace OHOS::Ace::NG {
47 namespace {
48 constexpr double DOUBLENESS = 2.0;
49 constexpr Dimension OUT_RANGE_SPACE = 40.0_vp;
50 constexpr Dimension MIN_BUTTON_FONT_SIZE = 9.0_vp;
51 constexpr int32_t BUTTON_MAX_LINE = 2;
52 constexpr float AGE_FONT_MAX_SIZE_SCALE = 2.0f;
53 constexpr float AGE_SCALE_NUMBER = 1.0f;
54 constexpr float AGE_BUTTONS_LAYOUT_HEIGHT_RATE = 15.0f;
55
GetDisplayWindowRectOffset()56 OffsetF GetDisplayWindowRectOffset()
57 {
58 auto pipelineContext = PipelineContext::GetCurrentContext();
59 CHECK_NULL_RETURN(pipelineContext, OffsetF());
60 auto overlayManager = pipelineContext->GetOverlayManager();
61 CHECK_NULL_RETURN(overlayManager, OffsetF());
62 auto displayWindowOffset = OffsetF(pipelineContext->GetDisplayWindowRectInfo().GetOffset().GetX(),
63 pipelineContext->GetDisplayWindowRectInfo().GetOffset().GetY());
64 return displayWindowOffset;
65 }
66
GetPopupTheme()67 RefPtr<PopupTheme> GetPopupTheme()
68 {
69 auto pipeline = PipelineBase::GetCurrentContext();
70 CHECK_NULL_RETURN(pipeline, nullptr);
71 auto popupTheme = pipeline->GetTheme<PopupTheme>();
72 CHECK_NULL_RETURN(popupTheme, nullptr);
73 return popupTheme;
74 }
75
GetMaxWith()76 Dimension GetMaxWith()
77 {
78 auto gridColumnInfo = GridSystemManager::GetInstance().GetInfoByType(GridColumnType::BUBBLE_TYPE);
79 auto parent = gridColumnInfo->GetParent();
80 if (parent) {
81 parent->BuildColumnWidth();
82 }
83 auto maxWidth = Dimension(gridColumnInfo->GetMaxWidth());
84 return maxWidth;
85 }
86
GetAgeFontSize(const std::optional<Dimension> & originalFontSize)87 Dimension GetAgeFontSize(const std::optional<Dimension>& originalFontSize)
88 {
89 auto fontSize = Dimension(originalFontSize->Value(), originalFontSize->Unit());
90 auto pipeline = PipelineBase::GetCurrentContext();
91 CHECK_NULL_RETURN(pipeline, fontSize);
92 auto fontSizeScale = pipeline->GetFontScale();
93 auto fontScale = fontSizeScale > AGE_FONT_MAX_SIZE_SCALE ? AGE_FONT_MAX_SIZE_SCALE : fontSizeScale;
94 fontSize.SetValue((originalFontSize->Value()) * fontScale);
95 return fontSize;
96 }
97
UpdateTextProperties(const RefPtr<PopupParam> & param,const RefPtr<TextLayoutProperty> & textLayoutProps)98 void UpdateTextProperties(const RefPtr<PopupParam>& param, const RefPtr<TextLayoutProperty>& textLayoutProps)
99 {
100 auto textColor = param->GetTextColor();
101 if (textColor.has_value()) {
102 textLayoutProps->UpdateTextColor(textColor.value());
103 }
104 auto fontSize = param->GetFontSize();
105 if (fontSize.has_value()) {
106 if (!param->IsUseCustom()) {
107 textLayoutProps->UpdateMaxFontScale(AGE_FONT_MAX_SIZE_SCALE);
108 textLayoutProps->UpdateFontSize(fontSize.value());
109 } else {
110 textLayoutProps->UpdateFontSize(fontSize.value());
111 }
112 }
113 auto fontWeight = param->GetFontWeight();
114 if (fontWeight.has_value()) {
115 textLayoutProps->UpdateFontWeight(fontWeight.value());
116 }
117 auto fontStyle = param->GetFontStyle();
118 if (fontStyle.has_value()) {
119 textLayoutProps->UpdateItalicFontStyle(fontStyle.value());
120 }
121 }
122 } // namespace
123
SetHitTestMode(RefPtr<FrameNode> & popupNode,bool isBlockEvent)124 void SetHitTestMode(RefPtr<FrameNode>& popupNode, bool isBlockEvent)
125 {
126 auto hub = popupNode->GetEventHub<BubbleEventHub>();
127 if (hub) {
128 auto ges = hub->GetOrCreateGestureEventHub();
129 if (!isBlockEvent) {
130 ges->SetHitTestMode(HitTestMode::HTMTRANSPARENT_SELF);
131 } else {
132 ges->SetHitTestMode(HitTestMode::HTMDEFAULT);
133 }
134 }
135 }
136
CreateBubbleNode(const std::string & targetTag,int32_t targetId,const RefPtr<PopupParam> & param)137 RefPtr<FrameNode> BubbleView::CreateBubbleNode(
138 const std::string& targetTag, int32_t targetId, const RefPtr<PopupParam>& param)
139 {
140 auto popupId = ElementRegister::GetInstance()->MakeUniqueId();
141 ACE_LAYOUT_SCOPED_TRACE("Create[%s][self:%d]", V2::POPUP_ETS_TAG, popupId);
142 auto popupNode =
143 FrameNode::CreateFrameNode(V2::POPUP_ETS_TAG, popupId, AceType::MakeRefPtr<BubblePattern>(targetId, targetTag));
144 auto popupProp = AceType::DynamicCast<BubbleLayoutProperty>(popupNode->GetLayoutProperty());
145 auto popupPaintProp = popupNode->GetPaintProperty<BubbleRenderProperty>();
146 auto useCustom = param->IsUseCustom();
147
148 // onstateChange.
149 auto bubbleHub = popupNode->GetEventHub<BubbleEventHub>();
150 if (bubbleHub) {
151 bubbleHub->SetOnStateChange(param->GetOnStateChange());
152 }
153
154 auto message = param->GetMessage();
155 auto primaryButton = param->GetPrimaryButtonProperties();
156 auto secondaryButton = param->GetSecondaryButtonProperties();
157 // Update props
158 popupProp->UpdateUseCustom(useCustom);
159 popupProp->UpdateEnableArrow(param->EnableArrow());
160 popupProp->UpdatePlacement(param->GetPlacement());
161 popupProp->UpdateShowInSubWindow(param->IsShowInSubWindow());
162 popupProp->UpdatePositionOffset(OffsetF(param->GetTargetOffset().GetX(), param->GetTargetOffset().GetY()));
163 popupProp->UpdateBlockEvent(param->IsBlockEvent());
164 popupProp->UpdateIsCaretMode(param->IsCaretMode());
165 if (param->GetArrowHeight().has_value()) {
166 popupProp->UpdateArrowHeight(param->GetArrowHeight().value());
167 }
168 if (param->GetArrowWidth().has_value()) {
169 popupProp->UpdateArrowWidth(param->GetArrowWidth().value());
170 }
171 if (param->GetRadius().has_value()) {
172 popupProp->UpdateRadius(param->GetRadius().value());
173 }
174 popupProp->UpdateFollowTransformOfTarget(param->IsFollowTransformOfTarget());
175 SetHitTestMode(popupNode, param->IsBlockEvent());
176 if (param->GetTargetSpace().has_value()) {
177 popupProp->UpdateTargetSpace(param->GetTargetSpace().value());
178 }
179 auto displayWindowOffset = GetDisplayWindowRectOffset();
180 popupProp->UpdateDisplayWindowOffset(displayWindowOffset);
181 popupPaintProp->UpdateEnableArrow(param->EnableArrow());
182 if (param->GetArrowOffset().has_value()) {
183 popupPaintProp->UpdateArrowOffset(param->GetArrowOffset().value());
184 }
185 if (param->IsMaskColorSetted()) {
186 popupPaintProp->UpdateMaskColor(param->GetMaskColor());
187 }
188 if (param->IsBackgroundColorSetted()) {
189 popupPaintProp->UpdateBackgroundColor(param->GetBackgroundColor());
190 }
191 popupPaintProp->UpdateAutoCancel(!param->HasAction());
192 popupPaintProp->UpdatePlacement(param->GetPlacement());
193 if (param->GetHasTransition()) {
194 popupNode->GetRenderContext()->UpdateChainedTransition(param->GetTransitionEffects());
195 }
196
197 auto bubbleAccessibilityProperty = popupNode->GetAccessibilityProperty<AccessibilityProperty>();
198 CHECK_NULL_RETURN(bubbleAccessibilityProperty, nullptr);
199 bubbleAccessibilityProperty->SetText(message);
200 auto bubblePattern = popupNode->GetPattern<BubblePattern>();
201 auto textColor = param->GetTextColor();
202 bubblePattern->SetMessageColor(textColor.has_value());
203 bubblePattern->SetHasTransition(param->GetHasTransition());
204 // Create child
205 RefPtr<FrameNode> child;
206 if (primaryButton.showButton || secondaryButton.showButton) {
207 auto columnNode = FrameNode::CreateFrameNode(V2::COLUMN_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
208 AceType::MakeRefPtr<LinearLayoutPattern>(true));
209 auto columnLayoutProperty = columnNode->GetLayoutProperty<LinearLayoutProperty>();
210 columnLayoutProperty->UpdateMainAxisAlign(FlexAlign::CENTER); // mainAxisAlign
211 columnLayoutProperty->UpdateCrossAxisAlign(FlexAlign::CENTER);
212 auto combinedChild = CreateCombinedChild(param, popupId, targetId, popupNode);
213 popupPaintProp->UpdatePrimaryButtonShow(primaryButton.showButton);
214 popupPaintProp->UpdateSecondaryButtonShow(secondaryButton.showButton);
215 if ((Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN))) {
216 popupPaintProp->UpdateAutoCancel(false);
217 }
218 combinedChild->MountToParent(columnNode);
219 child = columnNode;
220 } else {
221 auto columnNode = FrameNode::CreateFrameNode(V2::COLUMN_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
222 AceType::MakeRefPtr<LinearLayoutPattern>(true));
223 auto columnLayoutProperty = columnNode->GetLayoutProperty<LinearLayoutProperty>();
224 columnLayoutProperty->UpdateMainAxisAlign(FlexAlign::CENTER); // mainAxisAlign
225 columnLayoutProperty->UpdateCrossAxisAlign(FlexAlign::CENTER);
226 auto textNode = CreateMessage(message, useCustom);
227 bubblePattern->SetMessageNode(textNode);
228 auto popupTheme = GetPopupTheme();
229 auto padding = popupTheme->GetPadding();
230 auto layoutProps = textNode->GetLayoutProperty<TextLayoutProperty>();
231 PaddingProperty textPadding;
232 textPadding.left = CalcLength(padding.Left());
233 textPadding.right = CalcLength(padding.Right());
234 textPadding.top = CalcLength(padding.Top());
235 textPadding.bottom = CalcLength(padding.Bottom());
236 layoutProps->UpdatePadding(textPadding);
237 layoutProps->UpdateAlignment(Alignment::CENTER);
238 UpdateTextProperties(param, layoutProps);
239 auto buttonMiniMumHeight = popupTheme->GetBubbleMiniMumHeight().ConvertToPx();
240 layoutProps->UpdateCalcMinSize(CalcSize(std::nullopt, CalcLength(buttonMiniMumHeight)));
241 textNode->MarkModifyDone();
242 if ((Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN))) {
243 textNode->MountToParent(columnNode);
244 } else {
245 auto scrollNode = FrameNode::CreateFrameNode(V2::SCROLL_ETS_TAG,
246 ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<ScrollPattern>());
247 CHECK_NULL_RETURN(scrollNode, nullptr);
248 auto scrollProps = scrollNode->GetLayoutProperty<ScrollLayoutProperty>();
249 scrollProps->UpdateAxis(Axis::VERTICAL);
250 scrollProps->UpdateAlignment(Alignment::CENTER_LEFT);
251 scrollNode->MarkModifyDone();
252 textNode->MountToParent(scrollNode);
253 scrollNode->MountToParent(columnNode);
254 }
255 child = columnNode;
256 }
257 // GridSystemManager is not completed, need to check later.
258 auto childLayoutProperty = child->GetLayoutProperty();
259 CHECK_NULL_RETURN(childLayoutProperty, nullptr);
260 float popupMaxWidth = 0.0f;
261 float popupMaxHeight = 0.0f;
262 GetPopupMaxWidthAndHeight(param, popupMaxWidth, popupMaxHeight);
263 if (GreatNotEqual(popupMaxWidth, 0.0f) && GreatNotEqual(popupMaxHeight, 0.0f)) {
264 childLayoutProperty->UpdateCalcMaxSize(
265 CalcSize(NG::CalcLength(Dimension(popupMaxWidth)), NG::CalcLength(Dimension(popupMaxHeight))));
266 }
267 if (param->GetChildWidth().has_value()) {
268 childLayoutProperty->UpdateUserDefinedIdealSize(
269 CalcSize(CalcLength(param->GetChildWidth().value()), std::nullopt));
270 }
271 auto renderContext = child->GetRenderContext();
272 if (renderContext) {
273 if ((Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN))) {
274 renderContext->UpdateBackgroundColor(
275 popupPaintProp->GetBackgroundColor().value_or(GetPopupTheme()->GetBackgroundColor()));
276 } else {
277 auto backgroundColor = popupPaintProp->GetBackgroundColor().value_or(Color::TRANSPARENT);
278 renderContext->UpdateBackgroundColor(backgroundColor);
279 BlurStyleOption styleOption;
280 styleOption.blurStyle = param->GetBlurStyle();
281 renderContext->UpdateBackBlurStyle(styleOption);
282 }
283 if (param->GetShadow().has_value()) {
284 renderContext->UpdateBackShadow(param->GetShadow().value());
285 }
286 }
287 child->MountToParent(popupNode);
288 return popupNode;
289 }
CreateCustomBubbleNode(const std::string & targetTag,int32_t targetId,const RefPtr<UINode> & customNode,const RefPtr<PopupParam> & param)290 RefPtr<FrameNode> BubbleView::CreateCustomBubbleNode(
291 const std::string& targetTag, int32_t targetId, const RefPtr<UINode>& customNode, const RefPtr<PopupParam>& param)
292 {
293 auto popupId = ElementRegister::GetInstance()->MakeUniqueId();
294 auto popupNode =
295 FrameNode::CreateFrameNode(V2::POPUP_ETS_TAG, popupId, AceType::MakeRefPtr<BubblePattern>(targetId, targetTag));
296 auto bubbleHub = popupNode->GetEventHub<BubbleEventHub>();
297 if (bubbleHub) {
298 bubbleHub->SetOnStateChange(param->GetOnStateChange());
299 }
300 auto popupPattern = popupNode->GetPattern<BubblePattern>();
301 popupPattern->SetCustomPopupTag(true);
302 // update bubble props
303 auto layoutProps = popupNode->GetLayoutProperty<BubbleLayoutProperty>();
304 layoutProps->UpdateUseCustom(param->IsUseCustom());
305 layoutProps->UpdateEnableArrow(param->EnableArrow());
306 layoutProps->UpdatePlacement(param->GetPlacement());
307 layoutProps->UpdateShowInSubWindow(param->IsShowInSubWindow());
308 layoutProps->UpdateBlockEvent(param->IsBlockEvent());
309 if (param->GetArrowHeight().has_value()) {
310 layoutProps->UpdateArrowHeight(param->GetArrowHeight().value());
311 }
312 if (param->GetArrowWidth().has_value()) {
313 layoutProps->UpdateArrowWidth(param->GetArrowWidth().value());
314 }
315 if (param->GetRadius().has_value()) {
316 layoutProps->UpdateRadius(param->GetRadius().value());
317 }
318 layoutProps->UpdateFollowTransformOfTarget(param->IsFollowTransformOfTarget());
319 SetHitTestMode(popupNode, param->IsBlockEvent());
320 auto displayWindowOffset = GetDisplayWindowRectOffset();
321 layoutProps->UpdateDisplayWindowOffset(displayWindowOffset);
322 layoutProps->UpdatePositionOffset(OffsetF(param->GetTargetOffset().GetX(), param->GetTargetOffset().GetY()));
323 if (param->GetTargetSpace().has_value()) {
324 layoutProps->UpdateTargetSpace(param->GetTargetSpace().value());
325 }
326 auto popupPaintProps = popupNode->GetPaintProperty<BubbleRenderProperty>();
327 popupPaintProps->UpdateUseCustom(param->IsUseCustom());
328 popupPaintProps->UpdateEnableArrow(param->EnableArrow());
329 if (param->GetArrowOffset().has_value()) {
330 popupPaintProps->UpdateArrowOffset(param->GetArrowOffset().value());
331 }
332 if (param->IsMaskColorSetted()) {
333 popupPaintProps->UpdateMaskColor(param->GetMaskColor());
334 }
335 if (param->IsBackgroundColorSetted()) {
336 popupPaintProps->UpdateBackgroundColor(param->GetBackgroundColor());
337 }
338 if (param->GetHasTransition()) {
339 popupNode->GetRenderContext()->UpdateChainedTransition(param->GetTransitionEffects());
340 }
341 popupPattern->SetHasTransition(param->GetHasTransition());
342
343 auto columnNode = FrameNode::CreateFrameNode(V2::COLUMN_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
344 AceType::MakeRefPtr<LinearLayoutPattern>(false));
345 auto columnNodeClip = FrameNode::CreateFrameNode(V2::COLUMN_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
346 AceType::MakeRefPtr<LinearLayoutPattern>(false));
347 auto clipContext = columnNodeClip->GetRenderContext();
348 clipContext->SetClipToBounds(true);
349 customNode->MountToParent(columnNodeClip);
350 columnNodeClip->MountToParent(columnNode);
351 auto columnRenderContext = columnNode->GetRenderContext();
352 auto columnLayoutProperty = columnNode->GetLayoutProperty<LinearLayoutProperty>();
353 CHECK_NULL_RETURN(columnLayoutProperty, nullptr);
354 columnLayoutProperty->UpdateMainAxisAlign(FlexAlign::CENTER); // mainAxisAlign
355 columnLayoutProperty->UpdateCrossAxisAlign(FlexAlign::CENTER);
356 auto customFrameNode = AceType::DynamicCast<FrameNode>(customNode);
357 float popupMaxWidth = 0.0f;
358 float popupMaxHeight = 0.0f;
359 GetPopupMaxWidthAndHeight(param, popupMaxWidth, popupMaxHeight);
360 columnLayoutProperty->UpdateCalcMaxSize(CalcSize(std::nullopt, NG::CalcLength(Dimension(popupMaxHeight))));
361 if (param->GetChildWidth().has_value()) {
362 columnLayoutProperty->UpdateUserDefinedIdealSize(
363 CalcSize(CalcLength(param->GetChildWidth().value()), std::nullopt));
364 }
365 if (columnRenderContext) {
366 if ((Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN))) {
367 columnRenderContext->UpdateBackgroundColor(
368 popupPaintProps->GetBackgroundColor().value_or(GetPopupTheme()->GetBackgroundColor()));
369 } else {
370 auto backgroundColor = popupPaintProps->GetBackgroundColor().value_or(Color::TRANSPARENT);
371 columnRenderContext->UpdateBackgroundColor(backgroundColor);
372 BlurStyleOption styleOption;
373 styleOption.blurStyle = param->GetBlurStyle();
374 columnRenderContext->UpdateBackBlurStyle(styleOption);
375 }
376 if (param->GetShadow().has_value()) {
377 columnRenderContext->UpdateBackShadow(param->GetShadow().value());
378 }
379 }
380 popupPaintProps->UpdateAutoCancel(!param->HasAction());
381 popupPaintProps->UpdatePlacement(param->GetPlacement());
382 columnNode->MountToParent(popupNode);
383 return popupNode;
384 }
385
UpdateBubbleButtons(std::list<RefPtr<UINode>> & buttons,const RefPtr<PopupParam> & param)386 void BubbleView::UpdateBubbleButtons(std::list<RefPtr<UINode>>& buttons, const RefPtr<PopupParam>& param)
387 {
388 auto primaryButton = param->GetPrimaryButtonProperties();
389 auto secondaryButton = param->GetSecondaryButtonProperties();
390 if (primaryButton.showButton) {
391 auto button = AceType::DynamicCast<FrameNode>(buttons.front());
392 buttons.pop_front();
393 auto textNode = AceType::DynamicCast<FrameNode>(button->GetFirstChild());
394 auto layoutProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
395 layoutProperty->UpdateContent(primaryButton.value);
396 textNode->MarkModifyDone();
397 auto buttonEventHub = button->GetOrCreateGestureEventHub();
398 if (primaryButton.action) {
399 buttonEventHub->AddClickEvent(primaryButton.action);
400 }
401 }
402 if (secondaryButton.showButton) {
403 auto button = AceType::DynamicCast<FrameNode>(buttons.front());
404 buttons.pop_front();
405 auto textNode = AceType::DynamicCast<FrameNode>(button->GetFirstChild());
406 auto layoutProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
407 layoutProperty->UpdateContent(secondaryButton.value);
408 textNode->MarkModifyDone();
409 auto buttonEventHub = button->GetOrCreateGestureEventHub();
410 if (secondaryButton.action) {
411 buttonEventHub->AddClickEvent(secondaryButton.action);
412 }
413 }
414 }
415
UpdateBubbleContent(int32_t popupId,const RefPtr<PopupParam> & param)416 void BubbleView::UpdateBubbleContent(int32_t popupId, const RefPtr<PopupParam>& param)
417 {
418 auto popupNode = FrameNode::GetFrameNode(V2::POPUP_ETS_TAG, popupId);
419 CHECK_NULL_VOID(popupNode);
420 auto message = param->GetMessage();
421 auto primaryButton = param->GetPrimaryButtonProperties();
422 auto secondaryButton = param->GetSecondaryButtonProperties();
423 auto columnNode = popupNode->GetFirstChild();
424 if (primaryButton.showButton || secondaryButton.showButton) {
425 CHECK_NULL_VOID(columnNode);
426 auto combinedChild = columnNode->GetFirstChild();
427 CHECK_NULL_VOID(combinedChild);
428 const auto& children = combinedChild->GetChildren();
429 for (const auto& child: children) {
430 if (child->GetTag() == V2::TEXT_ETS_TAG) { // API10
431 auto textNode = AceType::DynamicCast<FrameNode>(child);
432 auto layoutProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
433 layoutProperty->UpdateContent(message);
434 UpdateTextProperties(param, layoutProperty);
435 textNode->MarkModifyDone();
436 } else if (child->GetTag() == V2::SCROLL_ETS_TAG) {
437 auto textNode = AceType::DynamicCast<FrameNode>(child->GetFirstChild());
438 auto layoutProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
439 layoutProperty->UpdateContent(message);
440 UpdateTextProperties(param, layoutProperty);
441 textNode->MarkModifyDone();
442 } else {
443 auto buttons = child->GetChildren();
444 UpdateBubbleButtons(buttons, param);
445 }
446 }
447 } else {
448 CHECK_NULL_VOID(columnNode);
449 auto childNode = columnNode->GetFirstChild();
450 if (!(Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN))) {
451 childNode = childNode->GetFirstChild();
452 }
453 auto textNode = AceType::DynamicCast<FrameNode>(childNode);
454 CHECK_NULL_VOID(textNode);
455 auto layoutProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
456 layoutProperty->UpdateContent(message);
457 UpdateTextProperties(param, layoutProperty);
458 textNode->MarkModifyDone();
459 }
460 }
461
UpdatePopupParam(int32_t popupId,const RefPtr<PopupParam> & param,const RefPtr<FrameNode> & targetNode)462 void BubbleView::UpdatePopupParam(int32_t popupId, const RefPtr<PopupParam>& param, const RefPtr<FrameNode>& targetNode)
463 {
464 UpdateCommonParam(popupId, param, false);
465 UpdateBubbleContent(popupId, param);
466 auto popupNode = FrameNode::GetFrameNode(V2::POPUP_ETS_TAG, popupId);
467 CHECK_NULL_VOID(popupNode);
468 auto popupProp = AceType::DynamicCast<BubbleLayoutProperty>(popupNode->GetLayoutProperty());
469 auto popupPaintProp = popupNode->GetPaintProperty<BubbleRenderProperty>();
470 auto message = param->GetMessage();
471 auto primaryButton = param->GetPrimaryButtonProperties();
472 auto secondaryButton = param->GetSecondaryButtonProperties();
473 if ((primaryButton.showButton || secondaryButton.showButton) &&
474 !(Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN))) {
475 auto pipelineContext = PipelineBase::GetCurrentContext();
476 CHECK_NULL_VOID(pipelineContext);
477 float popupMaxWidth = 0.0f;
478 float popupMaxHeight = 0.0f;
479 GetPopupMaxWidthAndHeight(param, popupMaxWidth, popupMaxHeight);
480 auto buttonTheme = pipelineContext->GetTheme<ButtonTheme>();
481 CHECK_NULL_VOID(buttonTheme);
482 auto childNode = AceType::DynamicCast<FrameNode>(popupNode->GetFirstChild());
483 CHECK_NULL_VOID(childNode);
484 const auto& children = childNode->GetChildren();
485 for (const auto& uinode : children) {
486 if (uinode->GetTag() == V2::SCROLL_ETS_TAG) {
487 auto scrollNode = AceType::DynamicCast<FrameNode>(uinode);
488 CHECK_NULL_VOID(scrollNode);
489 auto scrollProps = scrollNode->GetLayoutProperty<ScrollLayoutProperty>();
490 scrollProps->UpdateCalcMaxSize(CalcSize(
491 std::nullopt, CalcLength(Dimension(popupMaxHeight) - buttonTheme->GetHeight() * DOUBLENESS)));
492 }
493 }
494 }
495 // Update layout props
496 popupProp->UpdateUseCustom(param->IsUseCustom());
497 popupProp->UpdateEnableArrow(param->EnableArrow());
498 popupProp->UpdatePlacement(param->GetPlacement());
499 auto displayWindowOffset = GetDisplayWindowRectOffset();
500 popupProp->UpdateDisplayWindowOffset(displayWindowOffset);
501 // Update paint props
502 popupPaintProp->UpdatePlacement(param->GetPlacement());
503 popupPaintProp->UpdateUseCustom(param->IsUseCustom());
504 popupPaintProp->UpdateEnableArrow(param->EnableArrow());
505 }
506
UpdateCustomPopupParam(int32_t popupId,const RefPtr<PopupParam> & param)507 void BubbleView::UpdateCustomPopupParam(int32_t popupId, const RefPtr<PopupParam>& param)
508 {
509 UpdateCommonParam(popupId, param);
510 auto popupNode = FrameNode::GetFrameNode(V2::POPUP_ETS_TAG, popupId);
511 CHECK_NULL_VOID(popupNode);
512 auto popupLayoutProp = popupNode->GetLayoutProperty<BubbleLayoutProperty>();
513 CHECK_NULL_VOID(popupLayoutProp);
514 auto popupPaintProp = popupNode->GetPaintProperty<BubbleRenderProperty>();
515 CHECK_NULL_VOID(popupPaintProp);
516 popupLayoutProp->UpdatePlacement(param->GetPlacement());
517 popupPaintProp->UpdatePlacement(param->GetPlacement());
518 popupLayoutProp->UpdateEnableArrow(param->EnableArrow());
519 popupPaintProp->UpdateAutoCancel(!param->HasAction());
520 popupPaintProp->UpdateEnableArrow(param->EnableArrow());
521 }
522
GetPopupMaxWidthAndHeight(const RefPtr<PopupParam> & param,float & popupMaxWidth,float & popupMaxHeight)523 void BubbleView::GetPopupMaxWidthAndHeight(const RefPtr<PopupParam>& param, float& popupMaxWidth, float& popupMaxHeight)
524 {
525 auto pipelineContext = PipelineContext::GetCurrentContext();
526 CHECK_NULL_VOID(pipelineContext);
527 auto windowGlobalRect = pipelineContext->GetDisplayWindowRectInfo();
528 auto safeAreaManager = pipelineContext->GetSafeAreaManager();
529 CHECK_NULL_VOID(safeAreaManager);
530 auto bottom = safeAreaManager->GetSystemSafeArea().bottom_.Length();
531 auto top = safeAreaManager->GetSystemSafeArea().top_.Length();
532 auto maxHeight = windowGlobalRect.Height();
533 if (param->IsShowInSubWindow()) {
534 maxHeight = SystemProperties::GetDeviceHeight();
535 }
536 popupMaxHeight = maxHeight - OUT_RANGE_SPACE.ConvertToPx() - OUT_RANGE_SPACE.ConvertToPx() - bottom - top;
537 popupMaxWidth = GetMaxWith().Value();
538 }
539
UpdateCommonParam(int32_t popupId,const RefPtr<PopupParam> & param,bool custom)540 void BubbleView::UpdateCommonParam(int32_t popupId, const RefPtr<PopupParam>& param, bool custom)
541 {
542 auto popupNode = FrameNode::GetFrameNode(V2::POPUP_ETS_TAG, popupId);
543 CHECK_NULL_VOID(popupNode);
544 auto bubbleHub = popupNode->GetEventHub<BubbleEventHub>();
545 if (bubbleHub) {
546 bubbleHub->SetOnStateChange(param->GetOnStateChange());
547 }
548 auto popupLayoutProp = popupNode->GetLayoutProperty<BubbleLayoutProperty>();
549 CHECK_NULL_VOID(popupLayoutProp);
550 auto popupPaintProp = popupNode->GetPaintProperty<BubbleRenderProperty>();
551 CHECK_NULL_VOID(popupPaintProp);
552 if (param->GetArrowOffset().has_value()) {
553 popupPaintProp->UpdateArrowOffset(param->GetArrowOffset().value());
554 }
555 popupLayoutProp->UpdateShowInSubWindow(param->IsShowInSubWindow());
556 popupLayoutProp->UpdateBlockEvent(param->IsBlockEvent());
557 popupLayoutProp->UpdateIsCaretMode(param->IsCaretMode());
558 if (param->GetErrorArrowHeight()) {
559 popupLayoutProp->ResetArrowHeight();
560 }
561 if (param->GetErrorArrowWidth()) {
562 popupLayoutProp->ResetArrowWidth();
563 }
564 if (param->GetErrorRadius()) {
565 popupLayoutProp->ResetRadius();
566 }
567 if (param->GetArrowHeight().has_value()) {
568 popupLayoutProp->UpdateArrowHeight(param->GetArrowHeight().value());
569 }
570 if (param->GetArrowWidth().has_value()) {
571 popupLayoutProp->UpdateArrowWidth(param->GetArrowWidth().value());
572 }
573 if (param->GetRadius().has_value()) {
574 popupLayoutProp->UpdateRadius(param->GetRadius().value());
575 }
576 popupLayoutProp->UpdateFollowTransformOfTarget(param->IsFollowTransformOfTarget());
577 SetHitTestMode(popupNode, param->IsBlockEvent());
578 popupLayoutProp->UpdatePositionOffset(OffsetF(param->GetTargetOffset().GetX(), param->GetTargetOffset().GetY()));
579 if (param->IsMaskColorSetted()) {
580 popupPaintProp->UpdateMaskColor(param->GetMaskColor());
581 } else {
582 popupPaintProp->UpdateMaskColor(Color::TRANSPARENT);
583 }
584 if (param->GetTargetSpace().has_value()) {
585 popupLayoutProp->UpdateTargetSpace(param->GetTargetSpace().value());
586 }
587 if (param->IsBackgroundColorSetted()) {
588 popupPaintProp->UpdateBackgroundColor(param->GetBackgroundColor());
589 }
590 auto childNode = AceType::DynamicCast<FrameNode>(popupNode->GetFirstChild());
591 CHECK_NULL_VOID(childNode);
592 auto renderContext = childNode->GetRenderContext();
593 if (renderContext && param->GetShadow().has_value()) {
594 renderContext->UpdateBackShadow(param->GetShadow().value());
595 }
596 auto childLayoutProperty = childNode->GetLayoutProperty();
597 CHECK_NULL_VOID(childLayoutProperty);
598 float popupMaxWidth = 0.0f;
599 float popupMaxHeight = 0.0f;
600 GetPopupMaxWidthAndHeight(param, popupMaxWidth, popupMaxHeight);
601 if (custom) {
602 childLayoutProperty->UpdateCalcMaxSize(CalcSize(std::nullopt, NG::CalcLength(Dimension(popupMaxHeight))));
603 } else if (GreatNotEqual(popupMaxWidth, 0.0f) && GreatNotEqual(popupMaxHeight, 0.0f)) {
604 childLayoutProperty->UpdateCalcMaxSize(
605 CalcSize(NG::CalcLength(Dimension(popupMaxWidth)), NG::CalcLength(Dimension(popupMaxHeight))));
606 }
607 if (param->GetChildWidth().has_value()) {
608 childLayoutProperty->UpdateUserDefinedIdealSize(
609 CalcSize(CalcLength(param->GetChildWidth().value()), std::nullopt));
610 }
611 if (renderContext) {
612 if ((Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN))) {
613 renderContext->UpdateBackgroundColor(
614 popupPaintProp->GetBackgroundColor().value_or(GetPopupTheme()->GetBackgroundColor()));
615 } else {
616 auto backgroundColor = popupPaintProp->GetBackgroundColor().value_or(Color::TRANSPARENT);
617 renderContext->UpdateBackgroundColor(backgroundColor);
618 BlurStyleOption styleOption;
619 styleOption.blurStyle = param->GetBlurStyle();
620 renderContext->UpdateBackBlurStyle(styleOption);
621 }
622 }
623 RefPtr<BubblePattern> bubblePattern = popupNode->GetPattern<BubblePattern>();
624 bubblePattern->SetHasTransition(param->GetHasTransition());
625 if (param->GetHasTransition()) {
626 popupNode->GetRenderContext()->UpdateChainedTransition(param->GetTransitionEffects());
627 }
628 }
629
CreateMessage(const std::string & message,bool IsUseCustom)630 RefPtr<FrameNode> BubbleView::CreateMessage(const std::string& message, bool IsUseCustom)
631 {
632 auto textId = ElementRegister::GetInstance()->MakeUniqueId();
633 auto textNode = FrameNode::CreateFrameNode(V2::TEXT_ETS_TAG, textId, AceType::MakeRefPtr<TextPattern>());
634 // The buttons in popupNode can not get focus, if the textNode in the button is not focusable
635 textNode->GetOrCreateFocusHub()->SetFocusable(true);
636 auto layoutProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
637 layoutProperty->UpdateContent(message);
638 auto popupTheme = GetPopupTheme();
639 CHECK_NULL_RETURN(popupTheme, nullptr);
640 if (!IsUseCustom) {
641 layoutProperty->UpdateMaxFontScale(AGE_FONT_MAX_SIZE_SCALE);
642 layoutProperty->UpdateFontSize(popupTheme->GetFontSize());
643 } else {
644 layoutProperty->UpdateFontSize(popupTheme->GetFontSize());
645 }
646 if (IsUseCustom) {
647 layoutProperty->UpdateTextColor(Color::BLACK);
648 } else {
649 if ((Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN))) {
650 layoutProperty->UpdateTextColor(popupTheme->GetFontColor());
651 } else {
652 layoutProperty->UpdateTextColor(popupTheme->GetFontPrimaryColor());
653 }
654 }
655 textNode->MarkModifyDone();
656 return textNode;
657 }
658
CreateCombinedChild(const RefPtr<PopupParam> & param,int32_t popupId,int32_t targetId,const RefPtr<FrameNode> & bobbleNode)659 RefPtr<FrameNode> BubbleView::CreateCombinedChild(
660 const RefPtr<PopupParam>& param, int32_t popupId, int32_t targetId, const RefPtr<FrameNode>& bobbleNode)
661 {
662 auto columnNode = FrameNode::CreateFrameNode(V2::COLUMN_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
663 AceType::MakeRefPtr<LinearLayoutPattern>(true));
664 auto layoutProps = columnNode->GetLayoutProperty<LinearLayoutProperty>();
665 layoutProps->UpdateMainAxisAlign(FlexAlign::FLEX_START); // mainAxisAlign
666 layoutProps->UpdateCrossAxisAlign(FlexAlign::FLEX_START);
667 auto message = BubbleView::CreateMessage(param->GetMessage(), param->IsUseCustom());
668 auto bubblePattern = bobbleNode->GetPattern<BubblePattern>();
669 CHECK_NULL_RETURN(bubblePattern, nullptr);
670 bubblePattern->SetMessageNode(message);
671 auto popupTheme = GetPopupTheme();
672 CHECK_NULL_RETURN(popupTheme, nullptr);
673 auto padding = popupTheme->GetPadding();
674 auto textLayoutProps = message->GetLayoutProperty<TextLayoutProperty>();
675 PaddingProperty textPadding;
676 textPadding.left = CalcLength(padding.Left());
677 textPadding.right = CalcLength(padding.Right());
678 textPadding.top = CalcLength(padding.Top());
679 if (!param->IsUseCustom()) {
680 textPadding.left = CalcLength(popupTheme->GetAgingTextLeftPadding());
681 textPadding.right = CalcLength(popupTheme->GetAgingTextRightPadding());
682 }
683 textLayoutProps->UpdatePadding(textPadding);
684 textLayoutProps->UpdateAlignSelf(FlexAlign::FLEX_START);
685 UpdateTextProperties(param, textLayoutProps);
686 message->MarkModifyDone();
687 auto pipelineContext = PipelineBase::GetCurrentContext();
688 CHECK_NULL_RETURN(pipelineContext, nullptr);
689 float popupMaxWidth = 0.0f;
690 float popupMaxHeight = 0.0f;
691 if ((Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN))) {
692 message->MountToParent(columnNode);
693 } else {
694 GetPopupMaxWidthAndHeight(param, popupMaxWidth, popupMaxHeight);
695 auto buttonTheme = pipelineContext->GetTheme<ButtonTheme>();
696 CHECK_NULL_RETURN(buttonTheme, nullptr);
697 auto scrollNode = FrameNode::CreateFrameNode(
698 V2::SCROLL_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<ScrollPattern>());
699 CHECK_NULL_RETURN(scrollNode, nullptr);
700 auto scrollProps = scrollNode->GetLayoutProperty<ScrollLayoutProperty>();
701 scrollProps->UpdateAxis(Axis::VERTICAL);
702 scrollProps->UpdateAlignment(Alignment::CENTER_LEFT);
703 auto buttonFontSize = popupTheme->GetButtonFontSize();
704 auto fontScale = pipelineContext->GetFontScale();
705 if (fontScale == AGE_SCALE_NUMBER) {
706 scrollProps->UpdateCalcMaxSize(CalcSize(
707 std::nullopt, CalcLength(Dimension(popupMaxHeight) - GetAgeFontSize(buttonFontSize) *
708 AGE_BUTTONS_LAYOUT_HEIGHT_RATE * DOUBLENESS)));
709 } else {
710 scrollProps->UpdateCalcMaxSize(
711 CalcSize(std::nullopt, CalcLength(Dimension(popupMaxHeight) -
712 GetAgeFontSize(buttonFontSize) * AGE_BUTTONS_LAYOUT_HEIGHT_RATE)));
713 }
714 scrollNode->MarkModifyDone();
715 message->MountToParent(scrollNode);
716 scrollNode->MountToParent(columnNode);
717 }
718 auto buttonLayout = BubbleView::CreateButtons(param, popupId, targetId);
719 if ((Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN))) {
720 auto buttonRowLayoutProperty = buttonLayout->GetLayoutProperty<LinearLayoutProperty>();
721 buttonRowLayoutProperty->UpdateAlignSelf(FlexAlign::FLEX_END);
722 } else {
723 auto buttonFlexLayoutProperty = buttonLayout->GetLayoutProperty<FlexLayoutProperty>();
724 buttonFlexLayoutProperty->UpdateAlignSelf(FlexAlign::FLEX_END);
725 }
726 buttonLayout->MarkModifyDone();
727 auto childLayoutProperty = columnNode->GetLayoutProperty<LinearLayoutProperty>();
728 CHECK_NULL_RETURN(childLayoutProperty, nullptr);
729 if ((Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN))) {
730 popupMaxWidth = GetMaxWith().Value();
731 childLayoutProperty->UpdateCalcMaxSize(CalcSize(NG::CalcLength(popupMaxWidth), std::nullopt));
732 } else if (GreatNotEqual(popupMaxWidth, 0.0f) && GreatNotEqual(popupMaxHeight, 0.0f)) {
733 childLayoutProperty->UpdateCalcMaxSize(
734 CalcSize(NG::CalcLength(Dimension(popupMaxWidth)), NG::CalcLength(Dimension(popupMaxHeight))));
735 }
736 buttonLayout->MountToParent(columnNode);
737 columnNode->MarkModifyDone();
738 return columnNode;
739 }
740
CreateButtons(const RefPtr<PopupParam> & param,int32_t popupId,int32_t targetId)741 RefPtr<FrameNode> BubbleView::CreateButtons(const RefPtr<PopupParam>& param, int32_t popupId, int32_t targetId)
742 {
743 auto rowId = ElementRegister::GetInstance()->MakeUniqueId();
744 RefPtr<FrameNode> layoutNode;
745 if ((Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN))) {
746 layoutNode =
747 FrameNode::CreateFrameNode(V2::ROW_ETS_TAG, rowId, AceType::MakeRefPtr<LinearLayoutPattern>(false));
748 } else {
749 layoutNode = FrameNode::CreateFrameNode(V2::FLEX_ETS_TAG, rowId, AceType::MakeRefPtr<FlexLayoutPattern>(false));
750 layoutNode->GetPattern<FlexLayoutPattern>()->SetIsWrap(true);
751 }
752
753 auto primaryButtonProp = param->GetPrimaryButtonProperties();
754 auto primaryButton = BubbleView::CreateButton(primaryButtonProp, popupId, targetId, param);
755 if (primaryButton) {
756 primaryButton->MountToParent(layoutNode);
757 }
758 auto secondaryButtonProp = param->GetSecondaryButtonProperties();
759 auto secondaryButton = BubbleView::CreateButton(secondaryButtonProp, popupId, targetId, param);
760 if (secondaryButton) {
761 secondaryButton->MountToParent(layoutNode);
762 }
763 auto popupTheme = GetPopupTheme();
764 CHECK_NULL_RETURN(popupTheme, nullptr);
765 auto littlePadding = popupTheme->GetLittlePadding();
766 PaddingProperty rowPadding;
767 rowPadding.right = CalcLength(littlePadding);
768 rowPadding.bottom = CalcLength(littlePadding);
769 if ((Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN))) {
770 auto layoutProps = layoutNode->GetLayoutProperty<LinearLayoutProperty>();
771 layoutProps->UpdateSpace(GetPopupTheme()->GetButtonSpacing());
772 layoutProps->UpdatePadding(rowPadding);
773 } else {
774 auto layoutProps = layoutNode->GetLayoutProperty<FlexLayoutProperty>();
775 layoutProps->UpdatePadding(rowPadding);
776 }
777 layoutNode->MarkModifyDone();
778 return layoutNode;
779 }
780
UpdateButtonFontSize(RefPtr<TextLayoutProperty> & textLayoutProps)781 void UpdateButtonFontSize(RefPtr<TextLayoutProperty>& textLayoutProps)
782 {
783 auto popupTheme = GetPopupTheme();
784 CHECK_NULL_VOID(popupTheme);
785 auto pipeline = PipelineBase::GetCurrentContext();
786 auto fontSize = popupTheme->GetButtonFontSize();
787 auto fontSizeScale = pipeline->GetFontScale();
788 auto fontScale = fontSizeScale > AGE_FONT_MAX_SIZE_SCALE ? AGE_FONT_MAX_SIZE_SCALE : fontSizeScale;
789 if (fontScale == AGE_SCALE_NUMBER) {
790 textLayoutProps->UpdateAdaptMaxFontSize(popupTheme->GetButtonFontSize());
791 textLayoutProps->UpdateAdaptMinFontSize(MIN_BUTTON_FONT_SIZE);
792 } else {
793 textLayoutProps->UpdateMaxFontScale(AGE_FONT_MAX_SIZE_SCALE);
794 }
795 textLayoutProps->UpdateFontSize(fontSize);
796 }
797
CreateButton(ButtonProperties & buttonParam,int32_t popupId,int32_t targetId,const RefPtr<PopupParam> & param)798 RefPtr<FrameNode> BubbleView::CreateButton(
799 ButtonProperties& buttonParam, int32_t popupId, int32_t targetId, const RefPtr<PopupParam>& param)
800 {
801 if (!buttonParam.showButton) {
802 return nullptr;
803 }
804 auto pipelineContext = PipelineBase::GetCurrentContext();
805 CHECK_NULL_RETURN(pipelineContext, nullptr);
806 auto buttonTheme = pipelineContext->GetTheme<ButtonTheme>();
807 CHECK_NULL_RETURN(buttonTheme, nullptr);
808 auto popupTheme = GetPopupTheme();
809 auto focusColor = popupTheme->GetFocusColor();
810 auto buttonId = ElementRegister::GetInstance()->MakeUniqueId();
811 auto buttonPattern = AceType::MakeRefPtr<NG::ButtonPattern>();
812 CHECK_NULL_RETURN(buttonPattern, nullptr);
813 // set button focus color
814 buttonPattern->setComponentButtonType(ComponentButtonType::POPUP);
815 buttonPattern->SetFocusBorderColor(focusColor);
816 auto buttonNode = FrameNode::CreateFrameNode(V2::BUTTON_ETS_TAG, buttonId, buttonPattern);
817 CHECK_NULL_RETURN(buttonPattern, nullptr);
818
819 auto buttonProp = AceType::DynamicCast<ButtonLayoutProperty>(buttonNode->GetLayoutProperty());
820 auto isUseCustom = param->IsUseCustom();
821
822 auto buttonTextNode = BubbleView::CreateMessage(buttonParam.value, isUseCustom);
823 auto textLayoutProperty = buttonTextNode->GetLayoutProperty<TextLayoutProperty>();
824 UpdateButtonFontSize(textLayoutProperty);
825 textLayoutProperty->UpdateMaxLines(BUTTON_MAX_LINE);
826 textLayoutProperty->UpdateTextOverflow(TextOverflow::ELLIPSIS);
827 PaddingProperty buttonTextPadding;
828 buttonTextPadding.left = CalcLength(popupTheme->GetAgingButtonTextLeftPadding());
829 buttonTextPadding.right = CalcLength(popupTheme->GetAgingButtonTextRightPadding());
830 textLayoutProperty->UpdatePadding(buttonTextPadding);
831 if (!(Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN))) {
832 textLayoutProperty->UpdateTextColor(popupTheme->GetButtonFontColor());
833 }
834 auto buttonTextInsideMargin = popupTheme->GetButtonTextInsideMargin();
835 buttonTextNode->MountToParent(buttonNode);
836
837 PaddingProperty buttonPadding;
838 auto padding = buttonTheme->GetPadding();
839 buttonPadding.left = CalcLength(buttonTextInsideMargin);
840 buttonPadding.right = CalcLength(buttonTextInsideMargin);
841 if (!param->IsUseCustom()) {
842 buttonPadding.left = CalcLength(popupTheme->GetAgingButtonLeftPadding());
843 buttonPadding.right = CalcLength(popupTheme->GetAgingButtonRightPadding());
844 buttonProp->UpdatePadding(buttonPadding);
845 } else {
846 buttonProp->UpdatePadding(buttonPadding);
847 }
848 buttonProp->UpdateType(ButtonType::CAPSULE);
849 auto fontScale = pipelineContext->GetFontScale();
850 if (fontScale == AGE_SCALE_NUMBER) {
851 buttonProp->UpdateUserDefinedIdealSize(CalcSize(std::nullopt, CalcLength(buttonTheme->GetHeight())));
852 }
853 buttonProp->UpdateAlignment(Alignment::CENTER);
854 auto buttonMiniMumWidth = popupTheme->GetButtonMiniMumWidth().ConvertToPx();
855 buttonProp->UpdateCalcMinSize(CalcSize(CalcLength(buttonMiniMumWidth), std::nullopt));
856 auto renderContext = buttonNode->GetRenderContext();
857 if (renderContext) {
858 renderContext->UpdateBackgroundColor(Color::TRANSPARENT);
859 }
860
861 auto buttonEventHub = buttonNode->GetOrCreateGestureEventHub();
862 CHECK_NULL_RETURN(buttonEventHub, nullptr);
863 buttonEventHub->AddClickEvent(buttonParam.action);
864 auto popupNode = FrameNode::GetFrameNode(V2::POPUP_ETS_TAG, popupId);
865 auto closeCallback = [popupNode, targetId](GestureEvent& /* info */) {
866 auto container = Container::Current();
867 CHECK_NULL_VOID(container);
868 auto pipelineContext = container->GetPipelineContext();
869 CHECK_NULL_VOID(pipelineContext);
870 auto context = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
871 CHECK_NULL_VOID(context);
872 auto overlayManager = context->GetOverlayManager();
873 CHECK_NULL_VOID(overlayManager);
874 auto popupInfo = overlayManager->GetPopupInfo(targetId);
875 popupInfo.markNeedUpdate = true;
876 overlayManager->HidePopup(targetId, popupInfo);
877 };
878 if (buttonParam.action) {
879 buttonEventHub->AddClickEvent(buttonParam.action);
880 } else {
881 buttonEventHub->AddClickEvent(AceType::MakeRefPtr<ClickEvent>(closeCallback));
882 }
883
884 return buttonNode;
885 }
886 } // namespace OHOS::Ace::NG
887