• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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