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