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