1 /*
2  * Copyright (c) 2023-2024 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_PROGRESS_PROGRESS_MODIFIER_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_PROGRESS_PROGRESS_MODIFIER_H
18 
19 #include "base/geometry/arc.h"
20 #include "base/memory/ace_type.h"
21 #include "core/components/common/properties/color.h"
22 #include "core/components_ng/base/modifier.h"
23 #include "core/components_ng/pattern/progress/progress_date.h"
24 #include "core/components_ng/render/drawing.h"
25 
26 namespace OHOS::Ace::NG {
27 struct RingProgressData {
28     PointF centerPt;
29     float radius = 0.0f;
30     float thickness = 0.0f;
31     float angle = 0.0f;
32     float shadowBlurSigma = 0.0f;
33 };
34 
35 class ProgressModifier : public ContentModifier {
36     DECLARE_ACE_TYPE(ProgressModifier, ContentModifier);
37 
38 public:
39     explicit ProgressModifier(
40         const ProgressAnimatableProperty& progressAnimatableProperty = ProgressAnimatableProperty {});
41     ~ProgressModifier() override = default;
42     void onDraw(DrawingContext& context) override;
43 
44     void SetStrokeWidth(float width);
45     void SetColor(LinearColor color);
46     void SetBackgroundColor(LinearColor color);
47     void SetBorderColor(LinearColor color);
48     void SetProgressType(ProgressType type);
49     void SetMaxValue(float value);
50     void SetValue(float value);
51     void SetScaleWidth(float value);
52     void SetScaleCount(int32_t value);
53     void SetContentOffset(const OffsetF& offset);
54     void SetContentSize(const SizeF& contentSize);
55     void SetBorderWidth(float width);
56     void SetSweepEffect(bool value);
57     void SetRingProgressColor(const Gradient& color);
58     void SetPaintShadow(bool paintShadow);
59     void SetProgressStatus(ProgressStatus status);
60     void SetVisible(bool isVisible);
61     void SetRingSweepEffect(bool value);
62     void SetLinearSweepEffect(bool value);
63     void SetIsItalic(bool isItalic);
64     void SetSmoothEffect(bool value);
65     void SetStrokeRadius(float strokeRaidus);
66     void SetUseContentModifier(bool useContentModifier);
67     void SetIsRightToLeft(bool value);
68 
69 private:
70     void PaintScaleRingForApiNine(RSCanvas& canvas, const OffsetF& offset, const SizeF& contentSize) const;
71     void PaintCapsuleForApiNine(RSCanvas& canvas, const OffsetF& offset, const SizeF& contentSize) const;
72     void PaintVerticalCapsuleForApiNine(RSCanvas& canvas, const OffsetF& offset, const SizeF& contentSize) const;
73 
74     void ContentDrawWithFunction(DrawingContext& context);
75     void PaintLinear(RSCanvas& canvas, const OffsetF& offset, const SizeF& contentSize) const;
76     void PaintLinearSweeping(
77         RSCanvas& canvas, const OffsetF& offset, const RSPath& path, bool isHorizontal, const SizeF& contentSize) const;
78     void PaintRing(RSCanvas& canvas, const OffsetF& offset, const SizeF& contentSize) const;
79     void PaintRingBackground(RSCanvas& canvas, const RingProgressData& ringProgressData) const;
80     void PaintRingProgressOrShadow(RSCanvas& canvas, const RingProgressData& ringProgressData, bool isShadow) const;
81     void PaintWhole(RSCanvas& canvas, RSBrush& brush, const RingProgressData& ringProgressData,
82         std::vector<GradientColor>& gradientColor) const;
83     void PaintBeginHalf(RSCanvas& canvas, RSBrush& brush, const RingProgressData& ringProgressData,
84         std::vector<GradientColor>& gradientColors) const;
85     void PaintEndHalf(RSCanvas& canvas, RSBrush& brush, const RingProgressData& ringProgressData,
86         std::vector<GradientColor>& gradientColors) const;
87     void PaintRingSweeping(RSCanvas& canvas, const RingProgressData& ringProgressData) const;
88     void PaintTrailing(RSCanvas& canvas, const RingProgressData& ringProgressData) const;
89     void PaintScaleRing(RSCanvas& canvas, const OffsetF& offset, const SizeF& contentSize) const;
90     void PaintMoon(RSCanvas& canvas, const OffsetF& offset, const SizeF& contentSize) const;
91     void PaintCapsule(RSCanvas& canvas, const OffsetF& offset, const SizeF& contentSize) const;
92     void PaintVerticalCapsule(RSCanvas& canvas, const OffsetF& offset, const SizeF& contentSize) const;
93     void PaintCapsuleLightSweep(
94         RSCanvas& canvas, const SizeF& contentSize, const OffsetF& offset, const RSPath& path, bool isVertical) const;
95 
96     void ProcessSweepingAnimation(ProgressType type, float value);
97     void ProcessRingSweepingAnimation(float value);
98     void ProcessLinearSweepingAnimation(float value);
99     void StartRingSweepingAnimation(float value);
100     void StartRingSweepingAnimationImpl(float date, float speed);
101     void StartContinuousSweepingAnimation(float currentDate, float newDate, float speed);
102     void StartLinearSweepingAnimation(float value);
103     void StartLinearSweepingAnimationImpl(float date, float speed);
104     void StartCapsuleSweepingAnimation(float value);
105     void StartCapsuleSweepingAnimationImpl(float value, float speed);
106     void StopSweepingAnimation(float date = 0.0f);
107     void StartRingLoadingAnimation();
108     void StartRingLoadingHeadAnimation();
109     void StartRingLoadingTailAnimation();
110     void StopRingLoadingHeadAnimation();
111     void StopRingLoadingTailAnimation();
112     float CalcRingProgressAdditionalAngle() const;
113     std::vector<GradientColor> GetRingProgressGradientColors() const;
114     void GenerateLinearSweepingGradientInfo(std::vector<RSColorQuad>& colors, std::vector<float>& pos) const;
115     void GenerateRingSweepingGradientInfo(std::vector<RSColorQuad>& colors, std::vector<float>& pos) const;
116     Gradient CreateCapsuleGradient() const;
117     bool PostTask(const TaskExecutor::Task& task, const std::string& name);
118     Gradient SortGradientColorsByOffset(const Gradient& gradient) const;
119     bool IsSweepEffectOn();
120 
121     // Animatable
122     RefPtr<AnimatablePropertyFloat> strokeWidth_; // After adjusting to the content width and height
123     RefPtr<AnimatablePropertyColor> color_;
124     RefPtr<AnimatablePropertyColor> bgColor_;
125     RefPtr<AnimatablePropertyColor> borderColor_;
126     RefPtr<AnimatablePropertyFloat> value_;
127     RefPtr<AnimatablePropertyVectorColor> ringProgressColors_;
128     RefPtr<AnimatablePropertyFloat> sweepingDate_;
129     RefPtr<AnimatablePropertyFloat> trailingHeadDate_;
130     RefPtr<AnimatablePropertyFloat> trailingTailDate_;
131     RefPtr<AnimatablePropertyFloat> strokeRadius_;
132 
133     // no Animatable
134     RefPtr<PropertyOffsetF> offset_;
135     RefPtr<PropertySizeF> contentSize_;
136     RefPtr<PropertyFloat> maxValue_;
137     RefPtr<PropertyFloat> scaleWidth_;
138     RefPtr<PropertyInt> scaleCount_;
139     RefPtr<PropertyInt> progressType_;
140     RefPtr<PropertyFloat> capsuleBorderWidth_;
141     RefPtr<PropertyBool> sweepEffect_;
142     RefPtr<PropertyBool> ringSweepEffect_;
143     RefPtr<PropertyBool> linearSweepEffect_;
144     RefPtr<PropertyBool> paintShadow_;
145     RefPtr<PropertyInt> progressStatus_;
146     RefPtr<PropertyBool> isItalic_;
147     RefPtr<PropertyBool> smoothEffect_;
148     RefPtr<PropertyBool> useContentModifier_;
149     RefPtr<PropertyBool> isRightToLeft_;
150 
151     bool isVisible_ = true;
152     float valueBackup_ = 0.0f;
153     bool isLoading_ = false;
154     bool isSweeping_ = false;
155     float sweepingDateBackup_ = 0.0f;
156     bool dateUpdated_ = false;
157 
158     ACE_DISALLOW_COPY_AND_MOVE(ProgressModifier);
159 };
160 
161 class TailingHeadCurve final : public Curve {
162     DECLARE_ACE_TYPE(TailingHeadCurve, Curve);
163 
164 public:
MoveInternal(float time)165     float MoveInternal(float time) override
166     {
167         // v = f(time) = sin(PI * time) + PI
168         // => F(v) = - cos(PI * t) / PI + PI * time + C
169         // => S = F(time) - F(0) = PI * time + 1 / PI - cos(PI * time) / PI
170         // After normalizing, S = (PI * time + 1 / PI - cos(PI * time) / PI) / (PI + 2 / PI)
171         return (PI_NUM * time + 1.0f / PI_NUM - std::cos(PI_NUM * time) / PI_NUM) / (PI_NUM + 2.0f / PI_NUM);
172     }
173 };
174 } // namespace OHOS::Ace::NG
175 
176 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_PROGRESS_PROGRESS_MODIFIER_H
177