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_PATTERNS_DATA_PANEL_DATA_PANEL_MODIFIER_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_DATA_PANEL_DATA_PANEL_MODIFIER_H
18 
19 #include <vector>
20 
21 #include "base/geometry/ng/offset_t.h"
22 #include "core/animation/spring_curve.h"
23 #include "core/common/container.h"
24 #include "core/components_ng/base/modifier.h"
25 #include "core/components_ng/property/property.h"
26 #include "core/components_ng/render/animation_utils.h"
27 #include "core/components_ng/render/canvas_image.h"
28 #include "core/components_ng/render/drawing_forward.h"
29 #include "core/components_ng/render/paint_wrapper.h"
30 
31 namespace OHOS::Ace::NG {
32 constexpr int32_t ANIMATION_DURATION = 1200;        // The circle animation duration is 1200ms
33 constexpr int32_t ANIMATION_DELAY = 0;              // The circle animation delay is 0ms
34 constexpr int32_t ANIMATION_TIMES = 1;              // The circle animation repeat times is 1
35 constexpr float ANIMATION_START = 0.0f;             // The circle animation start from 0.0
36 constexpr float ANIMATION_END = 1.0f;               // The circle animation end with 1.0
37 constexpr float ANIMATION_CURVE_VELOCITY = 0.0f;    // The circle animation spring curve velocity is 0.0
38 constexpr float ANIMATION_CURVE_MASS = 1.0f;        // The circle animation spring curve mass is 1.0
39 constexpr float ANIMATION_CURVE_STIFFNESS = 110.0f; // The circle animation spring curve stiffness is 110.0
40 constexpr float ANIMATION_CURVE_DAMPING = 17.0f;    // The circle animation spring curve damping is 17.0
41 constexpr size_t MAX_COUNT = 9;
42 constexpr float DEFAULT_MAX_VALUE = 100.0f;
43 constexpr float START_ANGLE = 0.0f;
44 struct ArcData {
45     Offset center;
46     float progressValue = 0.0f;
47     float radius = 0.0f;
48     float thickness = 0.0f;
49     double maxValue = 0.0;
50     double totalValue = 0.0f;
51     Gradient progressColors;
52     Gradient shadowColor;
53     float drawAngle = 0.0f;
54     float gradientPointBase = 0.0f;
55     float lastAngle = 0.0f;
56     float totalAllValue = 0.0f;
57     float totalDrawAngle = 0.0f;
58     float circleAngle = 0.0f;
59 };
60 struct LinearData {
61     OffsetF offset;
62 
63     Gradient segmentColor;
64     Gradient segmentShadowColor;
65 
66     float segmentWidth = 0.0f;
67     float xSegment = 0.0f;
68     float height = 0.0f;
69     float totalWidth = 0.0f;
70 
71     bool isFirstData = false;
72     bool isEndData = false;
73 };
74 class DataPanelModifier : public ContentModifier {
75     DECLARE_ACE_TYPE(DataPanelModifier, ContentModifier);
76 
77 public:
78     DataPanelModifier();
79     ~DataPanelModifier() override = default;
80     void onDraw(DrawingContext& context) override;
81     void UpdateDate();
82 
SetValues(std::vector<double> values)83     void SetValues(std::vector<double> values)
84     {
85         for (size_t i = 0; i < values.size(); ++i) {
86             if (i >= MAX_COUNT) {
87                 return;
88             }
89             values_[i]->Set(values[i]);
90         }
91         valuesLastLength_ = values.size();
92     };
93 
SetMax(double max)94     void SetMax(double max)
95     {
96         max_->Set(max);
97     };
98 
SetDataPanelType(size_t dataPanelType)99     void SetDataPanelType(size_t dataPanelType)
100     {
101         if (isFirstCreate_) {
102             dataPanelType_ = dataPanelType;
103             isFirstCreate_ = false;
104         }
105     };
106 
SetEffect(bool effect)107     void SetEffect(bool effect)
108     {
109         isEffect_->Set(effect);
110     };
111 
SetOffset(OffsetF offset)112     void SetOffset(OffsetF offset)
113     {
114         offset_ = offset;
115     };
116 
SetValueColors(const std::vector<Gradient> & valueColors)117     void SetValueColors(const std::vector<Gradient>& valueColors)
118     {
119         for (size_t i = 0; i < valueColors.size(); ++i) {
120             if (i >= MAX_COUNT) {
121                 return;
122             }
123             valueColors_[i]->Set(GradientArithmetic(valueColors[i]));
124         }
125     };
126 
SetTrackBackground(const Color & trackBackgroundColor)127     void SetTrackBackground(const Color& trackBackgroundColor)
128     {
129         trackBackgroundColor_->Set(LinearColor(trackBackgroundColor));
130     };
131 
SetStrokeWidth(float strokeWidth)132     void SetStrokeWidth(float strokeWidth)
133     {
134         strokeWidth_->Set(strokeWidth);
135     };
136 
SetShadowVisible(bool isShadowVisible)137     void SetShadowVisible(bool isShadowVisible)
138     {
139         isShadowVisible_ = isShadowVisible;
140     };
141 
SetIsHasShadowValue(bool isHasShadowValue)142     void SetIsHasShadowValue(bool isHasShadowValue)
143     {
144         isHasShadowValue_ = isHasShadowValue;
145     };
146 
SetShadowRadius(float shadowRadius)147     void SetShadowRadius(float shadowRadius)
148     {
149         shadowRadiusFloat_->Set(shadowRadius);
150     };
151 
SetShadowOffsetX(float shadowOffsetX)152     void SetShadowOffsetX(float shadowOffsetX)
153     {
154         shadowOffsetXFloat_->Set(shadowOffsetX);
155     };
156 
SetShadowOffsetY(float shadowOffsetY)157     void SetShadowOffsetY(float shadowOffsetY)
158     {
159         shadowOffsetYFloat_->Set(shadowOffsetY);
160     };
161 
SetShadowColors(const std::vector<Gradient> & valueColors,const size_t shadowColorsLastLength)162     void SetShadowColors(const std::vector<Gradient>& valueColors, const size_t shadowColorsLastLength)
163     {
164         for (size_t i = 0; i < valueColors.size(); ++i) {
165             if (i >= MAX_COUNT) {
166                 return;
167             }
168             shadowColors_[i]->Set(GradientArithmetic(valueColors[i]));
169         }
170         shadowColorsLastLength_ = shadowColorsLastLength;
171     };
172 
SetUseContentModifier(bool useContentModifier)173     void SetUseContentModifier(bool useContentModifier)
174     {
175         if (useContentModifier_) {
176             useContentModifier_->Set(useContentModifier);
177         }
178     }
179 
SetIsRtl(bool isRtl)180     void SetIsRtl(bool isRtl)
181     {
182         isRtl_ = isRtl;
183     };
184 
185 private:
186     void PaintCircle(DrawingContext& context, OffsetF offset) const;
187     void PaintLinearProgress(DrawingContext& context, OffsetF offset) const;
188     void PaintBackground(RSCanvas& canvas, OffsetF offset, float totalWidth, float height, float segmentWidth) const;
189     void SetCornerRadius(RSRoundRect& paintRect, const LinearData& segmentLinearData, const float height) const;
190     void PaintColorSegment(RSCanvas& canvas, const LinearData& segmentLinearData) const;
191     void PaintSpace(RSCanvas& canvas, const LinearData& segmentLinearData, float spaceWidth) const;
192     void PaintTrackBackground(RSCanvas& canvas, ArcData arcData, const Color color) const;
193     void PaintProgress(RSCanvas& canvas, ArcData arcData, RSPath& path, RSPath& endPath, bool isShadow) const;
194     void GetPaintPath(ArcData& arcData, RSPath& path, RSPath& endPath) const;
195     void Path2DArc(
196         RSPath& path, double x, double y, double r, double startAngle, double endAngle, bool counterclockwise) const;
197     void PaintColorSegmentFilterMask(RSCanvas& canvas, const LinearData& segmentLinearData) const;
198     Gradient SortGradientColorsOffset(const Gradient& srcGradient) const;
199     RefPtr<AnimatablePropertyFloat> date_;
200     RefPtr<PropertyBool> isEffect_;
201     size_t dataPanelType_ = 0;
202     OffsetF offset_;
203     bool isFirstCreate_ = true;
204     bool isHasShadowValue_ = false;
205     bool isRtl_ = false;
206     RefPtr<PropertyBool> useContentModifier_;
207 
208     RefPtr<AnimatablePropertyFloat> max_;
209     std::vector<RefPtr<AnimatablePropertyFloat>> values_;
210     std::vector<RefPtr<AnimatablePropertyVectorColor>> valueColors_;
211     RefPtr<AnimatablePropertyColor> trackBackgroundColor_;
212     RefPtr<AnimatablePropertyFloat> strokeWidth_;
213 
214     // shadow param
215     bool isShadowVisible_ = false;
216     RefPtr<AnimatablePropertyFloat> shadowRadiusFloat_;
217     RefPtr<AnimatablePropertyFloat> shadowOffsetXFloat_;
218     RefPtr<AnimatablePropertyFloat> shadowOffsetYFloat_;
219     std::vector<RefPtr<AnimatablePropertyVectorColor>> shadowColors_;
220     size_t shadowColorsLastLength_ = MAX_COUNT;
221     size_t valuesLastLength_ = MAX_COUNT;
222 
223     ACE_DISALLOW_COPY_AND_MOVE(DataPanelModifier);
224 };
225 } // namespace OHOS::Ace::NG
226 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_DATA_PANEL_DATA_PANEL_MODIFIER_H
227