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