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