• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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, const ContentProperty& contentProperty, int32_t maxDisplayCount = 0,
125         bool isBindIndicator = false);
126     virtual LinearVector<float> GetItemHalfSizes(size_t index, ContentProperty& contentProperty);
127     void SetFocusedAndSelectedColor(ContentProperty& contentProperty);
128     // Update property
129     void UpdateShrinkPaintProperty(const OffsetF& margin, const LinearVector<float>& normalItemHalfSizes,
130         const LinearVector<float>& vectorBlackPointCenterX, const std::pair<float, float>& longPointCenterX);
131     void UpdateDilatePaintProperty(const LinearVector<float>& hoverItemHalfSizes,
132         const LinearVector<float>& vectorBlackPointCenterX, const std::pair<float, float>& longPointCenterX);
133     void UpdateBackgroundColor(const Color& backgroundColor);
134 
135     void UpdateNormalPaintProperty(const OffsetF& margin, const LinearVector<float>& normalItemHalfSizes,
136         const LinearVector<float>& vectorBlackPointCenterX, const std::pair<float, float>& longPointCenterX);
137     void UpdateHoverPaintProperty(const LinearVector<float>& hoverItemHalfSizes,
138         const LinearVector<float>& vectorBlackPointCenterX, const std::pair<float, float>& longPointCenterX);
139     void UpdatePressPaintProperty(const LinearVector<float>& hoverItemHalfSizes,
140         const LinearVector<float>& vectorBlackPointCenterX, const std::pair<float, float>& longPointCenterX);
141     // Update
142     void UpdateNormalToHoverPaintProperty(const LinearVector<float>& hoverItemHalfSizes,
143         const LinearVector<float>& vectorBlackPointCenterX, const std::pair<float, float>& longPointCenterX);
144     void UpdateHoverToNormalPaintProperty(const OffsetF& margin, const LinearVector<float>& normalItemHalfSizes,
145         const LinearVector<float>& vectorBlackPointCenterX, const std::pair<float, float>& longPointCenterX);
146     void UpdateNormalToPressPaintProperty(const LinearVector<float>& hoverItemHalfSizes,
147         const LinearVector<float>& vectorBlackPointCenterX, const std::pair<float, float>& longPointCenterX);
148     void UpdatePressToNormalPaintProperty(const OffsetF& margin, const LinearVector<float>& normalItemHalfSizes,
149         const LinearVector<float>& vectorBlackPointCenterX, const std::pair<float, float>& longPointCenterX);
150     void UpdateHoverAndPressConversionPaintProperty();
151 
152     // Point dilate ratio
153     void UpdateNormalToHoverPointDilateRatio();
154     void UpdateHoverToNormalPointDilateRatio();
155     void UpdateLongPointDilateRatio();
156 
157     void UpdateAllPointCenterXAnimation(GestureState gestureState, const LinearVector<float>& vectorBlackPointCenterX,
158         const std::pair<float, float>& longPointCenterX);
159 
160     // Touch bottom animation
161     void UpdateTouchBottomAnimation(TouchBottomType touchBottomType, const LinearVector<float>& vectorBlackPointCenterX,
162         const std::pair<float, float>& longPointCenterX, float touchBottomRate);
163 
SetAxis(Axis axis)164     void SetAxis(Axis axis)
165     {
166         axis_ = axis;
167     }
168 
SetUnselectedColor(const Color & unselectedColor)169     void SetUnselectedColor(const Color& unselectedColor)
170     {
171         if (unselectedColor_) {
172             unselectedColor_->Set(unselectedColor);
173             originalUnselectColor_ = unselectedColor_->Get();
174         }
175     }
176 
SetSelectedColor(const Color & selectedColor)177     void SetSelectedColor(const Color& selectedColor)
178     {
179         if (selectedColor_ && isSelectedColorAnimEnd_) {
180             selectedColor_->Set(LinearColor(selectedColor));
181             originalSelectColor_ = selectedColor_->Get().ToColor();
182         }
183         if (touchBottomPointColor_ && isSelectedColorAnimEnd_) {
184             touchBottomPointColor_->Set(LinearColor(selectedColor));
185         }
186     }
187 
SetCurrentIndex(int32_t index)188     void SetCurrentIndex(int32_t index)
189     {
190         currentIndex_ = index;
191     }
192 
SetCurrentIndexActual(int32_t currentIndexActual)193     void SetCurrentIndexActual(int32_t currentIndexActual)
194     {
195         currentIndexActual_ = currentIndexActual;
196     }
197 
SetNormalToHoverIndex(const std::optional<int32_t> & normalToHoverIndex)198     void SetNormalToHoverIndex(const std::optional<int32_t>& normalToHoverIndex)
199     {
200         normalToHoverIndex_ = normalToHoverIndex;
201     }
202 
SetIsFocused(bool isFocused)203     void SetIsFocused(bool isFocused)
204     {
205         if (isFocused_) {
206             isFocused_->Set(isFocused);
207         }
208     }
209 
SetHoverToNormalIndex(const std::optional<int32_t> & hoverToNormalIndex)210     void SetHoverToNormalIndex(const std::optional<int32_t>& hoverToNormalIndex)
211     {
212         hoverToNormalIndex_ = hoverToNormalIndex;
213     }
214 
GetNormalToHoverIndex()215     std::optional<int32_t> GetNormalToHoverIndex()
216     {
217         return normalToHoverIndex_;
218     }
219 
GetHoverToNormalIndex()220     std::optional<int32_t> GetHoverToNormalIndex()
221     {
222         return hoverToNormalIndex_;
223     }
224 
SetIndicatorMask(bool indicatorMask)225     void SetIndicatorMask(bool indicatorMask)
226     {
227         indicatorMask_ = indicatorMask;
228     }
229 
SetOffset(const OffsetF & offset)230     void SetOffset(const OffsetF& offset)
231     {
232         offset_ = offset;
233     }
234 
SetCenterY(const float & centerY)235     void SetCenterY(const float& centerY)
236     {
237         centerY_ = centerY;
238     }
239 
SetIsHover(bool isHover)240     void SetIsHover(bool isHover)
241     {
242         isHover_ = isHover;
243     }
244 
GetIsHover()245     bool GetIsHover() const
246     {
247         return isHover_;
248     }
249 
SetIsPressed(bool isPressed)250     void SetIsPressed(bool isPressed)
251     {
252         isPressed_ = isPressed;
253     }
254 
GetIsPressed()255     bool GetIsPressed() const
256     {
257         return isPressed_;
258     }
259 
SetLongPointIsHover(bool isHover)260     void SetLongPointIsHover(bool isHover)
261     {
262         longPointIsHover_ = isHover;
263     }
264 
GetLongPointIsHover()265     bool GetLongPointIsHover() const
266     {
267         return longPointIsHover_;
268     }
269 
SetItemWidth(const float itemWidth)270     void SetItemWidth(const float itemWidth)
271     {
272         itemWidth_ = itemWidth;
273     }
274 
SetItemHeight(const float itemHeight)275     void SetItemHeight(const float itemHeight)
276     {
277         itemHeight_ = itemHeight;
278     }
279 
SetSelectedItemWidth(const float selectedItemWidth)280     void SetSelectedItemWidth(const float selectedItemWidth)
281     {
282         selectedItemWidth_ = selectedItemWidth;
283     }
284 
SetSelectedItemHeight(const float selectedItemHeight)285     void SetSelectedItemHeight(const float selectedItemHeight)
286     {
287         selectedItemHeight_ = selectedItemHeight;
288     }
289 
SetIsIndicatorCustomSize(bool isCustomSize)290     void SetIsIndicatorCustomSize(bool isCustomSize)
291     {
292         isCustomSize_ = isCustomSize;
293     }
294 
SetAnimationDuration(int32_t duration)295     void SetAnimationDuration(int32_t duration)
296     {
297         animationDuration_ = duration;
298     }
299 
UpdateVectorBlackPointCenterX(const LinearVector<float> & value)300     inline void UpdateVectorBlackPointCenterX(const LinearVector<float>& value)
301     {
302         vectorBlackPointCenterX_->Set(value);
303     }
304 
GetLongPointCenterX()305     std::pair<float, float> GetLongPointCenterX()
306     {
307         return { longPointLeftCenterX_->Get(), longPointRightCenterX_->Get() };
308     }
309 
310     void PlayIndicatorAnimation(const LinearVector<float>& vectorBlackPointCenterX,
311         const std::vector<std::pair<float, float>>& longPointCenterX, GestureState gestureState,
312         TouchBottomTypeLoop touchBottomTypeLoop);
313     virtual void StopAnimation(bool ifImmediately = false);
SetLongPointHeadCurve(RefPtr<Curve> curve,float motionVelocity)314     void SetLongPointHeadCurve(RefPtr<Curve> curve, float motionVelocity)
315     {
316         headCurve_ = curve;
317         motionVelocity_ = motionVelocity;
318     }
319 
SetUserSetSwiperCurve(RefPtr<Curve> userSetSwiperCurve)320     void SetUserSetSwiperCurve(RefPtr<Curve> userSetSwiperCurve)
321     {
322         userSetSwiperCurve_ = userSetSwiperCurve;
323     }
324 
SetIndicatorDotItemSpace(const Dimension & indicatorDotItemSpace)325     void SetIndicatorDotItemSpace(const Dimension& indicatorDotItemSpace)
326     {
327         indicatorDotItemSpace_ = indicatorDotItemSpace;
328     }
329 
GetIndicatorDotItemSpace()330     const Dimension& GetIndicatorDotItemSpace() const
331     {
332         return indicatorDotItemSpace_;
333     }
334 
GetTargetCenter()335     std::pair<float, float> GetTargetCenter() const
336     {
337         return bottomCenterX_;
338     }
339 
GetIsBottomAnimationFinished()340     bool GetIsBottomAnimationFinished() const
341     {
342         return isBottomAnimationFinished_;
343     }
344     void FinishAnimationToTargetImmediately(std::pair<float, float> centerX);
345 protected:
GetSwiperIndicatorTheme()346     static RefPtr<OHOS::Ace::SwiperIndicatorTheme> GetSwiperIndicatorTheme()
347     {
348         auto pipelineContext = PipelineBase::GetCurrentContext();
349         CHECK_NULL_RETURN(pipelineContext, nullptr);
350         auto swiperTheme = pipelineContext->GetTheme<SwiperIndicatorTheme>();
351         CHECK_NULL_RETURN(swiperTheme, nullptr);
352         return swiperTheme;
353     }
354 
355     void PlayBlackPointsAnimation(const LinearVector<float>& vectorBlackPointCenterX);
356     void PlayLongPointAnimation(const std::vector<std::pair<float, float>>& longPointCenterX, GestureState gestureState,
357         TouchBottomTypeLoop touchBottomTypeLoop, const LinearVector<float>& vectorBlackPointCenterX,
358         bool isNormal = true);
359     void PlayTouchBottomAnimation(const std::vector<std::pair<float, float>>& longPointCenterX,
360         TouchBottomTypeLoop touchBottomTypeLoop, const LinearVector<float>& vectorBlackPointCenterX);
361     void PlayOpacityAnimation();
362     std::pair<float, float> GetTouchBottomCenterX(ContentProperty& contentProperty);
363     int32_t GetLoopTranslateDuration() const;
364     int32_t GetLoopOpacityDuration() const;
365     float CalculateMinimumAmplitudeRatio(
366         const std::vector<std::pair<float, float>>& longPointCenterX, GestureState gestureState) const;
367     RefPtr<InterpolatingSpring> GetTailCurve();
368     AnimationOption CreateTailOption(
369         const std::vector<std::pair<float, float>>& longPointCenterX, GestureState gestureState, bool isNormal);
370     std::tuple<float, float, float, float> CalcAndAdjustIndicatorPaintRect(
371         const ContentProperty& contentProperty, float& rectWidth, float& rectHeight);
372 
373     RefPtr<AnimatablePropertyColor> backgroundColor_;
374     RefPtr<AnimatablePropertyVectorFloat> vectorBlackPointCenterX_;
375     RefPtr<AnimatablePropertyFloat> longPointLeftCenterX_;
376     RefPtr<AnimatablePropertyFloat> longPointRightCenterX_;
377     RefPtr<AnimatablePropertyFloat> normalToHoverPointDilateRatio_;
378     RefPtr<AnimatablePropertyFloat> hoverToNormalPointDilateRatio_;
379     RefPtr<AnimatablePropertyFloat> longPointDilateRatio_;
380     RefPtr<AnimatablePropertyFloat> indicatorPadding_;
381     RefPtr<AnimatablePropertyOffsetF> indicatorMargin_;
382     RefPtr<AnimatablePropertyVectorFloat> itemHalfSizes_;
383     RefPtr<AnimatablePropertyFloat> backgroundWidthDilateRatio_;
384     RefPtr<AnimatablePropertyFloat> backgroundHeightDilateRatio_;
385     RefPtr<PropertyBool> isFocused_;
386 
387     RefPtr<Curve> headCurve_;
388     RefPtr<Curve> userSetSwiperCurve_;
389     float motionVelocity_ = 0;
390 
391     float centerY_ = 0;
392     Axis axis_ = Axis::HORIZONTAL;
393     RefPtr<PropertyColor> unselectedColor_;
394     RefPtr<AnimatablePropertyColor> selectedColor_;
395     bool isSelectedColorAnimEnd_ = true;
396     RefPtr<AnimatablePropertyColor> touchBottomPointColor_;
397     bool isTouchBottomLoop_ = false;
398     bool ifNeedFinishCallback_ = false;
399     bool isBottomAnimationFinished_ = true;
400     std::pair<float, float> bottomCenterX_;
401     TouchBottomAnimationStage animationState_ = TouchBottomAnimationStage::STAGE_NONE;
402     std::optional<int32_t> normalToHoverIndex_ = std::nullopt;
403     std::optional<int32_t> hoverToNormalIndex_ = std::nullopt;
404     bool longPointIsHover_ = false;
405     bool isHover_ = false;
406     bool isPressed_ = false;
407     bool longPointLeftAnimEnd_ = true;
408     bool longPointRightAnimEnd_ = true;
409 
410     bool indicatorMask_ = false;
411     bool isCustomSize_ = false;
412     int32_t currentIndex_ = 0;
413     int32_t currentIndexActual_ = 0;
414     int32_t animationDuration_ = 0;
415     OffsetF offset_;
416     float itemWidth_ = 0.0f;
417     float itemHeight_ = 0.0f;
418     float selectedItemWidth_ = 0.0f;
419     float selectedItemHeight_ = 0.0f;
420     Color originalUnselectColor_;
421     Color originalSelectColor_;
422     Dimension paddingSide_;
423     Dimension indicatorDotItemSpace_ = 8.0_vp;
424     float scaleIndicator_ = 1.33f;
425     TouchBottomType touchBottomType_ = TouchBottomType::NONE;
426     ACE_DISALLOW_COPY_AND_MOVE(DotIndicatorModifier);
427 };
428 } // namespace OHOS::Ace::NG
429 
430 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SWIPER_INDICATOR_SWIPER_INDICATOR_MODIFIER_H
431