1 /*
2 * Copyright (c) 2022 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
16 #include "core/components_ng/pattern/button/button_layout_algorithm.h"
17
18 #include "core/components/toggle/toggle_theme.h"
19 #include "core/components_ng/pattern/button/button_pattern.h"
20
21 namespace OHOS::Ace::NG {
22 namespace {
checkNegativeBorderRadius(std::optional<Dimension> & radius,const float defaultBorderRadius)23 void checkNegativeBorderRadius(std::optional<Dimension>& radius, const float defaultBorderRadius)
24 {
25 // Change the borderRadius size of a negative number to the default.
26 if (!radius.has_value() || LessNotEqual(radius.value().ConvertToPx(), 0.0)) {
27 radius = Dimension(defaultBorderRadius);
28 }
29 }
30 }
Measure(LayoutWrapper * layoutWrapper)31 void ButtonLayoutAlgorithm::Measure(LayoutWrapper* layoutWrapper)
32 {
33 auto host = layoutWrapper->GetHostNode();
34 CHECK_NULL_VOID(host);
35 auto pattern = host->GetPattern<ButtonPattern>();
36 CHECK_NULL_VOID(pattern);
37 auto buttonLayoutProperty = DynamicCast<ButtonLayoutProperty>(layoutWrapper->GetLayoutProperty());
38 CHECK_NULL_VOID(buttonLayoutProperty);
39 if (buttonLayoutProperty->HasType() && buttonLayoutProperty->GetType() == ButtonType::CIRCLE &&
40 !pattern->GetHasCustomPadding()) {
41 NG::PaddingProperty paddings;
42 paddings.top = std::optional<CalcLength>(CalcLength(0.0, DimensionUnit::VP));
43 paddings.bottom = std::optional<CalcLength>(CalcLength(0.0, DimensionUnit::VP));
44 paddings.left = std::optional<CalcLength>(CalcLength(0.0, DimensionUnit::VP));
45 paddings.right = std::optional<CalcLength>(CalcLength(0.0, DimensionUnit::VP));
46 buttonLayoutProperty->UpdatePadding(paddings);
47 }
48 if (pattern->UseContentModifier()) {
49 const auto& childList = layoutWrapper->GetAllChildrenWithBuild();
50 std::list<RefPtr<LayoutWrapper>> builderChildList;
51 for (const auto& child : childList) {
52 if (child->GetHostNode()->GetId() != pattern->GetBuilderId()) {
53 child->GetGeometryNode()->Reset();
54 child->GetGeometryNode()->SetContentSize(SizeF());
55 } else {
56 auto layoutConstraint = layoutWrapper->GetLayoutProperty()->CreateChildConstraint();
57 child->Measure(layoutConstraint);
58 builderChildList.push_back(child);
59 }
60 }
61 BoxLayoutAlgorithm::PerformMeasureSelfWithChildList(layoutWrapper, builderChildList);
62 return;
63 }
64 auto layoutConstraint = layoutWrapper->GetLayoutProperty()->CreateChildConstraint();
65 HandleChildLayoutConstraint(layoutWrapper, layoutConstraint);
66 if (buttonLayoutProperty->HasLabel()) {
67 // If the button has label, according to whether the font size is set to do the corresponding expansion button,
68 // font reduction, truncation and other operations.
69 HandleAdaptiveText(layoutWrapper, layoutConstraint);
70 } else {
71 // If the button has not label, measure the child directly.
72 for (auto&& child : layoutWrapper->GetAllChildrenWithBuild()) {
73 child->Measure(layoutConstraint);
74 }
75 }
76 PerformMeasureSelf(layoutWrapper);
77 }
78
HandleChildLayoutConstraint(LayoutWrapper * layoutWrapper,LayoutConstraintF & layoutConstraint)79 void ButtonLayoutAlgorithm::HandleChildLayoutConstraint(
80 LayoutWrapper* layoutWrapper, LayoutConstraintF& layoutConstraint)
81 {
82 auto buttonLayoutProperty = DynamicCast<ButtonLayoutProperty>(layoutWrapper->GetLayoutProperty());
83 CHECK_NULL_VOID(buttonLayoutProperty);
84 if (!buttonLayoutProperty->HasLabel()) {
85 return;
86 }
87 auto buttonType = buttonLayoutProperty->GetType().value_or(ButtonType::CAPSULE);
88 if (buttonType == ButtonType::CIRCLE) {
89 layoutConstraint.maxSize = HandleLabelCircleButtonConstraint(layoutWrapper).value_or(SizeF());
90 return;
91 }
92 const auto& selfLayoutConstraint = layoutWrapper->GetLayoutProperty()->GetLayoutConstraint();
93 // If height is not set, apply the default height.
94 if (selfLayoutConstraint && !selfLayoutConstraint->selfIdealSize.Height().has_value()) {
95 auto maxHeight = selfLayoutConstraint->maxSize.Height();
96 if (IsAging(layoutWrapper)) {
97 layoutConstraint.maxSize.SetHeight(maxHeight);
98 return;
99 }
100 auto defaultHeight = GetDefaultHeight(layoutWrapper);
101 layoutConstraint.maxSize.SetHeight(maxHeight > defaultHeight ? defaultHeight : maxHeight);
102 }
103 }
104
105 // If the ButtonType is CIRCLE, then omit text by the smaller edge.
HandleLabelCircleButtonConstraint(LayoutWrapper * layoutWrapper)106 std::optional<SizeF> ButtonLayoutAlgorithm::HandleLabelCircleButtonConstraint(LayoutWrapper* layoutWrapper)
107 {
108 SizeF constraintSize;
109 auto buttonLayoutProperty = DynamicCast<ButtonLayoutProperty>(layoutWrapper->GetLayoutProperty());
110 CHECK_NULL_RETURN(buttonLayoutProperty, constraintSize);
111 const auto& selfLayoutConstraint = layoutWrapper->GetLayoutProperty()->GetLayoutConstraint();
112 CHECK_NULL_RETURN(selfLayoutConstraint, constraintSize);
113 auto host = layoutWrapper->GetHostNode();
114 CHECK_NULL_RETURN(host, constraintSize);
115 auto* context = host->GetContextWithCheck();
116 CHECK_NULL_RETURN(context, constraintSize);
117 auto buttonTheme = context->GetTheme<ButtonTheme>();
118 CHECK_NULL_RETURN(buttonTheme, constraintSize);
119 const auto& padding = buttonLayoutProperty->CreatePaddingAndBorder();
120 auto defaultHeight = GetDefaultHeight(layoutWrapper);
121 float minLength = 0.0f;
122 if (selfLayoutConstraint->selfIdealSize.IsNull()) {
123 // Width and height are not set.
124 minLength = defaultHeight;
125 } else if (selfLayoutConstraint->selfIdealSize.Width().has_value() &&
126 !selfLayoutConstraint->selfIdealSize.Height().has_value()) {
127 // Only width is set.
128 minLength = selfLayoutConstraint->selfIdealSize.Width().value();
129 } else if (selfLayoutConstraint->selfIdealSize.Height().has_value() &&
130 !selfLayoutConstraint->selfIdealSize.Width().has_value()) {
131 // Only height is set.
132 minLength = selfLayoutConstraint->selfIdealSize.Height().value();
133 } else {
134 // Both width and height are set.
135 auto buttonWidth = selfLayoutConstraint->selfIdealSize.Width().value();
136 auto buttonHeight = selfLayoutConstraint->selfIdealSize.Height().value();
137 minLength = std::min(buttonWidth, buttonHeight);
138 }
139 if (buttonLayoutProperty->HasBorderRadius() && selfLayoutConstraint->selfIdealSize.IsNull()) {
140 auto radius =
141 static_cast<float>(GetFirstValidRadius(buttonLayoutProperty->GetBorderRadius().value()).ConvertToPx());
142 minLength = 2 * radius;
143 }
144 constraintSize.SetSizeT(SizeF(minLength, minLength));
145 MinusPaddingToSize(padding, constraintSize);
146 return ConstrainSize(constraintSize, selfLayoutConstraint->minSize, selfLayoutConstraint->maxSize);
147 }
148
HandleAdaptiveText(LayoutWrapper * layoutWrapper,LayoutConstraintF & layoutConstraint)149 void ButtonLayoutAlgorithm::HandleAdaptiveText(LayoutWrapper* layoutWrapper, LayoutConstraintF& layoutConstraint)
150 {
151 auto buttonLayoutProperty = DynamicCast<ButtonLayoutProperty>(layoutWrapper->GetLayoutProperty());
152 CHECK_NULL_VOID(buttonLayoutProperty);
153 auto host = layoutWrapper->GetHostNode();
154 CHECK_NULL_VOID(host);
155 auto* context = host->GetContextWithCheck();
156 CHECK_NULL_VOID(context);
157 auto buttonTheme = context->GetTheme<ButtonTheme>();
158 CHECK_NULL_VOID(buttonTheme);
159 auto childWrapper = layoutWrapper->GetOrCreateChildByIndex(0);
160 CHECK_NULL_VOID(childWrapper);
161 if (buttonLayoutProperty->HasFontSize() || buttonLayoutProperty->HasControlSize()) {
162 auto childConstraint = layoutWrapper->GetLayoutProperty()->GetContentLayoutConstraint();
163 childWrapper->Measure(childConstraint);
164 auto textSize = childWrapper->GetGeometryNode()->GetContentSize();
165 // Fonsize is set. When the font height is larger than the button height, make the button fit the font
166 // height.
167 if (GreatOrEqual(textSize.Height(), layoutConstraint.maxSize.Height())) {
168 layoutConstraint.maxSize.SetHeight(textSize.Height());
169 }
170 } else {
171 // Fonsize is not set. When the font width is greater than the button width, dynamically change the font
172 // size to no less than 9sp.
173 auto textLayoutProperty = DynamicCast<TextLayoutProperty>(childWrapper->GetLayoutProperty());
174 CHECK_NULL_VOID(textLayoutProperty);
175 if (buttonTheme->GetIsApplyTextFontSize() && !buttonLayoutProperty->GetMaxFontSize().has_value() &&
176 !buttonLayoutProperty->GetMinFontSize().has_value()) {
177 textLayoutProperty->ResetAdaptMaxFontSize();
178 textLayoutProperty->ResetAdaptMinFontSize();
179 } else {
180 textLayoutProperty->UpdateAdaptMaxFontSize(
181 buttonLayoutProperty->GetMaxFontSize().value_or(buttonTheme->GetMaxFontSize()));
182 textLayoutProperty->UpdateAdaptMinFontSize(
183 buttonLayoutProperty->GetMinFontSize().value_or(buttonTheme->GetMinFontSize()));
184 }
185 }
186 childWrapper->Measure(layoutConstraint);
187 childSize_ = childWrapper->GetGeometryNode()->GetContentSize();
188 }
189
HandleBorderRadius(LayoutWrapper * layoutWrapper)190 void ButtonLayoutAlgorithm::HandleBorderRadius(LayoutWrapper* layoutWrapper)
191 {
192 auto host = layoutWrapper->GetHostNode();
193 CHECK_NULL_VOID(host);
194 auto buttonLayoutProperty = DynamicCast<ButtonLayoutProperty>(layoutWrapper->GetLayoutProperty());
195 CHECK_NULL_VOID(buttonLayoutProperty);
196 auto frameSize = layoutWrapper->GetGeometryNode()->GetFrameSize();
197 auto renderContext = host->GetRenderContext();
198 CHECK_NULL_VOID(renderContext);
199 auto buttonType = buttonLayoutProperty->GetType().value_or(ButtonType::CAPSULE);
200 if (buttonType == ButtonType::CIRCLE) {
201 auto minSize = std::min(frameSize.Height(), frameSize.Width());
202 auto layoutConstraint = layoutWrapper->GetLayoutProperty()->CreateChildConstraint();
203 if (buttonLayoutProperty->HasBorderRadius() && layoutConstraint.parentIdealSize.IsNull()) {
204 auto borderRadius = buttonLayoutProperty->GetBorderRadius().value_or(NG::BorderRadiusProperty());
205 minSize = static_cast<float>(GetFirstValidRadius(borderRadius).ConvertToPx() * 2);
206 }
207 renderContext->UpdateBorderRadius(BorderRadiusProperty(Dimension(minSize / 2)));
208 MeasureCircleButton(layoutWrapper);
209 } else if (buttonType == ButtonType::CAPSULE) {
210 renderContext->UpdateBorderRadius(BorderRadiusProperty(Dimension(frameSize.Height() / 2)));
211 } else if (buttonType == ButtonType::NORMAL) {
212 auto normalRadius = buttonLayoutProperty->GetBorderRadiusValue(BorderRadiusProperty(Dimension()));
213 renderContext->UpdateBorderRadius(normalRadius);
214 } else if (buttonType == ButtonType::ROUNDED_RECTANGLE) {
215 auto defaultBorderRadius = GetDefaultBorderRadius(layoutWrapper);
216 auto roundedRectRadius =
217 buttonLayoutProperty->GetBorderRadiusValue(BorderRadiusProperty(Dimension(defaultBorderRadius)));
218 checkNegativeBorderRadius(roundedRectRadius.radiusTopLeft, defaultBorderRadius);
219 checkNegativeBorderRadius(roundedRectRadius.radiusTopRight, defaultBorderRadius);
220 checkNegativeBorderRadius(roundedRectRadius.radiusBottomLeft, defaultBorderRadius);
221 checkNegativeBorderRadius(roundedRectRadius.radiusBottomRight, defaultBorderRadius);
222 renderContext->UpdateBorderRadius(roundedRectRadius);
223 }
224 }
225
226 // Called to perform measure current render node.
PerformMeasureSelf(LayoutWrapper * layoutWrapper)227 void ButtonLayoutAlgorithm::PerformMeasureSelf(LayoutWrapper* layoutWrapper)
228 {
229 auto buttonLayoutProperty = DynamicCast<ButtonLayoutProperty>(layoutWrapper->GetLayoutProperty());
230 CHECK_NULL_VOID(buttonLayoutProperty);
231 BoxLayoutAlgorithm::PerformMeasureSelf(layoutWrapper);
232 if (NeedAgingMeasure(layoutWrapper)) {
233 return;
234 }
235 if (buttonLayoutProperty->HasLabel()) {
236 auto frameSize = layoutWrapper->GetGeometryNode()->GetFrameSize();
237 auto layoutConstraint = layoutWrapper->GetLayoutProperty()->CreateChildConstraint();
238 const auto& selfLayoutConstraint = layoutWrapper->GetLayoutProperty()->GetLayoutConstraint();
239 auto padding = buttonLayoutProperty->CreatePaddingAndBorder();
240 auto topPadding = padding.top.value_or(0.0);
241 auto bottomPadding = padding.bottom.value_or(0.0);
242 auto host = layoutWrapper->GetHostNode();
243 CHECK_NULL_VOID(host);
244 auto* context = host->GetContextWithCheck();
245 CHECK_NULL_VOID(context);
246 auto buttonTheme = context->GetTheme<ButtonTheme>();
247 CHECK_NULL_VOID(buttonTheme);
248
249 auto defaultHeight = GetDefaultHeight(layoutWrapper);
250 auto buttonType = buttonLayoutProperty->GetType().value_or(ButtonType::CAPSULE);
251 if (buttonType == ButtonType::CIRCLE) {
252 HandleLabelCircleButtonFrameSize(layoutConstraint, frameSize, defaultHeight);
253 } else {
254 if (selfLayoutConstraint && !selfLayoutConstraint->selfIdealSize.Height().has_value()) {
255 auto layoutContraint = buttonLayoutProperty->GetLayoutConstraint();
256 CHECK_NULL_VOID(layoutContraint);
257 auto maxHeight = layoutContraint->maxSize.Height();
258 auto minHeight = layoutContraint->minSize.Height();
259 auto actualHeight = static_cast<float>(childSize_.Height() + topPadding + bottomPadding);
260 actualHeight = std::min(actualHeight, maxHeight);
261 actualHeight = std::max(actualHeight, minHeight);
262 frameSize.SetHeight(maxHeight > defaultHeight ? std::max(defaultHeight, actualHeight) : maxHeight);
263 }
264 }
265 // Determine if the button needs to fit the font size.
266 if (buttonLayoutProperty->HasFontSize()) {
267 if (GreatOrEqual(childSize_.Height() + topPadding + bottomPadding, frameSize.Height())) {
268 frameSize = SizeF(frameSize.Width(), childSize_.Height() + topPadding + bottomPadding);
269 }
270 }
271 layoutWrapper->GetGeometryNode()->SetFrameSize(frameSize);
272 }
273 HandleBorderRadius(layoutWrapper);
274 }
275
HandleLabelCircleButtonFrameSize(const LayoutConstraintF & layoutConstraint,SizeF & frameSize,const float & defaultHeight)276 void ButtonLayoutAlgorithm::HandleLabelCircleButtonFrameSize(
277 const LayoutConstraintF& layoutConstraint, SizeF& frameSize, const float& defaultHeight)
278 {
279 float minLength = 0.0f;
280 if (layoutConstraint.parentIdealSize.IsNull()) {
281 minLength = static_cast<float>(defaultHeight);
282 } else if (layoutConstraint.parentIdealSize.Width().has_value() &&
283 !layoutConstraint.parentIdealSize.Height().has_value()) {
284 minLength = frameSize.Width();
285 } else if (layoutConstraint.parentIdealSize.Height().has_value() &&
286 !layoutConstraint.parentIdealSize.Width().has_value()) {
287 minLength = frameSize.Height();
288 } else {
289 minLength = std::min(frameSize.Width(), frameSize.Height());
290 }
291 frameSize.SetWidth(minLength);
292 frameSize.SetHeight(minLength);
293 }
294
MeasureCircleButton(LayoutWrapper * layoutWrapper)295 void ButtonLayoutAlgorithm::MeasureCircleButton(LayoutWrapper* layoutWrapper)
296 {
297 auto frameNode = layoutWrapper->GetHostNode();
298 CHECK_NULL_VOID(frameNode);
299 auto context = frameNode->GetRenderContext();
300 CHECK_NULL_VOID(context);
301 const auto& radius = context->GetBorderRadius();
302 SizeF frameSize = { -1, -1 };
303 if (radius.has_value()) {
304 auto radiusTopMax = std::max(radius->radiusTopLeft, radius->radiusTopRight);
305 auto radiusBottomMax = std::max(radius->radiusBottomLeft, radius->radiusBottomRight);
306 auto radiusMax = std::max(radiusTopMax, radiusBottomMax);
307 auto rrectRadius = radiusMax.value_or(0.0_vp).ConvertToPx();
308 frameSize.SetSizeT(SizeF { static_cast<float>(rrectRadius * 2), static_cast<float>(rrectRadius * 2) });
309 }
310 frameSize.UpdateIllegalSizeWithCheck(SizeF { 0.0f, 0.0f });
311 layoutWrapper->GetGeometryNode()->SetFrameSize(frameSize);
312 }
313
GetFirstValidRadius(const BorderRadiusProperty & borderRadius)314 Dimension ButtonLayoutAlgorithm::GetFirstValidRadius(const BorderRadiusProperty& borderRadius)
315 {
316 if (borderRadius.radiusTopLeft.has_value()) {
317 return borderRadius.radiusTopLeft.value();
318 }
319 if (borderRadius.radiusTopRight.has_value()) {
320 return borderRadius.radiusTopRight.value();
321 }
322 if (borderRadius.radiusBottomLeft.has_value()) {
323 return borderRadius.radiusBottomLeft.value();
324 }
325 if (borderRadius.radiusBottomRight.has_value()) {
326 return borderRadius.radiusBottomRight.value();
327 }
328 return 0.0_vp;
329 }
330
GetDefaultHeight(LayoutWrapper * layoutWrapper)331 float ButtonLayoutAlgorithm::GetDefaultHeight(LayoutWrapper* layoutWrapper)
332 {
333 auto layoutProperty = DynamicCast<ButtonLayoutProperty>(layoutWrapper->GetLayoutProperty());
334 CHECK_NULL_RETURN(layoutProperty, 0.0);
335 auto frameNode = layoutWrapper->GetHostNode();
336 CHECK_NULL_RETURN(frameNode, 0.0);
337 auto* context = frameNode->GetContext();
338 CHECK_NULL_RETURN(context, 0.0);
339 auto buttonTheme = context->GetTheme<ButtonTheme>();
340 CHECK_NULL_RETURN(buttonTheme, 0.0);
341 if (frameNode->GetTag() == V2::TOGGLE_ETS_TAG) {
342 auto toggleTheme = context->GetTheme<ToggleTheme>();
343 CHECK_NULL_RETURN(toggleTheme, 0.0);
344 return static_cast<float>(toggleTheme->GetButtonHeight().ConvertToPx());
345 }
346 ControlSize controlSize = layoutProperty->GetControlSize().value_or(ControlSize::NORMAL);
347 return static_cast<float>(buttonTheme->GetHeight(controlSize).ConvertToPx());
348 }
349
GetDefaultBorderRadius(LayoutWrapper * layoutWrapper)350 float ButtonLayoutAlgorithm::GetDefaultBorderRadius(LayoutWrapper* layoutWrapper)
351 {
352 auto layoutProperty = DynamicCast<ButtonLayoutProperty>(layoutWrapper->GetLayoutProperty());
353 CHECK_NULL_RETURN(layoutProperty, 0.0f);
354 auto frameNode = layoutWrapper->GetHostNode();
355 CHECK_NULL_RETURN(frameNode, 0.0f);
356 auto* context = frameNode->GetContext();
357 CHECK_NULL_RETURN(context, 0.0f);
358 auto buttonTheme = context->GetTheme<ButtonTheme>();
359 CHECK_NULL_RETURN(buttonTheme, 0.0f);
360 ControlSize controlSize = layoutProperty->GetControlSize().value_or(ControlSize::NORMAL);
361 return static_cast<float>(buttonTheme->GetBorderRadius(controlSize).ConvertToPx());
362 }
363
NeedAgingMeasure(LayoutWrapper * layoutWrapper)364 bool ButtonLayoutAlgorithm::NeedAgingMeasure(LayoutWrapper* layoutWrapper)
365 {
366 if (!IsAging(layoutWrapper)) {
367 return false;
368 }
369 auto buttonLayoutProperty = DynamicCast<ButtonLayoutProperty>(layoutWrapper->GetLayoutProperty());
370 CHECK_NULL_RETURN(buttonLayoutProperty, false);
371 auto pipeline = NG::PipelineContext::GetCurrentContextSafely();
372 CHECK_NULL_RETURN(pipeline, false);
373 auto buttonTheme = pipeline->GetTheme<ButtonTheme>();
374 float agingPadding = buttonTheme->GetAgingNormalPadding().ConvertToPx() * 2.0f;
375 if (buttonLayoutProperty->HasControlSize() && buttonLayoutProperty->GetControlSize() == ControlSize::SMALL) {
376 agingPadding = buttonTheme->GetAgingSmallPadding().ConvertToPx() * 2.0f;
377 }
378 auto host = layoutWrapper->GetHostNode();
379 CHECK_NULL_RETURN(host, false);
380 auto pattern = host->GetPattern<ButtonPattern>();
381 CHECK_NULL_RETURN(pattern, false);
382 if (!pattern->GetHasCustomPadding()) {
383 auto geometryNode = layoutWrapper->GetGeometryNode();
384 CHECK_NULL_RETURN(geometryNode, false);
385 auto frameSize = geometryNode->GetFrameSize();
386 if (buttonLayoutProperty->HasLabel()) {
387 auto childWrapper = layoutWrapper->GetOrCreateChildByIndex(0);
388 CHECK_NULL_RETURN(childWrapper, false);
389 auto childGeometryNode = childWrapper->GetGeometryNode();
390 CHECK_NULL_RETURN(childGeometryNode, false);
391 auto childFrameSize = childGeometryNode->GetContentSize();
392 frameSize.SetHeight(childFrameSize.Height() + agingPadding);
393 } else {
394 frameSize.SetHeight(frameSize.Height() + agingPadding);
395 }
396 auto layoutContraint = buttonLayoutProperty->GetLayoutConstraint();
397 CHECK_NULL_RETURN(layoutContraint, false);
398 auto maxHeight = layoutContraint->maxSize.Height();
399 auto minHeight = layoutContraint->minSize.Height();
400 auto actualHeight = frameSize.Height();
401 actualHeight = std::min(actualHeight, maxHeight);
402 actualHeight = std::max(actualHeight, minHeight);
403 frameSize.SetHeight(actualHeight);
404 geometryNode->SetFrameSize(frameSize);
405 }
406 HandleBorderRadius(layoutWrapper);
407 return true;
408 }
409
IsAging(LayoutWrapper * layoutWrapper)410 bool ButtonLayoutAlgorithm::IsAging(LayoutWrapper* layoutWrapper)
411 {
412 auto buttonLayoutProperty = DynamicCast<ButtonLayoutProperty>(layoutWrapper->GetLayoutProperty());
413 CHECK_NULL_RETURN(buttonLayoutProperty, false);
414
415 if (buttonLayoutProperty->HasType() && buttonLayoutProperty->GetType() == ButtonType::CIRCLE) {
416 return false;
417 }
418
419 if (buttonLayoutProperty->HasLabel() && buttonLayoutProperty->GetLabel()->empty()) {
420 return false;
421 }
422
423 if (buttonLayoutProperty->HasFontSize() && buttonLayoutProperty->GetFontSize()->Unit() != DimensionUnit::FP) {
424 return false;
425 }
426 const auto& calcConstraint = buttonLayoutProperty->GetCalcLayoutConstraint();
427 if (calcConstraint && calcConstraint->selfIdealSize->Height().has_value() &&
428 calcConstraint->selfIdealSize->Width().has_value()) {
429 return false;
430 }
431 auto pipeline = NG::PipelineContext::GetCurrentContextSafely();
432 CHECK_NULL_RETURN(pipeline, false);
433 auto buttonTheme = pipeline->GetTheme<ButtonTheme>();
434 CHECK_NULL_RETURN(buttonTheme, false);
435 auto fontScale = pipeline->GetFontScale();
436 if (!(NearEqual(fontScale, buttonTheme->GetBigFontSizeScale()) ||
437 NearEqual(fontScale, buttonTheme->GetLargeFontSizeScale()) ||
438 NearEqual(fontScale, buttonTheme->GetMaxFontSizeScale()))) {
439 return false;
440 }
441 return true;
442 }
443 } // namespace OHOS::Ace::NG
444