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 Gradient selectGradientColor; 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 void AddStepPoint(float startX, float startY, float endX, float endY, RSCanvas& canvas); 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(const Gradient & color)95 void SetSelectColor(const Gradient& color) 96 { 97 if (selectGradientColor_) { 98 selectGradientColor_->Set(GradientArithmetic(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 SetIsPressed(bool isPressed)260 void SetIsPressed(bool isPressed) 261 { 262 if (isPressed_) { 263 isPressed_->Set(isPressed); 264 } 265 } 266 SetIsHovered(bool isHovered)267 void SetIsHovered(bool isHovered) 268 { 269 if (isHovered_) { 270 isHovered_->Set(isHovered); 271 } 272 } 273 SetIsFocused(bool isFocused)274 void SetIsFocused(bool isFocused) 275 { 276 if (isFocused_) { 277 isFocused_->Set(isFocused); 278 } 279 } 280 GetVisible()281 bool GetVisible() const 282 { 283 return isVisible_; 284 } 285 286 void UpdateContentDirtyRect(const SizeF& frameSize); 287 SetUseContentModifier(bool useContentModifier)288 void SetUseContentModifier(bool useContentModifier) 289 { 290 if (useContentModifier_) { 291 useContentModifier_->Set(useContentModifier); 292 } 293 } 294 GetStepPointVec()295 const std::vector<PointF>& GetStepPointVec() const 296 { 297 return stepPointVec_; 298 } 299 300 private: 301 void InitializeShapeProperty(); 302 RSRect GetTrackRect(); 303 std::vector<GradientColor> GetTrackBackgroundColor() const; 304 Gradient SortGradientColorsByOffset(const Gradient& gradient) const; 305 void DrawSelectColor(RSBrush& brush, RSRect& rect); 306 void DrawBlock(DrawingContext& context); 307 void DrawBlockShape(DrawingContext& context); 308 void DrawBlockShapeCircle(DrawingContext& context, RefPtr<Circle>& circle); 309 void DrawBlockShapeEllipse(DrawingContext& context, RefPtr<Ellipse>& ellipse); 310 void DrawBlockShapePath(DrawingContext& context, RefPtr<Path>& path); 311 void DrawBlockShapeRect(DrawingContext& context, RefPtr<ShapeRect>& rect); 312 void SetShapeRectRadius(RSRoundRect& roundRect, float borderWidth); 313 void SetBlockClip(DrawingContext& context); 314 void StopSelectAnimation(); 315 void StopCircleCenterAnimation(); 316 317 private: 318 std::function<void(float)> updateImageCenterX_; 319 std::function<void(float)> updateImageCenterY_; 320 321 // animatable property 322 RefPtr<AnimatablePropertyOffsetF> selectStart_; 323 RefPtr<AnimatablePropertyOffsetF> selectEnd_; 324 RefPtr<AnimatablePropertyOffsetF> backStart_; 325 RefPtr<AnimatablePropertyOffsetF> backEnd_; 326 RefPtr<AnimatablePropertyFloat> blockCenterX_; 327 RefPtr<AnimatablePropertyFloat> blockCenterY_; 328 RefPtr<AnimatablePropertyFloat> trackThickness_; 329 RefPtr<AnimatablePropertyVectorColor> trackBackgroundColor_; 330 RefPtr<AnimatablePropertyVectorColor> selectGradientColor_; 331 RefPtr<AnimatablePropertyColor> blockColor_; 332 RefPtr<AnimatablePropertyColor> boardColor_; 333 334 RefPtr<AnimatablePropertyFloat> trackBorderRadius_; 335 RefPtr<AnimatablePropertyFloat> selectedBorderRadius_; 336 RefPtr<AnimatablePropertyFloat> stepSize_; 337 RefPtr<AnimatablePropertyColor> stepColor_; 338 RefPtr<AnimatablePropertySizeF> blockSize_; 339 RefPtr<AnimatablePropertyColor> blockBorderColor_; 340 RefPtr<AnimatablePropertyFloat> blockBorderWidth_; 341 RefPtr<AnimatablePropertyFloat> shapeWidth_; 342 RefPtr<AnimatablePropertyFloat> shapeHeight_; 343 RefPtr<AnimatablePropertyFloat> circleRadius_; 344 RefPtr<AnimatablePropertyFloat> ellipseRadiusX_; 345 RefPtr<AnimatablePropertyFloat> ellipseRadiusY_; 346 RefPtr<AnimatablePropertyFloat> rectTopLeftRadiusX_; 347 RefPtr<AnimatablePropertyFloat> rectTopLeftRadiusY_; 348 RefPtr<AnimatablePropertyFloat> rectTopRightRadiusX_; 349 RefPtr<AnimatablePropertyFloat> rectTopRightRadiusY_; 350 RefPtr<AnimatablePropertyFloat> rectBottomLeftRadiusX_; 351 RefPtr<AnimatablePropertyFloat> rectBottomLeftRadiusY_; 352 RefPtr<AnimatablePropertyFloat> rectBottomRightRadiusX_; 353 RefPtr<AnimatablePropertyFloat> rectBottomRightRadiusY_; 354 // non-animatable property 355 RefPtr<PropertyFloat> stepRatio_; 356 RefPtr<PropertyInt> sliderMode_; 357 RefPtr<PropertyInt> directionAxis_; 358 RefPtr<PropertyBool> isShowStep_; 359 RefPtr<PropertyInt> sliderInteractionMode_; 360 RefPtr<PropertyFloat> minResponse_; 361 RefPtr<PropertyInt> blockType_; 362 RefPtr<PropertyBool> useContentModifier_; 363 RefPtr<PropertyBool> isHovered_; 364 RefPtr<PropertyBool> isPressed_; 365 RefPtr<PropertyBool> isFocused_; 366 367 // others 368 struct MarkerPenAndPath { 369 RSPen pen; 370 RSBrush brush; 371 RSPath path; 372 } markerPenAndPath; 373 374 OffsetF targetSelectEnd_; 375 PointF targetCenter_; 376 bool isVisible_ = true; 377 bool mouseHoverFlag_ = false; 378 bool mousePressedFlag_ = false; 379 bool isEnlarge_ = false; 380 float scaleValue_ = 1.0f; 381 bool reverse_ = false; 382 SliderStatus animatorStatus_ = SliderStatus::DEFAULT; // Translate Animation on-off 383 float hotCircleShadowWidth_ = 0.0f; 384 Color blockOuterEdgeColor_; 385 Color blockShadowColor_; 386 RefPtr<BasicShape> shape_; 387 std::vector<PointF> stepPointVec_; 388 ACE_DISALLOW_COPY_AND_MOVE(SliderContentModifier); 389 }; 390 391 } // namespace OHOS::Ace::NG 392 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_SLIDER_SLIDER_CONTENT_MODIFIER_H 393