• 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, 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