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_DATA_PANEL_DATA_PANEL_PAINT_PROPERTY_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_DATA_PANEL_DATA_PANEL_PAINT_PROPERTY_H
18 
19 #include "core/components/common/layout/constants.h"
20 #include "core/components/common/properties/color.h"
21 #include "core/components/data_panel/data_panel_theme.h"
22 #include "core/components_ng/base/inspector_filter.h"
23 #include "core/components_ng/property/gradient_property.h"
24 #include "core/components_ng/render/paint_property.h"
25 #include "core/pipeline/pipeline_base.h"
26 
27 namespace OHOS::Ace::NG {
28 struct DataPanelShadow {
29     bool isShadowVisible = true;
30     double radius = 5.0;
31     double offsetX = 5.0;
32     double offsetY = 5.0;
33     std::vector<Gradient> colors;
34     bool operator==(const DataPanelShadow& rhs) const
35     {
36         return radius == rhs.radius && offsetX == rhs.offsetX && offsetY == rhs.offsetY && colors == rhs.colors &&
37                isShadowVisible == rhs.isShadowVisible;
38     }
39 };
40 class DataPanelPaintProperty : public PaintProperty {
41     DECLARE_ACE_TYPE(DataPanelPaintProperty, PaintProperty)
42 
43 public:
44     DataPanelPaintProperty() = default;
45     ~DataPanelPaintProperty() override = default;
46 
Clone()47     RefPtr<PaintProperty> Clone() const override
48     {
49         auto paintProperty = MakeRefPtr<DataPanelPaintProperty>();
50         paintProperty->UpdatePaintProperty(this);
51         paintProperty->propValues_ = CloneValues();
52         paintProperty->propMax_ = CloneMax();
53         paintProperty->propDataPanelType_ = CloneDataPanelType();
54         paintProperty->propEffect_ = CloneEffect();
55 
56         paintProperty->propValueColors_ = CloneValueColors();
57         paintProperty->propTrackBackground_ = CloneTrackBackground();
58         paintProperty->propStrokeWidth_ = CloneStrokeWidth();
59         paintProperty->propShadowOption_ = CloneShadowOption();
60         return paintProperty;
61     }
62 
Reset()63     void Reset() override
64     {
65         PaintProperty::Reset();
66         ResetValues();
67         ResetMax();
68         ResetDataPanelType();
69         ResetEffect();
70         ResetValueColors();
71         ResetTrackBackground();
72         ResetStrokeWidth();
73         ResetShadowOption();
74     }
75 
ToJsonValue(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter)76     void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const override
77     {
78         PaintProperty::ToJsonValue(json, filter);
79         /* no fixed attr below, just return */
80         if (filter.IsFastFilter()) {
81             ToJsonValueColors(json, filter);
82             ToJsonTrackShadow(json, filter);
83             return;
84         }
85         auto jsonDashArray = JsonUtil::CreateArray(true);
86         for (size_t i = 0; i < propValues_.value().size(); ++i) {
87             auto index = std::to_string(i);
88             double value = propValues_.value()[i];
89             jsonDashArray->Put(index.c_str(), value);
90         }
91         bool closeEffect = false;
92         if (propEffect_.has_value()) {
93             closeEffect = !propEffect_.value();
94         }
95         auto pipelineContext = PipelineBase::GetCurrentContext();
96         CHECK_NULL_VOID(pipelineContext);
97         auto theme = pipelineContext->GetTheme<DataPanelTheme>();
98         json->PutExtAttr("max", std::to_string(propMax_.value_or(100)).c_str(), filter);
99         json->PutExtAttr("closeEffect", closeEffect ? "true" : "false", filter);
100         json->PutExtAttr("type", propDataPanelType_ == 1 ? "DataPanelType.Line" : "DataPanelType.Circle", filter);
101         json->PutExtAttr("values", jsonDashArray, filter);
102         json->PutExtAttr("trackBackgroundColor",
103             GetTrackBackground().value_or(theme->GetBackgroundColor()).ColorToString().c_str(), filter);
104         json->PutExtAttr("strokeWidth",
105             GetStrokeWidth().value_or(theme->GetThickness()).ToString().c_str(), filter);
106 
107         ToJsonValueColors(json, filter);
108         ToJsonTrackShadow(json, filter);
109     }
110 
ToJsonValueColors(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter)111     void ToJsonValueColors(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
112     {
113         /* no fixed attr below, just return */
114         if (filter.IsFastFilter()) {
115             return;
116         }
117         std::vector<Gradient> valueColors;
118         if (propValueColors_.has_value()) {
119             valueColors = propValueColors_.value();
120         } else {
121             auto pipelineContext = PipelineBase::GetCurrentContext();
122             CHECK_NULL_VOID(pipelineContext);
123             auto theme = pipelineContext->GetTheme<DataPanelTheme>();
124             auto colors = theme->GetColorsArray();
125             for (const auto& item : colors) {
126                 Gradient gradient;
127                 CreateGradient(item, gradient);
128                 valueColors.emplace_back(gradient);
129             }
130         }
131 
132         auto valueColorsJosnArray = JsonUtil::CreateArray(true);
133         for (size_t i = 0; i < valueColors.size(); ++i) {
134             Gradient gradientItem = valueColors[i];
135             auto gradientItemJsonArray = JsonUtil::CreateArray(true);
136             for (size_t index = 0; index < gradientItem.GetColors().size(); ++index) {
137                 auto gradientColor = gradientItem.GetColors()[index];
138                 auto gradientColorJosn = JsonUtil::Create(true);
139                 gradientColorJosn->Put("color", gradientColor.GetLinearColor().ToColor().ColorToString().c_str());
140                 gradientColorJosn->Put("offset", std::to_string(gradientColor.GetDimension().Value()).c_str());
141                 gradientItemJsonArray->Put(std::to_string(index).c_str(), gradientColorJosn);
142             }
143             valueColorsJosnArray->Put(std::to_string(i).c_str(), gradientItemJsonArray);
144         }
145         json->PutExtAttr("valueColors", valueColorsJosnArray, filter);
146     }
147 
ToJsonTrackShadow(std::unique_ptr<JsonValue> & json,const InspectorFilter & filter)148     void ToJsonTrackShadow(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const
149     {
150         /* no fixed attr below, just return */
151         if (filter.IsFastFilter()) {
152             return;
153         }
154         auto pipelineContext = PipelineBase::GetCurrentContext();
155         CHECK_NULL_VOID(pipelineContext);
156         auto theme = pipelineContext->GetTheme<DataPanelTheme>();
157         DataPanelShadow trackShadow;
158         if (propShadowOption_.has_value()) {
159             trackShadow.radius = propShadowOption_.value().radius;
160             trackShadow.offsetX = propShadowOption_.value().offsetX;
161             trackShadow.offsetY = propShadowOption_.value().offsetY;
162             trackShadow.colors = propShadowOption_.value().colors;
163             trackShadow.isShadowVisible = propShadowOption_.value().isShadowVisible;
164         } else {
165             trackShadow.radius = theme->GetTrackShadowRadius().ConvertToVp();
166             trackShadow.offsetX = theme->GetTrackShadowOffsetX().ConvertToVp();
167             trackShadow.offsetY = theme->GetTrackShadowOffsetY().ConvertToVp();
168         }
169 
170         if (!trackShadow.isShadowVisible) {
171             json->PutExtAttr("trackShadow", "null", filter);
172             return;
173         }
174 
175         if (trackShadow.colors.size() == 0) {
176             if (propValueColors_.has_value() && (propValueColors_.value().size() != 0)) {
177                 trackShadow.colors = propValueColors_.value();
178             } else {
179                 auto colors = theme->GetColorsArray();
180                 for (const auto& item : colors) {
181                     Gradient gradient;
182                     CreateGradient(item, gradient);
183                     trackShadow.colors.emplace_back(gradient);
184                 }
185             }
186         }
187         auto shadowOptionJson = JsonUtil::Create(true);
188         shadowOptionJson->Put("radius", std::to_string(trackShadow.radius).c_str());
189         shadowOptionJson->Put("offsetX", std::to_string(trackShadow.offsetX).c_str());
190         shadowOptionJson->Put("offsetY", std::to_string(trackShadow.offsetY).c_str());
191 
192         auto colorsJosnArray = JsonUtil::CreateArray(true);
193         for (size_t i = 0; i < trackShadow.colors.size(); ++i) {
194             Gradient gradientItem = trackShadow.colors[i];
195             auto gradientItemJsonArray = JsonUtil::CreateArray(true);
196             for (size_t index = 0; index < gradientItem.GetColors().size(); ++index) {
197                 auto gradientColor = gradientItem.GetColors()[index];
198                 auto gradientColorJosn = JsonUtil::Create(true);
199                 gradientColorJosn->Put("color", gradientColor.GetLinearColor().ToColor().ColorToString().c_str());
200                 gradientColorJosn->Put("offset", std::to_string(gradientColor.GetDimension().Value()).c_str());
201                 gradientItemJsonArray->Put(std::to_string(index).c_str(), gradientColorJosn);
202             }
203             colorsJosnArray->Put(std::to_string(i).c_str(), gradientItemJsonArray);
204         }
205         shadowOptionJson->Put("colors", colorsJosnArray);
206         json->PutExtAttr("trackShadow", shadowOptionJson, filter);
207     }
208 
CreateGradient(const std::pair<Color,Color> & itemParam,Gradient & gradient)209     void CreateGradient(const std::pair<Color, Color>& itemParam, Gradient& gradient) const
210     {
211         GradientColor gradientColorStart;
212         gradientColorStart.SetLinearColor(LinearColor(itemParam.first));
213         gradientColorStart.SetDimension(Dimension(0.0));
214         gradient.AddColor(gradientColorStart);
215         GradientColor gradientColorEnd;
216         gradientColorEnd.SetLinearColor(LinearColor(itemParam.second));
217         gradientColorEnd.SetDimension(Dimension(1.0));
218         gradient.AddColor(gradientColorEnd);
219     }
220 
221     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(Values, std::vector<double>, PROPERTY_UPDATE_RENDER);
222     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(Max, double, PROPERTY_UPDATE_RENDER);
223     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(DataPanelType, size_t, PROPERTY_UPDATE_RENDER);
224     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(Effect, bool, PROPERTY_UPDATE_RENDER);
225 
226     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(ValueColors, std::vector<Gradient>, PROPERTY_UPDATE_RENDER);
227     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(TrackBackground, Color, PROPERTY_UPDATE_RENDER);
228     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(StrokeWidth, Dimension, PROPERTY_UPDATE_RENDER);
229     ACE_DEFINE_PROPERTY_ITEM_WITHOUT_GROUP(ShadowOption, DataPanelShadow, PROPERTY_UPDATE_RENDER);
230 
231     ACE_DISALLOW_COPY_AND_MOVE(DataPanelPaintProperty);
232 };
233 
234 } // namespace OHOS::Ace::NG
235 
236 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_DATA_PANEL_DATA_PANEL_PAINT_PROPERTY_H
237