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 } 170 }; 171 172 ~ButtonTheme() override = default; 173 GetRadius()174 const Dimension& GetRadius() const 175 { 176 return radius_; 177 } 178 GetBgColor()179 const Color& GetBgColor() const 180 { 181 return bgColor_; 182 } 183 GetBgFocusColor()184 const Color& GetBgFocusColor() const 185 { 186 return bgFocusColor_; 187 } 188 GetClickedColor()189 const Color& GetClickedColor() const 190 { 191 return clickedColor_; 192 } 193 GetDisabledColor()194 const Color& GetDisabledColor() const 195 { 196 return disabledColor_; 197 } 198 GetHoverColor()199 const Color& GetHoverColor() const 200 { 201 return hoverColor_; 202 } 203 GetBorderColor()204 const Color& GetBorderColor() const 205 { 206 return borderColor_; 207 } 208 GetBorderWidth()209 const Dimension& GetBorderWidth() const 210 { 211 return borderWidth_; 212 } 213 GetBgDisabledAlpha()214 double GetBgDisabledAlpha() const 215 { 216 return bgDisabledAlpha_; 217 } 218 GetTextFocusColor()219 const Color& GetTextFocusColor() const 220 { 221 return textFocusColor_; 222 } 223 GetTextDisabledColor()224 const Color& GetTextDisabledColor() const 225 { 226 return textDisabledColor_; 227 } 228 GetNormalTextColor()229 const Color& GetNormalTextColor() const 230 { 231 return normalTextColor_; 232 } 233 GetDownloadBackgroundColor()234 const Color& GetDownloadBackgroundColor() const 235 { 236 return downloadBackgroundColor_; 237 } 238 GetDownloadTextColor()239 const Color& GetDownloadTextColor() const 240 { 241 return downloadTextColor_; 242 } 243 GetTextWaitingColor()244 const Color& GetTextWaitingColor() const 245 { 246 return textWaitingColor_; 247 } 248 GetTextStyle()249 const TextStyle& GetTextStyle() const 250 { 251 return textStyle_; 252 } 253 GetMinWidth()254 const Dimension& GetMinWidth() const 255 { 256 return minWidth_; 257 } 258 GetHeight()259 const Dimension& GetHeight() const 260 { 261 return height_; 262 } 263 GetDownloadHeight()264 const Dimension& GetDownloadHeight() const 265 { 266 return downloadHeight_; 267 } 268 GetPadding()269 const Edge& GetPadding() const 270 { 271 return padding_; 272 } 273 GetMinFontSize()274 const Dimension& GetMinFontSize() const 275 { 276 return minFontSize_; 277 } 278 GetDownloadFontSize()279 const Dimension& GetDownloadFontSize() const 280 { 281 return downloadFontSize_; 282 } 283 GetMaxFontSize()284 const Dimension& GetMaxFontSize() const 285 { 286 return textStyle_.GetFontSize(); 287 } 288 GetTextMaxLines()289 uint32_t GetTextMaxLines() const 290 { 291 return textMaxLines_; 292 } 293 GetMinCircleButtonDiameter()294 const Dimension& GetMinCircleButtonDiameter() const 295 { 296 return minCircleButtonDiameter_; 297 } 298 GetMinCircleButtonIcon()299 const Dimension& GetMinCircleButtonIcon() const 300 { 301 return minCircleButtonIcon_; 302 } 303 GetMinCircleButtonPadding()304 const Edge& GetMinCircleButtonPadding() const 305 { 306 return minCircleButtonPadding_; 307 } 308 GetMaxCircleButtonDiameter()309 const Dimension& GetMaxCircleButtonDiameter() const 310 { 311 return maxCircleButtonDiameter_; 312 } 313 GetMaxCircleButtonIcon()314 const Dimension& GetMaxCircleButtonIcon() const 315 { 316 return maxCircleButtonIcon_; 317 } 318 GetMaxCircleButtonPadding()319 const Edge& GetMaxCircleButtonPadding() const 320 { 321 return maxCircleButtonPadding_; 322 } 323 GetProgressFocusColor()324 const Color& GetProgressFocusColor() const 325 { 326 return progressFocusColor_; 327 } 328 GetDownloadBorderColor()329 const Color& GetDownloadBorderColor() const 330 { 331 return downloadBorderColor_; 332 } 333 GetProgressColor()334 const Color& GetProgressColor() const 335 { 336 return progressColor_; 337 } 338 GetProgressDiameter()339 const Dimension& GetProgressDiameter() const 340 { 341 return progressDiameter_; 342 } 343 GetDownloadProgressColor()344 const Color& GetDownloadProgressColor() const 345 { 346 return downloadProgressColor_; 347 } 348 GetInnerPadding()349 const Dimension& GetInnerPadding() const 350 { 351 return innerPadding_; 352 } 353 GetBgColor(ButtonStyleMode buttonStyle,ButtonRole buttonRole)354 Color GetBgColor(ButtonStyleMode buttonStyle, ButtonRole buttonRole) const 355 { 356 auto bgColorMapByRole_ = bgColorMap_.find(buttonRole); 357 if (bgColorMapByRole_ != bgColorMap_.end()) { 358 std::unordered_map<ButtonStyleMode, Color> bgColorMapByStyle_ = bgColorMapByRole_->second; 359 auto result = bgColorMapByStyle_.find(buttonStyle); 360 if (result != bgColorMapByStyle_.end()) { 361 return result->second; 362 } 363 } 364 return bgColor_; 365 } 366 GetTextColor(ButtonStyleMode buttonStyle,ButtonRole buttonRole)367 const Color& GetTextColor(ButtonStyleMode buttonStyle, ButtonRole buttonRole) const 368 { 369 auto roleResult = textColorByRoleMap_.find(buttonRole); 370 auto result = textColorMap_.find(buttonStyle); 371 if (roleResult != textColorByRoleMap_.end() && result != textColorMap_.end()) { 372 if (buttonRole == ButtonRole::ERROR) { 373 if (buttonStyle == ButtonStyleMode::EMPHASIZE) { 374 return result->second; 375 } 376 return roleResult->second; 377 } 378 return result->second; 379 } 380 return normalTextColor_; 381 } 382 GetHeight(ControlSize controlSize)383 const Dimension& GetHeight(ControlSize controlSize) const 384 { 385 auto result = heightMap_.find(controlSize); 386 if (result != heightMap_.end()) { 387 return result->second; 388 } 389 return height_; 390 } 391 GetTextSize(ControlSize controlSize)392 const Dimension& GetTextSize(ControlSize controlSize) const 393 { 394 auto result = textSizeMap_.find(controlSize); 395 if (result != textSizeMap_.end()) { 396 return result->second; 397 } 398 return textStyle_.GetFontSize(); 399 } 400 GetPadding(ControlSize controlSize)401 const Edge& GetPadding(ControlSize controlSize) const 402 { 403 auto result = paddingMap_.find(controlSize); 404 if (result != paddingMap_.end()) { 405 return result->second; 406 } 407 return padding_; 408 } 409 GetBigFontSizeScale()410 float GetBigFontSizeScale() const 411 { 412 return bigFontSizeScale_; 413 } 414 GetLargeFontSizeScale()415 float GetLargeFontSizeScale() const 416 { 417 return largeFontSizeScale_; 418 } 419 GetMaxFontSizeScale()420 float GetMaxFontSizeScale() const 421 { 422 return maxFontSizeScale_; 423 } 424 GetAgingNormalPadding()425 const Dimension& GetAgingNormalPadding() const 426 { 427 return agingNormalPadding_; 428 } 429 GetAgingSmallPadding()430 const Dimension& GetAgingSmallPadding() const 431 { 432 return agingSmallPadding_; 433 } 434 GetAgingTextMaxLines()435 uint32_t GetAgingTextMaxLines() const 436 { 437 return agingTextMaxLines_; 438 } 439 440 protected: 441 ButtonTheme() = default; 442 443 private: 444 Color bgColor_; 445 Color roleWarningColor_; 446 Color bgFocusColor_; 447 Color clickedColor_; 448 Color disabledColor_; 449 Color hoverColor_; 450 Color borderColor_; 451 Color textFocusColor_; 452 Color textDisabledColor_; 453 Color textWaitingColor_; 454 Color progressColor_; 455 Color progressFocusColor_; 456 Color normalTextColor_; 457 Color downloadBackgroundColor_; 458 Color downloadTextColor_; 459 Color downloadBorderColor_; 460 Color downloadProgressColor_; 461 TextStyle textStyle_; 462 Edge padding_; 463 Edge minCircleButtonPadding_; 464 Edge maxCircleButtonPadding_; 465 466 Dimension radius_; 467 Dimension minWidth_; 468 Dimension height_; 469 Dimension progressDiameter_; 470 Dimension innerPadding_; 471 Dimension minFontSize_; 472 Dimension downloadFontSize_; 473 Dimension minCircleButtonDiameter_; 474 Dimension minCircleButtonIcon_; 475 Dimension maxCircleButtonDiameter_; 476 Dimension maxCircleButtonIcon_; 477 Dimension borderWidth_; 478 Dimension downloadHeight_; 479 std::unordered_map<ButtonRole, std::unordered_map<ButtonStyleMode, Color>> bgColorMap_; 480 std::unordered_map<ButtonRole, Color> textColorByRoleMap_; 481 std::unordered_map<ButtonStyleMode, Color> textColorMap_; 482 std::unordered_map<ControlSize, Dimension> heightMap_; 483 std::unordered_map<ControlSize, Dimension> textSizeMap_; 484 std::unordered_map<ControlSize, Edge> paddingMap_; 485 double bgDisabledAlpha_ = 1.0; 486 uint32_t textMaxLines_ = 1; 487 float bigFontSizeScale_ = 1.75f; 488 float largeFontSizeScale_ = 2.0f; 489 float maxFontSizeScale_ = 3.2f; 490 Dimension agingNormalPadding_; 491 Dimension agingSmallPadding_; 492 uint32_t agingTextMaxLines_ = 2; 493 }; 494 495 } // namespace OHOS::Ace 496 497 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_BUTTON_BUTTON_THEME_H 498