1 /* 2 * Copyright (c) 2021 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 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_BUTTON_BUTTON_THEME_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_BUTTON_BUTTON_THEME_H 18 19 #include "core/components/common/properties/color.h" 20 #include "core/components/common/properties/text_style.h" 21 #include "core/components/theme/theme.h" 22 #include "core/components/theme/theme_constants.h" 23 #include "core/components/theme/theme_constants_defines.h" 24 25 namespace OHOS::Ace { 26 27 /** 28 * ButtonTheme defines color and styles of ButtonComponent. ButtonTheme should be built 29 * using ButtonTheme::Builder. 30 */ 31 class ButtonTheme : public virtual Theme { 32 DECLARE_ACE_TYPE(ButtonTheme, Theme); 33 34 public: 35 class Builder { 36 public: 37 Builder() = default; 38 ~Builder() = default; 39 Build(const RefPtr<ThemeConstants> & themeConstants)40 RefPtr<ButtonTheme> Build(const RefPtr<ThemeConstants>& themeConstants) const 41 { 42 RefPtr<ButtonTheme> theme = AceType::Claim(new ButtonTheme()); 43 if (!themeConstants) { 44 return theme; 45 } 46 ParsePattern(themeConstants, theme); 47 return theme; 48 } 49 50 private: ParsePattern(const RefPtr<ThemeConstants> & themeConstants,const RefPtr<ButtonTheme> & theme)51 void ParsePattern(const RefPtr<ThemeConstants>& themeConstants, const RefPtr<ButtonTheme>& theme) const 52 { 53 if (!themeConstants) { 54 return; 55 } 56 RefPtr<ThemeStyle> buttonPattern = themeConstants->GetPatternByName(THEME_PATTERN_BUTTON); 57 if (!buttonPattern) { 58 LOGW("find pattern of button fail"); 59 return; 60 } 61 theme->bgColor_ = buttonPattern->GetAttr<Color>("button_bg_color", Color()); 62 theme->roleWarningColor_ = buttonPattern->GetAttr<Color>("role_warning", Color()); 63 theme->clickedColor_ = buttonPattern->GetAttr<Color>("bg_color_clicked_blend", Color()); 64 theme->disabledColor_ = 65 theme->bgColor_.BlendOpacity(buttonPattern->GetAttr<double>(PATTERN_BG_COLOR_DISABLED_ALPHA, 0.0)); 66 theme->hoverColor_ = buttonPattern->GetAttr<Color>("bg_color_hovered_blend", Color()); 67 theme->borderColor_ = buttonPattern->GetAttr<Color>("border_color", Color()); 68 theme->borderWidth_ = buttonPattern->GetAttr<Dimension>("border_width", 0.0_vp); 69 theme->textStyle_.SetTextColor(buttonPattern->GetAttr<Color>("button_text_color", Color())); 70 theme->textDisabledColor_ = 71 buttonPattern->GetAttr<Color>(PATTERN_TEXT_COLOR, Color()) 72 .BlendOpacity(buttonPattern->GetAttr<double>("text_color_disabled_alpha", 0.0)); 73 theme->textWaitingColor_ = buttonPattern->GetAttr<Color>("waiting_button_text_color", Color()); 74 theme->normalTextColor_ = buttonPattern->GetAttr<Color>("normal_text_color", Color()); 75 theme->downloadBackgroundColor_ = 76 buttonPattern->GetAttr<Color>("download_button_bg_color", Color()) 77 .BlendOpacity(buttonPattern->GetAttr<double>("download_button_bg_color_alpha", 0.0)); 78 theme->downloadBorderColor_ = 79 buttonPattern->GetAttr<Color>("download_button_border_color", Color()) 80 .BlendOpacity(buttonPattern->GetAttr<double>("download_button_border_color_alpha", 0.0)); 81 theme->downloadProgressColor_ = 82 buttonPattern->GetAttr<Color>("download_button_process_color", Color()) 83 .BlendOpacity(buttonPattern->GetAttr<double>("download_button_process_color_alpha", 0.0)); 84 theme->downloadTextColor_ = buttonPattern->GetAttr<Color>("download_button_text_color", Color()); 85 theme->progressColor_ = buttonPattern->GetAttr<Color>("process_button_text_color", Color()); 86 theme->radius_ = buttonPattern->GetAttr<Dimension>("button_radius", 0.0_vp); 87 theme->bgFocusColor_ = buttonPattern->GetAttr<Color>("button_bg_focus_color", Color()); 88 theme->bgDisabledAlpha_ = buttonPattern->GetAttr<double>("bg_color_disabled_alpha", 0.0); 89 theme->textFocusColor_ = buttonPattern->GetAttr<Color>("button_text_focus_color", Color()); 90 theme->textStyle_.SetFontSize(buttonPattern->GetAttr<Dimension>("button_font_size", 0.0_fp)); 91 theme->textStyle_.SetFontWeight( 92 FontWeight(static_cast<int32_t>(buttonPattern->GetAttr<double>("button_font_weight", 0.0)))); 93 theme->minWidth_ = buttonPattern->GetAttr<Dimension>("button_min_width", 0.0_vp); 94 theme->height_ = buttonPattern->GetAttr<Dimension>("button_height", 0.0_vp); 95 theme->downloadHeight_ = buttonPattern->GetAttr<Dimension>("button_download_height", 0.0_vp); 96 theme->padding_ = Edge(buttonPattern->GetAttr<Dimension>("button_horizontal_padding", 0.0_vp).Value(), 97 buttonPattern->GetAttr<Dimension>("button_vertical_padding", 0.0_vp).Value(), 98 buttonPattern->GetAttr<Dimension>("button_horizontal_padding", 0.0_vp).Value(), 99 buttonPattern->GetAttr<Dimension>("button_vertical_padding", 0.0_vp).Value(), 100 buttonPattern->GetAttr<Dimension>("button_vertical_padding", 0.0_vp).Unit()); 101 theme->minFontSize_ = buttonPattern->GetAttr<Dimension>("button_min_font_size", 0.0_fp); 102 ParseAdditionalStylePattern(buttonPattern, theme); 103 } ParseAdditionalStylePattern(const RefPtr<ThemeStyle> & buttonPattern,const RefPtr<ButtonTheme> & theme)104 void ParseAdditionalStylePattern( 105 const RefPtr<ThemeStyle>& buttonPattern, const RefPtr<ButtonTheme>& theme) const 106 { 107 int32_t maxlines = static_cast<int32_t>(buttonPattern->GetAttr<double>("button_text_max_lines", 0.0)); 108 theme->textMaxLines_ = maxlines < 0 ? theme->textMaxLines_ : static_cast<uint32_t>(maxlines); 109 theme->minCircleButtonDiameter_ = buttonPattern->GetAttr<Dimension>("min_circle_button_diameter", 0.0_vp); 110 theme->minCircleButtonIcon_ = buttonPattern->GetAttr<Dimension>("min_circle_button_icon_size", 0.0_vp); 111 theme->minCircleButtonPadding_ = 112 Edge(buttonPattern->GetAttr<Dimension>("min_circle_button_padding", 0.0_vp)); 113 theme->maxCircleButtonDiameter_ = buttonPattern->GetAttr<Dimension>("max_circle_button_diameter", 0.0_vp); 114 theme->maxCircleButtonIcon_ = buttonPattern->GetAttr<Dimension>("max_circle_button_icon_size", 0.0_vp); 115 theme->maxCircleButtonPadding_ = 116 Edge(buttonPattern->GetAttr<Dimension>("button_max_circle_button_padding", 0.0_vp)); 117 theme->progressFocusColor_ = buttonPattern->GetAttr<Color>("button_progress_focus_color", Color()); 118 theme->downloadFontSize_ = buttonPattern->GetAttr<Dimension>("button_download_font_size", 0.0_fp); 119 theme->progressDiameter_ = buttonPattern->GetAttr<Dimension>("button_progress_diameter", 0.0_vp); 120 theme->innerPadding_ = buttonPattern->GetAttr<Dimension>("button_inner_padding", 0.0_vp); 121 theme->bigFontSizeScale_ = buttonPattern->GetAttr<double>("button_aging_big_font_size_scale", 0.0); 122 theme->largeFontSizeScale_ = buttonPattern->GetAttr<double>("button_aging_large_font_size_scale", 0.0); 123 theme->maxFontSizeScale_ = buttonPattern->GetAttr<double>("button_aging_max_font_size_scale", 0.0); 124 theme->agingNormalPadding_ = buttonPattern->GetAttr<Dimension>("button_aging_normal_padding", 0.0_vp); 125 theme->agingSmallPadding_ = buttonPattern->GetAttr<Dimension>("button_aging_small_padding", 0.0_vp); 126 theme->agingTextMaxLines_ = 127 static_cast<uint32_t>(buttonPattern->GetAttr<double>("button_aging_text_max_lines", 0.0)); 128 ParseSubStylePattern(buttonPattern, theme); 129 } 130 ParseSubStylePattern(const RefPtr<ThemeStyle> & buttonPattern,const RefPtr<ButtonTheme> & theme)131 void ParseSubStylePattern(const RefPtr<ThemeStyle>& buttonPattern, const RefPtr<ButtonTheme>& theme) const 132 { 133 std::unordered_map<ButtonStyleMode, Color> normalBgColorMap_ = { { ButtonStyleMode::EMPHASIZE, 134 theme->bgColor_ }, 135 { ButtonStyleMode::NORMAL, buttonPattern->GetAttr<Color>("bg_color_normal", Color()) }, 136 { ButtonStyleMode::TEXT, Color::TRANSPARENT } }; 137 std::unordered_map<ButtonStyleMode, Color> errorBgColorMap_ = { { ButtonStyleMode::EMPHASIZE, 138 theme->roleWarningColor_ }, 139 { ButtonStyleMode::NORMAL, buttonPattern->GetAttr<Color>("bg_color_normal", Color()) }, 140 { ButtonStyleMode::TEXT, Color::TRANSPARENT } }; 141 theme->bgColorMap_.emplace(ButtonRole::NORMAL, normalBgColorMap_); 142 theme->bgColorMap_.emplace(ButtonRole::ERROR, errorBgColorMap_); 143 theme->textColorMap_.insert(std::pair<ButtonStyleMode, Color>( 144 ButtonStyleMode::EMPHASIZE, buttonPattern->GetAttr<Color>("emphasize_button_text_color", Color()))); 145 theme->textColorMap_.insert( 146 std::pair<ButtonStyleMode, Color>(ButtonStyleMode::NORMAL, theme->normalTextColor_)); 147 theme->textColorMap_.insert( 148 std::pair<ButtonStyleMode, Color>(ButtonStyleMode::TEXT, theme->normalTextColor_)); 149 theme->textColorByRoleMap_.insert( 150 std::pair<ButtonRole, Color>(ButtonRole::NORMAL, theme->normalTextColor_)); 151 theme->textColorByRoleMap_.insert( 152 std::pair<ButtonRole, Color>(ButtonRole::ERROR, theme->roleWarningColor_)); 153 theme->heightMap_.insert(std::pair<ControlSize, Dimension>(ControlSize::NORMAL, theme->height_)); 154 theme->heightMap_.insert(std::pair<ControlSize, Dimension>( 155 ControlSize::SMALL, buttonPattern->GetAttr<Dimension>("small_button_height", 0.0_vp))); 156 157 theme->textSizeMap_.insert(std::pair<ControlSize, Dimension>( 158 ControlSize::NORMAL, buttonPattern->GetAttr<Dimension>("button_font_size", 0.0_fp))); 159 theme->textSizeMap_.insert(std::pair<ControlSize, Dimension>( 160 ControlSize::SMALL, buttonPattern->GetAttr<Dimension>("small_button_font_size", 0.0_fp))); 161 162 theme->paddingMap_.insert(std::pair<ControlSize, Edge>(ControlSize::NORMAL, theme->padding_)); 163 theme->paddingMap_.insert(std::pair<ControlSize, Edge>(ControlSize::SMALL, 164 Edge(buttonPattern->GetAttr<Dimension>("small_button_horizontal_padding", 0.0_vp).Value(), 165 buttonPattern->GetAttr<Dimension>("button_vertical_padding", 0.0_vp).Value(), 166 buttonPattern->GetAttr<Dimension>("small_button_horizontal_padding", 0.0_vp).Value(), 167 buttonPattern->GetAttr<Dimension>("button_vertical_padding", 0.0_vp).Value(), 168 buttonPattern->GetAttr<Dimension>("button_vertical_padding", 0.0_vp).Unit()))); 169 theme->borderRadiusMap_.insert(std::pair<ControlSize, Dimension>( 170 ControlSize::NORMAL, buttonPattern->GetAttr<Dimension>("button_border_radius_normal", 20.0_vp))); 171 theme->borderRadiusMap_.insert(std::pair<ControlSize, Dimension>( 172 ControlSize::SMALL, buttonPattern->GetAttr<Dimension>("button_border_radius_small", 14.0_vp))); 173 } 174 }; 175 176 ~ButtonTheme() override = default; 177 GetRadius()178 const Dimension& GetRadius() const 179 { 180 return radius_; 181 } 182 GetBgColor()183 const Color& GetBgColor() const 184 { 185 return bgColor_; 186 } 187 GetBgFocusColor()188 const Color& GetBgFocusColor() const 189 { 190 return bgFocusColor_; 191 } 192 GetClickedColor()193 const Color& GetClickedColor() const 194 { 195 return clickedColor_; 196 } 197 GetDisabledColor()198 const Color& GetDisabledColor() const 199 { 200 return disabledColor_; 201 } 202 GetHoverColor()203 const Color& GetHoverColor() const 204 { 205 return hoverColor_; 206 } 207 GetBorderColor()208 const Color& GetBorderColor() const 209 { 210 return borderColor_; 211 } 212 GetBorderWidth()213 const Dimension& GetBorderWidth() const 214 { 215 return borderWidth_; 216 } 217 GetBgDisabledAlpha()218 double GetBgDisabledAlpha() const 219 { 220 return bgDisabledAlpha_; 221 } 222 GetTextFocusColor()223 const Color& GetTextFocusColor() const 224 { 225 return textFocusColor_; 226 } 227 GetTextDisabledColor()228 const Color& GetTextDisabledColor() const 229 { 230 return textDisabledColor_; 231 } 232 GetNormalTextColor()233 const Color& GetNormalTextColor() const 234 { 235 return normalTextColor_; 236 } 237 GetDownloadBackgroundColor()238 const Color& GetDownloadBackgroundColor() const 239 { 240 return downloadBackgroundColor_; 241 } 242 GetDownloadTextColor()243 const Color& GetDownloadTextColor() const 244 { 245 return downloadTextColor_; 246 } 247 GetTextWaitingColor()248 const Color& GetTextWaitingColor() const 249 { 250 return textWaitingColor_; 251 } 252 GetTextStyle()253 const TextStyle& GetTextStyle() const 254 { 255 return textStyle_; 256 } 257 GetMinWidth()258 const Dimension& GetMinWidth() const 259 { 260 return minWidth_; 261 } 262 GetHeight()263 const Dimension& GetHeight() const 264 { 265 return height_; 266 } 267 GetDownloadHeight()268 const Dimension& GetDownloadHeight() const 269 { 270 return downloadHeight_; 271 } 272 GetPadding()273 const Edge& GetPadding() const 274 { 275 return padding_; 276 } 277 GetMinFontSize()278 const Dimension& GetMinFontSize() const 279 { 280 return minFontSize_; 281 } 282 GetDownloadFontSize()283 const Dimension& GetDownloadFontSize() const 284 { 285 return downloadFontSize_; 286 } 287 GetMaxFontSize()288 const Dimension& GetMaxFontSize() const 289 { 290 return textStyle_.GetFontSize(); 291 } 292 GetTextMaxLines()293 uint32_t GetTextMaxLines() const 294 { 295 return textMaxLines_; 296 } 297 GetMinCircleButtonDiameter()298 const Dimension& GetMinCircleButtonDiameter() const 299 { 300 return minCircleButtonDiameter_; 301 } 302 GetMinCircleButtonIcon()303 const Dimension& GetMinCircleButtonIcon() const 304 { 305 return minCircleButtonIcon_; 306 } 307 GetMinCircleButtonPadding()308 const Edge& GetMinCircleButtonPadding() const 309 { 310 return minCircleButtonPadding_; 311 } 312 GetMaxCircleButtonDiameter()313 const Dimension& GetMaxCircleButtonDiameter() const 314 { 315 return maxCircleButtonDiameter_; 316 } 317 GetMaxCircleButtonIcon()318 const Dimension& GetMaxCircleButtonIcon() const 319 { 320 return maxCircleButtonIcon_; 321 } 322 GetMaxCircleButtonPadding()323 const Edge& GetMaxCircleButtonPadding() const 324 { 325 return maxCircleButtonPadding_; 326 } 327 GetProgressFocusColor()328 const Color& GetProgressFocusColor() const 329 { 330 return progressFocusColor_; 331 } 332 GetDownloadBorderColor()333 const Color& GetDownloadBorderColor() const 334 { 335 return downloadBorderColor_; 336 } 337 GetProgressColor()338 const Color& GetProgressColor() const 339 { 340 return progressColor_; 341 } 342 GetProgressDiameter()343 const Dimension& GetProgressDiameter() const 344 { 345 return progressDiameter_; 346 } 347 GetDownloadProgressColor()348 const Color& GetDownloadProgressColor() const 349 { 350 return downloadProgressColor_; 351 } 352 GetInnerPadding()353 const Dimension& GetInnerPadding() const 354 { 355 return innerPadding_; 356 } 357 GetBgColor(ButtonStyleMode buttonStyle,ButtonRole buttonRole)358 Color GetBgColor(ButtonStyleMode buttonStyle, ButtonRole buttonRole) const 359 { 360 auto bgColorMapByRole_ = bgColorMap_.find(buttonRole); 361 if (bgColorMapByRole_ != bgColorMap_.end()) { 362 std::unordered_map<ButtonStyleMode, Color> bgColorMapByStyle_ = bgColorMapByRole_->second; 363 auto result = bgColorMapByStyle_.find(buttonStyle); 364 if (result != bgColorMapByStyle_.end()) { 365 return result->second; 366 } 367 } 368 return bgColor_; 369 } 370 GetTextColor(ButtonStyleMode buttonStyle,ButtonRole buttonRole)371 const Color& GetTextColor(ButtonStyleMode buttonStyle, ButtonRole buttonRole) const 372 { 373 auto roleResult = textColorByRoleMap_.find(buttonRole); 374 auto result = textColorMap_.find(buttonStyle); 375 if (roleResult != textColorByRoleMap_.end() && result != textColorMap_.end()) { 376 if (buttonRole == ButtonRole::ERROR) { 377 if (buttonStyle == ButtonStyleMode::EMPHASIZE) { 378 return result->second; 379 } 380 return roleResult->second; 381 } 382 return result->second; 383 } 384 return normalTextColor_; 385 } 386 GetHeight(ControlSize controlSize)387 const Dimension& GetHeight(ControlSize controlSize) const 388 { 389 auto result = heightMap_.find(controlSize); 390 if (result != heightMap_.end()) { 391 return result->second; 392 } 393 return height_; 394 } 395 GetBorderRadius(ControlSize controlSize)396 const Dimension& GetBorderRadius(ControlSize controlSize) const 397 { 398 auto result = borderRadiusMap_.find(controlSize); 399 if (result != borderRadiusMap_.end()) { 400 return result->second; 401 } 402 return borderRadius_; 403 } 404 GetTextSize(ControlSize controlSize)405 const Dimension& GetTextSize(ControlSize controlSize) const 406 { 407 auto result = textSizeMap_.find(controlSize); 408 if (result != textSizeMap_.end()) { 409 return result->second; 410 } 411 return textStyle_.GetFontSize(); 412 } 413 GetPadding(ControlSize controlSize)414 const Edge& GetPadding(ControlSize controlSize) const 415 { 416 auto result = paddingMap_.find(controlSize); 417 if (result != paddingMap_.end()) { 418 return result->second; 419 } 420 return padding_; 421 } 422 GetBigFontSizeScale()423 float GetBigFontSizeScale() const 424 { 425 return bigFontSizeScale_; 426 } 427 GetLargeFontSizeScale()428 float GetLargeFontSizeScale() const 429 { 430 return largeFontSizeScale_; 431 } 432 GetMaxFontSizeScale()433 float GetMaxFontSizeScale() const 434 { 435 return maxFontSizeScale_; 436 } 437 GetAgingNormalPadding()438 const Dimension& GetAgingNormalPadding() const 439 { 440 return agingNormalPadding_; 441 } 442 GetAgingSmallPadding()443 const Dimension& GetAgingSmallPadding() const 444 { 445 return agingSmallPadding_; 446 } 447 GetAgingTextMaxLines()448 uint32_t GetAgingTextMaxLines() const 449 { 450 return agingTextMaxLines_; 451 } 452 453 protected: 454 ButtonTheme() = default; 455 456 private: 457 Color bgColor_; 458 Color roleWarningColor_; 459 Color bgFocusColor_; 460 Color clickedColor_; 461 Color disabledColor_; 462 Color hoverColor_; 463 Color borderColor_; 464 Color textFocusColor_; 465 Color textDisabledColor_; 466 Color textWaitingColor_; 467 Color progressColor_; 468 Color progressFocusColor_; 469 Color normalTextColor_; 470 Color downloadBackgroundColor_; 471 Color downloadTextColor_; 472 Color downloadBorderColor_; 473 Color downloadProgressColor_; 474 TextStyle textStyle_; 475 Edge padding_; 476 Edge minCircleButtonPadding_; 477 Edge maxCircleButtonPadding_; 478 479 Dimension radius_; 480 Dimension minWidth_; 481 Dimension height_; 482 Dimension progressDiameter_; 483 Dimension innerPadding_; 484 Dimension minFontSize_; 485 Dimension downloadFontSize_; 486 Dimension minCircleButtonDiameter_; 487 Dimension minCircleButtonIcon_; 488 Dimension maxCircleButtonDiameter_; 489 Dimension maxCircleButtonIcon_; 490 Dimension borderWidth_; 491 Dimension downloadHeight_; 492 Dimension borderRadius_; 493 std::unordered_map<ButtonRole, std::unordered_map<ButtonStyleMode, Color>> bgColorMap_; 494 std::unordered_map<ButtonRole, Color> textColorByRoleMap_; 495 std::unordered_map<ButtonStyleMode, Color> textColorMap_; 496 std::unordered_map<ControlSize, Dimension> heightMap_; 497 std::unordered_map<ControlSize, Dimension> textSizeMap_; 498 std::unordered_map<ControlSize, Edge> paddingMap_; 499 std::unordered_map<ControlSize, Dimension> borderRadiusMap_; 500 double bgDisabledAlpha_ = 1.0; 501 uint32_t textMaxLines_ = 1; 502 float bigFontSizeScale_ = 1.75f; 503 float largeFontSizeScale_ = 2.0f; 504 float maxFontSizeScale_ = 3.2f; 505 Dimension agingNormalPadding_; 506 Dimension agingSmallPadding_; 507 uint32_t agingTextMaxLines_ = 2; 508 }; 509 510 } // namespace OHOS::Ace 511 512 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_BUTTON_BUTTON_THEME_H 513