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(const RefPtr<FrameNode>& host); 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, const RefPtr<FrameNode>& host); 122 123 void SetCircleCenter(const PointF& center, const RefPtr<FrameNode>& host); 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 GetBlockBackStart()244 PointF GetBlockBackStart() 245 { 246 auto backStart = backStart_->Get(); 247 return { backStart.GetX(), backStart.GetY() }; 248 } 249 GetBlockBackEnd()250 PointF GetBlockBackEnd() 251 { 252 auto backEnd = backEnd_->Get(); 253 return { backEnd.GetX(), backEnd.GetY() }; 254 } 255 GetStepsLength()256 PointF GetStepsLength() 257 { 258 return stepsLength_; 259 } 260 GetTrackRectPosition()261 RSRect GetTrackRectPosition() 262 { 263 auto rect = GetTrackRect(); 264 return rect; 265 } 266 GetTrackThickness()267 float GetTrackThickness() const 268 { 269 return trackThickness_->Get(); 270 } 271 GetBlockSize()272 SizeF GetBlockSize() const 273 { 274 return blockSize_->Get(); 275 } 276 SetVisible(bool isVisible)277 void SetVisible(bool isVisible) 278 { 279 CHECK_NULL_VOID(isVisible_ != isVisible); 280 isVisible_ = isVisible; 281 } 282 SetIsPressed(bool isPressed)283 void SetIsPressed(bool isPressed) 284 { 285 if (isPressed_) { 286 isPressed_->Set(isPressed); 287 } 288 } 289 SetIsHovered(bool isHovered)290 void SetIsHovered(bool isHovered) 291 { 292 if (isHovered_) { 293 isHovered_->Set(isHovered); 294 } 295 } 296 SetIsFocused(bool isFocused)297 void SetIsFocused(bool isFocused) 298 { 299 if (isFocused_) { 300 isFocused_->Set(isFocused); 301 } 302 } 303 GetVisible()304 bool GetVisible() const 305 { 306 return isVisible_; 307 } 308 309 void UpdateContentDirtyRect(const SizeF& frameSize); 310 SetUseContentModifier(bool useContentModifier)311 void SetUseContentModifier(bool useContentModifier) 312 { 313 if (useContentModifier_) { 314 useContentModifier_->Set(useContentModifier); 315 } 316 } 317 SetHasPrefix(bool hasPrefix)318 void SetHasPrefix(bool hasPrefix) 319 { 320 hasPrefix_ = hasPrefix; 321 } 322 SetHasSuffix(bool hasSuffix)323 void SetHasSuffix(bool hasSuffix) 324 { 325 hasSuffix_ = hasSuffix; 326 } 327 GetStepPointVec()328 const std::vector<PointF>& GetStepPointVec() const 329 { 330 return stepPointVec_; 331 } SetHost(const WeakPtr<FrameNode> & host)332 void SetHost(const WeakPtr<FrameNode>& host) 333 { 334 host_ = host; 335 } 336 RegisterStepPointCallback(std::function<void ()> && callback)337 void RegisterStepPointCallback(std::function<void()>&& callback) 338 { 339 StepPointCallback_ = std::move(callback); 340 } 341 GetStepPointCallback()342 std::function<void()>& GetStepPointCallback() 343 { 344 return StepPointCallback_; 345 } 346 void DrawStepPoint(float x, float y, int32_t index, RSCanvas& canvas, int32_t numberOfSteps); 347 SetUpdateAccessibilityCallback(const std::function<void ()> && callback)348 void SetUpdateAccessibilityCallback(const std::function<void()>&& callback) 349 { 350 updateAccessibilityVirtualNode_ = std::move(callback); 351 } 352 private: 353 void InitializeShapeProperty(); 354 RSRect GetTrackRect(); 355 std::vector<GradientColor> GetTrackBackgroundColor() const; 356 Gradient SortGradientColorsByOffset(const Gradient& gradient) const; 357 void DrawSelectColor(RSBrush& brush, RSRect& rect); 358 void DrawBlock(DrawingContext& context); 359 void DrawBlockShape(DrawingContext& context); 360 void DrawBlockShapeCircle(DrawingContext& context, RefPtr<Circle>& circle); 361 void DrawBlockShapeEllipse(DrawingContext& context, RefPtr<Ellipse>& ellipse); 362 void DrawBlockShapePath(DrawingContext& context, RefPtr<Path>& path); 363 void DrawBlockShapeRect(DrawingContext& context, RefPtr<ShapeRect>& rect); 364 void SetShapeRectRadius(RSRoundRect& roundRect, float borderWidth); 365 void SetBlockClip(DrawingContext& context); 366 void StopSelectAnimation(const RefPtr<FrameNode>& host); 367 void StopCircleCenterAnimation(const RefPtr<FrameNode>& host); 368 void UpdateSliderEndsPosition(); 369 370 private: 371 std::function<void(float)> updateImageCenterX_; 372 std::function<void(float)> updateImageCenterY_; 373 std::function<void()> updateAccessibilityVirtualNode_; 374 WeakPtr<FrameNode> host_; 375 376 // animatable property 377 RefPtr<AnimatablePropertyOffsetF> selectStart_; 378 RefPtr<AnimatablePropertyOffsetF> selectEnd_; 379 RefPtr<AnimatablePropertyOffsetF> backStart_; 380 RefPtr<AnimatablePropertyOffsetF> backEnd_; 381 RefPtr<AnimatablePropertyFloat> blockCenterX_; 382 RefPtr<AnimatablePropertyFloat> blockCenterY_; 383 RefPtr<AnimatablePropertyFloat> trackThickness_; 384 RefPtr<AnimatablePropertyVectorColor> trackBackgroundColor_; 385 RefPtr<AnimatablePropertyVectorColor> selectGradientColor_; 386 RefPtr<AnimatablePropertyColor> blockColor_; 387 RefPtr<AnimatablePropertyColor> boardColor_; 388 389 RefPtr<AnimatablePropertyFloat> trackBorderRadius_; 390 RefPtr<AnimatablePropertyFloat> selectedBorderRadius_; 391 RefPtr<AnimatablePropertyFloat> stepSize_; 392 RefPtr<AnimatablePropertyColor> stepColor_; 393 RefPtr<AnimatablePropertySizeF> blockSize_; 394 RefPtr<AnimatablePropertyColor> blockBorderColor_; 395 RefPtr<AnimatablePropertyFloat> blockBorderWidth_; 396 RefPtr<AnimatablePropertyFloat> shapeWidth_; 397 RefPtr<AnimatablePropertyFloat> shapeHeight_; 398 RefPtr<AnimatablePropertyFloat> circleRadius_; 399 RefPtr<AnimatablePropertyFloat> ellipseRadiusX_; 400 RefPtr<AnimatablePropertyFloat> ellipseRadiusY_; 401 RefPtr<AnimatablePropertyFloat> rectTopLeftRadiusX_; 402 RefPtr<AnimatablePropertyFloat> rectTopLeftRadiusY_; 403 RefPtr<AnimatablePropertyFloat> rectTopRightRadiusX_; 404 RefPtr<AnimatablePropertyFloat> rectTopRightRadiusY_; 405 RefPtr<AnimatablePropertyFloat> rectBottomLeftRadiusX_; 406 RefPtr<AnimatablePropertyFloat> rectBottomLeftRadiusY_; 407 RefPtr<AnimatablePropertyFloat> rectBottomRightRadiusX_; 408 RefPtr<AnimatablePropertyFloat> rectBottomRightRadiusY_; 409 // non-animatable property 410 RefPtr<PropertyFloat> stepRatio_; 411 RefPtr<PropertyInt> sliderMode_; 412 RefPtr<PropertyInt> directionAxis_; 413 RefPtr<PropertyBool> isShowStep_; 414 RefPtr<PropertyInt> sliderInteractionMode_; 415 RefPtr<PropertyFloat> minResponse_; 416 RefPtr<PropertyInt> blockType_; 417 RefPtr<PropertyBool> useContentModifier_; 418 RefPtr<PropertyBool> isHovered_; 419 RefPtr<PropertyBool> isPressed_; 420 RefPtr<PropertyBool> isFocused_; 421 422 // others 423 struct MarkerPenAndPath { 424 RSPen pen; 425 RSBrush brush; 426 RSPath path; 427 } markerPenAndPath; 428 429 PointF stepsLength_; 430 OffsetF targetSelectEnd_; 431 PointF targetCenter_; 432 bool isVisible_ = true; 433 bool mouseHoverFlag_ = false; 434 bool mousePressedFlag_ = false; 435 bool isEnlarge_ = false; 436 float scaleValue_ = 1.0f; 437 bool reverse_ = false; 438 SliderStatus animatorStatus_ = SliderStatus::DEFAULT; // Translate Animation on-off 439 float hotCircleShadowWidth_ = 0.0f; 440 Color blockOuterEdgeColor_; 441 Color blockShadowColor_; 442 RefPtr<BasicShape> shape_; 443 std::vector<PointF> stepPointVec_; 444 ACE_DISALLOW_COPY_AND_MOVE(SliderContentModifier); 445 std::function<void()> StepPointCallback_; 446 bool hasPrefix_ = false; 447 bool hasSuffix_ = false; 448 }; 449 450 } // namespace OHOS::Ace::NG 451 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_SLIDER_SLIDER_CONTENT_MODIFIER_H 452