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