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_NG_PATTERN_GAUGE_GAUGE_MODIFIER_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_GAUGE_GAUGE_MODIFIER_H
18 
19 #include "base/geometry/ng/offset_t.h"
20 #include "core/animation/spring_curve.h"
21 #include "core/components_ng/base/modifier.h"
22 #include "core/components_ng/render/animation_utils.h"
23 #include "core/components_ng/render/drawing.h"
24 #include "core/components_ng/render/node_paint_method.h"
25 #include "core/components_ng/pattern/gauge/gauge_paint_property.h"
26 
27 
28 namespace OHOS::Ace::NG {
29 constexpr int32_t ANIMATION_DURATION = 1200;        // The circle animation duration is 1200ms
30 constexpr int32_t ANIMATION_DELAY = 0;              // The circle animation delay is 0ms
31 constexpr int32_t ANIMATION_TIMES = 1;              // The circle animation repeat times is 1
32 constexpr float ANIMATION_START = 0.0f;             // The circle animation start from 0.0
33 constexpr float ANIMATION_END = 1.0f;               // The circle animation end with 1.0
34 constexpr float RESPONSE = 0.416f;                  //SPRING_MOTION_RESPONSE
35 constexpr float DAMPING_FRACTION = 0.99f;           //SPRING_MOTION_DAMPING_FRACTION
36 struct RenderRingInfo {
37     float radius = 0.0f;
38     float startDegree = 0.0f;
39     float sweepDegree = 0.0f;
40     float thickness = 0.0f;
41     Offset center;
42     SizeF contentSize;
43     Color color;
44 };
45 
46 struct SingleSegmentGradientInfo {
47     bool isDrawShadow = false;
48     float drawStartDegree = 0.0f;
49     float drawSweepDegree = 0.0f;
50     float offsetDegree = 0.0f;
51     float shadowRadius = 0.0f;
52     ColorStopArray colorStopArray;
53 };
54 class GaugeModifier : public ForegroundModifier {
55     DECLARE_ACE_TYPE(GaugeModifier, ForegroundModifier);
56 public:
GaugeModifier(const WeakPtr<OHOS::Ace::NG::Pattern> & pattern)57     GaugeModifier(const WeakPtr<OHOS::Ace::NG::Pattern>& pattern): pattern_(pattern)
58     {
59         InitProperty();
60         useContentModifier_ = AceType::MakeRefPtr<PropertyBool>(false);
61         AttachProperty(min_);
62         AttachProperty(max_);
63         AttachProperty(startAngle_);
64         AttachProperty(endAngle_);
65         AttachProperty(strokeWidth_);
66         AttachProperty(indicatorSpace_);
67         AttachProperty(indicatorChange_);
68         AttachProperty(gaugeTypeValue_);
69         AttachProperty(isShowIndicator_);
70 
71         AttachProperty(shadowRadiusFloat_);
72         AttachProperty(shadowOffsetXFloat_);
73         AttachProperty(shadowOffsetYFloat_);
74 
75         value_ = AceType::MakeRefPtr<AnimatablePropertyFloat>(0.0);
76         AttachProperty(value_);
77     }
78     ~GaugeModifier() override = default;
79 
80     void onDraw(DrawingContext& context) override;
81     void UpdateValue();
SetUseContentModifier(bool useContentModifier)82     void SetUseContentModifier(bool useContentModifier)
83     {
84         if (useContentModifier_) {
85             useContentModifier_->Set(useContentModifier);
86         }
87     }
88 
89     float start_ = 0.0f;
90     float end_ = 0.0f;
91 
92 private:
93     void InitProperty();
94     void UpdateProperty(RefPtr<GaugePaintProperty>& paintProperty);
95 
96     void PaintCircularAndIndicator(RSCanvas& canvas);
97     void PaintDraw(RSCanvas& canvas, RefPtr<GaugePaintProperty>& paintProperty,
98         float startDegree, float sweepDegree, RenderRingInfo data);
99     void DrawGauge(RSCanvas& canvas, RenderRingInfo data);
100     void DrawIndicator(RSCanvas& canvas, RenderRingInfo data);
101     bool ShouldHighLight(float start, float interval, float percent);
102     void NewPaintCircularAndIndicator(RSCanvas& canvas);
103     void NewDrawIndicator(
104         RSCanvas& canvas, RefPtr<GaugePaintProperty>& paintProperty, RenderRingInfo& data);
105     void NewDrawImageIndicator(
106         RSCanvas& canvas, RefPtr<GaugePaintProperty>& paintProperty, RenderRingInfo& data);
107     void PaintMonochromeCircular(
108         RSCanvas& canvas, RenderRingInfo data, RefPtr<GaugePaintProperty>& paintProperty);
109     void PaintMonochromeCircularShadow(RSCanvas& canvas, RenderRingInfo& data, Color& color,
110         RefPtr<GaugePaintProperty>& paintProperty, float sweepDegree);
111     void PaintSingleSegmentGradientCircular(
112         RSCanvas& canvas, RenderRingInfo data, RefPtr<GaugePaintProperty>& paintProperty);
113     void PaintSingleSegmentGradientCircularShadow(RSCanvas& canvas, RenderRingInfo& data,
114         RefPtr<GaugePaintProperty>& paintProperty, std::vector<RSColorQuad>& colors,
115         std::vector<float>& pos);
116     void PaintMultiSegmentGradientCircular(
117         RSCanvas& canvas, RenderRingInfo data, RefPtr<GaugePaintProperty>& paintProperty);
118     void PaintMultiSegmentGradientCircularShadow(RSCanvas& canvas, RenderRingInfo& data,
119         RefPtr<GaugePaintProperty>& paintProperty, std::vector<ColorStopArray>& colors,
120         std::vector<float>& weights);
121     void DrawSingleSegmentGradient(RSCanvas& canvas, RenderRingInfo& data,
122         RefPtr<GaugePaintProperty>& paintProperty, SingleSegmentGradientInfo& info,
123         size_t index);
124     void DrawHighLight(RSCanvas& canvas, RenderRingInfo& data, float drawStartDegree);
125     void CalculateStartAndSweepDegree(RefPtr<GaugePaintProperty>& paintProperty, RenderRingInfo& data);
126     float GetOffsetDegree(RenderRingInfo& data, float oppositeSide);
127     void CreateDefaultColor(std::vector<RSColorQuad>& colors, std::vector<float>& pos);
128     void CreateDefaultTrianglePath(float pathStartVertexX, float pathStartVertexY, float radius, RSPath& path);
129     WeakPtr<Pattern> pattern_;
130     void GetDrawPath(RSPath& path, RenderRingInfo& data, float startAngle, float sweepAngle);
131 
132     RefPtr<AnimatablePropertyFloat> value_;
133     RefPtr<AnimatablePropertyFloat> min_;
134     RefPtr<AnimatablePropertyFloat> max_;
135     RefPtr<AnimatablePropertyFloat> startAngle_;
136     RefPtr<AnimatablePropertyFloat> endAngle_;
137     RefPtr<AnimatablePropertyFloat> strokeWidth_;
138     RefPtr<AnimatablePropertyFloat> indicatorSpace_;
139     RefPtr<AnimatablePropertyFloat> gaugeTypeValue_;
140 
141     RefPtr<AnimatablePropertyFloat> shadowRadiusFloat_;
142     RefPtr<AnimatablePropertyFloat> shadowOffsetXFloat_;
143     RefPtr<AnimatablePropertyFloat> shadowOffsetYFloat_;
144 
145     std::vector<RefPtr<AnimatablePropertyColor>> colors_;
146     std::vector<RefPtr<AnimatablePropertyColor>> gradientColors_;
147 
148     RefPtr<PropertyBool> isShowIndicator_;
149     RefPtr<PropertyBool> useContentModifier_;
150     RefPtr<PropertyBool> indicatorChange_;
151     ACE_DISALLOW_COPY_AND_MOVE(GaugeModifier);
152 };
153 } // namespace OHOS::Ace::NG
154 
155 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_GAUGE_GAUGE_MODIFIER_H
156 
157