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_PATTERNS_SWIPER_INDICATOR_SWIPER_INDICATOR_MODIFIER_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SWIPER_INDICATOR_SWIPER_INDICATOR_MODIFIER_H 18 19 #include <optional> 20 21 #include "core/components/swiper/swiper_indicator_theme.h" 22 #include "core/components_ng/base/modifier.h" 23 #include "core/components_ng/pattern/swiper_indicator/dot_indicator/dot_indicator_paint_property.h" 24 #include "core/components_ng/render/animation_utils.h" 25 #include "core/components_ng/render/drawing_prop_convertor.h" 26 #include "core/components_ng/render/paint_wrapper.h" 27 28 namespace OHOS::Ace::NG { 29 constexpr int32_t ITEM_SIZE = 4; 30 constexpr float INIT_SIZE_RATE = 1.0f; 31 32 enum class TouchBottomType { 33 NONE = 0, 34 START, 35 END, 36 }; 37 38 enum class TouchBottomAnimationStage { 39 STAGE_NONE, 40 STAGE_SHRINKT_TO_BLACK_POINT, 41 STAGE_EXPAND_TO_LONG_POINT, 42 }; 43 44 class DotIndicatorModifier : public ContentModifier { 45 DECLARE_ACE_TYPE(DotIndicatorModifier, ContentModifier); 46 public: DotIndicatorModifier()47 DotIndicatorModifier() 48 : backgroundColor_(AceType::MakeRefPtr<AnimatablePropertyColor>(LinearColor::TRANSPARENT)), 49 vectorBlackPointCenterX_(AceType::MakeRefPtr<AnimatablePropertyVectorFloat>(LinearVector<float>(0))), 50 longPointLeftCenterX_(AceType::MakeRefPtr<AnimatablePropertyFloat>(0)), 51 longPointRightCenterX_(AceType::MakeRefPtr<AnimatablePropertyFloat>(0)), 52 normalToHoverPointDilateRatio_(AceType::MakeRefPtr<AnimatablePropertyFloat>(1)), 53 hoverToNormalPointDilateRatio_(AceType::MakeRefPtr<AnimatablePropertyFloat>(1)), 54 longPointDilateRatio_(AceType::MakeRefPtr<AnimatablePropertyFloat>(1)), 55 indicatorPadding_(AceType::MakeRefPtr<AnimatablePropertyFloat>(0)), 56 indicatorMargin_(AceType::MakeRefPtr<AnimatablePropertyOffsetF>(OffsetF(0, 0))), 57 itemHalfSizes_(AceType::MakeRefPtr<AnimatablePropertyVectorFloat>(LinearVector<float>(ITEM_SIZE))), 58 backgroundWidthDilateRatio_(AceType::MakeRefPtr<AnimatablePropertyFloat>(1)), 59 backgroundHeightDilateRatio_(AceType::MakeRefPtr<AnimatablePropertyFloat>(1)), 60 isFocused_(AceType::MakeRefPtr<PropertyBool>(false)), 61 unselectedColor_(AceType::MakeRefPtr<PropertyColor>(Color::TRANSPARENT)), 62 selectedColor_(AceType::MakeRefPtr<AnimatablePropertyColor>(LinearColor::TRANSPARENT)), 63 touchBottomPointColor_(AceType::MakeRefPtr<AnimatablePropertyColor>(LinearColor::TRANSPARENT)) 64 { 65 AttachProperty(vectorBlackPointCenterX_); 66 AttachProperty(longPointLeftCenterX_); 67 AttachProperty(longPointRightCenterX_); 68 AttachProperty(normalToHoverPointDilateRatio_); 69 AttachProperty(hoverToNormalPointDilateRatio_); 70 AttachProperty(longPointDilateRatio_); 71 AttachProperty(backgroundColor_); 72 AttachProperty(indicatorPadding_); 73 AttachProperty(indicatorMargin_); 74 AttachProperty(itemHalfSizes_); 75 AttachProperty(isFocused_); 76 AttachProperty(unselectedColor_); 77 AttachProperty(selectedColor_); 78 AttachProperty(backgroundWidthDilateRatio_); 79 AttachProperty(backgroundHeightDilateRatio_); 80 AttachProperty(touchBottomPointColor_); 81 } 82 ~DotIndicatorModifier() override = default; 83 84 struct ContentProperty { 85 Color backgroundColor = Color::TRANSPARENT; 86 LinearVector<float> vectorBlackPointCenterX; 87 LinearVector<float> unselectedIndicatorWidth; 88 LinearVector<float> unselectedIndicatorHeight; 89 LinearVector<float> itemHalfSizes = {}; 90 float longPointLeftCenterX = 0; 91 float longPointRightCenterX = 0; 92 float normalToHoverPointDilateRatio = 1; 93 float hoverToNormalPointDilateRatio = 1; 94 float longPointDilateRatio = 0; 95 float indicatorPadding = 0; 96 OffsetF indicatorMargin = { 0, 0 }; 97 float theFirstPointMove = 0; 98 float theSecondPointMove = 0; 99 float theThirdPointMove = 0; 100 float fourthPointMove = 0; 101 float fifthPointMove = 0; 102 float sixthPointMove = 0; 103 float seventhPointMove = 0; 104 float eighthPointMove = 0; 105 float ninthPointMove = 0; 106 float newPointMove = 0; 107 float leftSecondPointSizeRate = INIT_SIZE_RATE; 108 float leftThirdPointSizeRate = INIT_SIZE_RATE; 109 float rightSecondPointSizeRate = INIT_SIZE_RATE; 110 float rightFirstPointSizeRate = INIT_SIZE_RATE; 111 uint8_t firstPointOpacity = 0; 112 uint8_t newPointOpacity = 0; 113 }; 114 115 void onDraw(DrawingContext& context) override; 116 // paint 117 virtual void PaintContent(DrawingContext& context, ContentProperty& contentProperty); 118 void PaintUnselectedIndicator(RSCanvas& canvas, const OffsetF& center, 119 const LinearVector<float>& itemHalfSizes, 120 bool currentIndexFlag, const LinearColor& indicatorColor); 121 void PaintSelectedIndicator(RSCanvas& canvas, const OffsetF& leftCenter, const OffsetF& rightCenter, 122 const LinearVector<float>& itemHalfSizes, bool isOverlong = false); 123 void PaintMask(DrawingContext& context); 124 void PaintBackground(DrawingContext& context, ContentProperty& contentProperty); 125 virtual LinearVector<float> GetItemHalfSizes(size_t index, ContentProperty& contentProperty); 126 void SetFocusedAndSelectedColor(ContentProperty& contentProperty); 127 // Update property 128 void UpdateShrinkPaintProperty(const OffsetF& margin, const LinearVector<float>& normalItemHalfSizes, 129 const LinearVector<float>& vectorBlackPointCenterX, const std::pair<float, float>& longPointCenterX); 130 void UpdateDilatePaintProperty(const LinearVector<float>& hoverItemHalfSizes, 131 const LinearVector<float>& vectorBlackPointCenterX, const std::pair<float, float>& longPointCenterX); 132 void UpdateBackgroundColor(const Color& backgroundColor); 133 134 void UpdateNormalPaintProperty(const OffsetF& margin, const LinearVector<float>& normalItemHalfSizes, 135 const LinearVector<float>& vectorBlackPointCenterX, const std::pair<float, float>& longPointCenterX); 136 void UpdateHoverPaintProperty(const LinearVector<float>& hoverItemHalfSizes, 137 const LinearVector<float>& vectorBlackPointCenterX, const std::pair<float, float>& longPointCenterX); 138 void UpdatePressPaintProperty(const LinearVector<float>& hoverItemHalfSizes, 139 const LinearVector<float>& vectorBlackPointCenterX, const std::pair<float, float>& longPointCenterX); 140 // Update 141 void UpdateNormalToHoverPaintProperty(const LinearVector<float>& hoverItemHalfSizes, 142 const LinearVector<float>& vectorBlackPointCenterX, const std::pair<float, float>& longPointCenterX); 143 void UpdateHoverToNormalPaintProperty(const OffsetF& margin, const LinearVector<float>& normalItemHalfSizes, 144 const LinearVector<float>& vectorBlackPointCenterX, const std::pair<float, float>& longPointCenterX); 145 void UpdateNormalToPressPaintProperty(const LinearVector<float>& hoverItemHalfSizes, 146 const LinearVector<float>& vectorBlackPointCenterX, const std::pair<float, float>& longPointCenterX); 147 void UpdatePressToNormalPaintProperty(const OffsetF& margin, const LinearVector<float>& normalItemHalfSizes, 148 const LinearVector<float>& vectorBlackPointCenterX, const std::pair<float, float>& longPointCenterX); 149 void UpdateHoverAndPressConversionPaintProperty(); 150 151 // Point dilate ratio 152 void UpdateNormalToHoverPointDilateRatio(); 153 void UpdateHoverToNormalPointDilateRatio(); 154 void UpdateLongPointDilateRatio(); 155 156 void UpdateAllPointCenterXAnimation(GestureState gestureState, const LinearVector<float>& vectorBlackPointCenterX, 157 const std::pair<float, float>& longPointCenterX); 158 159 // Touch bottom animation 160 void UpdateTouchBottomAnimation(TouchBottomType touchBottomType, const LinearVector<float>& vectorBlackPointCenterX, 161 const std::pair<float, float>& longPointCenterX, float touchBottomRate); 162 SetAxis(Axis axis)163 void SetAxis(Axis axis) 164 { 165 axis_ = axis; 166 } 167 SetUnselectedColor(const Color & unselectedColor)168 void SetUnselectedColor(const Color& unselectedColor) 169 { 170 if (unselectedColor_) { 171 unselectedColor_->Set(unselectedColor); 172 originalUnselectColor_ = unselectedColor_->Get(); 173 } 174 } 175 SetSelectedColor(const Color & selectedColor)176 void SetSelectedColor(const Color& selectedColor) 177 { 178 if (selectedColor_ && isSelectedColorAnimEnd_) { 179 selectedColor_->Set(LinearColor(selectedColor)); 180 originalSelectColor_ = selectedColor_->Get().ToColor(); 181 } 182 if (touchBottomPointColor_ && isSelectedColorAnimEnd_) { 183 touchBottomPointColor_->Set(LinearColor(selectedColor)); 184 } 185 } 186 SetCurrentIndex(int32_t index)187 void SetCurrentIndex(int32_t index) 188 { 189 currentIndex_ = index; 190 } 191 SetCurrentIndexActual(int32_t currentIndexActual)192 void SetCurrentIndexActual(int32_t currentIndexActual) 193 { 194 currentIndexActual_ = currentIndexActual; 195 } 196 SetNormalToHoverIndex(const std::optional<int32_t> & normalToHoverIndex)197 void SetNormalToHoverIndex(const std::optional<int32_t>& normalToHoverIndex) 198 { 199 normalToHoverIndex_ = normalToHoverIndex; 200 } 201 SetIsFocused(bool isFocused)202 void SetIsFocused(bool isFocused) 203 { 204 if (isFocused_) { 205 isFocused_->Set(isFocused); 206 } 207 } 208 SetHoverToNormalIndex(const std::optional<int32_t> & hoverToNormalIndex)209 void SetHoverToNormalIndex(const std::optional<int32_t>& hoverToNormalIndex) 210 { 211 hoverToNormalIndex_ = hoverToNormalIndex; 212 } 213 GetNormalToHoverIndex()214 std::optional<int32_t> GetNormalToHoverIndex() 215 { 216 return normalToHoverIndex_; 217 } 218 GetHoverToNormalIndex()219 std::optional<int32_t> GetHoverToNormalIndex() 220 { 221 return hoverToNormalIndex_; 222 } 223 SetIndicatorMask(bool indicatorMask)224 void SetIndicatorMask(bool indicatorMask) 225 { 226 indicatorMask_ = indicatorMask; 227 } 228 SetOffset(const OffsetF & offset)229 void SetOffset(const OffsetF& offset) 230 { 231 offset_ = offset; 232 } 233 SetCenterY(const float & centerY)234 void SetCenterY(const float& centerY) 235 { 236 centerY_ = centerY; 237 } 238 SetIsHover(bool isHover)239 void SetIsHover(bool isHover) 240 { 241 isHover_ = isHover; 242 } 243 GetIsHover()244 bool GetIsHover() const 245 { 246 return isHover_; 247 } 248 SetIsPressed(bool isPressed)249 void SetIsPressed(bool isPressed) 250 { 251 isPressed_ = isPressed; 252 } 253 GetIsPressed()254 bool GetIsPressed() const 255 { 256 return isPressed_; 257 } 258 SetLongPointIsHover(bool isHover)259 void SetLongPointIsHover(bool isHover) 260 { 261 longPointIsHover_ = isHover; 262 } 263 GetLongPointIsHover()264 bool GetLongPointIsHover() const 265 { 266 return longPointIsHover_; 267 } 268 SetItemWidth(const float itemWidth)269 void SetItemWidth(const float itemWidth) 270 { 271 itemWidth_ = itemWidth; 272 } 273 SetItemHeight(const float itemHeight)274 void SetItemHeight(const float itemHeight) 275 { 276 itemHeight_ = itemHeight; 277 } 278 SetSelectedItemWidth(const float selectedItemWidth)279 void SetSelectedItemWidth(const float selectedItemWidth) 280 { 281 selectedItemWidth_ = selectedItemWidth; 282 } 283 SetSelectedItemHeight(const float selectedItemHeight)284 void SetSelectedItemHeight(const float selectedItemHeight) 285 { 286 selectedItemHeight_ = selectedItemHeight; 287 } 288 SetIsIndicatorCustomSize(bool isCustomSize)289 void SetIsIndicatorCustomSize(bool isCustomSize) 290 { 291 isCustomSize_ = isCustomSize; 292 } 293 SetAnimationDuration(int32_t duration)294 void SetAnimationDuration(int32_t duration) 295 { 296 animationDuration_ = duration; 297 } 298 UpdateVectorBlackPointCenterX(const LinearVector<float> & value)299 inline void UpdateVectorBlackPointCenterX(const LinearVector<float>& value) 300 { 301 vectorBlackPointCenterX_->Set(value); 302 } 303 GetLongPointCenterX()304 std::pair<float, float> GetLongPointCenterX() 305 { 306 return { longPointLeftCenterX_->Get(), longPointRightCenterX_->Get() }; 307 } 308 309 void PlayIndicatorAnimation(const LinearVector<float>& vectorBlackPointCenterX, 310 const std::vector<std::pair<float, float>>& longPointCenterX, GestureState gestureState, 311 TouchBottomTypeLoop touchBottomTypeLoop); 312 virtual void StopAnimation(bool ifImmediately = false); SetLongPointHeadCurve(RefPtr<Curve> curve,float motionVelocity)313 void SetLongPointHeadCurve(RefPtr<Curve> curve, float motionVelocity) 314 { 315 headCurve_ = curve; 316 motionVelocity_ = motionVelocity; 317 } 318 SetUserSetSwiperCurve(RefPtr<Curve> userSetSwiperCurve)319 void SetUserSetSwiperCurve(RefPtr<Curve> userSetSwiperCurve) 320 { 321 userSetSwiperCurve_ = userSetSwiperCurve; 322 } 323 SetIndicatorDotItemSpace(const Dimension & indicatorDotItemSpace)324 void SetIndicatorDotItemSpace(const Dimension& indicatorDotItemSpace) 325 { 326 indicatorDotItemSpace_ = indicatorDotItemSpace; 327 } 328 GetIndicatorDotItemSpace()329 const Dimension& GetIndicatorDotItemSpace() const 330 { 331 return indicatorDotItemSpace_; 332 } 333 GetTargetCenter()334 std::pair<float, float> GetTargetCenter() const 335 { 336 return bottomCenterX_; 337 } 338 GetIsBottomAnimationFinished()339 bool GetIsBottomAnimationFinished() const 340 { 341 return isBottomAnimationFinished_; 342 } 343 GetBoundsRect()344 RectF GetBoundsRect() const 345 { 346 return boundsRectF_; 347 } 348 void FinishAnimationToTargetImmediately(std::pair<float, float> centerX); 349 protected: GetSwiperIndicatorTheme()350 static RefPtr<OHOS::Ace::SwiperIndicatorTheme> GetSwiperIndicatorTheme() 351 { 352 auto pipelineContext = PipelineBase::GetCurrentContext(); 353 CHECK_NULL_RETURN(pipelineContext, nullptr); 354 auto swiperTheme = pipelineContext->GetTheme<SwiperIndicatorTheme>(); 355 CHECK_NULL_RETURN(swiperTheme, nullptr); 356 return swiperTheme; 357 } 358 359 void PlayBlackPointsAnimation(const LinearVector<float>& vectorBlackPointCenterX); 360 void PlayLongPointAnimation(const std::vector<std::pair<float, float>>& longPointCenterX, GestureState gestureState, 361 TouchBottomTypeLoop touchBottomTypeLoop, const LinearVector<float>& vectorBlackPointCenterX, 362 bool isNormal = true); 363 void PlayTouchBottomAnimation(const std::vector<std::pair<float, float>>& longPointCenterX, 364 TouchBottomTypeLoop touchBottomTypeLoop, const LinearVector<float>& vectorBlackPointCenterX); 365 void PlayOpacityAnimation(); 366 std::pair<float, float> GetTouchBottomCenterX(ContentProperty& contentProperty); 367 int32_t GetLoopTranslateDuration() const; 368 int32_t GetLoopOpacityDuration() const; 369 float CalculateMinimumAmplitudeRatio( 370 const std::vector<std::pair<float, float>>& longPointCenterX, GestureState gestureState) const; 371 RefPtr<InterpolatingSpring> GetTailCurve(); 372 AnimationOption CreateTailOption( 373 const std::vector<std::pair<float, float>>& longPointCenterX, GestureState gestureState, bool isNormal); 374 std::tuple<float, float, float, float> CalcAndAdjustIndicatorPaintRect( 375 const ContentProperty& contentProperty, float& rectWidth, float& rectHeight); 376 377 RefPtr<AnimatablePropertyColor> backgroundColor_; 378 RefPtr<AnimatablePropertyVectorFloat> vectorBlackPointCenterX_; 379 RefPtr<AnimatablePropertyFloat> longPointLeftCenterX_; 380 RefPtr<AnimatablePropertyFloat> longPointRightCenterX_; 381 RefPtr<AnimatablePropertyFloat> normalToHoverPointDilateRatio_; 382 RefPtr<AnimatablePropertyFloat> hoverToNormalPointDilateRatio_; 383 RefPtr<AnimatablePropertyFloat> longPointDilateRatio_; 384 RefPtr<AnimatablePropertyFloat> indicatorPadding_; 385 RefPtr<AnimatablePropertyOffsetF> indicatorMargin_; 386 RefPtr<AnimatablePropertyVectorFloat> itemHalfSizes_; 387 RefPtr<AnimatablePropertyFloat> backgroundWidthDilateRatio_; 388 RefPtr<AnimatablePropertyFloat> backgroundHeightDilateRatio_; 389 RefPtr<PropertyBool> isFocused_; 390 391 RefPtr<Curve> headCurve_; 392 RefPtr<Curve> userSetSwiperCurve_; 393 float motionVelocity_ = 0; 394 395 float centerY_ = 0; 396 Axis axis_ = Axis::HORIZONTAL; 397 RefPtr<PropertyColor> unselectedColor_; 398 RefPtr<AnimatablePropertyColor> selectedColor_; 399 bool isSelectedColorAnimEnd_ = true; 400 RefPtr<AnimatablePropertyColor> touchBottomPointColor_; 401 bool isTouchBottomLoop_ = false; 402 bool ifNeedFinishCallback_ = false; 403 bool isBottomAnimationFinished_ = true; 404 std::pair<float, float> bottomCenterX_; 405 TouchBottomAnimationStage animationState_ = TouchBottomAnimationStage::STAGE_NONE; 406 std::optional<int32_t> normalToHoverIndex_ = std::nullopt; 407 std::optional<int32_t> hoverToNormalIndex_ = std::nullopt; 408 bool longPointIsHover_ = false; 409 bool isHover_ = false; 410 bool isPressed_ = false; 411 bool longPointLeftAnimEnd_ = true; 412 bool longPointRightAnimEnd_ = true; 413 414 bool indicatorMask_ = false; 415 bool isCustomSize_ = false; 416 int32_t currentIndex_ = 0; 417 int32_t currentIndexActual_ = 0; 418 int32_t animationDuration_ = 0; 419 OffsetF offset_; 420 float itemWidth_ = 0.0f; 421 float itemHeight_ = 0.0f; 422 float selectedItemWidth_ = 0.0f; 423 float selectedItemHeight_ = 0.0f; 424 Color originalUnselectColor_; 425 Color originalSelectColor_; 426 Dimension paddingSide_; 427 Dimension indicatorDotItemSpace_ = 8.0_vp; 428 float scaleIndicator_ = 1.33f; 429 RectF boundsRectF_; 430 TouchBottomType touchBottomType_ = TouchBottomType::NONE; 431 ACE_DISALLOW_COPY_AND_MOVE(DotIndicatorModifier); 432 }; 433 } // namespace OHOS::Ace::NG 434 435 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SWIPER_INDICATOR_SWIPER_INDICATOR_MODIFIER_H 436