• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2022 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_THEME_STYLE_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_THEME_THEME_STYLE_H
18 
19 #include <string>
20 #include <type_traits>
21 #include <unordered_map>
22 #include <variant>
23 
24 #include "base/geometry/dimension.h"
25 #include "base/log/log.h"
26 #include "base/memory/ace_type.h"
27 #include "base/resource/internal_resource.h"
28 #include "core/components/common/properties/color.h"
29 #include "core/components/theme/theme_utils.h"
30 
31 namespace OHOS::Ace {
32 
33 class ThemeStyle;
34 class ThemeUtils;
35 class StateResource;
36 
37 using ResRawValue = std::variant<Color, Dimension, int32_t, uint32_t, double, InternalResource::ResourceId, std::string,
38     RefPtr<ThemeStyle>, RefPtr<StateResource>>;
39 using BlendAlpha = std::variant<double, uint32_t>;
40 
41 enum class ThemeConstantsType {
42     // Error type for check if key is match with value
43     ERROR = -1,
44     COLOR = 0,
45     DIMENSION,
46     INT,
47     DOUBLE,
48     RESOURCE_ID,
49     REFERENCE,
50     REFERENCE_ATTR,
51     STRING,
52     PATTERN,
53     STATE_RESOURCE,
54     THEME,
55 };
56 
57 struct ResValueWrapper {
58 
59     template<typename T>
GetValueResValueWrapper60     std::pair<bool, T> GetValue(const T& errorValue) const
61     {
62         auto valuePtr = std::get_if<T>(&value);
63         if (!valuePtr) {
64             return std::make_pair(false, errorValue);
65         }
66         return std::make_pair(true, *valuePtr);
67     }
68 
69     ThemeConstantsType type { ThemeConstantsType::COLOR };
70     ResRawValue value;
71     // Whether style value is public to app.
72     bool isPublic { false };
73     // Extra alpha needs to blend with color(uint means an ID reference, double means an alpha value).
74     BlendAlpha blendAlpha { 1.0 };
75 };
76 
77 using ThemeConstantsMap = std::unordered_map<uint32_t, ResValueWrapper>;
78 
79 class ThemeStyle : public virtual AceType {
80     DECLARE_ACE_TYPE(ThemeStyle, AceType);
81 
82 public:
83     ThemeStyle() = default;
~ThemeStyle()84     ~ThemeStyle() override
85     {
86         attributes_.clear();
87     }
88 
SetName(const std::string & name)89     void SetName(const std::string& name)
90     {
91         name_ = name;
92     }
93 
GetName()94     std::string GetName() const
95     {
96         return name_;
97     }
98 
ParseContent()99     virtual void ParseContent() {}
100 
SetAttributes(const std::unordered_map<std::string,ResValueWrapper> & attributes)101     void SetAttributes(const std::unordered_map<std::string, ResValueWrapper>& attributes)
102     {
103         attributes_ = attributes;
104     }
105 
GetAttributes()106     const std::unordered_map<std::string, ResValueWrapper>& GetAttributes() const
107     {
108         return attributes_;
109     }
110 
HasAttr(const std::string & attr)111     bool HasAttr(const std::string& attr) const
112     {
113         return attributes_.find(attr) != attributes_.end();
114     }
115 
SetAttr(const std::string & attr,const ResValueWrapper & value)116     void SetAttr(const std::string& attr, const ResValueWrapper& value)
117     {
118         attributes_[attr] = value;
119     }
120 
121     template<typename T>
GetAttr(const std::string & attr,const T & errorValue)122     T GetAttr(const std::string& attr, const T& errorValue) const
123     {
124         auto findIter = attributes_.find(attr);
125         if (findIter == attributes_.end()) {
126             LOGE("style %{public}s not contains %{public}s!", name_.c_str(), attr.c_str());
127             return errorValue;
128         }
129         const auto& valueWrapper = findIter->second;
130         // parse attr reference.
131         if (valueWrapper.type == ThemeConstantsType::REFERENCE_ATTR) {
132             auto parent = parentStyle_.Upgrade();
133             if (!parent) {
134                 return errorValue;
135             }
136             auto parseResult = ThemeUtils::ParseThemeIdReference(valueWrapper.GetValue<std::string>("").second);
137             if (!parseResult.parseSuccess || parseResult.isIdRef) {
138                 return errorValue;
139             }
140             return parent->GetAttr<T>(parseResult.refAttr, errorValue);
141         }
142         auto valuePair = valueWrapper.GetValue<T>(errorValue);
143         if (!valuePair.first) {
144             LOGE("style %{public}s get attr %{public}s error!", name_.c_str(), attr.c_str());
145         }
146         return valuePair.second;
147     }
148 
149 protected:
150     std::string name_;
151     std::unordered_map<std::string, ResValueWrapper> attributes_;
152     WeakPtr<ThemeStyle> parentStyle_;
153 };
154 
155 class StateResource : public virtual AceType {
156     DECLARE_ACE_TYPE(StateResource, AceType);
157 
158 public:
159     StateResource() = default;
160     ~StateResource() override = default;
161 
SetName(const std::string & name)162     void SetName(const std::string& name)
163     {
164         name_ = name;
165     }
166 
SetStateValue(uint32_t state,const ResValueWrapper & value)167     void SetStateValue(uint32_t state, const ResValueWrapper& value)
168     {
169         states_[state] = value;
170     }
171 
172     template<typename T>
GetState(uint32_t state,const T & defaultValue)173     T GetState(uint32_t state, const T& defaultValue) const
174     {
175         auto findIter = states_.find(state);
176         if (findIter == states_.end()) {
177             return defaultValue;
178         }
179         auto valuePair = findIter->second.GetValue<T>(defaultValue);
180         if (!valuePair.first) {
181             LOGE("style %{public}s get state %{public}u error!", name_.c_str(), state);
182         }
183         return valuePair.second;
184     }
185 
186 private:
187     std::string name_;
188     std::unordered_map<uint32_t, ResValueWrapper> states_;
189 };
190 
191 } // namespace OHOS::Ace
192 
193 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_THEME_THEME_STYLE_H
194