1 /*
2  * Copyright (c) 2022-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_SWIPER_INDICATOR_DOT_INDICATOR_PAINT_METHOD_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_SWIPER_INDICATOR_DOT_INDICATOR_PAINT_METHOD_H
18 
19 #include "core/components/common/properties/swiper_indicator.h"
20 #include "core/components_ng/pattern/swiper_indicator/dot_indicator/dot_indicator_modifier.h"
21 #include "core/components_ng/pattern/swiper_indicator/dot_indicator/dot_indicator_paint_property.h"
22 #include "core/components_ng/render/canvas_image.h"
23 #include "core/components_ng/render/node_paint_method.h"
24 #include "core/components_ng/render/paint_wrapper.h"
25 #include "core/components_ng/render/render_context.h"
26 
27 namespace OHOS::Ace::NG {
28 enum class PointAnimationStage { STATE_SHRINKT_TO_BLACK_POINT, STATE_EXPAND_TO_LONG_POINT };
29 
30 class ACE_EXPORT DotIndicatorPaintMethod : public NodePaintMethod {
DECLARE_ACE_TYPE(DotIndicatorPaintMethod,NodePaintMethod)31     DECLARE_ACE_TYPE(DotIndicatorPaintMethod, NodePaintMethod)
32 public:
33     explicit DotIndicatorPaintMethod(const RefPtr<DotIndicatorModifier>& dotIndicatorModifier)
34         : dotIndicatorModifier_(dotIndicatorModifier)
35     {}
36     DotIndicatorPaintMethod() = default;
37     ~DotIndicatorPaintMethod() override = default;
38 
GetContentModifier(PaintWrapper * paintWrapper)39     RefPtr<Modifier> GetContentModifier(PaintWrapper* paintWrapper) override
40     {
41         CHECK_NULL_RETURN(dotIndicatorModifier_, nullptr);
42         return dotIndicatorModifier_;
43     }
44 
45     void UpdateContentModifier(PaintWrapper* paintWrapper) override;
46     virtual void PaintNormalIndicator(const PaintWrapper* paintWrapper);
47     void PaintHoverIndicator(const PaintWrapper* paintWrapper);
48     void PaintHoverIndicator(LinearVector<float>& itemHalfSizes, const Dimension paddingSide);
49     void PaintPressIndicator(const PaintWrapper* paintWrapper);
50     void CalculateNormalMargin(
51         const LinearVector<float>& itemHalfSizes, const SizeF& frameSize, const int32_t displayCount);
52     virtual std::pair<float, float> CalculatePointCenterX(
53         const LinearVector<float>& itemHalfSizes, float margin, float padding, float space, int32_t index);
54     void CalculateHoverIndex(const LinearVector<float>& itemHalfSizes);
55     bool isHoverPoint(const PointF& hoverPoint, const OffsetF& leftCenter,
56         const OffsetF& rightCenter, const LinearVector<float>& itemHalfSizes);
57 
58     void UpdateBackground(const PaintWrapper* paintWrapper);
SetCurrentIndex(int32_t index)59     void SetCurrentIndex(int32_t index)
60     {
61         currentIndex_ = index;
62     }
63 
SetItemCount(int32_t itemCount)64     void SetItemCount(int32_t itemCount)
65     {
66         itemCount_ = itemCount;
67     }
68 
SetDisplayCount(int32_t displayCount)69     void SetDisplayCount(int32_t displayCount)
70     {
71         displayCount_ = displayCount;
72     }
73 
SetAxis(Axis axis)74     void SetAxis(Axis axis)
75     {
76         axis_ = axis;
77     }
78 
GetAxis()79     Axis GetAxis() const
80     {
81         return axis_;
82     }
83 
SetIsLoop(bool isLoop)84     void SetIsLoop(bool isLoop)
85     {
86         isLoop_ = isLoop;
87     }
88 
SetIsHover(bool isHover)89     void SetIsHover(bool isHover)
90     {
91         isHover_ = isHover;
92     }
93 
SetIsPressed(bool isPressed)94     void SetIsPressed(bool isPressed)
95     {
96         isPressed_ = isPressed;
97     }
98 
SetHoverPoint(const PointF & hoverPoint)99     void SetHoverPoint(const PointF& hoverPoint)
100     {
101         hoverPoint_ = hoverPoint;
102     }
103 
SetTurnPageRate(float turnPageRate)104     void SetTurnPageRate(float turnPageRate)
105     {
106         turnPageRate_ = turnPageRate;
107     }
108 
SetGestureState(GestureState gestureState)109     void SetGestureState(GestureState gestureState)
110     {
111         gestureState_ = gestureState;
112     }
113 
SetTouchBottomTypeLoop(TouchBottomTypeLoop touchBottomTypeLoop)114     void SetTouchBottomTypeLoop(TouchBottomTypeLoop touchBottomTypeLoop)
115     {
116         touchBottomTypeLoop_ = touchBottomTypeLoop;
117     }
118 
SetTouchBottomRate(float touchBottomRate)119     void SetTouchBottomRate(float touchBottomRate)
120     {
121         touchBottomRate_ = touchBottomRate;
122     }
123 
SetMouseClickIndex(const std::optional<int32_t> & mouseClickIndex)124     void SetMouseClickIndex(const std::optional<int32_t>& mouseClickIndex)
125     {
126         mouseClickIndex_ = mouseClickIndex;
127     }
128 
SetIsTouchBottom(TouchBottomType touchBottomType)129     void SetIsTouchBottom(TouchBottomType touchBottomType)
130     {
131         touchBottomType_ = touchBottomType;
132     }
133 
SetPointAnimationStage(PointAnimationStage pointAnimationStage)134     void SetPointAnimationStage(PointAnimationStage pointAnimationStage)
135     {
136         pointAnimationStage_ = pointAnimationStage;
137     }
138 
SetCurrentIndexActual(int32_t currentIndexActual)139     void SetCurrentIndexActual(int32_t currentIndexActual)
140     {
141         currentIndexActual_ = currentIndexActual;
142     }
143 
SetNextValidIndex(int32_t nextValidIndex)144     void SetNextValidIndex(int32_t nextValidIndex)
145     {
146         nextValidIndex_ = nextValidIndex;
147     }
148 
SetHorizontalAndRightToLeft(TextDirection textDirection)149     void SetHorizontalAndRightToLeft(TextDirection textDirection)
150     {
151         isHorizontalAndRightToLeft_ = axis_ == Axis::HORIZONTAL && textDirection == TextDirection::RTL;
152     }
153 protected:
154     struct StarAndEndPointCenter {
155         float startLongPointLeftCenterX = 0.0f;
156         float endLongPointLeftCenterX = 0.0f;
157         float startLongPointRightCenterX = 0.0f;
158         float endLongPointRightCenterX = 0.0f;
159     };
160     virtual std::pair<float, float> CalculatePointCenterX(const StarAndEndPointCenter& starAndEndPointCenter,
161         const LinearVector<float>& startVectorBlackPointCenterX,
162         const LinearVector<float>& endVectorBlackPointCenterX);
163     virtual std::tuple<std::pair<float, float>, LinearVector<float>> CalculateLongPointCenterX(
164         const PaintWrapper* paintWrapper);
165     virtual std::pair<float, float> ForwardCalculation(
166         const LinearVector<float>& itemHalfSizes, float startCenterX, float endCenterX, float space, int32_t index);
167     std::pair<float, float> BackwardCalculation(
168         const LinearVector<float>& itemHalfSizes, float startCenterX, float endCenterX, float space, int32_t index);
GetSwiperIndicatorTheme()169     static RefPtr<OHOS::Ace::SwiperIndicatorTheme> GetSwiperIndicatorTheme()
170     {
171         auto pipelineContext = PipelineBase::GetCurrentContext();
172         CHECK_NULL_RETURN(pipelineContext, nullptr);
173         auto swiperTheme = pipelineContext->GetTheme<SwiperIndicatorTheme>();
174         CHECK_NULL_RETURN(swiperTheme, nullptr);
175         return swiperTheme;
176     }
177     virtual void UpdateNormalIndicator(LinearVector<float>& itemHalfSizes, const PaintWrapper* paintWrapper);
178     std::pair<int32_t, int32_t> GetStartAndEndIndex(int32_t index);
179     void GetLongPointAnimationStateSecondCenter(
180         const PaintWrapper* paintWrapper, std::vector<std::pair<float, float>>& pointCenterX);
181     std::tuple<float, float, float> GetMoveRate();
182     void AdjustPointCenterXForTouchBottom(StarAndEndPointCenter& pointCenter,
183         LinearVector<float>& endVectorBlackPointCenterX, int32_t startCurrentIndex, int32_t endCurrentIndex,
184         float selectedItemWidth, int32_t index);
185     std::pair<int32_t, int32_t> GetIndex(int32_t index);
186     std::pair<int32_t, int32_t> GetIndexOnRTL(int32_t index);
187 
188     RefPtr<DotIndicatorModifier> dotIndicatorModifier_;
189     PointF hoverPoint_;
190     std::optional<int32_t> hoverIndex_ = std::nullopt;
191     std::optional<int32_t> mouseClickIndex_ = std::nullopt;
192     Axis axis_ = Axis::HORIZONTAL;
193     int32_t currentIndex_ = 0;
194     int32_t currentIndexActual_ = 0;
195     int32_t nextValidIndex_ = 0;
196     int32_t itemCount_ = 0;
197     int32_t displayCount_ = 1;
198     float turnPageRate_ = 0.0f;
199     GestureState gestureState_ = GestureState::GESTURE_STATE_INIT;
200     TouchBottomTypeLoop touchBottomTypeLoop_ = TouchBottomTypeLoop::TOUCH_BOTTOM_TYPE_LOOP_NONE;
201     PointAnimationStage pointAnimationStage_ = PointAnimationStage::STATE_SHRINKT_TO_BLACK_POINT;
202     float touchBottomRate_ = 0.0f;
203     bool isHorizontalAndRightToLeft_ = false;
204     bool isLoop_ = true;
205     bool isHover_ = false;
206     bool isPressed_ = false;
207     bool longPointIsHover_ = false;
208     bool IsCustomSizeValue_ = false;
209     // Animatable properties for updating Modifier
210     LinearVector<float> vectorBlackPointCenterX_ = {};
211     std::pair<float, float> longPointCenterX_ = { 0, 0 };
212     OffsetF normalMargin_ = { 0, 0 };
213     float centerY_ = 0.0f;
214     TouchBottomType touchBottomType_ = TouchBottomType::NONE;
215     ACE_DISALLOW_COPY_AND_MOVE(DotIndicatorPaintMethod);
216 };
217 } // namespace OHOS::Ace::NG
218 
219 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERN_SWIPER_INDICATOR_DOT_INDICATOR_PAINT_METHOD_H