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_SLIDER_SLIDER_CONTENT_MODIFIER_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_SLIDER_SLIDER_CONTENT_MODIFIER_H 18 19 #include "base/memory/referenced.h" 20 #include "base/utils/utils.h" 21 #include "core/components/common/properties/animation_option.h" 22 #include "core/components/slider/slider_theme.h" 23 #include "core/components_ng/base/modifier.h" 24 #include "core/components_ng/pattern/slider/slider_paint_property.h" 25 #include "core/components_ng/render/animation_utils.h" 26 #include "core/components_ng/render/drawing.h" 27 #include "core/pipeline/pipeline_base.h" 28 29 namespace OHOS::Ace::NG { 30 enum class SliderStatus : uint32_t { 31 DEFAULT, 32 CLICK, 33 MOVE, 34 }; 35 class SliderContentModifier : public ContentModifier { 36 DECLARE_ACE_TYPE(SliderContentModifier, ContentModifier); 37 38 public: 39 struct Parameters { 40 float trackThickness = 0.0f; 41 SizeF blockSize; 42 float stepRatio = 0.0f; 43 float hotCircleShadowWidth = 0.0f; 44 bool mouseHoverFlag_ = false; 45 bool mousePressedFlag_ = false; 46 PointF selectStart; 47 PointF selectEnd; 48 PointF backStart; 49 PointF backEnd; 50 PointF circleCenter; 51 Color selectColor; 52 Gradient trackBackgroundColor; 53 Color blockColor; 54 }; 55 56 explicit SliderContentModifier(const Parameters& parameters, std::function<void(float)> updateImageCenterX, 57 std::function<void(float)> updateImageCenterY); 58 ~SliderContentModifier() override = default; 59 60 void onDraw(DrawingContext& context) override; 61 62 void DrawBackground(DrawingContext& context); 63 void DrawStep(DrawingContext& context); 64 void DrawSelect(DrawingContext& context); 65 void DrawDefaultBlock(DrawingContext& context); 66 void DrawHoverOrPress(DrawingContext& context); 67 void DrawShadow(DrawingContext& context); 68 UpdateThemeColor()69 void UpdateThemeColor() 70 { 71 auto pipeline = PipelineBase::GetCurrentContext(); 72 CHECK_NULL_VOID(pipeline); 73 auto sliderTheme = pipeline->GetTheme<SliderTheme>(); 74 CHECK_NULL_VOID(sliderTheme); 75 blockOuterEdgeColor_ = sliderTheme->GetBlockOuterEdgeColor(); 76 blockShadowColor_ = sliderTheme->GetBlockShadowColor(); 77 } 78 79 void UpdateData(const Parameters& parameters); 80 void JudgeNeedAnimate(bool reverse); 81 SetTrackThickness(float trackThickness)82 void SetTrackThickness(float trackThickness) 83 { 84 if (trackThickness_) { 85 trackThickness_->Set(trackThickness); 86 } 87 } 88 SetTrackBackgroundColor(const Gradient & color)89 void SetTrackBackgroundColor(const Gradient& color) 90 { 91 CHECK_NULL_VOID(trackBackgroundColor_); 92 trackBackgroundColor_->Set(GradientArithmetic(color)); 93 } 94 SetSelectColor(Color color)95 void SetSelectColor(Color color) 96 { 97 if (selectColor_) { 98 selectColor_->Set(LinearColor(color)); 99 } 100 } 101 SetBlockColor(Color color)102 void SetBlockColor(Color color) 103 { 104 if (blockColor_) { 105 blockColor_->Set(LinearColor(color)); 106 } 107 } 108 109 void SetBoardColor(); 110 SetBackgroundSize(const PointF & start,const PointF & end)111 void SetBackgroundSize(const PointF& start, const PointF& end) 112 { 113 if (backStart_) { 114 backStart_->Set(start - PointF()); 115 } 116 if (backEnd_) { 117 backEnd_->Set(end - PointF()); 118 } 119 } 120 121 void SetSelectSize(const PointF& start, const PointF& end); 122 123 void SetCircleCenter(const PointF& center); 124 SetStepRatio(float stepRatio)125 void SetStepRatio(float stepRatio) 126 { 127 if (stepRatio_) { 128 stepRatio_->Set(stepRatio); 129 } 130 } 131 SetAnimatorStatus(SliderStatus status)132 void SetAnimatorStatus(SliderStatus status) 133 { 134 animatorStatus_ = status; 135 } 136 SetSliderMode(SliderModelNG::SliderMode sliderMode)137 void SetSliderMode(SliderModelNG::SliderMode sliderMode) 138 { 139 if (sliderMode_) { 140 sliderMode_->Set(static_cast<int>(sliderMode)); 141 } 142 } 143 SetTrackBorderRadius(float trackBorderRadius)144 void SetTrackBorderRadius(float trackBorderRadius) 145 { 146 if (trackBorderRadius_) { 147 trackBorderRadius_->Set(trackBorderRadius); 148 } 149 } 150 SetSelectedBorderRadius(float selectedBorderRadius)151 void SetSelectedBorderRadius(float selectedBorderRadius) 152 { 153 if (selectedBorderRadius_) { 154 selectedBorderRadius_->Set(selectedBorderRadius); 155 } 156 } 157 SetStepSize(float stepSize)158 void SetStepSize(float stepSize) 159 { 160 if (stepSize_) { 161 stepSize_->Set(stepSize); 162 } 163 } 164 SetStepColor(const Color & stepColor)165 void SetStepColor(const Color& stepColor) 166 { 167 if (stepColor_) { 168 stepColor_->Set(LinearColor(stepColor)); 169 } 170 } 171 SetShowSteps(bool showSteps)172 void SetShowSteps(bool showSteps) 173 { 174 if (isShowStep_) { 175 isShowStep_->Set(showSteps); 176 } 177 } 178 SetSliderInteractionMode(SliderModelNG::SliderInteraction mode)179 void SetSliderInteractionMode(SliderModelNG::SliderInteraction mode) 180 { 181 if (sliderInteractionMode_) { 182 sliderInteractionMode_->Set(static_cast<int>(mode)); 183 } 184 } 185 SetMinResponsiveDistance(float minResponse)186 void SetMinResponsiveDistance(float minResponse) 187 { 188 if (minResponse_) { 189 minResponse_->Set(minResponse); 190 } 191 } 192 SetBlockType(SliderModelNG::BlockStyleType type)193 void SetBlockType(SliderModelNG::BlockStyleType type) 194 { 195 if (blockType_) { 196 blockType_->Set(static_cast<int>(type)); 197 } 198 } 199 SetBlockSize(const SizeF & blockSize)200 void SetBlockSize(const SizeF& blockSize) 201 { 202 if (blockSize_) { 203 blockSize_->Set(blockSize); 204 } 205 } 206 SetBlockBorderColor(const Color & blockBorderColor)207 void SetBlockBorderColor(const Color& blockBorderColor) 208 { 209 if (blockBorderColor_) { 210 blockBorderColor_->Set(LinearColor(blockBorderColor)); 211 } 212 } 213 SetBlockBorderWidth(float blockBorderWidth)214 void SetBlockBorderWidth(float blockBorderWidth) 215 { 216 if (blockBorderWidth_) { 217 blockBorderWidth_->Set(blockBorderWidth); 218 } 219 } 220 221 void SetBlockShape(const RefPtr<BasicShape>& shape); 222 SetDirection(Axis axis)223 void SetDirection(Axis axis) 224 { 225 if (directionAxis_) { 226 directionAxis_->Set(static_cast<int>(axis)); 227 } 228 } 229 GetBlockCenter()230 PointF GetBlockCenter() 231 { 232 auto blockCenterX = blockCenterX_->Get(); 233 auto blockCenterY = blockCenterY_->Get(); 234 auto backStart = backStart_->Get(); 235 auto backEnd = backEnd_->Get(); 236 if (static_cast<Axis>(directionAxis_->Get()) == Axis::HORIZONTAL) { 237 blockCenterX = std::clamp(blockCenterX, backStart.GetX(), backEnd.GetX()); 238 } else { 239 blockCenterY = std::clamp(blockCenterY, backStart.GetY(), backEnd.GetY()); 240 } 241 return { blockCenterX, blockCenterY }; 242 } 243 GetTrackThickness()244 float GetTrackThickness() const 245 { 246 return trackThickness_->Get(); 247 } 248 GetBlockSize()249 SizeF GetBlockSize() const 250 { 251 return blockSize_->Get(); 252 } 253 SetVisible(bool isVisible)254 void SetVisible(bool isVisible) 255 { 256 CHECK_NULL_VOID(isVisible_ != isVisible); 257 isVisible_ = isVisible; 258 } 259 GetVisible()260 bool GetVisible() const 261 { 262 return isVisible_; 263 } 264 265 void UpdateContentDirtyRect(const SizeF& frameSize); 266 SetUseContentModifier(bool useContentModifier)267 void SetUseContentModifier(bool useContentModifier) 268 { 269 if (useContentModifier_) { 270 useContentModifier_->Set(useContentModifier); 271 } 272 } 273 GetStepPointVec()274 const std::vector<PointF>& GetStepPointVec() const 275 { 276 return stepPointVec_; 277 } 278 279 private: 280 void InitializeShapeProperty(); 281 RSRect GetTrackRect(); 282 std::vector<GradientColor> GetTrackBackgroundColor() const; 283 Gradient SortGradientColorsByOffset(const Gradient& gradient) const; 284 285 void DrawBlock(DrawingContext& context); 286 void DrawBlockShape(DrawingContext& context); 287 void DrawBlockShapeCircle(DrawingContext& context, RefPtr<Circle>& circle); 288 void DrawBlockShapeEllipse(DrawingContext& context, RefPtr<Ellipse>& ellipse); 289 void DrawBlockShapePath(DrawingContext& context, RefPtr<Path>& path); 290 void DrawBlockShapeRect(DrawingContext& context, RefPtr<ShapeRect>& rect); 291 void SetShapeRectRadius(RSRoundRect& roundRect, float borderWidth); 292 void SetBlockClip(DrawingContext& context); 293 void StopSelectAnimation(); 294 void StopCircleCenterAnimation(); 295 296 private: 297 std::function<void(float)> updateImageCenterX_; 298 std::function<void(float)> updateImageCenterY_; 299 300 // animatable property 301 RefPtr<AnimatablePropertyOffsetF> selectStart_; 302 RefPtr<AnimatablePropertyOffsetF> selectEnd_; 303 RefPtr<AnimatablePropertyOffsetF> backStart_; 304 RefPtr<AnimatablePropertyOffsetF> backEnd_; 305 RefPtr<AnimatablePropertyFloat> blockCenterX_; 306 RefPtr<AnimatablePropertyFloat> blockCenterY_; 307 RefPtr<AnimatablePropertyFloat> trackThickness_; 308 RefPtr<AnimatablePropertyVectorColor> trackBackgroundColor_; 309 RefPtr<AnimatablePropertyColor> selectColor_; 310 RefPtr<AnimatablePropertyColor> blockColor_; 311 RefPtr<AnimatablePropertyColor> boardColor_; 312 313 RefPtr<AnimatablePropertyFloat> trackBorderRadius_; 314 RefPtr<AnimatablePropertyFloat> selectedBorderRadius_; 315 RefPtr<AnimatablePropertyFloat> stepSize_; 316 RefPtr<AnimatablePropertyColor> stepColor_; 317 RefPtr<AnimatablePropertySizeF> blockSize_; 318 RefPtr<AnimatablePropertyColor> blockBorderColor_; 319 RefPtr<AnimatablePropertyFloat> blockBorderWidth_; 320 RefPtr<AnimatablePropertyFloat> shapeWidth_; 321 RefPtr<AnimatablePropertyFloat> shapeHeight_; 322 RefPtr<AnimatablePropertyFloat> circleRadius_; 323 RefPtr<AnimatablePropertyFloat> ellipseRadiusX_; 324 RefPtr<AnimatablePropertyFloat> ellipseRadiusY_; 325 RefPtr<AnimatablePropertyFloat> rectTopLeftRadiusX_; 326 RefPtr<AnimatablePropertyFloat> rectTopLeftRadiusY_; 327 RefPtr<AnimatablePropertyFloat> rectTopRightRadiusX_; 328 RefPtr<AnimatablePropertyFloat> rectTopRightRadiusY_; 329 RefPtr<AnimatablePropertyFloat> rectBottomLeftRadiusX_; 330 RefPtr<AnimatablePropertyFloat> rectBottomLeftRadiusY_; 331 RefPtr<AnimatablePropertyFloat> rectBottomRightRadiusX_; 332 RefPtr<AnimatablePropertyFloat> rectBottomRightRadiusY_; 333 // non-animatable property 334 RefPtr<PropertyFloat> stepRatio_; 335 RefPtr<PropertyInt> sliderMode_; 336 RefPtr<PropertyInt> directionAxis_; 337 RefPtr<PropertyBool> isShowStep_; 338 RefPtr<PropertyInt> sliderInteractionMode_; 339 RefPtr<PropertyFloat> minResponse_; 340 RefPtr<PropertyInt> blockType_; 341 RefPtr<PropertyBool> useContentModifier_; 342 343 // others 344 struct MarkerPenAndPath { 345 RSPen pen; 346 RSBrush brush; 347 RSPath path; 348 } markerPenAndPath; 349 350 OffsetF targetSelectEnd_; 351 PointF targetCenter_; 352 bool isVisible_ = true; 353 bool mouseHoverFlag_ = false; 354 bool mousePressedFlag_ = false; 355 bool reverse_ = false; 356 SliderStatus animatorStatus_ = SliderStatus::DEFAULT; // Translate Animation on-off 357 float hotCircleShadowWidth_ = 0.0f; 358 Color blockOuterEdgeColor_; 359 Color blockShadowColor_; 360 RefPtr<BasicShape> shape_; 361 std::vector<PointF> stepPointVec_; 362 ACE_DISALLOW_COPY_AND_MOVE(SliderContentModifier); 363 }; 364 365 } // namespace OHOS::Ace::NG 366 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_SLIDER_SLIDER_CONTENT_MODIFIER_H 367