• 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/toast/toast_view.h"
16 
17 #include "core/components/theme/shadow_theme.h"
18 #include "core/components_ng/pattern/text/text_pattern.h"
19 #include "core/components_ng/pattern/toast/toast_pattern.h"
20 #include "core/components_v2/inspector/inspector_constants.h"
21 
22 namespace OHOS::Ace::NG {
23 constexpr float MAX_TOAST_SCALE = 2.0f;
CreateToastNode(const ToastInfo & toastInfo)24 RefPtr<FrameNode> ToastView::CreateToastNode(const ToastInfo& toastInfo)
25 {
26     auto textId = ElementRegister::GetInstance()->MakeUniqueId();
27     auto toastId = ElementRegister::GetInstance()->MakeUniqueId();
28     // make toast node
29     ACE_LAYOUT_SCOPED_TRACE("Create[%s][self:%d]", V2::TOAST_ETS_TAG, toastId);
30     auto toastNode = FrameNode::CreateFrameNode(V2::TOAST_ETS_TAG, toastId, AceType::MakeRefPtr<ToastPattern>());
31     CHECK_NULL_RETURN(toastNode, nullptr);
32     auto toastProperty = toastNode->GetLayoutProperty<ToastLayoutProperty>();
33     CHECK_NULL_RETURN(toastProperty, nullptr);
34     auto toastContext = toastNode->GetRenderContext();
35     CHECK_NULL_RETURN(toastContext, nullptr);
36     auto context = toastNode->GetContext();
37     CHECK_NULL_RETURN(context, nullptr);
38     auto toastTheme = context->GetTheme<ToastTheme>();
39     CHECK_NULL_RETURN(toastTheme, nullptr);
40     auto toastAccessibilityProperty = toastNode->GetAccessibilityProperty<AccessibilityProperty>();
41     CHECK_NULL_RETURN(toastAccessibilityProperty, nullptr);
42     toastAccessibilityProperty->SetUserTextValue(toastInfo.message);
43     toastAccessibilityProperty->SetAccessibilityLevel(AccessibilityProperty::Level::NO_HIDE_DESCENDANTS);
44     // create text in toast
45     auto textNode = FrameNode::CreateFrameNode(V2::TEXT_ETS_TAG, textId, AceType::MakeRefPtr<TextPattern>());
46     CHECK_NULL_RETURN(textNode, nullptr);
47     auto textLayoutProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
48     CHECK_NULL_RETURN(textLayoutProperty, nullptr);
49     auto pattern = toastNode->GetPattern<ToastPattern>();
50     CHECK_NULL_RETURN(pattern, nullptr);
51     pattern->SetToastInfo(toastInfo);
52     pattern->SetTextNode(textNode);
53     UpdateTextLayoutProperty(textNode, toastInfo.message, toastInfo.isRightToLeft, toastInfo.textColor);
54     UpdateToastContext(toastNode);
55     textNode->MountToParent(toastNode);
56     auto align = Alignment::ParseAlignment(toastInfo.alignment);
57     if (align.has_value()) {
58         toastProperty->UpdateToastAlignment(align.value());
59     } else {
60         toastProperty->ResetToastAlignment();
61     }
62     if (toastInfo.offset.has_value()) {
63         toastProperty->UpdateToastOffset(toastInfo.offset.value());
64     } else {
65         toastProperty->ResetToastOffset();
66     }
67     toastProperty->UpdateBottom(
68         StringUtils::StringToDimensionWithThemeValue(toastInfo.bottom, true, toastTheme->GetBottom()));
69     toastProperty->UpdateShowMode(toastInfo.showMode);
70     toastProperty->UpdateHoverModeArea(toastInfo.hoverModeArea);
71     toastNode->GetOrCreateEventHub<EventHub>()->GetOrCreateGestureEventHub()
72         ->SetHitTestMode(HitTestMode::HTMTRANSPARENT);
73     toastNode->MarkModifyDone();
74     return toastNode;
75 }
76 
UpdateTextLayoutProperty(const RefPtr<FrameNode> & textNode,const std::string & message,bool isRightToLeft,const std::optional<Color> & textColor)77 void ToastView::UpdateTextLayoutProperty(
78     const RefPtr<FrameNode>& textNode, const std::string& message,
79     bool isRightToLeft, const std::optional<Color>& textColor)
80 {
81     auto textLayoutProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
82     CHECK_NULL_VOID(textLayoutProperty);
83     auto context = textNode->GetContext();
84     CHECK_NULL_VOID(context);
85     auto toastTheme = context->GetTheme<ToastTheme>();
86     CHECK_NULL_VOID(toastTheme);
87     auto fontSize = toastTheme->GetTextStyle().GetFontSize();
88     auto padding = toastTheme->GetPadding();
89     auto fontWeight = toastTheme->GetTextStyle().GetFontWeight();
90     auto defaultColor = toastTheme->GetTextStyle().GetTextColor();
91     textLayoutProperty->UpdateMaxFontScale(std::min(MAX_TOAST_SCALE, context->GetMaxAppFontScale()));
92     PaddingProperty paddings;
93     paddings.top = NG::CalcLength(padding.Top());
94     paddings.bottom = NG::CalcLength(padding.Bottom());
95     paddings.left = NG::CalcLength(padding.Left());
96     paddings.right = NG::CalcLength(padding.Right());
97 
98     textLayoutProperty->UpdateContent(message);
99     textLayoutProperty->UpdateTextAlign(TextAlign::CENTER);
100     textLayoutProperty->UpdateFontSize(fontSize);
101     textLayoutProperty->UpdatePadding(paddings);
102     textLayoutProperty->UpdateTextColor(textColor.value_or(defaultColor));
103     textLayoutProperty->UpdateFontWeight(fontWeight);
104     auto textContext = textNode->GetRenderContext();
105     CHECK_NULL_VOID(textContext);
106     textContext->UpdateClipEdge(false);
107 
108     if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
109         textLayoutProperty->UpdateTextOverflow(TextOverflow::ELLIPSIS);
110         textLayoutProperty->UpdateEllipsisMode(EllipsisMode::TAIL);
111     }
112 }
113 
UpdateToastContext(const RefPtr<FrameNode> & toastNode)114 void ToastView::UpdateToastContext(const RefPtr<FrameNode>& toastNode)
115 {
116     auto toastContext = toastNode->GetRenderContext();
117     CHECK_NULL_VOID(toastContext);
118     auto pattern = toastNode->GetPattern<ToastPattern>();
119     CHECK_NULL_VOID(pattern);
120     auto pipelineContext = toastNode->GetContext();
121     CHECK_NULL_VOID(pipelineContext);
122     auto toastTheme = pipelineContext->GetTheme<ToastTheme>();
123     CHECK_NULL_VOID(toastTheme);
124     auto radius = toastTheme->GetRadius();
125     BorderRadiusProperty borderRadius;
126     borderRadius.SetRadius(Dimension(radius.GetX().ConvertToPx()));
127     toastContext->UpdateBorderRadius(borderRadius);
128     if (toastTheme->GetToastDoubleBorderEnable()) {
129         toastContext->UpdateOuterBorderRadius(borderRadius);
130         auto toastProperty = toastNode->GetLayoutProperty<ToastLayoutProperty>();
131         CHECK_NULL_VOID(toastProperty);
132 
133         BorderWidthProperty innerWidthProp;
134         innerWidthProp.SetBorderWidth(Dimension(toastTheme->GetToastInnerBorderWidth()));
135         toastContext->UpdateBorderWidth(innerWidthProp);
136         BorderColorProperty innerColorProp;
137         innerColorProp.SetColor(toastTheme->GetToastInnerBorderColor());
138         toastContext->UpdateBorderColor(innerColorProp);
139         toastProperty->UpdateBorderWidth(innerWidthProp);
140 
141         BorderWidthProperty outerWidthProp;
142         outerWidthProp.SetBorderWidth(Dimension(toastTheme->GetToastOuterBorderWidth()));
143         toastContext->UpdateOuterBorderWidth(outerWidthProp);
144         BorderColorProperty outerColorProp;
145         outerColorProp.SetColor(toastTheme->GetToastOuterBorderColor());
146         toastContext->UpdateOuterBorderColor(outerColorProp);
147     }
148     auto toastInfo = pattern->GetToastInfo();
149     ToastView::UpdateToastNodeStyle(toastNode);
150 }
151 
UpdateToastNodeStyle(const RefPtr<FrameNode> & toastNode)152 void ToastView::UpdateToastNodeStyle(const RefPtr<FrameNode>& toastNode)
153 {
154     auto toastContext = toastNode->GetRenderContext();
155     CHECK_NULL_VOID(toastContext);
156     auto pattern = toastNode->GetPattern<ToastPattern>();
157     CHECK_NULL_VOID(pattern);
158     auto pipelineContext = toastNode->GetContext();
159     CHECK_NULL_VOID(pipelineContext);
160     auto toastTheme = pipelineContext->GetTheme<ToastTheme>();
161     CHECK_NULL_VOID(toastTheme);
162     auto toastInfo = pattern->GetToastInfo();
163     auto shadowStyle = toastTheme->GetToastShadowStyle();
164     auto shadow = toastInfo.shadow.value_or(Shadow::CreateShadow(shadowStyle));
165 
166     if (toastInfo.isTypeStyleShadow) {
167         auto colorMode = pipelineContext->GetColorMode();
168         auto shadowStyle = shadow.GetStyle();
169         auto shadowTheme = pipelineContext->GetTheme<ShadowTheme>();
170         if (shadowTheme) {
171             shadow = shadowTheme->GetShadow(shadowStyle, colorMode);
172         }
173     }
174     toastContext->UpdateBackShadow(shadow);
175     if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_TWELVE)) {
176         toastContext->UpdateBackgroundColor(toastInfo.backgroundColor.value_or(toastTheme->GetDefaultBGColor()));
177         BlurStyleOption styleOption;
178         styleOption.blurStyle = static_cast<BlurStyle>(
179             toastInfo.backgroundBlurStyle.value_or(toastTheme->GetToastBackgroundBlurStyle()));
180         styleOption.policy = BlurStyleActivePolicy::ALWAYS_ACTIVE;
181         if (!toastInfo.backgroundColor.has_value()) {
182             styleOption.colorMode = static_cast<ThemeColorMode>(toastTheme->GetBgThemeColorMode());
183         }
184         toastContext->UpdateBackBlurStyle(styleOption);
185     } else {
186         auto toastBackgroundColor = toastTheme->GetBackgroundColor();
187         toastContext->UpdateBackgroundColor(toastBackgroundColor);
188     }
189 }
190 } // namespace OHOS::Ace::NG
191