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