• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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_NG_PATTERN_GAUGE_GAUGE_PAINT_PROPERTY_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_GAUGE_GAUGE_PAINT_PROPERTY_H
18 
19 #include "core/common/container.h"
20 #include "core/common/resource/resource_object.h"
21 #include "core/components/common/layout/constants.h"
22 #include "core/components/common/properties/color.h"
23 #include "core/components_ng/base/inspector_filter.h"
24 #include "core/components_ng/pattern/gauge/gauge_theme.h"
25 #include "core/components_ng/render/paint_property.h"
26 #include "core/image/image_source_info.h"
27 
28 namespace OHOS::Ace::NG {
29 using ColorStopArray = std::vector<std::pair<Color, Dimension>>;
30 enum class GaugeType : int32_t {
31     TYPE_CIRCULAR_MULTI_SEGMENT_GRADIENT = 0,
32     TYPE_CIRCULAR_SINGLE_SEGMENT_GRADIENT = 1,
33     TYPE_CIRCULAR_MONOCHROME = 2,
34 };
35 
36 struct GaugeShadowOptions {
37     bool isShadowVisible = true;
38     float radius = DEFAULT_GAUGE_SHADOW_RADIUS;
39     float offsetX = DEFAULT_GAUGE_SHADOW_OFFSETX;
40     float offsetY = DEFAULT_GAUGE_SHADOW_OFFSETY;
41     bool operator==(const GaugeShadowOptions& rhs) const
42     {
43         return radius == rhs.radius && offsetX == rhs.offsetX && offsetY == rhs.offsetY &&
44                isShadowVisible == rhs.isShadowVisible;
45     }
46     using UpdateFunc = std::function<void(const RefPtr<ResourceObject>&, GaugeShadowOptions&)>;
AddResourceGaugeShadowOptions47     void AddResource(const std::string& key, const RefPtr<ResourceObject>& resObj, UpdateFunc&& updateFunc)
48     {
49         if (resObj == nullptr || !updateFunc) {
50             return;
51         }
52         resMap_[key] = { resObj, std::move(updateFunc) };
53     }
54 
ReloadResourcesGaugeShadowOptions55     void ReloadResources()
56     {
57         for (const auto& [key, resourceUpdater] : resMap_) {
58             resourceUpdater.updateFunc(resourceUpdater.obj, *this);
59         }
60     }
61 
62 private:
63     struct ResourceUpdater {
64         RefPtr<ResourceObject> obj;
65         UpdateFunc updateFunc;
66     };
67 
68     std::unordered_map<std::string, ResourceUpdater> resMap_;
69 };
70 class GaugePaintProperty : public PaintProperty {
71     DECLARE_ACE_TYPE(GaugePaintProperty, PaintProperty);
72 
73 public:
74     GaugePaintProperty() = default;
75     ~GaugePaintProperty() override = default;
76 
Clone()77     RefPtr<PaintProperty> Clone() const override
78     {
79         auto paintProperty = MakeRefPtr<GaugePaintProperty>();
80         paintProperty->UpdatePaintProperty(this);
81         paintProperty->propValue_ = CloneValue();
82         paintProperty->propMin_ = CloneMin();
83         paintProperty->propMax_ = CloneMax();
84         paintProperty->propStartAngle_ = CloneStartAngle();
85         paintProperty->propEndAngle_ = CloneEndAngle();
86         paintProperty->propColors_ = CloneColors();
87         paintProperty->propGradientColors_ = CloneGradientColors();
88         paintProperty->propValues_ = CloneValues();
89         paintProperty->propStrokeWidth_ = CloneStrokeWidth();
90         paintProperty->propGaugeType_ = CloneGaugeType();
91         paintProperty->propShadowOptions_ = CloneShadowOptions();
92         paintProperty->propIsShowIndicator_ = CloneIsShowIndicator();
93         paintProperty->propIndicatorIconSourceInfo_ = CloneIndicatorIconSourceInfo();
94         paintProperty->propIndicatorSpace_ = CloneIndicatorSpace();
95         paintProperty->propIndicatorChange_ = CloneIndicatorChange();
96         paintProperty->propIsSensitive_ = CloneIsSensitive();
97         return paintProperty;
98     }
99 
Reset()100     void Reset() override
101     {
102         PaintProperty::Reset();
103         ResetValue();
104         ResetMin();
105         ResetMax();
106         ResetStartAngle();
107         ResetEndAngle();
108         ResetColors();
109         ResetGradientColors();
110         ResetValues();
111         ResetStrokeWidth();
112         ResetGaugeType();
113         ResetShadowOptions();
114         ResetIsShowIndicator();
115         ResetIndicatorIconSourceInfo();
116         ResetIndicatorSpace();
117         ResetIsSensitive();
118     }
119 
ToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter)120     void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const override
121     {
122         PaintProperty::ToJsonValue(json, filter);
123         /* no fixed attr below, just return */
124         if (filter.IsFastFilter()) {
125             if (Container::GreatOrEqualAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
126                 ToJsonColor(json, filter);
127                 ToJsonIndicator(json, filter);
128                 ToJsonTrackShadow(json, filter);
129             }
130             return;
131         }
132         json->PutExtAttr("value", StringUtils::DoubleToString(propValue_.value_or(0)).c_str(), filter);
133         json->PutExtAttr("max", StringUtils::DoubleToString(propMax_.value_or(100)).c_str(), filter);
134         json->PutExtAttr("min", StringUtils::DoubleToString(propMin_.value_or(0)).c_str(), filter);
135         json->PutExtAttr("startAngle", StringUtils::DoubleToString(propStartAngle_.value_or(0)).c_str(), filter);
136         json->PutExtAttr("endAngle", StringUtils::DoubleToString(propEndAngle_.value_or(360)).c_str(), filter);
137         json->PutExtAttr("isSensitive", std::to_string(GetIsSensitive().value_or(false)).c_str(), filter);
138         json->PutExtAttr("privacySensitive", GetIsSensitive().value_or(false)? "true": "false", filter);
139         if (propStrokeWidth_.has_value()) {
140             json->PutExtAttr("strokeWidth", propStrokeWidth_.value().ToString().c_str(), filter);
141         } else {
142             json->PutExtAttr("strokeWidth", "", filter);
143         }
144 
145         if (Container::LessThanAPIVersion(PlatformVersion::VERSION_ELEVEN)) {
146             auto jsonColors = JsonUtil::CreateArray(true);
147             if (propColors_.has_value() && propColors_.has_value()) {
148                 for (size_t i = 0; i < propValues_.value().size(); i++) {
149                     auto jsonObject = JsonUtil::CreateArray(true);
150                     jsonObject->Put("0", propColors_.value()[i].ColorToString().c_str());
151                     jsonObject->Put("1", propValues_.value()[i]);
152                     auto index = std::to_string(i);
153                     jsonColors->Put(index.c_str(), jsonObject);
154                 }
155             }
156             json->PutExtAttr("colors", jsonColors->ToString().c_str(), filter);
157         } else {
158             ToJsonColor(json, filter);
159             ToJsonIndicator(json, filter);
160             ToJsonTrackShadow(json, filter);
161         }
162     }
163 
ToJsonColor(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter)164     void ToJsonColor(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
165     {
166         /* no fixed attr below, just return */
167         if (filter.IsFastFilter()) {
168             return;
169         }
170         if (!propGaugeType_.has_value()) {
171             auto jsonColor = JsonUtil::CreateArray(true);
172             for (size_t j = 0; j < GAUGE_DEFAULT_COLOR.size(); j++) {
173                 jsonColor->Put(std::to_string(j).c_str(), GAUGE_DEFAULT_COLOR[j].ColorToString().c_str());
174             }
175             json->PutExtAttr("colors", jsonColor->ToString().c_str(), filter);
176             return;
177         }
178 
179         if (propGaugeType_.value() == GaugeType::TYPE_CIRCULAR_MONOCHROME) {
180             if (propGradientColors_.has_value()) {
181                 json->PutExtAttr("colors",
182                     propGradientColors_.value().at(0).at(0).first.ColorToString().c_str(), filter);
183             }
184             return;
185         }
186 
187         if (propGaugeType_.value() == GaugeType::TYPE_CIRCULAR_SINGLE_SEGMENT_GRADIENT) {
188             if (propGradientColors_.has_value()) {
189                 auto jsonColor = JsonUtil::CreateArray(true);
190                 auto colorStopArray = propGradientColors_.value().at(0);
191                 for (size_t j = 0; j < colorStopArray.size(); j++) {
192                     auto jsonColorObject = JsonUtil::CreateArray(true);
193                     jsonColorObject->Put("0", colorStopArray[j].first.ColorToString().c_str());
194                     jsonColorObject->Put("1", std::to_string(colorStopArray[j].second.Value()).c_str());
195                     auto indexStr = std::to_string(j);
196                     jsonColor->Put(indexStr.c_str(), jsonColorObject);
197                 }
198                 json->PutExtAttr("colors", jsonColor->ToString().c_str(), filter);
199             }
200             return;
201         }
202         ToJsonColorHasValue(json, filter);
203     }
204 
ToJsonColorHasValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter)205     void ToJsonColorHasValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
206     {
207         auto jsonGradientColors = JsonUtil::CreateArray(true);
208         if (propGradientColors_.has_value() && propValues_.has_value() &&
209             (propGradientColors_.value().size() == propValues_.value().size())) {
210             for (size_t i = 0; i < propValues_.value().size(); i++) {
211                 auto jsonObject = JsonUtil::CreateArray(true);
212                 auto jsonColor = JsonUtil::CreateArray(true);
213                 auto colorStopArray = propGradientColors_.value()[i];
214                 for (size_t j = 0; j < colorStopArray.size(); j++) {
215                     auto jsonColorObject = JsonUtil::CreateArray(true);
216                     jsonColorObject->Put("0", colorStopArray[j].first.ColorToString().c_str());
217                     jsonColorObject->Put("1", std::to_string(colorStopArray[j].second.Value()).c_str());
218                     auto indexStr = std::to_string(j);
219                     jsonColor->Put(indexStr.c_str(), jsonColorObject);
220                 }
221                 jsonObject->Put("0", jsonColor);
222                 jsonObject->Put("1", propValues_.value()[i]);
223                 auto index = std::to_string(i);
224                 jsonGradientColors->Put(index.c_str(), jsonObject);
225             }
226         }
227         json->PutExtAttr("colors", jsonGradientColors->ToString().c_str(), filter);
228     }
229 
ToJsonIndicator(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter)230     void ToJsonIndicator(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
231     {
232         /* no fixed attr below, just return */
233         if (filter.IsFastFilter()) {
234             return;
235         }
236         if (!propIsShowIndicator_.value_or(true)) {
237             json->PutExtAttr("indicator", "null", filter);
238             return;
239         }
240         auto indicatorJsonValue = JsonUtil::Create(true);
241         if (propIndicatorIconSourceInfo_.has_value()) {
242             indicatorJsonValue->Put("icon", propIndicatorIconSourceInfo_.value().GetSrc().c_str());
243         } else {
244             indicatorJsonValue->Put("icon", "SystemStyle");
245         }
246 
247         if (propIndicatorSpace_.has_value()) {
248             indicatorJsonValue->Put("space", propIndicatorSpace_.value().ToString().c_str());
249         } else {
250             indicatorJsonValue->Put("space", INDICATOR_DISTANCE_TO_TOP.ToString().c_str());
251         }
252         json->PutExtAttr("indicator", indicatorJsonValue, filter);
253     }
254 
ToJsonTrackShadow(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter)255     void ToJsonTrackShadow(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
256     {
257         /* no fixed attr below, just return */
258         if (filter.IsFastFilter()) {
259             return;
260         }
261         GaugeShadowOptions trackShadow;
262         if (propShadowOptions_.has_value()) {
263             trackShadow.radius = propShadowOptions_.value().radius;
264             trackShadow.offsetX = propShadowOptions_.value().offsetX;
265             trackShadow.offsetY = propShadowOptions_.value().offsetY;
266             trackShadow.isShadowVisible = propShadowOptions_.value().isShadowVisible;
267         } else {
268             trackShadow.radius = DEFAULT_GAUGE_SHADOW_RADIUS;
269             trackShadow.offsetX = DEFAULT_GAUGE_SHADOW_OFFSETX;
270             trackShadow.offsetY = DEFAULT_GAUGE_SHADOW_OFFSETY;
271         }
272 
273         if (!trackShadow.isShadowVisible) {
274             json->PutExtAttr("trackShadow", "null", filter);
275             return;
276         }
277 
278         auto shadowOptionJson = JsonUtil::Create(true);
279         shadowOptionJson->Put("radius", std::to_string(trackShadow.radius).c_str());
280         shadowOptionJson->Put("offsetX", std::to_string(trackShadow.offsetX).c_str());
281         shadowOptionJson->Put("offsetY", std::to_string(trackShadow.offsetY).c_str());
282 
283         json->PutExtAttr("trackShadow", shadowOptionJson, filter);
284     }
285 
286     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(Value, float, PROPERTY_UPDATE_RENDER);
287     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(Min, float, PROPERTY_UPDATE_RENDER);
288     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(Max, float, PROPERTY_UPDATE_RENDER);
289     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(StartAngle, float, PROPERTY_UPDATE_RENDER);
290     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(EndAngle, float, PROPERTY_UPDATE_RENDER);
291     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(GaugeType, GaugeType, PROPERTY_UPDATE_RENDER);
292     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(Colors, std::vector<Color>, PROPERTY_UPDATE_RENDER);
293     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(GradientColors, std::vector<ColorStopArray>, PROPERTY_UPDATE_RENDER);
294     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(Values, std::vector<float>, PROPERTY_UPDATE_RENDER);
295     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(StrokeWidth, Dimension, PROPERTY_UPDATE_RENDER);
296     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(ShadowOptions, GaugeShadowOptions, PROPERTY_UPDATE_RENDER);
297     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(IsShowIndicator, bool, PROPERTY_UPDATE_RENDER);
298     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(IndicatorIconSourceInfo, ImageSourceInfo, PROPERTY_UPDATE_RENDER);
299     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(IndicatorSpace, Dimension, PROPERTY_UPDATE_RENDER);
300     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(IndicatorChange, bool, PROPERTY_UPDATE_RENDER);
301     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(IsSensitive, bool, PROPERTY_UPDATE_RENDER);
302     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(UseJsLinearGradient, bool, PROPERTY_UPDATE_RENDER);
303     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(UseSpecialDefaultIndicator, bool, PROPERTY_UPDATE_RENDER);
304     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(GradientColorsInit, std::vector<ColorStopArray>, PROPERTY_UPDATE_RENDER);
305     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(ColorModeInit, int, PROPERTY_UPDATE_RENDER);
306     ACE_DISALLOW_COPY_AND_MOVE(GaugePaintProperty);
307 };
308 
309 } // namespace OHOS::Ace::NG
310 
311 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_GAUGE_GAUGE_PAINT_PROPERTY_H
312