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