• 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/subwindow/subwindow_manager.h"
22 #include "base/utils/utils.h"
23 #include "core/common/container.h"
24 #include "core/components/button/button_theme.h"
25 #include "core/components/common/layout/constants.h"
26 #include "core/components/common/layout/grid_system_manager.h"
27 #include "core/components/common/properties/alignment.h"
28 #include "core/components/common/properties/color.h"
29 #include "core/components/theme/shadow_theme.h"
30 #include "core/components_ng/pattern/bubble/bubble_pattern.h"
31 #include "core/components_ng/pattern/button/button_pattern.h"
32 #include "core/components_ng/pattern/flex/flex_layout_pattern.h"
33 #include "core/components_ng/pattern/scroll/scroll_pattern.h"
34 #include "core/components_ng/pattern/text/text_layout_algorithm.h"
35 #include "core/components_ng/pattern/text/text_pattern.h"
36 
37 namespace OHOS::Ace::NG {
38 namespace {
39 constexpr double DOUBLENESS = 2.0;
40 constexpr Dimension OUT_RANGE_SPACE = 40.0_vp;
41 constexpr Dimension MAX_WIDTH = 480.0_vp;
42 constexpr Dimension MIN_BUTTON_FONT_SIZE = 9.0_vp;
43 constexpr int32_t BUTTON_MAX_LINE = 2;
44 constexpr float AGE_FONT_MAX_SIZE_SCALE = 2.0f;
45 constexpr float AGE_SCALE_NUMBER = 1.0f;
46 constexpr float AGE_BUTTONS_LAYOUT_HEIGHT_RATE = 15.0f;
47 const int32_t PRIMARY_BUTTON_NUMBER = 1;
48 const int32_t SECONDARY_BUTTON_NUMBER = 2;
49 
GetDisplayWindowRectOffset(int32_t popupNodeId)50 OffsetF GetDisplayWindowRectOffset(int32_t popupNodeId)
51 {
52     auto popupNode = FrameNode::GetFrameNode(V2::POPUP_ETS_TAG, popupNodeId);
53     CHECK_NULL_RETURN(popupNode, OffsetF());
54     auto pipelineContext = popupNode->GetContextRefPtr();
55     CHECK_NULL_RETURN(pipelineContext, OffsetF());
56     auto overlayManager = pipelineContext->GetOverlayManager();
57     CHECK_NULL_RETURN(overlayManager, OffsetF());
58     auto displayWindowOffset = OffsetF(pipelineContext->GetDisplayWindowRectInfo().GetOffset().GetX(),
59         pipelineContext->GetDisplayWindowRectInfo().GetOffset().GetY());
60     return displayWindowOffset;
61 }
62 
GetPopupTheme()63 RefPtr<PopupTheme> GetPopupTheme()
64 {
65     auto pipeline = PipelineBase::GetCurrentContext();
66     CHECK_NULL_RETURN(pipeline, nullptr);
67     auto popupTheme = pipeline->GetTheme<PopupTheme>();
68     CHECK_NULL_RETURN(popupTheme, nullptr);
69     return popupTheme;
70 }
71 
GetMaxWith()72 Dimension GetMaxWith()
73 {
74     auto gridColumnInfo = GridSystemManager::GetInstance().GetInfoByType(GridColumnType::BUBBLE_TYPE);
75     auto parent = gridColumnInfo->GetParent();
76     if (parent) {
77         parent->BuildColumnWidth();
78     }
79     auto maxWidth = Dimension(gridColumnInfo->GetMaxWidth());
80     auto popupTheme = GetPopupTheme();
81     CHECK_NULL_RETURN(popupTheme, maxWidth);
82     uint32_t maxColumns = popupTheme->GetMaxColumns();
83     if (maxColumns > 0) {
84         maxWidth = Dimension(gridColumnInfo->GetWidth(maxColumns));
85     }
86     return maxWidth;
87 }
88 
GetAgeFontSize(const std::optional<Dimension> & originalFontSize,const RefPtr<FrameNode> & bubbleNode)89 static Dimension GetAgeFontSize(const std::optional<Dimension>& originalFontSize, const RefPtr<FrameNode>& bubbleNode)
90 {
91     auto fontSize = Dimension(originalFontSize->Value(), originalFontSize->Unit());
92     CHECK_NULL_RETURN(bubbleNode, fontSize);
93     auto pipeline = bubbleNode->GetContext();
94     CHECK_NULL_RETURN(pipeline, fontSize);
95     auto fontSizeScale = pipeline->GetFontScale();
96     auto fontScale = fontSizeScale > AGE_FONT_MAX_SIZE_SCALE ? AGE_FONT_MAX_SIZE_SCALE : fontSizeScale;
97     fontSize.SetValue((originalFontSize->Value()) * fontScale);
98     return fontSize;
99 }
100 
UpdateTextProperties(const RefPtr<PopupParam> & param,const RefPtr<TextLayoutProperty> & textLayoutProps,const RefPtr<FrameNode> & popupNode)101 void UpdateTextProperties(const RefPtr<PopupParam>& param, const RefPtr<TextLayoutProperty>& textLayoutProps,
102     const RefPtr<FrameNode>& popupNode)
103 {
104     auto textColor = param->GetTextColor();
105     if (textColor.has_value()) {
106         textLayoutProps->UpdateTextColor(textColor.value());
107     }
108     CHECK_NULL_VOID(popupNode);
109     auto pipelineContext = popupNode->GetContextRefPtr();
110     CHECK_NULL_VOID(pipelineContext);
111     double maxAppFontScale = pipelineContext->GetMaxAppFontScale();
112     auto fontSize = param->GetFontSize();
113     if (fontSize.has_value()) {
114         if (!param->IsUseCustom()) {
115             textLayoutProps->UpdateMaxFontScale(std::min<double>(AGE_FONT_MAX_SIZE_SCALE, maxAppFontScale));
116             textLayoutProps->UpdateFontSize(fontSize.value());
117         } else {
118             textLayoutProps->UpdateFontSize(fontSize.value());
119         }
120     }
121     auto fontWeight = param->GetFontWeight();
122     if (fontWeight.has_value()) {
123         textLayoutProps->UpdateFontWeight(fontWeight.value());
124     }
125     auto fontStyle = param->GetFontStyle();
126     if (fontStyle.has_value()) {
127         textLayoutProps->UpdateItalicFontStyle(fontStyle.value());
128     }
129 }
130 } // namespace
131 
SetHitTestMode(RefPtr<FrameNode> & popupNode,bool isBlockEvent)132 void SetHitTestMode(RefPtr<FrameNode>& popupNode, bool isBlockEvent)
133 {
134     auto hub = popupNode->GetOrCreateEventHub<BubbleEventHub>();
135     if (hub) {
136         auto ges = hub->GetOrCreateGestureEventHub();
137         CHECK_NULL_VOID(ges);
138         if (!isBlockEvent) {
139             ges->SetHitTestMode(HitTestMode::HTMTRANSPARENT_SELF);
140         } else {
141             ges->SetHitTestMode(HitTestMode::HTMDEFAULT);
142         }
143     }
144 }
145 
GetTextLineHeight(const RefPtr<FrameNode> & textNode)146 int32_t GetTextLineHeight(const RefPtr<FrameNode>& textNode)
147 {
148     auto textLayoutProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
149     CHECK_NULL_RETURN(textLayoutProperty, 0);
150     auto layoutConstraint = textLayoutProperty->GetLayoutConstraint();
151     auto textLayoutWrapper = textNode->CreateLayoutWrapper();
152     CHECK_NULL_RETURN(textLayoutWrapper, 0);
153     textLayoutWrapper->Measure(layoutConstraint);
154     auto layoutAlgorithmWrapper = AceType::DynamicCast<LayoutAlgorithmWrapper>(textLayoutWrapper->GetLayoutAlgorithm());
155     CHECK_NULL_RETURN(layoutAlgorithmWrapper, 0);
156     auto textLayoutAlgorithm = AceType::DynamicCast<TextLayoutAlgorithm>(layoutAlgorithmWrapper->GetLayoutAlgorithm());
157     CHECK_NULL_RETURN(textLayoutAlgorithm, 0);
158     auto paragraph = textLayoutAlgorithm->GetSingleParagraph();
159     CHECK_NULL_RETURN(paragraph, 0);
160     auto paragHeight = paragraph->GetHeight();
161     auto paragLineCount = paragraph->GetLineCount();
162     int32_t paragLineHeight = 0;
163     if (paragLineCount > 0) {
164         paragLineHeight = static_cast<int32_t>(paragHeight / paragLineCount);
165     }
166     return paragLineHeight;
167 }
168 
CreateBubbleNode(const std::string & targetTag,int32_t targetId,const RefPtr<PopupParam> & param,const RefPtr<SpanString> & spanString)169 RefPtr<FrameNode> BubbleView::CreateBubbleNode(const std::string& targetTag, int32_t targetId,
170     const RefPtr<PopupParam>& param, const RefPtr<SpanString>& spanString)
171 {
172     auto popupId = ElementRegister::GetInstance()->MakeUniqueId();
173     ACE_LAYOUT_SCOPED_TRACE("Create[%s][self:%d]", V2::POPUP_ETS_TAG, popupId);
174     auto popupNode =
175         FrameNode::CreateFrameNode(V2::POPUP_ETS_TAG, popupId, AceType::MakeRefPtr<BubblePattern>(targetId, targetTag));
176     auto popupProp = AceType::DynamicCast<BubbleLayoutProperty>(popupNode->GetLayoutProperty());
177     auto popupPaintProp = popupNode->GetPaintProperty<BubbleRenderProperty>();
178     auto useCustom = param->IsUseCustom();
179 
180     // onstateChange.
181     auto bubbleHub = popupNode->GetOrCreateEventHub<BubbleEventHub>();
182     if (bubbleHub) {
183         bubbleHub->SetOnStateChange(param->GetOnStateChange());
184     }
185 
186     auto message = param->GetMessage();
187     auto primaryButton = param->GetPrimaryButtonProperties();
188     auto secondaryButton = param->GetSecondaryButtonProperties();
189     // Update props
190     popupProp->UpdateIsTips(param->IsTips());
191     popupProp->UpdateUseCustom(useCustom);
192     popupProp->UpdateEnableArrow(param->EnableArrow());
193     popupProp->UpdatePlacement(param->GetPlacement());
194     popupProp->UpdateShowInSubWindow(param->IsShowInSubWindow());
195     popupProp->UpdatePositionOffset(OffsetF(param->GetTargetOffset().GetX(), param->GetTargetOffset().GetY()));
196     popupProp->UpdateBlockEvent(param->IsBlockEvent());
197     popupProp->UpdateIsCaretMode(param->IsCaretMode());
198     popupProp->UpdateShowAtAnchor(param->GetAnchorType());
199     if (param->HasEnableHoverMode()) {
200         popupProp->UpdateEnableHoverMode(param->EnableHoverMode());
201     } else {
202         popupProp->ResetEnableHoverMode();
203     }
204 
205     if (param->GetArrowHeight().has_value()) {
206         popupProp->UpdateArrowHeight(param->GetArrowHeight().value());
207     }
208     if (param->GetArrowWidth().has_value()) {
209         popupProp->UpdateArrowWidth(param->GetArrowWidth().value());
210     }
211     if (param->GetRadius().has_value()) {
212         popupProp->UpdateRadius(param->GetRadius().value());
213     }
214     popupProp->UpdateFollowTransformOfTarget(param->IsFollowTransformOfTarget());
215     SetHitTestMode(popupNode, param->IsBlockEvent());
216     if (param->GetTargetSpace().has_value()) {
217         popupProp->UpdateTargetSpace(param->GetTargetSpace().value());
218     }
219     auto displayWindowOffset = GetDisplayWindowRectOffset(popupId);
220     popupProp->UpdateDisplayWindowOffset(displayWindowOffset);
221     popupPaintProp->UpdateEnableArrow(param->EnableArrow());
222     popupPaintProp->UpdateIsTips(param->IsTips());
223     popupPaintProp->UpdateShowAtAnchor(param->GetAnchorType());
224     if (param->GetArrowOffset().has_value()) {
225         popupPaintProp->UpdateArrowOffset(param->GetArrowOffset().value());
226     }
227     if (param->IsMaskColorSetted()) {
228         popupPaintProp->UpdateMaskColor(param->GetMaskColor());
229     }
230     if (param->IsBackgroundColorSetted()) {
231         popupPaintProp->UpdateBackgroundColor(param->GetBackgroundColor());
232     }
233     popupPaintProp->UpdateAutoCancel(!param->HasAction());
234     popupPaintProp->UpdatePlacement(param->GetPlacement());
235     if (param->GetHasTransition()) {
236         popupNode->GetRenderContext()->UpdateChainedTransition(param->GetTransitionEffects());
237     }
238 
239     auto bubbleAccessibilityProperty = popupNode->GetAccessibilityProperty<AccessibilityProperty>();
240     CHECK_NULL_RETURN(bubbleAccessibilityProperty, nullptr);
241     bubbleAccessibilityProperty->SetText(message);
242     auto bubblePattern = popupNode->GetPattern<BubblePattern>();
243     auto textColor = param->GetTextColor();
244     bubblePattern->SetMessageColor(textColor.has_value());
245     bubblePattern->SetHasTransition(param->GetHasTransition());
246     bubblePattern->SetAvoidKeyboard(param->GetKeyBoardAvoidMode() == PopupKeyboardAvoidMode::DEFAULT);
247     bubblePattern->SetAvoidTarget(param->GetAvoidTarget());
248     bubblePattern->SetHasWidth(param->GetChildWidth().has_value());
249     bubblePattern->SetHasPlacement(param->HasPlacement());
250     bubblePattern->SetOutlineLinearGradient(param->GetOutlineLinearGradient());
251     bubblePattern->SetOutlineWidth(param->GetOutlineWidth());
252     bubblePattern->SetInnerBorderLinearGradient(param->GetInnerBorderLinearGradient());
253     bubblePattern->SetInnerBorderWidth(param->GetInnerBorderWidth());
254     if (param->IsTips()) {
255         bubblePattern->SetTipsTag(true);
256     }
257     auto popupTheme = GetPopupTheme();
258     CHECK_NULL_RETURN(popupTheme, nullptr);
259     // Create child
260     RefPtr<FrameNode> child;
261     int textLineHeight = 0;
262     RefPtr<TextLayoutProperty> layoutProps;
263     if (primaryButton.showButton || secondaryButton.showButton) {
264         auto columnNode = FrameNode::CreateFrameNode(V2::COLUMN_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
265             AceType::MakeRefPtr<LinearLayoutPattern>(true));
266         auto columnLayoutProperty = columnNode->GetLayoutProperty<LinearLayoutProperty>();
267         columnLayoutProperty->UpdateMainAxisAlign(FlexAlign::CENTER); // mainAxisAlign
268         columnLayoutProperty->UpdateCrossAxisAlign(FlexAlign::CENTER);
269         auto combinedChild = CreateCombinedChild(param, popupId, targetId, popupNode);
270         popupPaintProp->UpdatePrimaryButtonShow(primaryButton.showButton);
271         popupPaintProp->UpdateSecondaryButtonShow(secondaryButton.showButton);
272         if ((Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN))) {
273             popupPaintProp->UpdateAutoCancel(false);
274         }
275         combinedChild->MountToParent(columnNode);
276         child = columnNode;
277     } else {
278         auto columnNode = FrameNode::CreateFrameNode(V2::COLUMN_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
279             AceType::MakeRefPtr<LinearLayoutPattern>(true));
280         auto columnLayoutProperty = columnNode->GetLayoutProperty<LinearLayoutProperty>();
281         columnLayoutProperty->UpdateMainAxisAlign(FlexAlign::CENTER); // mainAxisAlign
282         columnLayoutProperty->UpdateCrossAxisAlign(FlexAlign::CENTER);
283         auto textNode = CreateMessage(message, useCustom);
284         bubblePattern->SetMessageNode(textNode);
285         auto popupTheme = GetPopupTheme();
286         auto padding = param->IsTips() ? popupTheme->GetTipsPadding() : popupTheme->GetPadding();
287         layoutProps = textNode->GetLayoutProperty<TextLayoutProperty>();
288         PaddingProperty textPadding;
289         textPadding.left = CalcLength(padding.Left());
290         textPadding.right = CalcLength(padding.Right());
291         textPadding.top = CalcLength(padding.Top());
292         textPadding.bottom = CalcLength(padding.Bottom());
293         layoutProps->UpdatePadding(textPadding);
294         layoutProps->UpdateAlignment(Alignment::CENTER);
295         UpdateTextProperties(param, layoutProps, columnNode);
296         if (!param->IsTips()) {
297             auto buttonMiniMumHeight = popupTheme->GetBubbleMiniMumHeight().ConvertToPx();
298             layoutProps->UpdateCalcMinSize(CalcSize(std::nullopt, CalcLength(buttonMiniMumHeight)));
299         }
300         textNode->MarkModifyDone();
301         if ((Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN))) {
302             textNode->MountToParent(columnNode);
303         } else if (param->IsTips()) {
304             textNode->MountToParent(columnNode);
305             textLineHeight = GetTextLineHeight(textNode);
306         } else {
307             auto scrollNode = FrameNode::CreateFrameNode(V2::SCROLL_ETS_TAG,
308                 ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<ScrollPattern>());
309             CHECK_NULL_RETURN(scrollNode, nullptr);
310             auto scrollProps = scrollNode->GetLayoutProperty<ScrollLayoutProperty>();
311             scrollProps->UpdateAxis(Axis::VERTICAL);
312             scrollProps->UpdateAlignment(Alignment::CENTER_LEFT);
313             scrollNode->MarkModifyDone();
314             textNode->MountToParent(scrollNode);
315             scrollNode->MountToParent(columnNode);
316         }
317         child = columnNode;
318     }
319     // GridSystemManager is not completed, need to check later.
320     auto childLayoutProperty = child->GetLayoutProperty();
321     CHECK_NULL_RETURN(childLayoutProperty, nullptr);
322     float popupMaxWidth = 0.0f;
323     float popupMaxHeight = 0.0f;
324     GetPopupMaxWidthAndHeight(param, popupMaxWidth, popupMaxHeight, popupId);
325     if (param->IsTips()) {
326         layoutProps->UpdateTextOverflow(TextOverflow::ELLIPSIS);
327         if (textLineHeight > 0) {
328             auto maxLines = static_cast<int32_t>(std::floor(popupMaxHeight / textLineHeight)) - 1;
329             layoutProps->UpdateMaxLines(maxLines);
330         }
331     }
332     if (GreatNotEqual(popupMaxWidth, 0.0f) && GreatNotEqual(popupMaxHeight, 0.0f)) {
333         childLayoutProperty->UpdateCalcMaxSize(
334             CalcSize(NG::CalcLength(Dimension(popupMaxWidth)), NG::CalcLength(Dimension(popupMaxHeight))));
335     }
336     if (param->GetChildWidth().has_value()) {
337         childLayoutProperty->UpdateUserDefinedIdealSize(
338             CalcSize(CalcLength(param->GetChildWidth().value()), std::nullopt));
339     }
340     auto renderContext = child->GetRenderContext();
341     if (renderContext) {
342         if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_ELEVEN) &&
343             IsSupportBlurStyle(renderContext, param->IsShowInSubWindow(), param->IsTips())) {
344             auto backgroundColor = popupPaintProp->GetBackgroundColor().value_or(popupTheme->GetDefaultBGColor());
345             renderContext->UpdateBackgroundColor(backgroundColor);
346             BlurStyleOption styleOption;
347             if (param->IsTips()) {
348                 styleOption.blurStyle = BlurStyle::COMPONENT_REGULAR;
349             } else {
350                 styleOption.blurStyle = param->GetBlurStyle();
351             }
352             styleOption.colorMode = static_cast<ThemeColorMode>(popupTheme->GetBgThemeColorMode());
353             renderContext->UpdateBackBlurStyle(styleOption);
354         } else {
355             renderContext->UpdateBackgroundColor(
356                 popupPaintProp->GetBackgroundColor().value_or(popupTheme->GetBackgroundColor()));
357         }
358         if (param->GetShadow().has_value()) {
359             renderContext->UpdateBackShadow(param->GetShadow().value());
360         }
361         if (param->IsTips()) {
362             do {
363                 auto pipelineContext = popupNode->GetContextRefPtr();
364                 CHECK_NULL_BREAK(pipelineContext);
365                 auto shadowTheme = pipelineContext->GetTheme<ShadowTheme>();
366                 CHECK_NULL_BREAK(shadowTheme);
367                 Shadow shadow = shadowTheme->GetShadow(ShadowStyle::OuterDefaultSM, Container::CurrentColorMode());
368                 renderContext->UpdateBackShadow(shadow);
369             } while (false);
370         }
371     }
372     if (spanString) {
373         auto messageNode = bubblePattern->GetMessageNode();
374         if (messageNode) {
375             auto textPattern = messageNode->GetPattern<TextPattern>();
376             textPattern->SetStyledString(spanString, false);
377         }
378     }
379     child->MountToParent(popupNode);
380     return popupNode;
381 }
CreateCustomBubbleNode(const std::string & targetTag,int32_t targetId,const RefPtr<UINode> & customNode,const RefPtr<PopupParam> & param)382 RefPtr<FrameNode> BubbleView::CreateCustomBubbleNode(
383     const std::string& targetTag, int32_t targetId, const RefPtr<UINode>& customNode, const RefPtr<PopupParam>& param)
384 {
385     auto popupId = ElementRegister::GetInstance()->MakeUniqueId();
386     auto popupNode =
387         FrameNode::CreateFrameNode(V2::POPUP_ETS_TAG, popupId, AceType::MakeRefPtr<BubblePattern>(targetId, targetTag));
388     auto bubbleHub = popupNode->GetOrCreateEventHub<BubbleEventHub>();
389     if (bubbleHub) {
390         bubbleHub->SetOnStateChange(param->GetOnStateChange());
391     }
392     auto popupPattern = popupNode->GetPattern<BubblePattern>();
393     popupPattern->SetCustomPopupTag(true);
394     // update bubble props
395     auto layoutProps = popupNode->GetLayoutProperty<BubbleLayoutProperty>();
396     layoutProps->UpdateUseCustom(param->IsUseCustom());
397     layoutProps->UpdateEnableArrow(param->EnableArrow());
398     layoutProps->UpdatePlacement(param->GetPlacement());
399     layoutProps->UpdateShowInSubWindow(param->IsShowInSubWindow());
400     layoutProps->UpdateBlockEvent(param->IsBlockEvent());
401     if (param->HasEnableHoverMode()) {
402         layoutProps->UpdateEnableHoverMode(param->EnableHoverMode());
403     } else {
404         layoutProps->ResetEnableHoverMode();
405     }
406 
407     if (param->GetArrowHeight().has_value()) {
408         layoutProps->UpdateArrowHeight(param->GetArrowHeight().value());
409     }
410     if (param->GetArrowWidth().has_value()) {
411         layoutProps->UpdateArrowWidth(param->GetArrowWidth().value());
412     }
413     if (param->GetRadius().has_value()) {
414         layoutProps->UpdateRadius(param->GetRadius().value());
415     }
416     layoutProps->UpdateFollowTransformOfTarget(param->IsFollowTransformOfTarget());
417     SetHitTestMode(popupNode, param->IsBlockEvent());
418     auto displayWindowOffset = GetDisplayWindowRectOffset(popupId);
419     layoutProps->UpdateDisplayWindowOffset(displayWindowOffset);
420     layoutProps->UpdatePositionOffset(OffsetF(param->GetTargetOffset().GetX(), param->GetTargetOffset().GetY()));
421     if (param->GetTargetSpace().has_value()) {
422         layoutProps->UpdateTargetSpace(param->GetTargetSpace().value());
423     }
424     auto popupPaintProps = popupNode->GetPaintProperty<BubbleRenderProperty>();
425     popupPaintProps->UpdateUseCustom(param->IsUseCustom());
426     popupPaintProps->UpdateEnableArrow(param->EnableArrow());
427     if (param->GetArrowOffset().has_value()) {
428         popupPaintProps->UpdateArrowOffset(param->GetArrowOffset().value());
429     }
430     if (param->IsMaskColorSetted()) {
431         popupPaintProps->UpdateMaskColor(param->GetMaskColor());
432     }
433     if (param->IsBackgroundColorSetted()) {
434         popupPaintProps->UpdateBackgroundColor(param->GetBackgroundColor());
435     }
436     if (param->GetHasTransition()) {
437         popupNode->GetRenderContext()->UpdateChainedTransition(param->GetTransitionEffects());
438     }
439     popupPattern->SetHasTransition(param->GetHasTransition());
440     popupPattern->SetAvoidKeyboard(param->GetKeyBoardAvoidMode() == PopupKeyboardAvoidMode::DEFAULT);
441     popupPattern->SetAvoidTarget(param->GetAvoidTarget());
442     popupPattern->SetHasWidth(param->GetChildWidth().has_value());
443     popupPattern->SetHasPlacement(param->HasPlacement());
444     popupPattern->SetOutlineLinearGradient(param->GetOutlineLinearGradient());
445     popupPattern->SetOutlineWidth(param->GetOutlineWidth());
446     popupPattern->SetInnerBorderLinearGradient(param->GetInnerBorderLinearGradient());
447     popupPattern->SetInnerBorderWidth(param->GetInnerBorderWidth());
448 
449     auto columnNode = FrameNode::CreateFrameNode(V2::COLUMN_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
450         AceType::MakeRefPtr<LinearLayoutPattern>(false));
451     auto columnNodeClip = FrameNode::CreateFrameNode(V2::COLUMN_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
452         AceType::MakeRefPtr<LinearLayoutPattern>(false));
453     auto clipContext = columnNodeClip->GetRenderContext();
454     clipContext->SetClipToBounds(true);
455     customNode->MountToParent(columnNodeClip);
456     columnNodeClip->MountToParent(columnNode);
457     auto columnRenderContext = columnNode->GetRenderContext();
458     auto columnLayoutProperty = columnNode->GetLayoutProperty<LinearLayoutProperty>();
459     CHECK_NULL_RETURN(columnLayoutProperty, nullptr);
460     columnLayoutProperty->UpdateMainAxisAlign(FlexAlign::CENTER); // mainAxisAlign
461     columnLayoutProperty->UpdateCrossAxisAlign(FlexAlign::CENTER);
462     auto customFrameNode = AceType::DynamicCast<FrameNode>(customNode);
463     float popupMaxWidth = 0.0f;
464     float popupMaxHeight = 0.0f;
465     GetPopupMaxWidthAndHeight(param, popupMaxWidth, popupMaxHeight, popupId);
466     columnLayoutProperty->UpdateCalcMaxSize(CalcSize(std::nullopt, NG::CalcLength(Dimension(popupMaxHeight))));
467     if (param->GetChildWidth().has_value()) {
468         columnLayoutProperty->UpdateUserDefinedIdealSize(
469             CalcSize(CalcLength(param->GetChildWidth().value()), std::nullopt));
470     }
471     if (columnRenderContext) {
472         auto popupTheme = GetPopupTheme();
473         CHECK_NULL_RETURN(popupTheme, nullptr);
474         if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_ELEVEN) &&
475             IsSupportBlurStyle(columnRenderContext, param->IsShowInSubWindow(), param->IsTips())) {
476             auto backgroundColor = popupPaintProps->GetBackgroundColor().value_or(popupTheme->GetDefaultBGColor());
477             columnRenderContext->UpdateBackgroundColor(backgroundColor);
478             BlurStyleOption styleOption;
479             styleOption.blurStyle = param->GetBlurStyle();
480             styleOption.colorMode = static_cast<ThemeColorMode>(popupTheme->GetBgThemeColorMode());
481             columnRenderContext->UpdateBackBlurStyle(styleOption);
482         } else {
483             columnRenderContext->UpdateBackgroundColor(
484                 popupPaintProps->GetBackgroundColor().value_or(popupTheme->GetBackgroundColor()));
485         }
486         if (param->GetShadow().has_value()) {
487             columnRenderContext->UpdateBackShadow(param->GetShadow().value());
488         }
489     }
490     popupPaintProps->UpdateAutoCancel(!param->HasAction());
491     popupPaintProps->UpdatePlacement(param->GetPlacement());
492     columnNode->MountToParent(popupNode);
493     return popupNode;
494 }
495 
UpdateBubbleButtons(std::list<RefPtr<UINode>> & buttons,const RefPtr<PopupParam> & param)496 void BubbleView::UpdateBubbleButtons(std::list<RefPtr<UINode>>& buttons, const RefPtr<PopupParam>& param)
497 {
498     auto primaryButton = param->GetPrimaryButtonProperties();
499     auto secondaryButton = param->GetSecondaryButtonProperties();
500     if (primaryButton.showButton) {
501         auto button = AceType::DynamicCast<FrameNode>(buttons.front());
502         buttons.pop_front();
503         auto textNode = AceType::DynamicCast<FrameNode>(button->GetFirstChild());
504         CHECK_NULL_VOID(textNode);
505         auto layoutProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
506         CHECK_NULL_VOID(layoutProperty);
507         layoutProperty->UpdateContent(primaryButton.value);
508         textNode->MarkModifyDone();
509         auto buttonEventHub = button->GetOrCreateGestureEventHub();
510         if (primaryButton.action) {
511             buttonEventHub->AddClickEvent(primaryButton.action);
512         }
513     }
514     if (secondaryButton.showButton) {
515         auto button = AceType::DynamicCast<FrameNode>(buttons.front());
516         buttons.pop_front();
517         auto textNode = AceType::DynamicCast<FrameNode>(button->GetFirstChild());
518         CHECK_NULL_VOID(textNode);
519         auto layoutProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
520         CHECK_NULL_VOID(layoutProperty);
521         layoutProperty->UpdateContent(secondaryButton.value);
522         textNode->MarkModifyDone();
523         auto buttonEventHub = button->GetOrCreateGestureEventHub();
524         if (secondaryButton.action) {
525             buttonEventHub->AddClickEvent(secondaryButton.action);
526         }
527     }
528 }
529 
UpdateBubbleContent(int32_t popupId,const RefPtr<PopupParam> & param)530 void BubbleView::UpdateBubbleContent(int32_t popupId, const RefPtr<PopupParam>& param)
531 {
532     auto popupNode = FrameNode::GetFrameNode(V2::POPUP_ETS_TAG, popupId);
533     CHECK_NULL_VOID(popupNode);
534     auto message = param->GetMessage();
535     auto primaryButton = param->GetPrimaryButtonProperties();
536     auto secondaryButton = param->GetSecondaryButtonProperties();
537     auto columnNode = popupNode->GetFirstChild();
538     if (primaryButton.showButton || secondaryButton.showButton) {
539         CHECK_NULL_VOID(columnNode);
540         auto combinedChild = columnNode->GetFirstChild();
541         CHECK_NULL_VOID(combinedChild);
542         const auto& children = combinedChild->GetChildren();
543         for (const auto& child : children) {
544             if (child->GetTag() == V2::TEXT_ETS_TAG) { // API10
545                 auto textNode = AceType::DynamicCast<FrameNode>(child);
546                 auto layoutProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
547                 CHECK_NULL_VOID(layoutProperty);
548                 layoutProperty->UpdateContent(message);
549                 UpdateTextProperties(param, layoutProperty, popupNode);
550                 textNode->MarkModifyDone();
551             } else if (child->GetTag() == V2::SCROLL_ETS_TAG) {
552                 auto textNode = AceType::DynamicCast<FrameNode>(child->GetFirstChild());
553                 CHECK_NULL_VOID(textNode);
554                 auto layoutProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
555                 CHECK_NULL_VOID(layoutProperty);
556                 layoutProperty->UpdateContent(message);
557                 UpdateTextProperties(param, layoutProperty, popupNode);
558                 textNode->MarkModifyDone();
559             } else {
560                 auto buttons = child->GetChildren();
561                 UpdateBubbleButtons(buttons, param);
562             }
563         }
564     } else {
565         CHECK_NULL_VOID(columnNode);
566         auto childNode = columnNode->GetFirstChild();
567         if (!(Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN))) {
568             childNode = childNode->GetFirstChild();
569         }
570         auto textNode = AceType::DynamicCast<FrameNode>(childNode);
571         CHECK_NULL_VOID(textNode);
572         auto layoutProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
573         CHECK_NULL_VOID(layoutProperty);
574         layoutProperty->UpdateContent(message);
575         UpdateTextProperties(param, layoutProperty, popupNode);
576         textNode->MarkModifyDone();
577     }
578 }
579 
UpdatePopupParam(int32_t popupId,const RefPtr<PopupParam> & param,const RefPtr<FrameNode> & targetNode)580 void BubbleView::UpdatePopupParam(int32_t popupId, const RefPtr<PopupParam>& param, const RefPtr<FrameNode>& targetNode)
581 {
582     UpdateCommonParam(popupId, param, false);
583     UpdateBubbleContent(popupId, param);
584     auto popupNode = FrameNode::GetFrameNode(V2::POPUP_ETS_TAG, popupId);
585     CHECK_NULL_VOID(popupNode);
586     auto popupProp = AceType::DynamicCast<BubbleLayoutProperty>(popupNode->GetLayoutProperty());
587     auto popupPaintProp = popupNode->GetPaintProperty<BubbleRenderProperty>();
588     auto message = param->GetMessage();
589     auto primaryButton = param->GetPrimaryButtonProperties();
590     auto secondaryButton = param->GetSecondaryButtonProperties();
591     if (!(Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN))) {
592         if (primaryButton.showButton || secondaryButton.showButton) {
593             auto pipelineContext = popupNode->GetContext();
594             CHECK_NULL_VOID(pipelineContext);
595             float popupMaxWidth = 0.0f;
596             float popupMaxHeight = 0.0f;
597             GetPopupMaxWidthAndHeight(param, popupMaxWidth, popupMaxHeight, popupId);
598             auto buttonTheme = pipelineContext->GetTheme<ButtonTheme>();
599             CHECK_NULL_VOID(buttonTheme);
600             auto childNode = AceType::DynamicCast<FrameNode>(popupNode->GetFirstChild());
601             CHECK_NULL_VOID(childNode);
602             const auto& children = childNode->GetChildren();
603             for (const auto& uinode : children) {
604                 if (uinode->GetTag() == V2::SCROLL_ETS_TAG) {
605                     auto scrollNode = AceType::DynamicCast<FrameNode>(uinode);
606                     CHECK_NULL_VOID(scrollNode);
607                     auto scrollProps = scrollNode->GetLayoutProperty<ScrollLayoutProperty>();
608                     scrollProps->UpdateCalcMaxSize(CalcSize(
609                         std::nullopt, CalcLength(Dimension(popupMaxHeight) - buttonTheme->GetHeight() * DOUBLENESS)));
610                 }
611             }
612         }
613     }
614     // Update layout props
615     popupProp->UpdateUseCustom(param->IsUseCustom());
616     popupProp->UpdateIsTips(param->IsTips());
617     popupProp->UpdateEnableArrow(param->EnableArrow());
618     popupProp->UpdatePlacement(param->GetPlacement());
619     auto displayWindowOffset = GetDisplayWindowRectOffset(popupId);
620     popupProp->UpdateDisplayWindowOffset(displayWindowOffset);
621     // Update paint props
622     popupPaintProp->UpdatePlacement(param->GetPlacement());
623     popupPaintProp->UpdateUseCustom(param->IsUseCustom());
624     popupPaintProp->UpdateIsTips(param->IsTips());
625     popupPaintProp->UpdateEnableArrow(param->EnableArrow());
626     auto popupPattern = popupNode->GetPattern<BubblePattern>();
627     popupPattern->SetOutlineLinearGradient(param->GetOutlineLinearGradient());
628     popupPattern->SetOutlineWidth(param->GetOutlineWidth());
629     popupPattern->SetInnerBorderLinearGradient(param->GetInnerBorderLinearGradient());
630     popupPattern->SetInnerBorderWidth(param->GetInnerBorderWidth());
631 }
632 
UpdateCustomPopupParam(int32_t popupId,const RefPtr<PopupParam> & param)633 void BubbleView::UpdateCustomPopupParam(int32_t popupId, const RefPtr<PopupParam>& param)
634 {
635     UpdateCommonParam(popupId, param);
636     auto popupNode = FrameNode::GetFrameNode(V2::POPUP_ETS_TAG, popupId);
637     CHECK_NULL_VOID(popupNode);
638     auto popupLayoutProp = popupNode->GetLayoutProperty<BubbleLayoutProperty>();
639     CHECK_NULL_VOID(popupLayoutProp);
640     auto popupPaintProp = popupNode->GetPaintProperty<BubbleRenderProperty>();
641     CHECK_NULL_VOID(popupPaintProp);
642     popupLayoutProp->UpdatePlacement(param->GetPlacement());
643     popupPaintProp->UpdatePlacement(param->GetPlacement());
644     popupLayoutProp->UpdateEnableArrow(param->EnableArrow());
645     popupPaintProp->UpdateAutoCancel(!param->HasAction());
646     popupPaintProp->UpdateEnableArrow(param->EnableArrow());
647     auto popupPattern = popupNode->GetPattern<BubblePattern>();
648     popupPattern->SetOutlineLinearGradient(param->GetOutlineLinearGradient());
649     popupPattern->SetOutlineWidth(param->GetOutlineWidth());
650     popupPattern->SetInnerBorderLinearGradient(param->GetInnerBorderLinearGradient());
651     popupPattern->SetInnerBorderWidth(param->GetInnerBorderWidth());
652 }
653 
GetPopupMaxWidthAndHeight(const RefPtr<PopupParam> & param,float & popupMaxWidth,float & popupMaxHeight,int32_t popupNodeId)654 void BubbleView::GetPopupMaxWidthAndHeight(
655     const RefPtr<PopupParam>& param, float& popupMaxWidth, float& popupMaxHeight, int32_t popupNodeId)
656 {
657     auto popupNode = FrameNode::GetFrameNode(V2::POPUP_ETS_TAG, popupNodeId);
658     CHECK_NULL_VOID(popupNode);
659     auto pipelineContext = popupNode->GetContextRefPtr();
660     CHECK_NULL_VOID(pipelineContext);
661     auto windowGlobalRect = pipelineContext->GetDisplayWindowRectInfo();
662     TAG_LOGI(AceLogTag::ACE_OVERLAY, "popup GetDisplayWindowRectInfo: %{public}s", windowGlobalRect.ToString().c_str());
663     auto safeAreaManager = pipelineContext->GetSafeAreaManager();
664     CHECK_NULL_VOID(safeAreaManager);
665     auto bottom = safeAreaManager->GetSystemSafeArea().bottom_.Length();
666     auto top = safeAreaManager->GetSystemSafeArea().top_.Length();
667     auto maxHeight = windowGlobalRect.Height();
668     auto theme = pipelineContext->GetTheme<PopupTheme>();
669     CHECK_NULL_VOID(theme);
670     auto container = Container::Current();
671     CHECK_NULL_VOID(container);
672     auto isFreeMultiWindow = container->IsFreeMultiWindow();
673     bool isExpandDisplay;
674     if (param->IsTips()) {
675         isExpandDisplay = theme->GetTipsDoubleBorderEnable() || isFreeMultiWindow;
676     } else {
677         isExpandDisplay = theme->GetPopupDoubleBorderEnable() || isFreeMultiWindow;
678     }
679     if (param->IsShowInSubWindow()) {
680         if (isExpandDisplay) {
681             maxHeight = SystemProperties::GetDeviceHeight();
682         } else if (container->IsUIExtensionWindow()) {
683             auto rect = container->GetUIExtensionHostWindowRect();
684             TAG_LOGI(AceLogTag::ACE_OVERLAY, "popup GetUIExtensionHostWindowRect: %{public}s",
685                 rect.ToString().c_str());
686             maxHeight = rect.Height();
687         }
688     }
689     popupMaxHeight = maxHeight - OUT_RANGE_SPACE.ConvertToPx() - OUT_RANGE_SPACE.ConvertToPx() - bottom - top;
690     popupMaxWidth = GetMaxWith().Value();
691     if (param->IsTips()) {
692         popupMaxWidth = (popupMaxWidth > MAX_WIDTH.ConvertToPx()) ? MAX_WIDTH.ConvertToPx() : popupMaxWidth;
693         popupMaxHeight = maxHeight - bottom - top;
694     }
695 }
696 
UpdateCommonParam(int32_t popupId,const RefPtr<PopupParam> & param,bool custom)697 void BubbleView::UpdateCommonParam(int32_t popupId, const RefPtr<PopupParam>& param, bool custom)
698 {
699     auto popupNode = FrameNode::GetFrameNode(V2::POPUP_ETS_TAG, popupId);
700     CHECK_NULL_VOID(popupNode);
701     auto bubbleHub = popupNode->GetOrCreateEventHub<BubbleEventHub>();
702     if (bubbleHub && (!(param->GetIsPartialUpdate().has_value()))) {
703         bubbleHub->SetOnStateChange(param->GetOnStateChange());
704     }
705     auto popupLayoutProp = popupNode->GetLayoutProperty<BubbleLayoutProperty>();
706     CHECK_NULL_VOID(popupLayoutProp);
707     auto popupPaintProp = popupNode->GetPaintProperty<BubbleRenderProperty>();
708     CHECK_NULL_VOID(popupPaintProp);
709     if (param->GetArrowOffset().has_value()) {
710         popupPaintProp->UpdateArrowOffset(param->GetArrowOffset().value());
711     }
712     popupLayoutProp->UpdateShowInSubWindow(param->IsShowInSubWindow());
713     popupLayoutProp->UpdateBlockEvent(param->IsBlockEvent());
714     popupLayoutProp->UpdateIsCaretMode(param->IsCaretMode());
715     if (param->GetErrorArrowHeight()) {
716         popupLayoutProp->ResetArrowHeight();
717     }
718     if (param->GetErrorArrowWidth()) {
719         popupLayoutProp->ResetArrowWidth();
720     }
721     if (param->GetErrorRadius()) {
722         popupLayoutProp->ResetRadius();
723     }
724     if (param->GetArrowHeight().has_value()) {
725         popupLayoutProp->UpdateArrowHeight(param->GetArrowHeight().value());
726     }
727     if (param->GetArrowWidth().has_value()) {
728         popupLayoutProp->UpdateArrowWidth(param->GetArrowWidth().value());
729     }
730     if (param->GetRadius().has_value()) {
731         popupLayoutProp->UpdateRadius(param->GetRadius().value());
732     }
733     popupLayoutProp->UpdateFollowTransformOfTarget(param->IsFollowTransformOfTarget());
734     SetHitTestMode(popupNode, param->IsBlockEvent());
735     popupLayoutProp->UpdatePositionOffset(OffsetF(param->GetTargetOffset().GetX(), param->GetTargetOffset().GetY()));
736     if (param->IsMaskColorSetted()) {
737         popupPaintProp->UpdateMaskColor(param->GetMaskColor());
738     } else {
739         popupPaintProp->UpdateMaskColor(Color::TRANSPARENT);
740     }
741     if (param->GetTargetSpace().has_value()) {
742         popupLayoutProp->UpdateTargetSpace(param->GetTargetSpace().value());
743     }
744     if (param->IsBackgroundColorSetted()) {
745         popupPaintProp->UpdateBackgroundColor(param->GetBackgroundColor());
746     }
747     auto childNode = AceType::DynamicCast<FrameNode>(popupNode->GetFirstChild());
748     CHECK_NULL_VOID(childNode);
749     auto renderContext = childNode->GetRenderContext();
750     if (renderContext && param->GetShadow().has_value()) {
751         renderContext->UpdateBackShadow(param->GetShadow().value());
752     }
753     auto childLayoutProperty = childNode->GetLayoutProperty();
754     CHECK_NULL_VOID(childLayoutProperty);
755     float popupMaxWidth = 0.0f;
756     float popupMaxHeight = 0.0f;
757     GetPopupMaxWidthAndHeight(param, popupMaxWidth, popupMaxHeight, popupId);
758     if (custom) {
759         childLayoutProperty->UpdateCalcMaxSize(CalcSize(std::nullopt, NG::CalcLength(Dimension(popupMaxHeight))));
760     } else if (GreatNotEqual(popupMaxWidth, 0.0f) && GreatNotEqual(popupMaxHeight, 0.0f)) {
761         childLayoutProperty->UpdateCalcMaxSize(
762             CalcSize(NG::CalcLength(Dimension(popupMaxWidth)), NG::CalcLength(Dimension(popupMaxHeight))));
763     }
764     if (param->GetChildWidth().has_value()) {
765         childLayoutProperty->UpdateUserDefinedIdealSize(
766             CalcSize(CalcLength(param->GetChildWidth().value()), std::nullopt));
767     } else {
768         childLayoutProperty->ClearUserDefinedIdealSize(true, false);
769     }
770     if (renderContext) {
771         auto popupTheme = GetPopupTheme();
772         CHECK_NULL_VOID(popupTheme);
773         if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_ELEVEN) &&
774             IsSupportBlurStyle(renderContext, param->IsShowInSubWindow(), param->IsTips())) {
775             auto defaultBGcolor = popupTheme->GetDefaultBGColor();
776             auto backgroundColor = popupPaintProp->GetBackgroundColor().value_or(defaultBGcolor);
777             renderContext->UpdateBackgroundColor(backgroundColor);
778             BlurStyleOption styleOption;
779             if (param->IsTips()) {
780                 styleOption.blurStyle = BlurStyle::COMPONENT_REGULAR;
781             } else {
782                 styleOption.blurStyle = param->GetBlurStyle();
783             }
784             styleOption.colorMode = static_cast<ThemeColorMode>(popupTheme->GetBgThemeColorMode());
785             renderContext->UpdateBackBlurStyle(styleOption);
786         } else {
787             renderContext->UpdateBackgroundColor(
788                 popupPaintProp->GetBackgroundColor().value_or(popupTheme->GetBackgroundColor()));
789         }
790         if (param->IsTips()) {
791             do {
792                 auto pipelineContext = popupNode->GetContextRefPtr();
793                 CHECK_NULL_BREAK(pipelineContext);
794                 auto shadowTheme = pipelineContext->GetTheme<ShadowTheme>();
795                 CHECK_NULL_BREAK(shadowTheme);
796                 Shadow shadow = shadowTheme->GetShadow(ShadowStyle::OuterDefaultSM, Container::CurrentColorMode());
797                 renderContext->UpdateBackShadow(shadow);
798             } while (false);
799         }
800     }
801     RefPtr<BubblePattern> bubblePattern = popupNode->GetPattern<BubblePattern>();
802     bubblePattern->SetAvoidKeyboard(param->GetKeyBoardAvoidMode() == PopupKeyboardAvoidMode::DEFAULT);
803     bubblePattern->SetAvoidTarget(param->GetAvoidTarget());
804     bubblePattern->SetHasWidth(param->GetChildWidth().has_value());
805     bubblePattern->SetHasPlacement(param->HasPlacement());
806 
807     if (!(param->GetIsPartialUpdate().has_value())) {
808         bubblePattern->SetHasTransition(param->GetHasTransition());
809         if (param->GetHasTransition()) {
810             popupNode->GetRenderContext()->UpdateChainedTransition(param->GetTransitionEffects());
811         }
812     }
813 }
814 
ResetBubbleProperty(int32_t popupId)815 void BubbleView::ResetBubbleProperty(int32_t popupId)
816 {
817     auto popupNode = FrameNode::GetFrameNode(V2::POPUP_ETS_TAG, popupId);
818     CHECK_NULL_VOID(popupNode);
819     auto popupLayoutProp = popupNode->GetLayoutProperty<BubbleLayoutProperty>();
820     CHECK_NULL_VOID(popupLayoutProp);
821     popupLayoutProp->ResetEnableArrow();
822     popupLayoutProp->ResetPlacement();
823     popupLayoutProp->ResetTargetSpace();
824     popupLayoutProp->ResetPositionOffset();
825     popupLayoutProp->ResetArrowHeight();
826     popupLayoutProp->ResetArrowWidth();
827     popupLayoutProp->ResetRadius();
828     popupLayoutProp->ResetFollowTransformOfTarget();
829 
830     auto popupPaintProp = popupNode->GetPaintProperty<BubbleRenderProperty>();
831     CHECK_NULL_VOID(popupPaintProp);
832     popupPaintProp->ResetAutoCancel();
833     popupPaintProp->ResetBackgroundColor();
834     popupPaintProp->ResetEnableArrow();
835     popupPaintProp->ResetMaskColor();
836     popupPaintProp->ResetPlacement();
837     popupPaintProp->ResetArrowOffset();
838 
839     auto childNode = AceType::DynamicCast<FrameNode>(popupNode->GetFirstChild());
840     CHECK_NULL_VOID(childNode);
841     auto renderContext = childNode->GetRenderContext();
842     if (renderContext) {
843         renderContext->ResetBackShadow();
844     }
845     auto childLayoutProperty = childNode->GetLayoutProperty();
846     CHECK_NULL_VOID(childLayoutProperty);
847     childLayoutProperty->ClearUserDefinedIdealSize(true, false);
848 }
849 
CreateMessage(const std::string & message,bool IsUseCustom)850 RefPtr<FrameNode> BubbleView::CreateMessage(const std::string& message, bool IsUseCustom)
851 {
852     auto textId = ElementRegister::GetInstance()->MakeUniqueId();
853     auto textNode = FrameNode::CreateFrameNode(V2::TEXT_ETS_TAG, textId, AceType::MakeRefPtr<TextPattern>());
854     // The buttons in popupNode can not get focus, if the textNode in the button is not focusable
855     textNode->GetOrCreateFocusHub()->SetFocusable(true);
856     auto layoutProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
857     CHECK_NULL_RETURN(layoutProperty, nullptr);
858     layoutProperty->UpdateContent(message);
859     auto popupTheme = GetPopupTheme();
860     CHECK_NULL_RETURN(popupTheme, nullptr);
861     if (!IsUseCustom) {
862         auto pipelineContext = textNode->GetContextRefPtr();
863         CHECK_NULL_RETURN(pipelineContext, nullptr);
864         double maxAppFontScale = pipelineContext->GetMaxAppFontScale();
865         layoutProperty->UpdateMaxFontScale(std::min<double>(AGE_FONT_MAX_SIZE_SCALE, maxAppFontScale));
866         layoutProperty->UpdateFontSize(popupTheme->GetFontSize());
867     } else {
868         layoutProperty->UpdateFontSize(popupTheme->GetFontSize());
869     }
870     if (IsUseCustom) {
871         layoutProperty->UpdateTextColor(Color::BLACK);
872     } else {
873         if ((Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN))) {
874             layoutProperty->UpdateTextColor(popupTheme->GetFontColor());
875         } else {
876             layoutProperty->UpdateTextColor(popupTheme->GetFontPrimaryColor());
877         }
878     }
879     textNode->MarkModifyDone();
880     return textNode;
881 }
882 
CreateCombinedChild(const RefPtr<PopupParam> & param,int32_t popupId,int32_t targetId,const RefPtr<FrameNode> & bubbleNode)883 RefPtr<FrameNode> BubbleView::CreateCombinedChild(
884     const RefPtr<PopupParam>& param, int32_t popupId, int32_t targetId, const RefPtr<FrameNode>& bubbleNode)
885 {
886     auto columnNode = FrameNode::CreateFrameNode(V2::COLUMN_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(),
887         AceType::MakeRefPtr<LinearLayoutPattern>(true));
888     auto layoutProps = columnNode->GetLayoutProperty<LinearLayoutProperty>();
889     layoutProps->UpdateMainAxisAlign(FlexAlign::FLEX_START); // mainAxisAlign
890     layoutProps->UpdateCrossAxisAlign(FlexAlign::FLEX_START);
891     auto message = BubbleView::CreateMessage(param->GetMessage(), param->IsUseCustom());
892     CHECK_NULL_RETURN(bubbleNode, nullptr);
893     auto bubblePattern = bubbleNode->GetPattern<BubblePattern>();
894     CHECK_NULL_RETURN(bubblePattern, nullptr);
895     bubblePattern->SetMessageNode(message);
896     auto popupTheme = GetPopupTheme();
897     CHECK_NULL_RETURN(popupTheme, nullptr);
898     auto padding = popupTheme->GetPadding();
899     auto textLayoutProps = message->GetLayoutProperty<TextLayoutProperty>();
900     PaddingProperty textPadding;
901     textPadding.left = CalcLength(padding.Left());
902     textPadding.right = CalcLength(padding.Right());
903     textPadding.top = CalcLength(padding.Top());
904     if (!param->IsUseCustom()) {
905         textPadding.left = CalcLength(popupTheme->GetAgingTextLeftPadding());
906         textPadding.right = CalcLength(popupTheme->GetAgingTextRightPadding());
907     }
908     textLayoutProps->UpdatePadding(textPadding);
909     textLayoutProps->UpdateAlignSelf(FlexAlign::FLEX_START);
910     UpdateTextProperties(param, textLayoutProps, columnNode);
911     message->MarkModifyDone();
912     auto pipelineContext = bubbleNode->GetContext();
913     CHECK_NULL_RETURN(pipelineContext, nullptr);
914     float popupMaxWidth = 0.0f;
915     float popupMaxHeight = 0.0f;
916     if ((Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN))) {
917         message->MountToParent(columnNode);
918     } else {
919         GetPopupMaxWidthAndHeight(param, popupMaxWidth, popupMaxHeight, popupId);
920         auto buttonTheme = pipelineContext->GetTheme<ButtonTheme>();
921         CHECK_NULL_RETURN(buttonTheme, nullptr);
922         auto scrollNode = FrameNode::CreateFrameNode(
923             V2::SCROLL_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<ScrollPattern>());
924         CHECK_NULL_RETURN(scrollNode, nullptr);
925         auto scrollProps = scrollNode->GetLayoutProperty<ScrollLayoutProperty>();
926         scrollProps->UpdateAxis(Axis::VERTICAL);
927         scrollProps->UpdateAlignment(Alignment::CENTER_LEFT);
928         auto buttonFontSize = popupTheme->GetButtonFontSize();
929         auto fontScale = pipelineContext->GetFontScale();
930         if (fontScale == AGE_SCALE_NUMBER) {
931             scrollProps->UpdateCalcMaxSize(CalcSize(
932                 std::nullopt, CalcLength(Dimension(popupMaxHeight) - GetAgeFontSize(buttonFontSize, bubbleNode) *
933                                                                          AGE_BUTTONS_LAYOUT_HEIGHT_RATE * DOUBLENESS)));
934         } else {
935             scrollProps->UpdateCalcMaxSize(
936                 CalcSize(std::nullopt, CalcLength(Dimension(popupMaxHeight) -
937                                          GetAgeFontSize(buttonFontSize, bubbleNode) * AGE_BUTTONS_LAYOUT_HEIGHT_RATE)));
938         }
939         scrollNode->MarkModifyDone();
940         message->MountToParent(scrollNode);
941         scrollNode->MountToParent(columnNode);
942     }
943     auto buttonLayout = BubbleView::CreateButtons(param, popupId, targetId);
944     if ((Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN))) {
945         auto buttonRowLayoutProperty = buttonLayout->GetLayoutProperty<LinearLayoutProperty>();
946         buttonRowLayoutProperty->UpdateAlignSelf(FlexAlign::FLEX_END);
947     } else {
948         auto buttonFlexLayoutProperty = buttonLayout->GetLayoutProperty<FlexLayoutProperty>();
949         buttonFlexLayoutProperty->UpdateAlignSelf(FlexAlign::FLEX_END);
950     }
951     buttonLayout->MarkModifyDone();
952     auto childLayoutProperty = columnNode->GetLayoutProperty<LinearLayoutProperty>();
953     CHECK_NULL_RETURN(childLayoutProperty, nullptr);
954     if ((Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN))) {
955         popupMaxWidth = GetMaxWith().Value();
956         childLayoutProperty->UpdateCalcMaxSize(CalcSize(NG::CalcLength(popupMaxWidth), std::nullopt));
957     } else if (GreatNotEqual(popupMaxWidth, 0.0f) && GreatNotEqual(popupMaxHeight, 0.0f)) {
958         childLayoutProperty->UpdateCalcMaxSize(
959             CalcSize(NG::CalcLength(Dimension(popupMaxWidth)), NG::CalcLength(Dimension(popupMaxHeight))));
960     }
961     buttonLayout->MountToParent(columnNode);
962     columnNode->MarkModifyDone();
963     return columnNode;
964 }
965 
CreateButtons(const RefPtr<PopupParam> & param,int32_t popupId,int32_t targetId)966 RefPtr<FrameNode> BubbleView::CreateButtons(const RefPtr<PopupParam>& param, int32_t popupId, int32_t targetId)
967 {
968     auto rowId = ElementRegister::GetInstance()->MakeUniqueId();
969     RefPtr<FrameNode> layoutNode;
970     if ((Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN))) {
971         layoutNode =
972             FrameNode::CreateFrameNode(V2::ROW_ETS_TAG, rowId, AceType::MakeRefPtr<LinearLayoutPattern>(false));
973     } else {
974         layoutNode = FrameNode::CreateFrameNode(V2::FLEX_ETS_TAG, rowId, AceType::MakeRefPtr<FlexLayoutPattern>(false));
975         layoutNode->GetPattern<FlexLayoutPattern>()->SetIsWrap(true);
976     }
977 
978     auto primaryButtonProp = param->GetPrimaryButtonProperties();
979     auto primaryButton = BubbleView::CreateButton(primaryButtonProp, popupId, targetId, param, PRIMARY_BUTTON_NUMBER);
980     if (primaryButton) {
981         primaryButton->MountToParent(layoutNode);
982     }
983     auto secondaryButtonProp = param->GetSecondaryButtonProperties();
984     auto secondaryButton = BubbleView::CreateButton(secondaryButtonProp, popupId,
985         targetId, param, SECONDARY_BUTTON_NUMBER);
986     if (secondaryButton) {
987         secondaryButton->MountToParent(layoutNode);
988     }
989     auto popupTheme = GetPopupTheme();
990     CHECK_NULL_RETURN(popupTheme, nullptr);
991     auto littlePadding = popupTheme->GetLittlePadding();
992     PaddingProperty rowPadding;
993     rowPadding.top = CalcLength(popupTheme->GetButtonTopMargin());
994     rowPadding.left = CalcLength(popupTheme->GetButtonLeftMargin());
995     rowPadding.right = CalcLength(littlePadding);
996     rowPadding.bottom = CalcLength(popupTheme->GetButtonBottomMargin());
997     if ((Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN))) {
998         auto layoutProps = layoutNode->GetLayoutProperty<LinearLayoutProperty>();
999         layoutProps->UpdateSpace(GetPopupTheme()->GetButtonSpacing());
1000         layoutProps->UpdatePadding(rowPadding);
1001     } else {
1002         auto layoutProps = layoutNode->GetLayoutProperty<FlexLayoutProperty>();
1003         layoutProps->UpdateSpace(GetPopupTheme()->GetButtonSpacingNewVersion());
1004         layoutProps->UpdatePadding(rowPadding);
1005     }
1006     layoutNode->MarkModifyDone();
1007     return layoutNode;
1008 }
1009 
UpdateButtonFontSize(RefPtr<TextLayoutProperty> & textLayoutProps,const RefPtr<FrameNode> & buttonTextNode)1010 void UpdateButtonFontSize(RefPtr<TextLayoutProperty>& textLayoutProps,
1011     const RefPtr<FrameNode>& buttonTextNode)
1012 {
1013     CHECK_NULL_VOID(textLayoutProps);
1014     auto host = textLayoutProps->GetHost();
1015     CHECK_NULL_VOID(host);
1016     auto pipeline = host->GetContext();
1017     CHECK_NULL_VOID(pipeline);
1018     auto popupTheme = GetPopupTheme();
1019     CHECK_NULL_VOID(popupTheme);
1020     auto fontSize = popupTheme->GetButtonFontSize();
1021     auto fontSizeScale = pipeline->GetFontScale();
1022     auto fontScale = fontSizeScale > AGE_FONT_MAX_SIZE_SCALE ? AGE_FONT_MAX_SIZE_SCALE : fontSizeScale;
1023     if (fontScale == AGE_SCALE_NUMBER) {
1024         textLayoutProps->UpdateAdaptMaxFontSize(popupTheme->GetButtonFontSize());
1025         textLayoutProps->UpdateAdaptMinFontSize(MIN_BUTTON_FONT_SIZE);
1026     } else {
1027         CHECK_NULL_VOID(buttonTextNode);
1028         auto pipelineContext = buttonTextNode->GetContextRefPtr();
1029         CHECK_NULL_VOID(pipelineContext);
1030         double maxAppFontScale = pipelineContext->GetMaxAppFontScale();
1031         textLayoutProps->UpdateMaxFontScale(std::min<double>(AGE_FONT_MAX_SIZE_SCALE, maxAppFontScale));
1032     }
1033     textLayoutProps->UpdateFontSize(fontSize);
1034 }
1035 
UpdateButtonTextColorForDiff(const RefPtr<TextLayoutProperty> & textLayoutProperty,const int32_t buttonNumber)1036 void UpdateButtonTextColorForDiff(const RefPtr<TextLayoutProperty>& textLayoutProperty,
1037     const int32_t buttonNumber)
1038 {
1039     auto popupTheme = GetPopupTheme();
1040     CHECK_NULL_VOID(popupTheme);
1041     if (buttonNumber == PRIMARY_BUTTON_NUMBER) {
1042         textLayoutProperty->UpdateTextColor(popupTheme->GetPrimaryButtonFontColor());
1043     } else if (buttonNumber == SECONDARY_BUTTON_NUMBER) {
1044         textLayoutProperty->UpdateTextColor(popupTheme->GetSecondaryButtonFontColor());
1045     } else {
1046         textLayoutProperty->UpdateTextColor(popupTheme->GetButtonFontColor());
1047     }
1048 }
1049 
CreateButton(ButtonProperties & buttonParam,int32_t popupId,int32_t targetId,const RefPtr<PopupParam> & param,const int32_t buttonNumber)1050 RefPtr<FrameNode> BubbleView::CreateButton(ButtonProperties& buttonParam, int32_t popupId,
1051     int32_t targetId, const RefPtr<PopupParam>& param, const int32_t buttonNumber)
1052 {
1053     if (!buttonParam.showButton) {
1054         return nullptr;
1055     }
1056     auto popupNode = FrameNode::GetFrameNode(V2::POPUP_ETS_TAG, popupId);
1057     CHECK_NULL_RETURN(popupNode, nullptr);
1058     auto pipelineContext = popupNode->GetContext();
1059     CHECK_NULL_RETURN(pipelineContext, nullptr);
1060     auto buttonTheme = pipelineContext->GetTheme<ButtonTheme>();
1061     CHECK_NULL_RETURN(buttonTheme, nullptr);
1062     auto popupTheme = GetPopupTheme();
1063     CHECK_NULL_RETURN(popupTheme, nullptr);
1064     auto focusColor = popupTheme->GetFocusColor();
1065     auto buttonId = ElementRegister::GetInstance()->MakeUniqueId();
1066     auto buttonPattern = AceType::MakeRefPtr<NG::ButtonPattern>();
1067     CHECK_NULL_RETURN(buttonPattern, nullptr);
1068     // set button focus color
1069     buttonPattern->setComponentButtonType(ComponentButtonType::POPUP);
1070     buttonPattern->SetFocusBorderColor(focusColor);
1071     auto buttonNode = FrameNode::CreateFrameNode(V2::BUTTON_ETS_TAG, buttonId, buttonPattern);
1072     CHECK_NULL_RETURN(buttonPattern, nullptr);
1073 
1074     auto buttonProp = AceType::DynamicCast<ButtonLayoutProperty>(buttonNode->GetLayoutProperty());
1075     auto isUseCustom = param->IsUseCustom();
1076 
1077     auto buttonTextNode = BubbleView::CreateMessage(buttonParam.value, isUseCustom);
1078     auto textLayoutProperty = buttonTextNode->GetLayoutProperty<TextLayoutProperty>();
1079     UpdateButtonFontSize(textLayoutProperty, buttonTextNode);
1080     textLayoutProperty->UpdateMaxLines(BUTTON_MAX_LINE);
1081     textLayoutProperty->UpdateTextOverflow(TextOverflow::ELLIPSIS);
1082     auto buttonTextFontWeight = static_cast<FontWeight>(popupTheme->GetButtonTextFontWeight());
1083     textLayoutProperty->UpdateFontWeight(buttonTextFontWeight);
1084     PaddingProperty buttonTextPadding;
1085     buttonTextPadding.left = CalcLength(popupTheme->GetAgingButtonTextLeftPadding());
1086     buttonTextPadding.right = CalcLength(popupTheme->GetAgingButtonTextRightPadding());
1087     textLayoutProperty->UpdatePadding(buttonTextPadding);
1088     if (!(Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN))) {
1089         if (!popupTheme->GetPopupDoubleButtonIsSameStyle()) {
1090             UpdateButtonTextColorForDiff(textLayoutProperty, buttonNumber);
1091         } else {
1092             textLayoutProperty->UpdateTextColor(popupTheme->GetButtonFontColor());
1093         }
1094     }
1095     auto buttonTextInsideMargin = popupTheme->GetButtonTextInsideMargin();
1096     buttonTextNode->MountToParent(buttonNode);
1097 
1098     PaddingProperty buttonPadding;
1099     auto padding = buttonTheme->GetPadding();
1100     buttonPadding.left = CalcLength(buttonTextInsideMargin);
1101     buttonPadding.right = CalcLength(buttonTextInsideMargin);
1102     if (!param->IsUseCustom()) {
1103         buttonPadding.left = CalcLength(popupTheme->GetAgingButtonLeftPadding());
1104         buttonPadding.right = CalcLength(popupTheme->GetAgingButtonRightPadding());
1105         buttonProp->UpdatePadding(buttonPadding);
1106     } else {
1107         buttonProp->UpdatePadding(buttonPadding);
1108     }
1109     if (buttonNode->GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_EIGHTEEN)) {
1110         buttonProp->UpdateType(ButtonType::ROUNDED_RECTANGLE);
1111     } else {
1112         auto popupButtonType = static_cast<ButtonType>(popupTheme->GetPopupButtonType());
1113         buttonProp->UpdateType(popupButtonType);
1114     }
1115     auto fontScale = pipelineContext->GetFontScale();
1116     if (fontScale == AGE_SCALE_NUMBER) {
1117         buttonProp->UpdateUserDefinedIdealSize(CalcSize(std::nullopt, CalcLength(popupTheme->GetButtonHeight())));
1118     }
1119     buttonProp->UpdateAlignment(Alignment::CENTER);
1120     auto buttonMiniMumWidth = popupTheme->GetButtonMiniMumWidth().ConvertToPx();
1121     buttonProp->UpdateCalcMinSize(CalcSize(CalcLength(buttonMiniMumWidth), std::nullopt));
1122     auto renderContext = buttonNode->GetRenderContext();
1123     if (renderContext) {
1124         if (buttonNumber == PRIMARY_BUTTON_NUMBER) {
1125             renderContext->UpdateBackgroundColor(popupTheme->GetPrimaryButtonBackgroundColor());
1126         } else if (buttonNumber == SECONDARY_BUTTON_NUMBER) {
1127             renderContext->UpdateBackgroundColor(popupTheme->GetSecondaryButtonBackgroundColor());
1128         } else {
1129             renderContext->UpdateBackgroundColor(Color::TRANSPARENT);
1130         }
1131     }
1132 
1133     auto buttonEventHub = buttonNode->GetOrCreateGestureEventHub();
1134     CHECK_NULL_RETURN(buttonEventHub, nullptr);
1135     buttonEventHub->AddClickEvent(buttonParam.action);
1136     auto closeCallback = [weak = AceType::WeakClaim(AceType::RawPtr(popupNode)), targetId](GestureEvent& /* info */) {
1137         auto node = weak.Upgrade();
1138         CHECK_NULL_VOID(node);
1139         auto context = node->GetContext();
1140         CHECK_NULL_VOID(context);
1141         auto overlayManager = context->GetOverlayManager();
1142         CHECK_NULL_VOID(overlayManager);
1143         auto popupInfo = overlayManager->GetPopupInfo(targetId);
1144         popupInfo.markNeedUpdate = true;
1145         overlayManager->HidePopup(targetId, popupInfo);
1146     };
1147     if (buttonParam.action) {
1148         buttonEventHub->AddClickEvent(buttonParam.action);
1149     } else {
1150         buttonEventHub->AddClickEvent(AceType::MakeRefPtr<ClickEvent>(closeCallback));
1151     }
1152     buttonNode->MarkModifyDone();
1153     return buttonNode;
1154 }
1155 
IsSupportBlurStyle(RefPtr<RenderContext> & renderContext,bool isShowInSubWindow,bool isTips)1156 bool BubbleView::IsSupportBlurStyle(RefPtr<RenderContext>& renderContext, bool isShowInSubWindow, bool isTips)
1157 {
1158     if (isTips) {
1159         return true;
1160     }
1161     if (isShowInSubWindow) {
1162         return renderContext->IsUniRenderEnabled();
1163     }
1164     return true;
1165 }
1166 
GetPopupInfoHelper(const RefPtr<UINode> & customNode,const std::function<PopupInfo (const RefPtr<OverlayManager> &)> & getPopupInfoFunc)1167 PopupInfo GetPopupInfoHelper(
1168     const RefPtr<UINode>& customNode, const std::function<PopupInfo(const RefPtr<OverlayManager>&)>& getPopupInfoFunc)
1169 {
1170     PopupInfo popupInfoError;
1171     auto context = customNode->GetContextWithCheck();
1172     CHECK_NULL_RETURN(context, popupInfoError);
1173     auto instanceId = context->GetInstanceId();
1174     auto subwindow = SubwindowManager::GetInstance()->GetSubwindowByType(instanceId, SubwindowType::TYPE_POPUP);
1175     if (subwindow) {
1176         auto overlayManager = subwindow->GetOverlayManager();
1177         if (overlayManager) {
1178             auto popupInfo = getPopupInfoFunc(overlayManager);
1179             if (popupInfo.popupNode) {
1180                 return popupInfo;
1181             }
1182         }
1183     }
1184     auto overlayManager = context->GetOverlayManager();
1185     if (overlayManager) {
1186         auto popupInfo = getPopupInfoFunc(overlayManager);
1187         if (popupInfo.popupNode) {
1188             return popupInfo;
1189         }
1190     }
1191     return popupInfoError;
1192 }
1193 
GetPopupInfoWithCustomNode(const RefPtr<UINode> & customNode)1194 PopupInfo BubbleView::GetPopupInfoWithCustomNode(const RefPtr<UINode>& customNode)
1195 {
1196     return GetPopupInfoHelper(customNode, [customNode](const RefPtr<OverlayManager>& overlayManager) {
1197         return overlayManager->GetPopupInfoWithExistContent(customNode);
1198     });
1199 }
1200 
GetPopupInfoWithTargetId(const RefPtr<UINode> & customNode,const int32_t targetId)1201 PopupInfo BubbleView::GetPopupInfoWithTargetId(const RefPtr<UINode>& customNode, const int32_t targetId)
1202 {
1203     return GetPopupInfoHelper(customNode,
1204         [targetId](const RefPtr<OverlayManager>& overlayManager) { return overlayManager->GetPopupInfo(targetId); });
1205 }
1206 
GetPopupOverlayManager(const RefPtr<UINode> & customNode,const int32_t targetId)1207 RefPtr<OverlayManager> BubbleView::GetPopupOverlayManager(const RefPtr<UINode>& customNode, const int32_t targetId)
1208 {
1209     auto context = customNode->GetContextWithCheck();
1210     CHECK_NULL_RETURN(context, nullptr);
1211     auto instanceId = context->GetInstanceId();
1212     auto subwindow = SubwindowManager::GetInstance()->GetSubwindowByType(instanceId, SubwindowType::TYPE_POPUP);
1213     if (subwindow) {
1214         auto overlayManager = subwindow->GetOverlayManager();
1215         if (overlayManager) {
1216             auto popupInfo = overlayManager->GetPopupInfo(targetId);
1217             if (popupInfo.popupNode) {
1218                 return overlayManager;
1219             }
1220         }
1221     }
1222     auto overlayManager = context->GetOverlayManager();
1223     if (overlayManager) {
1224         auto popupInfo = overlayManager->GetPopupInfo(targetId);
1225         if (popupInfo.popupNode) {
1226             return overlayManager;
1227         }
1228     }
1229     return nullptr;
1230 }
1231 } // namespace OHOS::Ace::NG
1232