• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 #include "core/components_ng/pattern/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/linear_layout/linear_layout_pattern.h"
35 #include "core/components_ng/pattern/linear_layout/linear_layout_property.h"
36 #include "core/components_ng/pattern/text/text_pattern.h"
37 #include "core/components_ng/property/calc_length.h"
38 #include "core/components_ng/render/paint_property.h"
39 #include "core/components_v2/inspector/inspector_constants.h"
40 #include "core/pipeline/base/element_register.h"
41 #include "core/pipeline/pipeline_base.h"
42 #include "core/pipeline_ng/pipeline_context.h"
43 
44 namespace OHOS::Ace::NG {
45 namespace {
GetDisplayWindowRectOffset()46 OffsetF GetDisplayWindowRectOffset()
47 {
48     auto pipelineContext = PipelineContext::GetCurrentContext();
49     CHECK_NULL_RETURN(pipelineContext, OffsetF());
50     auto overlayManager = pipelineContext->GetOverlayManager();
51     CHECK_NULL_RETURN(overlayManager, OffsetF());
52     auto displayWindowOffset = OffsetF(pipelineContext->GetDisplayWindowRectInfo().GetOffset().GetX(),
53         pipelineContext->GetDisplayWindowRectInfo().GetOffset().GetY());
54     return displayWindowOffset;
55 }
56 
GetPopupTheme()57 RefPtr<PopupTheme> GetPopupTheme()
58 {
59     auto pipeline = PipelineBase::GetCurrentContext();
60     CHECK_NULL_RETURN(pipeline, nullptr);
61     auto popupTheme = pipeline->GetTheme<PopupTheme>();
62     CHECK_NULL_RETURN(popupTheme, nullptr);
63     return popupTheme;
64 }
65 
GetMaxWith()66 Dimension GetMaxWith()
67 {
68     auto gridColumnInfo = GridSystemManager::GetInstance().GetInfoByType(GridColumnType::BUBBLE_TYPE);
69     auto parent = gridColumnInfo->GetParent();
70     if (parent) {
71         parent->BuildColumnWidth();
72     }
73     auto maxWidth = Dimension(gridColumnInfo->GetMaxWidth());
74     return maxWidth;
75 }
76 
UpdateTextProperties(const RefPtr<PopupParam> & param,const RefPtr<TextLayoutProperty> & textLayoutProps)77 void UpdateTextProperties(const RefPtr<PopupParam>& param, const RefPtr<TextLayoutProperty>& textLayoutProps)
78 {
79     auto textColor = param->GetTextColor();
80     if (textColor.has_value()) {
81         textLayoutProps->UpdateTextColor(textColor.value());
82     }
83     auto fontSize = param->GetFontSize();
84     if (fontSize.has_value()) {
85         textLayoutProps->UpdateFontSize(fontSize.value());
86     }
87     auto fontWeight = param->GetFontWeight();
88     if (fontWeight.has_value()) {
89         textLayoutProps->UpdateFontWeight(fontWeight.value());
90     }
91     auto fontStyle = param->GetFontStyle();
92     if (fontStyle.has_value()) {
93         textLayoutProps->UpdateItalicFontStyle(fontStyle.value());
94     }
95 }
96 } // namespace
97 
SetHitTestMode(RefPtr<FrameNode> & popupNode,bool isBlockEvent)98 void SetHitTestMode(RefPtr<FrameNode>& popupNode, bool isBlockEvent)
99 {
100     auto hub = popupNode->GetEventHub<BubbleEventHub>();
101     if (hub) {
102         auto ges = hub->GetOrCreateGestureEventHub();
103         if (!isBlockEvent) {
104             ges->SetHitTestMode(HitTestMode::HTMTRANSPARENT_SELF);
105         } else {
106             ges->SetHitTestMode(HitTestMode::HTMDEFAULT);
107         }
108     }
109 }
110 
CreateBubbleNode(const std::string & targetTag,int32_t targetId,const RefPtr<PopupParam> & param)111 RefPtr<FrameNode> BubbleView::CreateBubbleNode(
112     const std::string& targetTag, int32_t targetId, const RefPtr<PopupParam>& param)
113 {
114     auto popupId = ElementRegister::GetInstance()->MakeUniqueId();
115     auto popupNode =
116         FrameNode::CreateFrameNode(V2::POPUP_ETS_TAG, popupId, AceType::MakeRefPtr<BubblePattern>(targetId, targetTag));
117     auto popupProp = AceType::DynamicCast<BubbleLayoutProperty>(popupNode->GetLayoutProperty());
118     auto popupPaintProp = popupNode->GetPaintProperty<BubbleRenderProperty>();
119     auto useCustom = param->IsUseCustom();
120 
121     // onstateChange.
122     auto bubbleHub = popupNode->GetEventHub<BubbleEventHub>();
123     if (bubbleHub) {
124         bubbleHub->SetOnStateChange(param->GetOnStateChange());
125     }
126 
127     auto message = param->GetMessage();
128     auto primaryButton = param->GetPrimaryButtonProperties();
129     auto secondaryButton = param->GetSecondaryButtonProperties();
130     // Update props
131     popupProp->UpdateUseCustom(useCustom);
132     popupProp->UpdateEnableArrow(param->EnableArrow());
133     popupProp->UpdatePlacement(param->GetPlacement());
134     popupProp->UpdateShowInSubWindow(param->IsShowInSubWindow());
135     popupProp->UpdatePositionOffset(OffsetF(param->GetTargetOffset().GetX(), param->GetTargetOffset().GetY()));
136     popupProp->UpdateBlockEvent(param->IsBlockEvent());
137     SetHitTestMode(popupNode, param->IsBlockEvent());
138     if (param->GetTargetSpace().has_value()) {
139         popupProp->UpdateTargetSpace(param->GetTargetSpace().value());
140     }
141     auto displayWindowOffset = GetDisplayWindowRectOffset();
142     popupProp->UpdateDisplayWindowOffset(displayWindowOffset);
143     popupPaintProp->UpdateEnableArrow(param->EnableArrow());
144     if (param->GetArrowOffset().has_value()) {
145         popupPaintProp->UpdateArrowOffset(param->GetArrowOffset().value());
146     }
147     if (param->IsMaskColorSetted()) {
148         popupPaintProp->UpdateMaskColor(param->GetMaskColor());
149     }
150     if (param->IsBackgroundColorSetted()) {
151         popupPaintProp->UpdateBackgroundColor(param->GetBackgroundColor());
152     }
153     popupPaintProp->UpdateAutoCancel(!param->HasAction());
154     popupPaintProp->UpdatePlacement(param->GetPlacement());
155 
156     auto bubbleAccessibilityProperty = popupNode->GetAccessibilityProperty<AccessibilityProperty>();
157     CHECK_NULL_RETURN(bubbleAccessibilityProperty, nullptr);
158     bubbleAccessibilityProperty->SetText(message);
159     auto bobblePattern = popupNode->GetPattern<BubblePattern>();
160     // Create child
161     RefPtr<FrameNode> child;
162     if (primaryButton.showButton || secondaryButton.showButton) {
163         child = CreateCombinedChild(param, popupId, targetId, popupNode);
164         popupPaintProp->UpdatePrimaryButtonShow(primaryButton.showButton);
165         popupPaintProp->UpdateSecondaryButtonShow(secondaryButton.showButton);
166         popupPaintProp->UpdateAutoCancel(false);
167     } else {
168         auto textNode = CreateMessage(message, useCustom);
169         bobblePattern->SetMessageNode(textNode);
170         auto popupTheme = GetPopupTheme();
171         auto padding = popupTheme->GetPadding();
172         auto layoutProps = textNode->GetLayoutProperty<TextLayoutProperty>();
173         PaddingProperty textPadding;
174         textPadding.left = CalcLength(padding.Left());
175         textPadding.right = CalcLength(padding.Right());
176         textPadding.top = CalcLength(padding.Top());
177         textPadding.bottom = CalcLength(padding.Bottom());
178         layoutProps->UpdatePadding(textPadding);
179         layoutProps->UpdateAlignment(Alignment::CENTER);
180         UpdateTextProperties(param, layoutProps);
181         auto buttonMiniMumHeight = popupTheme->GetBubbleMiniMumHeight().ConvertToPx();
182         layoutProps->UpdateCalcMinSize(CalcSize(std::nullopt, CalcLength(buttonMiniMumHeight)));
183         textNode->MarkModifyDone();
184         child = textNode;
185     }
186     // TODO: GridSystemManager is not completed, need to check later.
187     auto maxWidth = GetMaxWith();
188     auto childLayoutProperty = child->GetLayoutProperty();
189     CHECK_NULL_RETURN(childLayoutProperty, nullptr);
190     childLayoutProperty->UpdateCalcMaxSize(CalcSize(NG::CalcLength(maxWidth), std::nullopt));
191     child->MountToParent(popupNode);
192     return popupNode;
193 }
CreateCustomBubbleNode(const std::string & targetTag,int32_t targetId,const RefPtr<UINode> & customNode,const RefPtr<PopupParam> & param)194 RefPtr<FrameNode> BubbleView::CreateCustomBubbleNode(
195     const std::string& targetTag, int32_t targetId, const RefPtr<UINode>& customNode, const RefPtr<PopupParam>& param)
196 {
197     auto popupId = ElementRegister::GetInstance()->MakeUniqueId();
198     auto popupNode =
199         FrameNode::CreateFrameNode(V2::POPUP_ETS_TAG, popupId, AceType::MakeRefPtr<BubblePattern>(targetId, targetTag));
200     auto bubbleHub = popupNode->GetEventHub<BubbleEventHub>();
201     if (bubbleHub) {
202         bubbleHub->SetOnStateChange(param->GetOnStateChange());
203     }
204     auto popupPattern = popupNode->GetPattern<BubblePattern>();
205     popupPattern->SetCustomPopupTag(true);
206     // update bubble props
207     auto layoutProps = popupNode->GetLayoutProperty<BubbleLayoutProperty>();
208     layoutProps->UpdateUseCustom(param->IsUseCustom());
209     layoutProps->UpdateEnableArrow(param->EnableArrow());
210     layoutProps->UpdatePlacement(param->GetPlacement());
211     layoutProps->UpdateShowInSubWindow(param->IsShowInSubWindow());
212     layoutProps->UpdateBlockEvent(param->IsBlockEvent());
213     SetHitTestMode(popupNode, param->IsBlockEvent());
214     auto displayWindowOffset = GetDisplayWindowRectOffset();
215     layoutProps->UpdateDisplayWindowOffset(displayWindowOffset);
216     layoutProps->UpdatePositionOffset(OffsetF(param->GetTargetOffset().GetX(), param->GetTargetOffset().GetY()));
217     if (param->GetTargetSpace().has_value()) {
218         layoutProps->UpdateTargetSpace(param->GetTargetSpace().value());
219     }
220     auto popupPaintProps = popupNode->GetPaintProperty<BubbleRenderProperty>();
221     popupPaintProps->UpdateUseCustom(param->IsUseCustom());
222     popupPaintProps->UpdateEnableArrow(param->EnableArrow());
223     if (param->GetArrowOffset().has_value()) {
224         popupPaintProps->UpdateArrowOffset(param->GetArrowOffset().value());
225     }
226     if (param->IsMaskColorSetted()) {
227         popupPaintProps->UpdateMaskColor(param->GetMaskColor());
228     }
229     if (param->IsBackgroundColorSetted()) {
230         popupPaintProps->UpdateBackgroundColor(param->GetBackgroundColor());
231     }
232 
233     auto columnNode = FrameNode::CreateFrameNode(V2::COLUMN_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
234         AceType::MakeRefPtr<LinearLayoutPattern>(true));
235     customNode->MountToParent(columnNode);
236     auto renderContext = columnNode->GetRenderContext();
237     if (renderContext) {
238         renderContext->UpdateBackgroundColor(Color::TRANSPARENT);
239     }
240     popupPaintProps->UpdateAutoCancel(!param->HasAction());
241     popupPaintProps->UpdatePlacement(param->GetPlacement());
242     columnNode->MountToParent(popupNode);
243     return popupNode;
244 }
245 
UpdatePopupParam(int32_t popupId,const RefPtr<PopupParam> & param,const RefPtr<FrameNode> & targetNode)246 void BubbleView::UpdatePopupParam(int32_t popupId, const RefPtr<PopupParam>& param, const RefPtr<FrameNode>& targetNode)
247 {
248     UpdateCommonParam(popupId, param);
249     auto popupNode = FrameNode::GetFrameNode(V2::POPUP_ETS_TAG, popupId);
250     CHECK_NULL_VOID(popupNode);
251     auto popupProp = AceType::DynamicCast<BubbleLayoutProperty>(popupNode->GetLayoutProperty());
252     auto popupPaintProp = popupNode->GetPaintProperty<BubbleRenderProperty>();
253     auto message = param->GetMessage();
254     auto primaryButton = param->GetPrimaryButtonProperties();
255     auto secondaryButton = param->GetSecondaryButtonProperties();
256     // Update layout props
257     popupProp->UpdateUseCustom(param->IsUseCustom());
258     popupProp->UpdateEnableArrow(param->EnableArrow());
259     popupProp->UpdatePlacement(param->GetPlacement());
260     auto displayWindowOffset = GetDisplayWindowRectOffset();
261     popupProp->UpdateDisplayWindowOffset(displayWindowOffset);
262     // Update paint props
263     popupPaintProp->UpdatePlacement(param->GetPlacement());
264     popupPaintProp->UpdateUseCustom(param->IsUseCustom());
265     popupPaintProp->UpdateEnableArrow(param->EnableArrow());
266 }
267 
UpdateCustomPopupParam(int32_t popupId,const RefPtr<PopupParam> & param)268 void BubbleView::UpdateCustomPopupParam(int32_t popupId, const RefPtr<PopupParam>& param)
269 {
270     UpdateCommonParam(popupId, param);
271     auto popupNode = FrameNode::GetFrameNode(V2::POPUP_ETS_TAG, popupId);
272     CHECK_NULL_VOID(popupNode);
273     auto popupLayoutProp = popupNode->GetLayoutProperty<BubbleLayoutProperty>();
274     CHECK_NULL_VOID(popupLayoutProp);
275     auto popupPaintProp = popupNode->GetPaintProperty<BubbleRenderProperty>();
276     CHECK_NULL_VOID(popupPaintProp);
277     popupLayoutProp->UpdatePlacement(param->GetPlacement());
278     popupPaintProp->UpdatePlacement(param->GetPlacement());
279     if (param->IsBackgroundColorSetted()) {
280         popupPaintProp->UpdateBackgroundColor(param->GetBackgroundColor());
281     }
282     popupLayoutProp->UpdateEnableArrow(param->EnableArrow());
283     popupPaintProp->UpdateAutoCancel(!param->HasAction());
284 }
285 
UpdateCommonParam(int32_t popupId,const RefPtr<PopupParam> & param)286 void BubbleView::UpdateCommonParam(int32_t popupId, const RefPtr<PopupParam>& param)
287 {
288     auto popupNode = FrameNode::GetFrameNode(V2::POPUP_ETS_TAG, popupId);
289     CHECK_NULL_VOID(popupNode);
290     auto bubbleHub = popupNode->GetEventHub<BubbleEventHub>();
291     if (bubbleHub) {
292         bubbleHub->SetOnStateChange(param->GetOnStateChange());
293     }
294     auto popupLayoutProp = popupNode->GetLayoutProperty<BubbleLayoutProperty>();
295     CHECK_NULL_VOID(popupLayoutProp);
296     auto popupPaintProp = popupNode->GetPaintProperty<BubbleRenderProperty>();
297     CHECK_NULL_VOID(popupPaintProp);
298     if (param->GetArrowOffset().has_value()) {
299         popupPaintProp->UpdateArrowOffset(param->GetArrowOffset().value());
300     }
301     popupLayoutProp->UpdateShowInSubWindow(param->IsShowInSubWindow());
302     popupLayoutProp->UpdateBlockEvent(param->IsBlockEvent());
303     SetHitTestMode(popupNode, param->IsBlockEvent());
304     popupLayoutProp->UpdatePositionOffset(OffsetF(param->GetTargetOffset().GetX(), param->GetTargetOffset().GetY()));
305     if (param->IsMaskColorSetted()) {
306         popupPaintProp->UpdateMaskColor(param->GetMaskColor());
307     }
308     if (param->GetTargetSpace().has_value()) {
309         popupLayoutProp->UpdateTargetSpace(param->GetTargetSpace().value());
310     }
311 }
312 
CreateMessage(const std::string & message,bool IsUseCustom)313 RefPtr<FrameNode> BubbleView::CreateMessage(const std::string& message, bool IsUseCustom)
314 {
315     auto textId = ElementRegister::GetInstance()->MakeUniqueId();
316     auto textNode = FrameNode::CreateFrameNode(V2::TEXT_ETS_TAG, textId, AceType::MakeRefPtr<TextPattern>());
317     // The buttons in popupNode can not get focus, if the textNode in the button is not focusable
318     textNode->GetOrCreateFocusHub()->SetFocusable(true);
319     auto layoutProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
320     layoutProperty->UpdateContent(message);
321     auto popupTheme = GetPopupTheme();
322     layoutProperty->UpdateFontSize(popupTheme->GetFontSize());
323     if (IsUseCustom) {
324         layoutProperty->UpdateTextColor(Color::BLACK);
325     } else {
326         layoutProperty->UpdateTextColor(popupTheme->GetFontColor());
327     }
328     textNode->MarkModifyDone();
329     return textNode;
330 }
331 
CreateCombinedChild(const RefPtr<PopupParam> & param,int32_t popupId,int32_t targetId,const RefPtr<FrameNode> & bobbleNode)332 RefPtr<FrameNode> BubbleView::CreateCombinedChild(
333     const RefPtr<PopupParam>& param, int32_t popupId, int32_t targetId, const RefPtr<FrameNode>& bobbleNode)
334 {
335     auto columnNode = FrameNode::CreateFrameNode(V2::COLUMN_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
336         AceType::MakeRefPtr<LinearLayoutPattern>(true));
337     auto layoutProps = columnNode->GetLayoutProperty<LinearLayoutProperty>();
338     layoutProps->UpdateMainAxisAlign(FlexAlign::FLEX_START); // mainAxisAlign
339     auto message = BubbleView::CreateMessage(param->GetMessage(), param->IsUseCustom());
340     auto bubblePattern = bobbleNode->GetPattern<BubblePattern>();
341     CHECK_NULL_RETURN(bubblePattern, nullptr);
342     bubblePattern->SetMessageNode(message);
343     auto popupTheme = GetPopupTheme();
344     auto padding = popupTheme->GetPadding();
345     auto textLayoutProps = message->GetLayoutProperty<TextLayoutProperty>();
346     PaddingProperty textPadding;
347     textPadding.left = CalcLength(padding.Left());
348     textPadding.right = CalcLength(padding.Right());
349     textPadding.top = CalcLength(padding.Top());
350     textLayoutProps->UpdatePadding(textPadding);
351     textLayoutProps->UpdateAlignSelf(FlexAlign::FLEX_START);
352     UpdateTextProperties(param, textLayoutProps);
353     message->MarkModifyDone();
354     message->MountToParent(columnNode);
355 
356     auto buttonRow = BubbleView::CreateButtons(param, popupId, targetId);
357     auto buttonRowLayoutProperty = buttonRow->GetLayoutProperty<LinearLayoutProperty>();
358     buttonRowLayoutProperty->UpdateAlignSelf(FlexAlign::FLEX_END);
359     buttonRow->MarkModifyDone();
360     auto maxWidth = GetMaxWith();
361     auto childLayoutProperty = columnNode->GetLayoutProperty<LinearLayoutProperty>();
362     CHECK_NULL_RETURN(childLayoutProperty, nullptr);
363     childLayoutProperty->UpdateCalcMaxSize(CalcSize(NG::CalcLength(maxWidth), std::nullopt));
364     buttonRow->MountToParent(columnNode);
365 
366     columnNode->MarkModifyDone();
367     return columnNode;
368 }
369 
CreateButtons(const RefPtr<PopupParam> & param,int32_t popupId,int32_t targetId)370 RefPtr<FrameNode> BubbleView::CreateButtons(const RefPtr<PopupParam>& param, int32_t popupId, int32_t targetId)
371 {
372     auto rowId = ElementRegister::GetInstance()->MakeUniqueId();
373     auto rowNode = FrameNode::CreateFrameNode(V2::ROW_ETS_TAG, rowId, AceType::MakeRefPtr<LinearLayoutPattern>(false));
374     auto layoutProps = rowNode->GetLayoutProperty<LinearLayoutProperty>();
375     layoutProps->UpdateSpace(GetPopupTheme()->GetButtonSpacing());
376     auto primaryButtonProp = param->GetPrimaryButtonProperties();
377     auto primaryButton = BubbleView::CreateButton(primaryButtonProp, popupId, targetId, param);
378     if (primaryButton) {
379         primaryButton->MountToParent(rowNode);
380     }
381     auto secondaryButtonProp = param->GetSecondaryButtonProperties();
382     auto secondaryButton = BubbleView::CreateButton(secondaryButtonProp, popupId, targetId, param);
383     if (secondaryButton) {
384         secondaryButton->MountToParent(rowNode);
385     }
386     auto popupTheme = GetPopupTheme();
387     auto littlePadding = popupTheme->GetLittlePadding();
388     PaddingProperty rowPadding;
389     rowPadding.right = CalcLength(littlePadding);
390     rowPadding.bottom = CalcLength(littlePadding);
391     layoutProps->UpdatePadding(rowPadding);
392 
393     rowNode->MarkModifyDone();
394     return rowNode;
395 }
396 
CreateButton(ButtonProperties & buttonParam,int32_t popupId,int32_t targetId,const RefPtr<PopupParam> & param)397 RefPtr<FrameNode> BubbleView::CreateButton(
398     ButtonProperties& buttonParam, int32_t popupId, int32_t targetId, const RefPtr<PopupParam>& param)
399 {
400     if (!buttonParam.showButton) {
401         return nullptr;
402     }
403     auto pipelineContext = PipelineBase::GetCurrentContext();
404     CHECK_NULL_RETURN(pipelineContext, nullptr);
405     auto buttonTheme = pipelineContext->GetTheme<ButtonTheme>();
406     CHECK_NULL_RETURN(buttonTheme, nullptr);
407     auto popupTheme = GetPopupTheme();
408     auto focusColor = popupTheme->GetFocusColor();
409     auto buttonId = ElementRegister::GetInstance()->MakeUniqueId();
410     auto buttonPattern = AceType::MakeRefPtr<NG::ButtonPattern>();
411     CHECK_NULL_RETURN(buttonPattern, nullptr);
412     // set button focus color
413     buttonPattern->setComponentButtonType(ComponentButtonType::POPUP);
414     buttonPattern->SetFocusBorderColor(focusColor);
415     auto buttonNode = FrameNode::CreateFrameNode(V2::BUTTON_ETS_TAG, buttonId, buttonPattern);
416     CHECK_NULL_RETURN(buttonPattern, nullptr);
417 
418     auto buttonProp = AceType::DynamicCast<ButtonLayoutProperty>(buttonNode->GetLayoutProperty());
419     auto isUseCustom = param->IsUseCustom();
420     auto isShow = param->IsShow();
421 
422     auto buttonTextNode = BubbleView::CreateMessage(buttonParam.value, isUseCustom);
423     auto textLayoutProperty = buttonTextNode->GetLayoutProperty<TextLayoutProperty>();
424     textLayoutProperty->UpdateFontSize(popupTheme->GetButtonFontSize());
425     auto buttonTextInsideMargin = popupTheme->GetButtonTextInsideMargin();
426     buttonTextNode->MountToParent(buttonNode);
427 
428     PaddingProperty buttonPadding;
429     auto padding = buttonTheme->GetPadding();
430     buttonPadding.left = CalcLength(buttonTextInsideMargin);
431     buttonPadding.right = CalcLength(buttonTextInsideMargin);
432     buttonProp->UpdatePadding(buttonPadding);
433     buttonProp->UpdateType(ButtonType::CAPSULE);
434     buttonProp->UpdateUserDefinedIdealSize(CalcSize(std::nullopt, CalcLength(buttonTheme->GetHeight())));
435     buttonProp->UpdateAlignment(Alignment::CENTER);
436     auto buttonMiniMumWidth = popupTheme->GetButtonMiniMumWidth().ConvertToPx();
437     buttonProp->UpdateCalcMinSize(CalcSize(CalcLength(buttonMiniMumWidth), std::nullopt));
438     auto renderContext = buttonNode->GetRenderContext();
439     if (renderContext) {
440         renderContext->UpdateBackgroundColor(Color::TRANSPARENT);
441     }
442 
443     auto buttonEventHub = buttonNode->GetOrCreateGestureEventHub();
444     CHECK_NULL_RETURN(buttonEventHub, nullptr);
445     buttonEventHub->AddClickEvent(buttonParam.action);
446     auto popupNode = FrameNode::GetFrameNode(V2::POPUP_ETS_TAG, popupId);
447     auto closeCallback = [popupNode, targetId, isShow](GestureEvent& /* info */) {
448         auto container = Container::Current();
449         CHECK_NULL_VOID(container);
450         auto pipelineContext = container->GetPipelineContext();
451         CHECK_NULL_VOID(pipelineContext);
452         auto context = AceType::DynamicCast<NG::PipelineContext>(pipelineContext);
453         CHECK_NULL_VOID(context);
454         auto overlayManager = context->GetOverlayManager();
455         CHECK_NULL_VOID(overlayManager);
456         auto popupInfo = overlayManager->GetPopupInfo(targetId);
457         popupInfo.markNeedUpdate = true;
458         popupInfo.popupId = -1;
459         popupInfo.markNeedUpdate = isShow;
460         overlayManager->HidePopup(targetId, popupInfo);
461     };
462     if (buttonParam.action) {
463         buttonEventHub->AddClickEvent(buttonParam.action);
464     } else {
465         buttonEventHub->AddClickEvent(AceType::MakeRefPtr<ClickEvent>(closeCallback));
466     }
467 
468     return buttonNode;
469 }
470 } // namespace OHOS::Ace::NG
471