1 /*
2 * Copyright (c) 2021-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 "frameworks/bridge/common/dom/dom_button.h"
17
18 #include "base/log/event_report.h"
19 #include "core/common/ace_application_info.h"
20 #include "frameworks/bridge/common/dom/dom_div.h"
21 #include "frameworks/bridge/common/utils/utils.h"
22
23 namespace OHOS::Ace::Framework {
24 namespace {
25
26 // Button types definition
27 const char BUTTON_TYPE_CAPSULE[] = "capsule";
28 const char BUTTON_TYPE_TEXT[] = "text";
29 const char BUTTON_TYPE_CIRCLE[] = "circle";
30 const char BUTTON_TYPE_DOWNLOAD[] = "download";
31 const char BUTTON_TYPE_ICON[] = "icon";
32 const char BUTTON_TYPE_ARC[] = "arc"; // for watch
33
34 // Button children placement definition
35 const char PLACEMENT_START[] = "start";
36 const char PLACEMENT_TOP[] = "top";
37 const char PLACEMENT_BOTTOM[] = "bottom";
38
39 // Watch button definitions
40 constexpr Dimension ARC_FONT_SIZE = 19.0_fp;
41 constexpr Dimension ARC_FONT_MIN_SIZE = 16.0_fp;
42 constexpr Dimension ARC_PADDING_TOP = 8.0_vp;
43 constexpr Dimension ARC_PADDING_BOTTOM = 0.0_vp;
44 constexpr Dimension ARC_PADDING_HORIZONTAL = 30.0_vp;
45 constexpr Dimension WATCH_TEXT_PADDING = 2.0_vp;
46 constexpr Dimension WATCH_TEXT_RADIUS = 4.0_vp;
47 constexpr uint32_t MAX_LINES = 2;
48
49 // TV button definitions
50 constexpr Dimension TEXT_PADDING_HORIZONTAL = 8.0_vp;
51 constexpr Dimension TEXT_PADDING_VERTICAL = 0.0_vp;
52 constexpr Dimension TEXT_FONT_MIN_SIZE = 12.0_fp;
53 constexpr double TEXT_FOCUS_HEIGHT = 24.0;
54
55 constexpr uint32_t TRANSPARENT_COLOR = 0x00000000;
56 constexpr double FLEX_ITEM_SHRINK = 1.0;
57 constexpr double INIT_HEIGHT = -1.0;
58 constexpr Dimension DOWNLOAD_BORDER_WIDTH = Dimension(1.0, DimensionUnit::VP);
59 constexpr Dimension ICON_BUTTON_PADDING = 0.0_vp;
60 constexpr Dimension ICON_BUTTON_RADIUS = 0.0_vp;
61 constexpr Dimension INNER_PADDING = 4.0_vp;
62
63 } // namespace
64
DOMButton(NodeId nodeId,const std::string & nodeName)65 DOMButton::DOMButton(NodeId nodeId, const std::string& nodeName) : DOMNode(nodeId, nodeName)
66 {
67 std::list<RefPtr<Component>> buttonChildren;
68 buttonChild_ = AceType::MakeRefPtr<ButtonComponent>(buttonChildren);
69 buttonChild_->SetCatchMode(false);
70 textChild_ = AceType::MakeRefPtr<TextComponent>("");
71 imageChild_ = AceType::MakeRefPtr<ImageComponent>("");
72 paddingChild_ = AceType::MakeRefPtr<PaddingComponent>();
73 buttonChild_->AppendChild(paddingChild_);
74 isWatch_ = (SystemProperties::GetDeviceType() == DeviceType::WATCH);
75 isTv_ = (SystemProperties::GetDeviceType() == DeviceType::TV);
76 Component::MergeRSNode(textChild_);
77 Component::MergeRSNode(imageChild_);
78 }
79
ResetInitializedStyle()80 void DOMButton::ResetInitializedStyle()
81 {
82 if (declaration_) {
83 declaration_->InitializeStyle();
84 }
85 }
86
PrepareSpecializedComponent()87 void DOMButton::PrepareSpecializedComponent()
88 {
89 buttonTheme_ = GetTheme<ButtonTheme>();
90 buttonDeclaration_ = AceType::DynamicCast<ButtonDeclaration>(declaration_);
91 if (!buttonDeclaration_ || !buttonTheme_) {
92 return;
93 }
94 textChild_->SetTextDirection(IsRightToLeft() ? TextDirection::RTL : TextDirection::LTR);
95 imageChild_->SetTextDirection(IsRightToLeft() ? TextDirection::RTL : TextDirection::LTR);
96 buttonChild_->SetLayoutFlag(LAYOUT_FLAG_EXTEND_TO_PARENT);
97 buttonType_ = buttonDeclaration_->GetType();
98 textStyle_ = buttonDeclaration_->GetTextStyle();
99 edge_ = buttonDeclaration_->GetBorderEdge();
100 blendOpacity_ = buttonDeclaration_->GetBlendOpacity();
101 diameter_ = buttonDeclaration_->GetProgressDiameter();
102 imageChild_->SetSrc(buttonDeclaration_->GetIconSrc());
103 imageChild_->SetImageFill(GetImageFill());
104 imageChild_->SetWidth(buttonDeclaration_->GetIconWidth());
105 imageChild_->SetHeight(buttonDeclaration_->GetIconHeight());
106 imageChild_->SetFitMaxSize(false);
107 paddingChild_->SetPadding(buttonDeclaration_->GetPadding());
108 textChild_->SetData(buttonDeclaration_->GetTextData());
109 bool isCard = AceApplicationInfo::GetInstance().GetIsCardType();
110 if (isCard) {
111 textStyle_.SetAllowScale(false);
112 if (textStyle_.GetFontSize().Unit() == DimensionUnit::FP) {
113 textStyle_.SetAllowScale(true);
114 }
115 }
116 if (!focusColorChanged_) {
117 focusColor_ = buttonDeclaration_->GetFocusColor();
118 }
119 paddingChild_->SetChild(textChild_);
120 PrepareBoxSize();
121 PrepareUniversalButton();
122 PrepareBorderStyle();
123 PrepareBackDecorationStyle();
124 PrepareButtonState();
125 PreparePseudoStyle();
126 if (!isTv_) {
127 textChild_->SetFocusColor(textStyle_.GetTextColor());
128 if (!isWatch_) {
129 PrepareClickedColor();
130 }
131 }
132 if (buttonDeclaration_->GetFontSizeState()) {
133 textStyle_.SetAdaptTextSize(textStyle_.GetFontSize(), textStyle_.GetFontSize());
134 }
135 textChild_->SetTextStyle(textStyle_);
136 buttonDeclaration_->SetBorderEdge(edge_);
137 buttonChild_->SetDeclaration(buttonDeclaration_);
138 AddPadding();
139 }
140
PrepareBoxSize()141 void DOMButton::PrepareBoxSize()
142 {
143 if (!boxComponent_) {
144 return;
145 }
146 boxComponent_->SetDeliverMinToChild(true);
147 backDecoration_ = boxComponent_->GetBackDecoration();
148 if (buttonType_ == BUTTON_TYPE_ARC) {
149 return;
150 }
151 buttonChild_->SetWidth(buttonDeclaration_->GetWidth());
152 buttonChild_->SetHeight(buttonDeclaration_->GetHeight());
153 if (GreatOrEqual(buttonChild_->GetWidth().Value(), 0.0)) {
154 boxComponent_->SetWidth(buttonChild_->GetWidth().Value(), buttonChild_->GetWidth().Unit());
155 }
156 if (GreatOrEqual(buttonChild_->GetHeight().Value(), 0.0)) {
157 boxComponent_->SetHeight(buttonChild_->GetHeight().Value(), buttonChild_->GetHeight().Unit());
158 }
159 // Use theme height if user not define. Circle button will calculate height when rendering.
160 if ((buttonType_ != BUTTON_TYPE_CIRCLE) && (LessNotEqual(buttonChild_->GetHeight().Value(), 0.0))) {
161 if ((buttonType_ == BUTTON_TYPE_DOWNLOAD) && (SystemProperties::GetDeviceType() == DeviceType::PHONE)) {
162 boxComponent_->SetHeight(buttonTheme_->GetDownloadHeight().Value(),
163 buttonTheme_->GetDownloadHeight().Unit());
164 return;
165 }
166 boxComponent_->SetHeight(buttonTheme_->GetHeight().Value(), buttonTheme_->GetHeight().Unit());
167 }
168 }
169
PreparePseudoStyle()170 void DOMButton::PreparePseudoStyle()
171 {
172 if (!HasPseudo()) {
173 return;
174 }
175 if (HasActivePseudo()) {
176 buttonDeclaration_->SetClickedColor(buttonDeclaration_->GetBackgroundColor());
177 }
178 if (HasFocusPseudo()) {
179 buttonDeclaration_->SetFocusColor(buttonDeclaration_->GetBackgroundColor());
180 }
181 }
182
PrepareUniversalButton()183 void DOMButton::PrepareUniversalButton()
184 {
185 UpdateCustomizedColorFlag();
186 if (buttonType_ == BUTTON_TYPE_ICON) {
187 PrepareIconButton();
188 } else if (buttonType_ == BUTTON_TYPE_CAPSULE) {
189 PrepareCapsuleButton();
190 } else if (buttonType_ == BUTTON_TYPE_TEXT) {
191 PrepareTextButton();
192 } else if (buttonType_ == BUTTON_TYPE_CIRCLE) {
193 PrepareCircleButton();
194 } else if (buttonType_ == BUTTON_TYPE_DOWNLOAD) {
195 PrepareDownloadButton();
196 } else if (buttonType_ == BUTTON_TYPE_ARC) {
197 PrepareArcButton();
198 } else {
199 PrepareDefaultButton();
200 }
201 }
202
PrepareDefaultButton()203 void DOMButton::PrepareDefaultButton()
204 {
205 paddingChild_->SetPadding(Edge());
206 if (!buttonDeclaration_->GetHeightState()) {
207 ResetBoxHeight(INIT_HEIGHT);
208 }
209 if (!imageChild_->GetSrc().empty()) {
210 if (textChild_->GetData().empty()) {
211 paddingChild_->SetChild(imageChild_);
212 return;
213 }
214 textStyle_.DisableAdaptTextSize();
215 PrepareChildren();
216 }
217 }
218
PrepareIconButton()219 void DOMButton::PrepareIconButton()
220 {
221 buttonChild_->SetType(ButtonType::ICON);
222 buttonDeclaration_->SetRectRadius(ICON_BUTTON_RADIUS);
223 paddingChild_->SetChild(imageChild_);
224 paddingChild_->SetPadding(Edge(ICON_BUTTON_PADDING));
225 ResetBoxHeight(INIT_HEIGHT);
226 }
227
PrepareCapsuleButton()228 void DOMButton::PrepareCapsuleButton()
229 {
230 buttonChild_->SetType(ButtonType::CAPSULE);
231 if (!buttonDeclaration_->GetRadiusState()) {
232 if (!NearZero(buttonChild_->GetHeight().Value())) {
233 buttonDeclaration_->SetRectRadius(buttonChild_->GetHeight() / 2.0);
234 }
235 } else {
236 ResetBoxHeight(buttonDeclaration_->GetRectRadius().Value() * 2.0, buttonDeclaration_->GetRectRadius().Unit());
237 }
238 if (isCustomizedColor_ && isTv_) {
239 buttonDeclaration_->SetFocusColor(buttonDeclaration_->GetBackgroundColor());
240 textChild_->SetFocusColor(textStyle_.GetTextColor());
241 }
242 }
243
PrepareTextButton()244 void DOMButton::PrepareTextButton()
245 {
246 buttonChild_->SetType(ButtonType::TEXT);
247 if (!isCustomizedColor_) {
248 buttonDeclaration_->SetBackgroundColor(Color(TRANSPARENT_COLOR));
249 }
250 textStyle_.SetTextAlign(TextAlign::CENTER);
251 if (isTv_) {
252 textStyle_.SetAdaptTextSize(textStyle_.GetFontSize(), TEXT_FONT_MIN_SIZE);
253 paddingChild_->SetPadding(Edge(TEXT_PADDING_HORIZONTAL, TEXT_PADDING_VERTICAL,
254 TEXT_PADDING_HORIZONTAL, TEXT_PADDING_VERTICAL));
255 if (!buttonDeclaration_->GetFontSizeState()) {
256 ResetBoxHeight(TEXT_FOCUS_HEIGHT, DimensionUnit::VP);
257 buttonDeclaration_->SetRectRadius(Dimension(TEXT_FOCUS_HEIGHT / 2.0, DimensionUnit::VP));
258 }
259 return;
260 }
261 if (isWatch_) {
262 if (!buttonDeclaration_->GetFontSizeState()) {
263 std::vector<TextSizeGroup> preferTextSizeGroups;
264 preferTextSizeGroups.push_back({ buttonTheme_->GetTextStyle().GetFontSize(), 1 });
265 preferTextSizeGroups.push_back({ buttonTheme_->GetMinFontSize(), MAX_LINES, TextOverflow::ELLIPSIS });
266 textStyle_.SetPreferTextSizeGroups(preferTextSizeGroups);
267 }
268 ResetBoxHeight(INIT_HEIGHT);
269 paddingChild_->SetPadding(Edge(WATCH_TEXT_PADDING));
270 buttonDeclaration_->SetRectRadius(WATCH_TEXT_RADIUS);
271 return;
272 }
273 if (!buttonDeclaration_->GetTextColorState()) {
274 textStyle_.SetTextColor(buttonTheme_->GetNormalTextColor());
275 }
276 }
277
PrepareCircleButton()278 void DOMButton::PrepareCircleButton()
279 {
280 buttonChild_->SetType(ButtonType::CIRCLE);
281 paddingChild_->SetPadding(Edge());
282 if (!imageChild_->GetSrc().empty()) {
283 paddingChild_->SetChild(imageChild_);
284 }
285 if (isCustomizedColor_ && isTv_) {
286 buttonDeclaration_->SetFocusColor(buttonDeclaration_->GetBackgroundColor());
287 }
288 }
289
PrepareDownloadButton()290 void DOMButton::PrepareDownloadButton()
291 {
292 buttonChild_->SetType(ButtonType::DOWNLOAD);
293 if (!isWatch_) {
294 edge_.SetWidth(DOWNLOAD_BORDER_WIDTH);
295 buttonDeclaration_->SetProgressColor(buttonTheme_->GetDownloadProgressColor());
296 if (!isTv_) {
297 if (!buttonDeclaration_->GetRadiusState()) {
298 buttonDeclaration_->SetRectRadius(buttonTheme_->GetDownloadHeight() / 2.0);
299 }
300 if (!buttonDeclaration_->GetBgColorState()) {
301 buttonDeclaration_->SetBackgroundColor(buttonTheme_->GetDownloadBackgroundColor());
302 }
303 if (!buttonDeclaration_->GetTextColorState()) {
304 textStyle_.SetTextColor(buttonTheme_->GetDownloadTextColor());
305 }
306 if (!buttonDeclaration_->GetFontSizeState()) {
307 textStyle_.SetFontSize(buttonTheme_->GetDownloadFontSize());
308 }
309 }
310 return;
311 }
312 if (!isCustomizedColor_) {
313 buttonDeclaration_->SetBackgroundColor(Color(TRANSPARENT_COLOR));
314 }
315 if (!imageChild_->GetSrc().empty()) {
316 paddingChild_->SetChild(imageChild_);
317 }
318 paddingChild_->SetPadding(Edge());
319 buttonDeclaration_->SetProgressDiameter(diameter_);
320 buttonDeclaration_->SetProgressColor(buttonDeclaration_->GetProgressColor());
321 ResetBoxHeight(INIT_HEIGHT);
322 }
323
PrepareArcButton()324 void DOMButton::PrepareArcButton()
325 {
326 buttonChild_->SetType(ButtonType::ARC);
327 textStyle_.SetAdaptTextSize(ARC_FONT_SIZE, ARC_FONT_MIN_SIZE);
328 paddingChild_->SetPadding(Edge(ARC_PADDING_HORIZONTAL, ARC_PADDING_TOP,
329 ARC_PADDING_HORIZONTAL, ARC_PADDING_BOTTOM));
330 }
331
PrepareButtonState()332 void DOMButton::PrepareButtonState()
333 {
334 UpdateCustomizedColorFlag();
335 if (buttonDeclaration_->GetWaitingState()) {
336 PrepareWaiting();
337 } else {
338 if (!textColorChanged_) {
339 textColor_ = textStyle_.GetTextColor();
340 }
341 textStyle_.SetTextColor(textColor_);
342 if (!disabledColorEffected_) {
343 edgeColor_ = edge_.GetColor();
344 disabledColor_ = buttonDeclaration_->GetDisabledColor();
345 }
346 edge_.SetColor(edgeColor_);
347 if (focusColorChanged_) {
348 buttonDeclaration_->SetFocusColor(focusColor_);
349 }
350 }
351 if (buttonDeclaration_->GetDisabledState()) {
352 if (HasDisabledPseudo()) {
353 buttonDeclaration_->SetDisabledColor(buttonDeclaration_->GetBackgroundColor());
354 } else {
355 PrepareDisabledBackgroundColor();
356 PrepareDisabledChildStyle();
357 }
358 }
359 }
360
PrepareDisabledBackgroundColor()361 void DOMButton::PrepareDisabledBackgroundColor()
362 {
363 edge_.SetColor(edge_.GetColor().BlendOpacity(blendOpacity_));
364 if ((SystemProperties::GetDeviceType() == DeviceType::PHONE) && (buttonType_ == BUTTON_TYPE_DOWNLOAD)) {
365 buttonDeclaration_->SetProgressColor(buttonDeclaration_->GetProgressColor().BlendOpacity(blendOpacity_));
366 }
367
368 // Disabled background color not defined by user.
369 if (disabledColor_ == Color()) {
370 Color bgColor = buttonDeclaration_->GetBackgroundColor();
371 Color customizedColor = (isWatch_ ? bgColor : bgColor.BlendOpacity(blendOpacity_));
372 buttonDeclaration_->SetDisabledColor(isCustomizedColor_ ? customizedColor : buttonTheme_->GetDisabledColor());
373 } else {
374 buttonDeclaration_->SetDisabledColor(disabledColor_);
375 }
376 disabledColorEffected_ = true;
377 }
378
PrepareDisabledChildStyle()379 void DOMButton::PrepareDisabledChildStyle()
380 {
381 bool isWatchDownload = isWatch_ && (buttonType_ == BUTTON_TYPE_DOWNLOAD);
382 if ((buttonType_ == BUTTON_TYPE_CIRCLE) || isWatchDownload || buttonDeclaration_->GetWaitingState()) {
383 auto displayChild = AceType::MakeRefPtr<DisplayComponent>(paddingChild_->GetChild());
384 displayChild->SetOpacity(blendOpacity_);
385 paddingChild_->SetChild(displayChild);
386 return;
387 }
388
389 // Disabled text color not defined by user.
390 Color disabledTextColor = buttonDeclaration_->GetDisabledTextColor();
391 if (disabledTextColor == Color()) {
392 Color textColor = textStyle_.GetTextColor().BlendOpacity(blendOpacity_);
393 textStyle_.SetTextColor(isCustomizedColor_ ? textColor : buttonTheme_->GetTextDisabledColor());
394 } else {
395 textStyle_.SetTextColor(disabledTextColor);
396 }
397 textColorChanged_ = true;
398 }
399
PrepareClickedColor()400 void DOMButton::PrepareClickedColor()
401 {
402 if (buttonDeclaration_->GetClickedColor() != buttonTheme_->GetClickedColor()) {
403 return;
404 }
405 Color defaultClickedColor = buttonDeclaration_->GetBackgroundColor().BlendColor(buttonTheme_->GetClickedColor());
406 buttonDeclaration_->SetClickedColor(defaultClickedColor);
407 }
408
PrepareWaiting()409 void DOMButton::PrepareWaiting()
410 {
411 if ((!buttonTheme_) || isWatch_ || (buttonType_ == BUTTON_TYPE_DOWNLOAD)) {
412 return;
413 }
414 buttonDeclaration_->SetFocusColor(focusColor_.BlendOpacity(blendOpacity_));
415 buttonDeclaration_->SetFocusAnimationColor(buttonTheme_->GetBgFocusColor().BlendOpacity(blendOpacity_));
416 focusColorChanged_ = true;
417 if (buttonType_ == BUTTON_TYPE_CIRCLE) {
418 diameter_ = LessNotEqual(buttonChild_->GetWidth().Value(), 0.0)
419 ? buttonDeclaration_->GetRectRadius()
420 : std::min(buttonChild_->GetHeight(), buttonChild_->GetWidth()) / 2.0;
421 }
422 auto progressComponent = AceType::MakeRefPtr<LoadingProgressComponent>();
423 progressComponent->SetDiameter(diameter_);
424 progressComponent->SetProgressColor(buttonDeclaration_->GetProgressColor());
425 if ((buttonType_ == BUTTON_TYPE_CIRCLE) || (buttonType_ == BUTTON_TYPE_TEXT) || textChild_->GetData().empty()) {
426 paddingChild_->SetChild(progressComponent);
427 return;
428 }
429 PrepareWaitingWithText(progressComponent);
430 }
431
PrepareWaitingWithText(const RefPtr<LoadingProgressComponent> & progressComponent)432 void DOMButton::PrepareWaitingWithText(const RefPtr<LoadingProgressComponent>& progressComponent)
433 {
434 if (!progressComponent) {
435 return;
436 }
437 if (!isCustomizedColor_) {
438 textStyle_.SetTextColor(buttonTheme_->GetTextWaitingColor());
439 textColorChanged_ = true;
440 }
441 textStyle_.DisableAdaptTextSize();
442 auto innerPadding = AceType::MakeRefPtr<PaddingComponent>();
443 Edge edge;
444 edge.SetLeft(buttonDeclaration_->GetInnerPadding());
445 innerPadding->SetChild(textChild_);
446 innerPadding->SetPadding(edge);
447 auto flexItemProgress = AceType::MakeRefPtr<FlexItemComponent>(0.0, 0.0, 0.0, progressComponent);
448 auto flexItemText = AceType::MakeRefPtr<FlexItemComponent>(0.0, 0.0, 0.0, innerPadding);
449 flexItemText->SetFlexShrink(FLEX_ITEM_SHRINK);
450 std::list<RefPtr<Component>> children;
451 children.emplace_back(flexItemProgress);
452 children.emplace_back(flexItemText);
453 auto rowComponent = AceType::MakeRefPtr<RowComponent>(FlexAlign::CENTER, FlexAlign::CENTER, children);
454 paddingChild_->SetChild(rowComponent);
455 }
456
PrepareBorderStyle()457 void DOMButton::PrepareBorderStyle()
458 {
459 if (!isCustomizedColor_) {
460 return;
461 }
462 if ((buttonType_ == BUTTON_TYPE_CAPSULE) || (buttonType_ == BUTTON_TYPE_CIRCLE)) {
463 edge_.SetColor(buttonTheme_->GetBorderColor());
464 edge_.SetWidth(buttonTheme_->GetBorderWidth());
465 }
466 }
467
PrepareBackDecorationStyle()468 void DOMButton::PrepareBackDecorationStyle()
469 {
470 if (!backDecoration_) {
471 return;
472 }
473 if (backDecoration_->GetImage() || backDecoration_->GetGradient().IsValid()) {
474 buttonDeclaration_->SetBackgroundColor(Color(TRANSPARENT_COLOR));
475 }
476 if (buttonChild_->GetType() == ButtonType::CIRCLE) {
477 return;
478 }
479 auto border = backDecoration_->GetBorder();
480 if (!HasBorderRadiusStyle() || buttonDeclaration_->GetRadiusState()) {
481 if (buttonDeclaration_->GetRectRadius().Unit() == border.Top().GetWidth().Unit()) {
482 backDecoration_->SetBorderRadius(Radius(buttonDeclaration_->GetRectRadius() + border.Top().GetWidth()));
483 }
484 } else {
485 if (border.TopLeftRadius().GetX().Unit() == border.Top().GetWidth().Unit()) {
486 buttonDeclaration_->SetRectRadius(border.TopLeftRadius().GetX() - border.Top().GetWidth());
487 }
488 }
489 }
490
PrepareChildren()491 void DOMButton::PrepareChildren()
492 {
493 Edge edge;
494 placement_ = buttonDeclaration_->GetPlacement();
495 if (placement_ == PLACEMENT_BOTTOM) {
496 edge.SetBottom(INNER_PADDING);
497 } else if (placement_ == PLACEMENT_TOP) {
498 edge.SetTop(INNER_PADDING);
499 } else if (placement_ == PLACEMENT_START) {
500 edge.SetLeft(INNER_PADDING);
501 } else {
502 edge.SetRight(INNER_PADDING);
503 edge.SetBottom(Dimension(1.0, DimensionUnit::PX));
504 }
505 innerPaddingChild_ = AceType::MakeRefPtr<PaddingComponent>();
506 innerPaddingChild_->SetChild(textChild_);
507 innerPaddingChild_->SetPadding(edge);
508 PrepareChildrenLayout();
509
510 }
511
PrepareChildrenLayout()512 void DOMButton::PrepareChildrenLayout()
513 {
514 auto flexItemText = AceType::MakeRefPtr<FlexItemComponent>(0.0, 1.0, 0.0, innerPaddingChild_);
515 auto flexItemIcon = AceType::MakeRefPtr<FlexItemComponent>(0.0, 0.0, 0.0, imageChild_);
516 std::list<RefPtr<Component>> children;
517 if ((placement_ == PLACEMENT_START) || (placement_ == PLACEMENT_TOP)) {
518 children.emplace_back(flexItemIcon);
519 children.emplace_back(flexItemText);
520 } else {
521 children.emplace_back(flexItemText);
522 children.emplace_back(flexItemIcon);
523 }
524 auto flexComponent = AceType::MakeRefPtr<FlexComponent>(FlexDirection::ROW, FlexAlign::CENTER,
525 FlexAlign::CENTER, children);
526 if ((placement_ == PLACEMENT_TOP) || (placement_ == PLACEMENT_BOTTOM)) {
527 flexComponent->SetDirection(FlexDirection::COLUMN);
528 }
529 flexComponent->SetMainAxisSize(MainAxisSize::MIN);
530 paddingChild_->SetChild(flexComponent);
531 }
532
AddPadding()533 void DOMButton::AddPadding()
534 {
535 if (!boxComponent_) {
536 return;
537 }
538 auto edge = boxComponent_->GetPadding();
539 if (edge == Edge::NONE) {
540 return;
541 }
542 paddingChild_->SetPadding(edge);
543 boxComponent_->SetPadding(Edge());
544 }
545
ResetBoxHeight(double height,DimensionUnit unit)546 void DOMButton::ResetBoxHeight(double height, DimensionUnit unit)
547 {
548 if (!boxComponent_) {
549 return;
550 }
551 boxComponent_->SetHeight(height, unit);
552 }
553
UpdateCustomizedColorFlag()554 void DOMButton::UpdateCustomizedColorFlag()
555 {
556 isCustomizedColor_ = buttonDeclaration_->GetBackgroundColor() != buttonTheme_->GetBgColor();
557 }
558
GetHeight() const559 Dimension DOMButton::GetHeight() const
560 {
561 Dimension height = Dimension(-1.0, DimensionUnit::PX);
562 auto buttonDeclaration = buttonDeclaration_;
563 if (IsPlatformFive()) {
564 // less api 5 should set height of box component in UpdateBoxSize, buttonDeclaration_ != nullptr after
565 // PrepareSpecializedComponent
566 buttonDeclaration = AceType::DynamicCast<ButtonDeclaration>(declaration_);
567 }
568 if (buttonDeclaration) {
569 height = buttonDeclaration->GetHeight();
570 }
571 return height;
572 }
573
GetWidth() const574 Dimension DOMButton::GetWidth() const
575 {
576 Dimension width = Dimension(-1.0, DimensionUnit::PX);
577 auto buttonDeclaration = buttonDeclaration_;
578 if (IsPlatformFive()) {
579 // less api 5 should set width of box component in UpdateBoxSize, buttonDeclaration_ != nullptr after
580 // PrepareSpecializedComponent
581 buttonDeclaration = AceType::DynamicCast<ButtonDeclaration>(declaration_);
582 }
583 if (buttonDeclaration) {
584 width = buttonDeclaration->GetWidth();
585 }
586
587 return width;
588 }
589
IsPlatformFive() const590 bool DOMButton::IsPlatformFive() const
591 {
592 const static int32_t PLATFORM_VERSION_FIVE = 5;
593 auto context = GetPipelineContext().Upgrade();
594 return context && context->GetMinPlatformVersion() <= PLATFORM_VERSION_FIVE;
595 }
596
597 } // namespace OHOS::Ace::Framework
598