• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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_pattern.h"
16 
17 #include "base/utils/utils.h"
18 #include "core/components/common/layout/grid_system_manager.h"
19 #include "core/components_ng/layout/layout_wrapper.h"
20 #include "core/components_ng/pattern/text/text_layout_property.h"
21 #include "core/pipeline/pipeline_base.h"
22 #include "core/pipeline_ng/pipeline_context.h"
23 
24 namespace OHOS::Ace::NG {
25 namespace {
26 constexpr int32_t API_VERSION_9 = 9;
27 
GetTextHeight(const RefPtr<FrameNode> & textNode)28 float GetTextHeight(const RefPtr<FrameNode>& textNode)
29 {
30     auto textLayoutProperty = textNode->GetLayoutProperty<TextLayoutProperty>();
31     CHECK_NULL_RETURN(textLayoutProperty, 0.0f);
32     auto layoutConstraint = textLayoutProperty->GetLayoutConstraint();
33 
34     auto textLayoutWrapper = textNode->CreateLayoutWrapper();
35     CHECK_NULL_RETURN(textLayoutWrapper, 0.0f);
36     textLayoutWrapper->Measure(layoutConstraint);
37     auto textGeometry = textLayoutWrapper->GetGeometryNode();
38     CHECK_NULL_RETURN(textGeometry, 0.0f);
39     auto textSize = textGeometry->GetMarginFrameSize();
40     return textSize.Height();
41 }
42 } // namespace
43 
OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper> & dirty,const DirtySwapConfig & changeConfig)44 bool ToastPattern::OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& changeConfig)
45 {
46     CHECK_NULL_RETURN(dirty, false);
47 
48     auto toastBottom = GetBottomValue(dirty);
49     // todo get parent width and height
50     auto context = PipelineContext::GetCurrentContext();
51     auto rootHeight = context->GetRootHeight();
52     auto rootWidth = context->GetRootWidth();
53     auto text = dirty->GetOrCreateChildByIndex(0);
54     CHECK_NULL_RETURN(text, false);
55     auto toastNode = dirty->GetHostNode();
56     auto toastContext = toastNode->GetRenderContext();
57     CHECK_NULL_RETURN(toastContext, false);
58 
59     OffsetT<Dimension> offset { Dimension((rootWidth - text->GetGeometryNode()->GetMarginFrameSize().Width()) / 2.0f),
60         {} };
61     if (context->GetMinPlatformVersion() > API_VERSION_9) {
62         auto layoutProperty = dirty->GetLayoutProperty();
63         CHECK_NULL_RETURN(layoutProperty, false);
64         const auto& safeArea = layoutProperty->GetSafeAreaInsets();
65         offset.SetY(Dimension { rootHeight - toastBottom - dirty->GetGeometryNode()->GetMarginFrameSize().Height() -
66                                 (safeArea ? safeArea->bottom_.Length() : 0.0f) });
67     } else {
68         offset.SetY(Dimension { rootHeight - toastBottom });
69     }
70     LOGD("Toast bottom value: [%{public}f], offsetX [%{public}s] offsetY [%{public}s]", toastBottom,
71         offset.GetX().ToString().c_str(), offset.GetY().ToString().c_str());
72     toastContext->UpdateOffset(offset);
73 
74     return true;
75 }
76 
GetBottomValue(const RefPtr<LayoutWrapper> & layoutWrapper)77 double ToastPattern::GetBottomValue(const RefPtr<LayoutWrapper>& layoutWrapper)
78 {
79     auto pipeline = PipelineBase::GetCurrentContext();
80     CHECK_NULL_RETURN(pipeline, 0.0);
81     auto rootHeight = Dimension(pipeline->GetRootHeight());
82     auto toastTheme = pipeline->GetTheme<ToastTheme>();
83     CHECK_NULL_RETURN(toastTheme, 0.0);
84 
85     auto toastProp = DynamicCast<ToastLayoutProperty>(layoutWrapper->GetLayoutProperty());
86     CHECK_NULL_RETURN(toastProp, 0.0);
87     auto toastBottom = toastProp->GetBottomValue(toastTheme->GetBottom());
88     if (toastBottom.Unit() == DimensionUnit::PERCENT) {
89         toastBottom = rootHeight * toastBottom.Value();
90     }
91     return GreatOrEqual(toastBottom.ConvertToPx(), 0.0) ? toastBottom.ConvertToPx()
92                                                         : toastTheme->GetBottom().ConvertToPx();
93 }
94 
BeforeCreateLayoutWrapper()95 void ToastPattern::BeforeCreateLayoutWrapper()
96 {
97     PopupBasePattern::BeforeCreateLayoutWrapper();
98 
99     auto toastNode = GetHost();
100     CHECK_NULL_VOID(toastNode);
101     UpdateToastSize(toastNode);
102 
103     auto textNode = DynamicCast<FrameNode>(toastNode->GetFirstChild());
104     CHECK_NULL_VOID(textNode);
105     UpdateTextSizeConstraint(textNode);
106 
107     auto context = PipelineBase::GetCurrentContext();
108     CHECK_NULL_VOID(context);
109     auto toastTheme = context->GetTheme<ToastTheme>();
110     CHECK_NULL_VOID(toastTheme);
111     auto textHeight = GetTextHeight(textNode);
112     if (textHeight > toastTheme->GetMinHeight().ConvertToPx()) {
113         textNode->GetLayoutProperty<TextLayoutProperty>()->UpdateTextAlign(TextAlign::START);
114     }
115 }
116 
UpdateToastSize(const RefPtr<FrameNode> & toast)117 void ToastPattern::UpdateToastSize(const RefPtr<FrameNode>& toast)
118 {
119     CHECK_NULL_VOID(toast);
120     auto toastProperty = toast->GetLayoutProperty<ToastLayoutProperty>();
121     CHECK_NULL_VOID(toastProperty);
122     auto context = PipelineBase::GetCurrentContext();
123     CHECK_NULL_VOID(context);
124     auto rootWidth = Dimension(context->GetRootWidth());
125     toastProperty->UpdateUserDefinedIdealSize(CalcSize(NG::CalcLength(rootWidth), std::nullopt));
126 }
127 
UpdateTextSizeConstraint(const RefPtr<FrameNode> & text)128 void ToastPattern::UpdateTextSizeConstraint(const RefPtr<FrameNode>& text)
129 {
130     CHECK_NULL_VOID(text);
131     auto context = PipelineBase::GetCurrentContext();
132     CHECK_NULL_VOID(context);
133     auto gridColumnInfo = GridSystemManager::GetInstance().GetInfoByType(GridColumnType::TOAST);
134     auto parent = gridColumnInfo->GetParent();
135     if (parent) {
136         parent->BuildColumnWidth(context->GetRootWidth());
137     }
138     auto maxWidth = Dimension(gridColumnInfo->GetMaxWidth());
139     auto textLayoutProperty = text->GetLayoutProperty();
140     CHECK_NULL_VOID(textLayoutProperty);
141     textLayoutProperty->UpdateCalcMaxSize(CalcSize(NG::CalcLength(maxWidth), std::nullopt));
142 
143     auto toastTheme = context->GetTheme<ToastTheme>();
144     CHECK_NULL_VOID(toastTheme);
145     auto minWidth = Dimension(toastTheme->GetMinWidth().ConvertToPx());
146     auto minHeight = Dimension(toastTheme->GetMinHeight().ConvertToPx());
147     textLayoutProperty->UpdateCalcMinSize(CalcSize(NG::CalcLength(minWidth), NG::CalcLength(minHeight)));
148 }
149 
OnColorConfigurationUpdate()150 void ToastPattern::OnColorConfigurationUpdate()
151 {
152     auto host = GetHost();
153     CHECK_NULL_VOID(host);
154     auto textContext = host->GetRenderContext();
155     CHECK_NULL_VOID(textContext);
156     auto pipelineContext = PipelineBase::GetCurrentContext();
157     CHECK_NULL_VOID(pipelineContext);
158     auto toastTheme = pipelineContext->GetTheme<ToastTheme>();
159     CHECK_NULL_VOID(toastTheme);
160     auto textColor = toastTheme->GetTextStyle().GetTextColor();
161     auto textLayoutProperty = textNode_->GetLayoutProperty<TextLayoutProperty>();
162     CHECK_NULL_VOID(textLayoutProperty);
163     textLayoutProperty->UpdateTextColor(textColor);
164     host->SetNeedCallChildrenUpdate(false);
165 }
166 } // namespace OHOS::Ace::NG
167