1 /*
2  * Copyright (c) 2023 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_THEME_SHADOW_THEME_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_THEME_SHADOW_THEME_H
18 
19 #include <string>
20 #include "theme_attributes.h"
21 
22 #include "base/utils/device_config.h"
23 #include "core/components/common/properties/shadow.h"
24 #include "core/components/theme/theme.h"
25 #include "core/components/theme/theme_constants.h"
26 
27 namespace OHOS::Ace {
28 
29 enum class BlurStyle;
30 enum class ThemeColorMode;
31 
32 class ShadowTheme : public virtual Theme {
33     DECLARE_ACE_TYPE(ShadowTheme, Theme);
34 
35 public:
36     class Builder {
37     public:
38         Builder() = default;
39         ~Builder() = default;
Build(const RefPtr<ThemeConstants> & themeConstants)40         RefPtr<ShadowTheme> Build(const RefPtr<ThemeConstants>& themeConstants)
41         {
42             RefPtr<ShadowTheme> theme = AceType::Claim(new ShadowTheme());
43             CHECK_NULL_RETURN(themeConstants, theme);
44             RefPtr<ThemeStyle> shadowTheme = themeConstants->GetPatternByName(THEME_PATTERN_SHADOW);
45             if (!shadowTheme) {
46                 TAG_LOGW(AceLogTag::ACE_THEME, "find pattern of shadow fail");
47                 return theme;
48             }
49             ParsePattern(shadowTheme, theme);
50             return theme;
51         }
52 
53     private:
ParsePattern(const RefPtr<ThemeStyle> & themeStyle,const RefPtr<ShadowTheme> & theme)54         void ParsePattern(const RefPtr<ThemeStyle>& themeStyle, const RefPtr<ShadowTheme>& theme)
55         {
56             std::unordered_map<ShadowStyle, std::string> shadowStyles { { ShadowStyle::OuterDefaultXS, "default_xs" },
57                 { ShadowStyle::OuterDefaultSM, "default_sm" }, { ShadowStyle::OuterDefaultMD, "default_md" },
58                 { ShadowStyle::OuterDefaultLG, "default_lg" }, { ShadowStyle::OuterFloatingSM, "floating_sm" },
59                 { ShadowStyle::OuterFloatingMD, "floating_md" } };
60 
61             for (auto iter = shadowStyles.begin(); iter != shadowStyles.end(); ++iter) {
62                 auto shadowDark = ParseShadowParam(themeStyle, iter->first, iter->second, true);
63                 auto shadowLight = ParseShadowParam(themeStyle, iter->first, iter->second, false);
64                 theme->shadowStyles_.emplace(GetKeyOfShadowStyle(iter->first, ColorMode::DARK), shadowDark);
65                 theme->shadowStyles_.emplace(GetKeyOfShadowStyle(iter->first, ColorMode::LIGHT), shadowLight);
66             }
67         }
68 
ParseShadowParam(const RefPtr<ThemeStyle> & themeStyle,ShadowStyle shadowStyle,const std::string & name,bool isDark)69         Shadow ParseShadowParam(
70             const RefPtr<ThemeStyle>& themeStyle, ShadowStyle shadowStyle, const std::string& name, bool isDark)
71         {
72             // shadow_style_floating_sm_shadow prefix + name +
73             const std::string prefix = std::string("shadow_style_") + name;
74             const char* attrs[] = { "_shadow", "_offset_x", "_offset_y", "_color", "_radius" };
75             const std::string suffix = isDark ? "_dark" : "";
76 
77             Shadow shadow;
78 
79             auto elevationName = prefix + std::string(attrs[0]) + suffix;
80             auto elevation = themeStyle->GetAttr<double>(elevationName, 0.0);
81 
82             auto offsetXName = prefix + std::string(attrs[1]) + suffix;
83             auto offsetX = themeStyle->GetAttr<double>(offsetXName, 0.0);
84             auto offsetYName = prefix + std::string(attrs[2]) + suffix;
85             auto offsetY = themeStyle->GetAttr<double>(offsetYName, 0.0);
86             Offset offset(offsetX, offsetY);
87 
88             auto colorName = prefix + std::string(attrs[3]) + suffix;
89             auto color = themeStyle->GetAttr<Color>(colorName, Color());
90             auto radiusName =  prefix + std::string(attrs[4]) + suffix;
91             auto radius  =  themeStyle->GetAttr<double>(radiusName, 0.0);
92             if (radius != 0.0) {
93                 return Shadow(radius, offset, color, shadowStyle);
94             }
95             return Shadow(static_cast<float>(elevation), offset, color, shadowStyle);
96         }
97     };
98     ~ShadowTheme() override = default;
GetShadow(ShadowStyle style,ColorMode colorMode)99     Shadow GetShadow(ShadowStyle style, ColorMode colorMode) const
100     {
101         auto key = GetKeyOfShadowStyle(style, colorMode);
102         auto iter = shadowStyles_.find(key);
103         return iter != shadowStyles_.end() ? iter->second : Shadow();
104     }
105 
106 protected:
107     ShadowTheme() = default;
108 
109 private:
GetKeyOfShadowStyle(ShadowStyle style,ColorMode colorMode)110     static uint32_t GetKeyOfShadowStyle(ShadowStyle style, ColorMode colorMode)
111     {
112         return (static_cast<uint32_t>(colorMode) << 8) + static_cast<uint32_t>(style); // can hold 2^8 shadowStyle enums
113     }
114 
115     std::unordered_map<uint32_t, Shadow> shadowStyles_;
116 };
117 
118 } // namespace OHOS::Ace
119 
120 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_THEME_BLUR_STYLE_THEME_H
121