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