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