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_PICKER_PICKER_THEME_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_PICKER_PICKER_THEME_H 18 19 #include "base/geometry/dimension.h" 20 #include "base/utils/system_properties.h" 21 #include "core/components/common/layout/constants.h" 22 #include "core/components/common/properties/border.h" 23 #include "core/components/common/properties/color.h" 24 #include "core/components/common/properties/decoration.h" 25 #include "core/components/common/properties/edge.h" 26 #include "core/components/common/properties/text_style.h" 27 #include "core/components/theme/theme.h" 28 #include "core/components/theme/theme_constants.h" 29 #include "core/components/theme/theme_constants_defines.h" 30 31 namespace OHOS::Ace { 32 namespace { 33 constexpr Dimension DIVIDER_THICKNESS = 1.0_px; 34 } // namespace 35 36 class PickerTheme final : public virtual Theme { 37 DECLARE_ACE_TYPE(PickerTheme, Theme); 38 39 public: 40 class Builder final { 41 public: 42 Builder() = default; 43 ~Builder() = default; 44 Build(const RefPtr<ThemeConstants> & themeConstants)45 RefPtr<PickerTheme> Build(const RefPtr<ThemeConstants>& themeConstants) const 46 { 47 RefPtr<PickerTheme> theme = AceType::Claim(new PickerTheme()); 48 if (!themeConstants) { 49 return theme; 50 } 51 InitializeTextStyles(theme, themeConstants); 52 theme->popupDecoration_ = AceType::MakeRefPtr<Decoration>(); 53 theme->popupDecoration_->SetBackgroundColor(themeConstants->GetColor(THEME_PICKER_BACK_COLOR)); 54 theme->popupDecoration_->SetBorderRadius(Radius(themeConstants->GetDimension(THEME_PICKER_POPUP_RADIUS))); 55 theme->popupEdge_.SetLeft(themeConstants->GetDimension(THEME_PICKER_POPUP_PADDING)); 56 theme->popupEdge_.SetTop(themeConstants->GetDimension(THEME_PICKER_POPUP_PADDING)); 57 theme->popupEdge_.SetRight(themeConstants->GetDimension(THEME_PICKER_POPUP_PADDING)); 58 theme->popupEdge_.SetBottom(themeConstants->GetDimension(THEME_PICKER_POPUP_PADDING_BOTTOM)); 59 auto showOptionCount = themeConstants->GetInt(THEME_PICKER_SHOW_OPTION_COUNT); 60 theme->showOptionCount_ = 61 showOptionCount < 0 ? theme->showOptionCount_ : static_cast<uint32_t>(showOptionCount); 62 theme->showButtons_ = static_cast<bool>(themeConstants->GetInt(THEME_PICKER_SHOW_BUTTONS)); 63 theme->focusColor_ = themeConstants->GetColor(THEME_PICKER_FOCUS_COLOR); 64 theme->focusRadius_ = Radius(themeConstants->GetDimension(THEME_PICKER_FOCUS_RADIUS)); 65 theme->selectedOptionSize_ = Size(themeConstants->GetDouble(THEME_PICKER_OPTION_WIDTH), 66 themeConstants->GetDouble(THEME_PICKER_SELECT_OPTION_HEIGHT)); 67 theme->normalOptionSize_ = Size(themeConstants->GetDouble(THEME_PICKER_OPTION_WIDTH), 68 themeConstants->GetDouble(THEME_PICKER_NORMAL_OPTION_HEIGHT)); 69 theme->optionPadding_ = themeConstants->GetDouble(THEME_PICKER_OPTION_PADDING); 70 theme->optionSizeUnit_ = DimensionUnit::VP; 71 theme->jumpInterval_ = themeConstants->GetDimension(THEME_PICKER_JUMP_INTERVAL); 72 theme->columnIntervalMargin_ = themeConstants->GetDimension(THEME_PICKER_COLUMN_MARGIN); 73 theme->selectedOptionDecoration_ = AceType::MakeRefPtr<Decoration>(); 74 theme->selectedOptionDecoration_->SetBackgroundColor( 75 themeConstants->GetColor(THEME_PICKER_SELECT_OPTION_BACK_COLOR)); 76 theme->selectedOptionDecoration_->SetBorderRadius( 77 Radius(themeConstants->GetDimension(THEME_PICKER_SELECT_OPTION_RADIUS))); 78 theme->focusOptionDecoration_ = AceType::MakeRefPtr<Decoration>(); 79 theme->focusOptionDecoration_->SetBackgroundColor( 80 themeConstants->GetColor(THEME_PICKER_FOCUS_OPTION_BACK_COLOR)); 81 theme->focusOptionDecoration_->SetBorderRadius( 82 Radius(themeConstants->GetDimension(THEME_PICKER_FOCUS_OPTION_RADIUS))); 83 theme->lunarWidth_ = Dimension(36.0, DimensionUnit::VP); // this width do not need setting by outer. 84 theme->lunarHeight_ = Dimension(18.0, DimensionUnit::VP); // this height do not need setting by outer. 85 theme->buttonWidth_ = themeConstants->GetDimension(THEME_PICKER_BUTTON_WIDTH); 86 theme->buttonHeight_ = themeConstants->GetDimension(THEME_PICKER_BUTTON_HEIGHT); 87 theme->buttonTopPadding_ = themeConstants->GetDimension(THEME_PICKER_BUTTON_TOP_PADDING); 88 theme->titleBottomPadding_ = themeConstants->GetDimension(THEME_PICKER_TITLE_BOTTOM_PADDING); 89 theme->popupOutDecoration_ = AceType::MakeRefPtr<Decoration>(); 90 theme->popupOutDecoration_->SetBackgroundColor(themeConstants->GetColor(THEME_PICKER_DIALOG_MASK_COLOR)); 91 auto timeSplitter = themeConstants->GetInt(THEME_PICKER_TIME_SPLITTER); 92 theme->timeSplitter_ = timeSplitter < 0 ? theme->timeSplitter_ : static_cast<uint32_t>(timeSplitter); 93 theme->rotateInterval_ = 15.0; // when rotate 15.0 angle handle scroll of picker column. 94 theme->dividerThickness_ = DIVIDER_THICKNESS; 95 theme->dividerSpacing_ = themeConstants->GetDimension(THEME_PICKER_SELECT_DIVIDER_SPACING); 96 theme->dividerColor_ = themeConstants->GetColor(THEME_PICKER_SELECT_DIVIDER_COLOR); 97 theme->gradientHeight_ = themeConstants->GetDimension(THEME_PICKER_GRADIENT_HEIGHT); 98 theme->columnFixedWidth_ = themeConstants->GetDimension(THEME_PICKER_COLUMN_FIXED_WIDTH); 99 theme->pressColor_ = themeConstants->GetColor(THEME_PICKER_PRESS_COLOR); 100 Parse(themeConstants->GetThemeStyle(), theme); 101 return theme; 102 } 103 Parse(const RefPtr<ThemeStyle> & style,const RefPtr<PickerTheme> & theme)104 void Parse(const RefPtr<ThemeStyle>& style, const RefPtr<PickerTheme>& theme) const 105 { 106 if (!style || !theme || !theme->popupDecoration_) { 107 return; 108 } 109 auto pattern = style->GetAttr<RefPtr<ThemeStyle>>("picker_pattern", nullptr); 110 if (!pattern) { 111 LOGE("Pattern of picker is null, please check!"); 112 return; 113 } 114 theme->hoverColor_ = pattern->GetAttr<Color>(PATTERN_BG_COLOR_HOVERED, theme->hoverColor_); 115 theme->pressColor_ = pattern->GetAttr<Color>(PATTERN_BG_COLOR_PRESSED, theme->pressColor_); 116 if (SystemProperties::GetDeviceType() != DeviceType::PHONE) { 117 return; // light, dart color only for phone 118 } 119 theme->popupDecoration_->SetBackgroundColor( 120 pattern->GetAttr<Color>("popup_bg_color", theme->popupDecoration_->GetBackgroundColor())); 121 theme->focusColor_ = pattern->GetAttr<Color>(PATTERN_BG_COLOR_FOCUSED, theme->focusColor_); 122 theme->selectedOptionStyle_.SetTextColor( 123 pattern->GetAttr<Color>("selected_text_color", theme->selectedOptionStyle_.GetTextColor())); 124 theme->focusOptionStyle_.SetTextColor(theme->selectedOptionStyle_.GetTextColor()); 125 theme->normalOptionStyle_.SetTextColor( 126 pattern->GetAttr<Color>(PATTERN_TEXT_COLOR, theme->normalOptionStyle_.GetTextColor())); 127 theme->disappearOptionStyle_.SetTextColor(theme->normalOptionStyle_.GetTextColor()); 128 theme->titleStyle_.SetTextColor(theme->normalOptionStyle_.GetTextColor()); 129 theme->dividerColor_ = pattern->GetAttr<Color>("divider_color", theme->dividerColor_); 130 } 131 132 private: InitializeTextStyles(const RefPtr<PickerTheme> & theme,const RefPtr<ThemeConstants> & themeConstants)133 void InitializeTextStyles(const RefPtr<PickerTheme>& theme, const RefPtr<ThemeConstants>& themeConstants) const 134 { 135 theme->selectedOptionStyle_.SetFontSize(themeConstants->GetDimension(THEME_PICKER_SELECT_OPTION_FONT_SIZE)); 136 theme->selectedOptionStyle_.SetTextColor(themeConstants->GetColor(THEME_PICKER_SELECT_OPTION_TEXT_COLOR)); 137 theme->selectedOptionStyle_.SetFontWeight( 138 FontWeight(themeConstants->GetInt(THEME_PICKER_SELECT_OPTION_WEIGHT))); 139 theme->selectedOptionStyle_.SetAdaptTextSize(theme->selectedOptionStyle_.GetFontSize(), 140 themeConstants->GetDimension(THEME_PICKER_SELECT_OPTION_MIN_FONT_SIZE)); 141 theme->selectedOptionStyle_.SetMaxLines(1); 142 theme->selectedOptionStyle_.SetTextOverflow(TextOverflow::ELLIPSIS); 143 theme->focusOptionStyle_.SetFontSize(themeConstants->GetDimension(THEME_PICKER_FOCUS_OPTION_FONT_SIZE)); 144 theme->focusOptionStyle_.SetTextColor(themeConstants->GetColor(THEME_PICKER_FOCUS_OPTION_TEXT_COLOR)); 145 theme->focusOptionStyle_.SetFontWeight( 146 FontWeight(themeConstants->GetInt(THEME_PICKER_FOCUS_OPTION_WEIGHT))); 147 theme->focusOptionStyle_.SetAdaptTextSize(theme->focusOptionStyle_.GetFontSize(), 148 themeConstants->GetDimension(THEME_PICKER_SELECT_OPTION_MIN_FONT_SIZE)); 149 theme->focusOptionStyle_.SetMaxLines(1); 150 theme->focusOptionStyle_.SetTextOverflow(TextOverflow::ELLIPSIS); 151 theme->normalOptionStyle_.SetFontSize(themeConstants->GetDimension(THEME_PICKER_NORMAL_OPTION_FONT_SIZE)); 152 theme->normalOptionStyle_.SetTextColor(themeConstants->GetColor(THEME_PICKER_NORMAL_OPTION_FONT_COLOR)); 153 theme->normalOptionStyle_.SetFontWeight( 154 FontWeight(themeConstants->GetInt(THEME_PICKER_NORMAL_OPTION_WEIGHT))); 155 theme->normalOptionStyle_.SetAdaptTextSize(theme->normalOptionStyle_.GetFontSize(), 156 themeConstants->GetDimension(THEME_PICKER_NORMAL_OPTION_MIN_FONT_SIZE)); 157 theme->normalOptionStyle_.SetMaxLines(1); 158 theme->normalOptionStyle_.SetTextOverflow(TextOverflow::ELLIPSIS); 159 theme->normalOptionStyle_.SetFontWeight( 160 FontWeight(themeConstants->GetInt(THEME_PICKER_NORMAL_OPTION_WEIGHT))); 161 theme->disappearOptionStyle_.SetFontSize( 162 themeConstants->GetDimension(THEME_PICKER_DISAPPEAR_OPTION_FONT_SIZE)); 163 theme->disappearOptionStyle_.SetTextColor(themeConstants->GetColor(THEME_PICKER_NORMAL_OPTION_FONT_COLOR)); 164 theme->normalOptionStyle_.SetFontWeight( 165 FontWeight(themeConstants->GetInt(THEME_PICKER_NORMAL_OPTION_WEIGHT))); 166 theme->disappearOptionStyle_.SetAdaptTextSize(theme->disappearOptionStyle_.GetFontSize(), 167 themeConstants->GetDimension(THEME_PICKER_NORMAL_OPTION_MIN_FONT_SIZE)); 168 theme->disappearOptionStyle_.SetMaxLines(1); 169 theme->disappearOptionStyle_.SetTextOverflow(TextOverflow::ELLIPSIS); 170 theme->buttonStyle_.SetFontSize(themeConstants->GetDimension(THEME_PICKER_BUTTON_FONT_SIZE)); 171 theme->buttonStyle_.SetTextColor(themeConstants->GetColor(THEME_PICKER_BUTTON_TEXT_COLOR)); 172 theme->titleStyle_.SetFontSize(themeConstants->GetDimension(THEME_PICKER_TITLE_FONT_SIZE)); 173 theme->titleStyle_.SetTextColor(themeConstants->GetColor(THEME_PICKER_TITLE_TEXT_COLOR)); 174 theme->titleStyle_.SetFontWeight(FontWeight::W500); 175 theme->titleStyle_.SetMaxLines(1); 176 theme->titleStyle_.SetTextOverflow(TextOverflow::ELLIPSIS); 177 if (SystemProperties::GetDeviceType() == DeviceType::PHONE) { 178 theme->focusOptionStyle_ = theme->selectedOptionStyle_; // focus style the same with selected on phone 179 } 180 } 181 }; 182 183 ~PickerTheme() override = default; 184 clone()185 RefPtr<PickerTheme> clone() const 186 { 187 auto theme = AceType::Claim(new PickerTheme()); 188 theme->selectedOptionSize_ = selectedOptionSize_; 189 theme->selectedOptionStyle_ = selectedOptionStyle_; 190 theme->normalOptionSize_ = normalOptionSize_; 191 theme->normalOptionStyle_ = normalOptionStyle_; 192 theme->disappearOptionStyle_ = disappearOptionStyle_; 193 theme->showOptionCount_ = showOptionCount_; 194 theme->optionSizeUnit_ = optionSizeUnit_; 195 theme->popupDecoration_ = popupDecoration_; 196 theme->focusColor_ = focusColor_; 197 theme->popupEdge_ = popupEdge_; 198 theme->focusOptionStyle_ = focusOptionStyle_; 199 theme->focusOptionDecoration_ = focusOptionDecoration_; 200 theme->selectedOptionDecoration_ = selectedOptionDecoration_; 201 theme->buttonStyle_ = buttonStyle_; 202 theme->showButtons_ = showButtons_; 203 theme->buttonWidth_ = buttonWidth_; 204 theme->buttonHeight_ = buttonHeight_; 205 theme->buttonTopPadding_ = buttonTopPadding_; 206 theme->jumpInterval_ = jumpInterval_; 207 theme->columnIntervalMargin_ = columnIntervalMargin_; 208 theme->focusRadius_ = focusRadius_; 209 theme->optionPadding_ = optionPadding_; 210 theme->titleStyle_ = titleStyle_; 211 theme->titleBottomPadding_ = titleBottomPadding_; 212 theme->popupOutDecoration_ = popupOutDecoration_; 213 theme->lunarWidth_ = lunarWidth_; 214 theme->lunarHeight_ = lunarHeight_; 215 theme->timeSplitter_ = timeSplitter_; 216 theme->rotateInterval_ = rotateInterval_; 217 theme->dividerThickness_ = dividerThickness_; 218 theme->dividerSpacing_ = dividerSpacing_; 219 theme->dividerColor_ = dividerColor_; 220 theme->gradientHeight_ = gradientHeight_; 221 theme->columnFixedWidth_ = columnFixedWidth_; 222 theme->disappearOptionStyle_ = disappearOptionStyle_; 223 theme->pressColor_ = pressColor_; 224 theme->hoverColor_ = hoverColor_; 225 return theme; 226 } 227 GetOptionStyle(bool selected,bool focus)228 const TextStyle& GetOptionStyle(bool selected, bool focus) const 229 { 230 if (!selected) { 231 return normalOptionStyle_; 232 } 233 234 if (focus) { 235 return focusOptionStyle_; 236 } 237 238 return selectedOptionStyle_; 239 } SetOptionStyle(bool selected,bool focus,const TextStyle & value)240 void SetOptionStyle(bool selected, bool focus, const TextStyle& value) 241 { 242 if (!selected) { 243 normalOptionStyle_ = value; 244 } else if (focus) { 245 focusOptionStyle_ = value; 246 } else { 247 selectedOptionStyle_ = value; 248 } 249 } 250 GetDisappearOptionStyle()251 const TextStyle& GetDisappearOptionStyle() const 252 { 253 return disappearOptionStyle_; 254 } SetDisappearOptionStyle(const TextStyle & value)255 void SetDisappearOptionStyle(const TextStyle& value) 256 { 257 disappearOptionStyle_ = value; 258 } 259 GetButtonStyle()260 const TextStyle& GetButtonStyle() const 261 { 262 return buttonStyle_; 263 } 264 GetOptionDecoration(bool focus)265 const RefPtr<Decoration>& GetOptionDecoration(bool focus) 266 { 267 if (focus) { 268 return focusOptionDecoration_; 269 } 270 271 return selectedOptionDecoration_; 272 } SetOptionDecoration(bool focus,const RefPtr<Decoration> & value)273 void SetOptionDecoration(bool focus, const RefPtr<Decoration>& value) 274 { 275 if (focus) { 276 focusOptionDecoration_ = value; 277 } else { 278 selectedOptionDecoration_ = value; 279 } 280 } 281 GetOptionSize(bool selected)282 const Size& GetOptionSize(bool selected) const 283 { 284 if (selected) { 285 return selectedOptionSize_; 286 } 287 288 return normalOptionSize_; 289 } 290 GetShowOptionCount()291 uint32_t GetShowOptionCount() const 292 { 293 return showOptionCount_; 294 } 295 GetOptionSizeUnit()296 DimensionUnit GetOptionSizeUnit() const 297 { 298 return optionSizeUnit_; 299 } 300 GetPopupDecoration(bool isOutBox)301 const RefPtr<Decoration>& GetPopupDecoration(bool isOutBox) const 302 { 303 if (!isOutBox) { 304 return popupDecoration_; 305 } 306 return popupOutDecoration_; 307 } 308 GetFocusColor()309 const Color& GetFocusColor() const 310 { 311 return focusColor_; 312 } 313 GetPopupEdge()314 const Edge& GetPopupEdge() const 315 { 316 return popupEdge_; 317 } 318 GetShowButtons()319 bool GetShowButtons() const 320 { 321 return showButtons_; 322 } 323 GetButtonWidth()324 const Dimension& GetButtonWidth() const 325 { 326 return buttonWidth_; 327 } 328 GetButtonHeight()329 const Dimension& GetButtonHeight() const 330 { 331 return buttonHeight_; 332 } 333 GetButtonTopPadding()334 const Dimension& GetButtonTopPadding() const 335 { 336 return buttonTopPadding_; 337 } 338 GetJumpInterval()339 const Dimension& GetJumpInterval() const 340 { 341 return jumpInterval_; 342 } 343 GetColumnIntervalMargin()344 const Dimension& GetColumnIntervalMargin() const 345 { 346 return columnIntervalMargin_; 347 } 348 GetFocusRadius()349 const Radius& GetFocusRadius() const 350 { 351 return focusRadius_; 352 } 353 GetOptionPadding()354 double GetOptionPadding() const 355 { 356 return optionPadding_; 357 } SetOptionPadding(double value)358 void SetOptionPadding(double value) 359 { 360 optionPadding_ = value; 361 } 362 GetTitleStyle()363 const TextStyle& GetTitleStyle() const 364 { 365 return titleStyle_; 366 } 367 GetTitleBottomPadding()368 const Dimension& GetTitleBottomPadding() const 369 { 370 return titleBottomPadding_; 371 } 372 GetLunarWidth()373 const Dimension& GetLunarWidth() const 374 { 375 return lunarWidth_; 376 } 377 GetLunarHeight()378 const Dimension& GetLunarHeight() const 379 { 380 return lunarHeight_; 381 } 382 HasTimeSplitter()383 bool HasTimeSplitter() const 384 { 385 return (timeSplitter_ > 0); 386 } 387 GetRotateInterval()388 double GetRotateInterval() const 389 { 390 return rotateInterval_; 391 } 392 GetDividerThickness()393 const Dimension& GetDividerThickness() const 394 { 395 return dividerThickness_; 396 } 397 GetDividerSpacing()398 const Dimension& GetDividerSpacing() const 399 { 400 return dividerSpacing_; 401 } 402 GetDividerColor()403 const Color& GetDividerColor() const 404 { 405 return dividerColor_; 406 } 407 GetGradientHeight()408 const Dimension& GetGradientHeight() const 409 { 410 return gradientHeight_; 411 } 412 GetColumnFixedWidth()413 const Dimension& GetColumnFixedWidth() const 414 { 415 return columnFixedWidth_; 416 } 417 GetColumnBottomTotalHeight(bool hasLunar)418 Dimension GetColumnBottomTotalHeight(bool hasLunar) const 419 { 420 if (hasLunar) { 421 return buttonHeight_ + lunarHeight_ + buttonTopPadding_ * 2 + popupEdge_.Bottom(); 422 } else { 423 return buttonHeight_ + buttonTopPadding_ + popupEdge_.Bottom(); 424 } 425 } 426 GetPressColor()427 const Color& GetPressColor() const 428 { 429 return pressColor_; 430 } 431 GetHoverColor()432 const Color& GetHoverColor() const 433 { 434 return hoverColor_; 435 } 436 437 private: 438 PickerTheme() = default; 439 440 Color focusColor_; 441 Color hoverColor_; 442 Color pressColor_; 443 Radius focusRadius_; 444 uint32_t showOptionCount_ = 0; 445 bool showButtons_ = false; 446 Dimension jumpInterval_; 447 448 // popup style 449 RefPtr<Decoration> popupDecoration_; 450 RefPtr<Decoration> popupOutDecoration_; 451 Edge popupEdge_; 452 453 // column 454 Dimension columnIntervalMargin_; 455 456 // text style 457 TextStyle focusOptionStyle_; 458 TextStyle selectedOptionStyle_; 459 TextStyle normalOptionStyle_; 460 TextStyle disappearOptionStyle_; 461 TextStyle buttonStyle_; 462 TextStyle titleStyle_; 463 464 // text around decoration 465 RefPtr<Decoration> selectedOptionDecoration_; 466 RefPtr<Decoration> focusOptionDecoration_; 467 468 // option size 469 Size selectedOptionSize_; 470 Size normalOptionSize_; 471 double optionPadding_ = 0.0; 472 DimensionUnit optionSizeUnit_ = DimensionUnit::PX; 473 474 // buttons size 475 Dimension buttonWidth_; 476 Dimension buttonHeight_; 477 Dimension buttonTopPadding_; 478 Dimension titleBottomPadding_; 479 480 // lunar size 481 Dimension lunarWidth_; 482 Dimension lunarHeight_; 483 484 uint32_t timeSplitter_ = 0; 485 486 double rotateInterval_ = 0.0; 487 Dimension dividerThickness_; 488 Dimension dividerSpacing_; 489 Color dividerColor_; 490 Dimension gradientHeight_; 491 Dimension columnFixedWidth_; 492 }; 493 494 } // namespace OHOS::Ace 495 496 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_PICKER_PICKER_THEME_H 497