• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "core/components_ng/pattern/swiper_indicator/dot_indicator/dot_indicator_paint_method.h"
17 
18 #include <valarray>
19 
20 #include "core/components/common/layout/constants.h"
21 #include "core/components/common/properties/color.h"
22 #include "core/components/swiper/render_swiper.h"
23 #include "core/components_ng/pattern/swiper_indicator/indicator_common/swiper_indicator_utils.h"
24 #include "core/components_ng/pattern/swiper/swiper_layout_property.h"
25 #include "core/components_ng/render/paint_property.h"
26 #include "core/pipeline/pipeline_base.h"
27 namespace OHOS::Ace::NG {
28 namespace {
29 // for indicator
30 constexpr Dimension INDICATOR_ITEM_SPACE = 8.0_vp;
31 constexpr Dimension INDICATOR_PADDING_DEFAULT = 12.0_vp;
32 constexpr Dimension INDICATOR_PADDING_HOVER = 12.0_vp;
33 constexpr float INDICATOR_ZOOM_IN_SCALE = 1.33f;
34 
35 constexpr float BLACK_POINT_CENTER_BEZIER_CURVE_VELOCITY = 0.4f;
36 constexpr float LONG_POINT_LEFT_CENTER_BEZIER_CURVE_VELOCITY = 0.2f;
37 constexpr float LONG_POINT_RIGHT_CENTER_BEZIER_CURVE_VELOCITY = 1.0f;
38 constexpr float CENTER_BEZIER_CURVE_MASS = 0.0f;
39 constexpr float CENTER_BEZIER_CURVE_STIFFNESS = 1.0f;
40 constexpr float CENTER_BEZIER_CURVE_DAMPING = 1.0f;
41 constexpr uint32_t ITEM_HALF_WIDTH = 0;
42 constexpr uint32_t ITEM_HALF_HEIGHT = 1;
43 constexpr uint32_t SELECTED_ITEM_HALF_WIDTH = 2;
44 constexpr uint32_t SELECTED_ITEM_HALF_HEIGHT = 3;
45 constexpr float TOUCH_BOTTOM_BACKGROUND_WIDTH_MULTIPLE = 1.225f;
46 constexpr float TOUCH_BOTTOM_DOT_WIDTH_MULTIPLE = 0.0125f;
47 
48 constexpr int TWOFOLD = 2;
49 } // namespace
50 
UpdateContentModifier(PaintWrapper * paintWrapper)51 void DotIndicatorPaintMethod::UpdateContentModifier(PaintWrapper* paintWrapper)
52 {
53     CHECK_NULL_VOID(dotIndicatorModifier_);
54     CHECK_NULL_VOID(paintWrapper);
55 
56     auto pipelineContext = PipelineBase::GetCurrentContext();
57     CHECK_NULL_VOID(pipelineContext);
58     auto swiperTheme = pipelineContext->GetTheme<SwiperIndicatorTheme>();
59     CHECK_NULL_VOID(swiperTheme);
60 
61     const auto& geometryNode = paintWrapper->GetGeometryNode();
62     CHECK_NULL_VOID(geometryNode);
63 
64     auto paintProperty = DynamicCast<DotIndicatorPaintProperty>(paintWrapper->GetPaintProperty());
65     IsCustomSizeValue_ = paintProperty->GetIsCustomSizeValue(false);
66     dotIndicatorModifier_->SetAxis(axis_);
67     dotIndicatorModifier_->SetCurrentIndex(currentIndex_);
68     dotIndicatorModifier_->SetUnselectedColor(paintProperty->GetColorValue(swiperTheme->GetColor()));
69     dotIndicatorModifier_->SetSelectedColor(paintProperty->GetSelectedColorValue(swiperTheme->GetSelectedColor()));
70     dotIndicatorModifier_->SetIndicatorMask(paintProperty->GetIndicatorMaskValue(false));
71     dotIndicatorModifier_->SetIsIndicatorCustomSize(IsCustomSizeValue_);
72     dotIndicatorModifier_->SetOffset(geometryNode->GetContentOffset());
73     SizeF contentSize = geometryNode->GetFrameSize();
74     centerY_ = (axis_ == Axis::HORIZONTAL ? contentSize.Height() : contentSize.Width()) * 0.5;
75     dotIndicatorModifier_->SetCenterY(centerY_);
76     if (touchBottomType_ != TouchBottomType::NONE) {
77         if (!dotIndicatorModifier_->GetIsPressed()) {
78             PaintPressIndicator(paintWrapper);
79             dotIndicatorModifier_->SetIsPressed(true);
80         }
81         UpdateBackground(paintWrapper);
82     } else if (isPressed_) {
83         PaintPressIndicator(paintWrapper);
84         dotIndicatorModifier_->SetIsPressed(true);
85     } else if (isHover_) {
86         PaintHoverIndicator(paintWrapper);
87         dotIndicatorModifier_->SetIsHover(true);
88     } else {
89         PaintNormalIndicator(paintWrapper);
90         dotIndicatorModifier_->SetIsHover(false);
91         dotIndicatorModifier_->SetIsPressed(false);
92     }
93 }
94 
PaintNormalIndicator(const PaintWrapper * paintWrapper)95 void DotIndicatorPaintMethod::PaintNormalIndicator(const PaintWrapper* paintWrapper)
96 {
97     CHECK_NULL_VOID(paintWrapper);
98     const auto& geometryNode = paintWrapper->GetGeometryNode();
99     CHECK_NULL_VOID(geometryNode);
100     auto paintProperty = DynamicCast<DotIndicatorPaintProperty>(paintWrapper->GetPaintProperty());
101     CHECK_NULL_VOID(paintProperty);
102     auto swiperTheme = GetSwiperIndicatorTheme();
103     CHECK_NULL_VOID(swiperTheme);
104     SizeF frameSize = geometryNode->GetFrameSize();
105     // diameter calculation
106     auto itemWidth = static_cast<float>(paintProperty->GetItemWidthValue(swiperTheme->GetSize()).ConvertToPx());
107     auto itemHeight = static_cast<float>(paintProperty->GetItemHeightValue(swiperTheme->GetSize()).ConvertToPx());
108     auto selectedItemWidth = static_cast<float>(
109         paintProperty->GetSelectedItemWidthValue(swiperTheme->GetSize()).ConvertToPx());
110     auto selectedItemHeight = static_cast<float>(
111         paintProperty->GetSelectedItemHeightValue(swiperTheme->GetSize()).ConvertToPx());
112     // use radius calculation
113     LinearVector<float> itemHalfSizes;
114     itemHalfSizes.emplace_back(itemWidth * 0.5);
115     itemHalfSizes.emplace_back(itemHeight * 0.5);
116     itemHalfSizes.emplace_back(selectedItemWidth * 0.5);
117     itemHalfSizes.emplace_back(selectedItemHeight * 0.5);
118     CalculateNormalMargin(itemHalfSizes, frameSize);
119     CalculatePointCenterX(
120         itemHalfSizes, normalMargin_.GetX(), static_cast<float>(INDICATOR_PADDING_DEFAULT.ConvertToPx()),
121         static_cast<float>(INDICATOR_ITEM_SPACE.ConvertToPx()), currentIndex_);
122 
123     if (dotIndicatorModifier_->GetIsHover()) {
124         dotIndicatorModifier_->UpdateHoverToNormalPaintProperty(
125             normalMargin_, itemHalfSizes, vectorBlackPointCenterX_, longPointCenterX_);
126     } else if (dotIndicatorModifier_->GetIsPressed()) {
127         dotIndicatorModifier_->UpdatePressToNormalPaintProperty(
128             normalMargin_, itemHalfSizes, vectorBlackPointCenterX_, longPointCenterX_);
129     } else {
130         dotIndicatorModifier_->UpdateNormalPaintProperty(
131             normalMargin_, itemHalfSizes, vectorBlackPointCenterX_, longPointCenterX_);
132     }
133 }
134 
PaintHoverIndicator(const PaintWrapper * paintWrapper)135 void DotIndicatorPaintMethod::PaintHoverIndicator(const PaintWrapper* paintWrapper)
136 {
137     CHECK_NULL_VOID(paintWrapper);
138     auto paintProperty = DynamicCast<DotIndicatorPaintProperty>(paintWrapper->GetPaintProperty());
139     CHECK_NULL_VOID(paintProperty);
140     auto swiperTheme = GetSwiperIndicatorTheme();
141     CHECK_NULL_VOID(swiperTheme);
142     // diameter calculation
143     auto itemWidth = static_cast<float>(paintProperty->GetItemWidthValue(swiperTheme->GetSize()).ConvertToPx());
144     auto itemHeight = static_cast<float>(paintProperty->GetItemHeightValue(swiperTheme->GetSize()).ConvertToPx());
145     auto selectedItemWidth = static_cast<float>(
146         paintProperty->GetSelectedItemWidthValue(swiperTheme->GetSize()).ConvertToPx());
147     auto selectedItemHeight = static_cast<float>(
148         paintProperty->GetSelectedItemHeightValue(swiperTheme->GetSize()).ConvertToPx());
149     // use radius calculation
150     LinearVector<float> itemHalfSizes;
151     itemHalfSizes.emplace_back(itemWidth * 0.5 * INDICATOR_ZOOM_IN_SCALE);
152     itemHalfSizes.emplace_back(itemHeight * 0.5 * INDICATOR_ZOOM_IN_SCALE);
153     itemHalfSizes.emplace_back(selectedItemWidth * 0.5 * INDICATOR_ZOOM_IN_SCALE);
154     itemHalfSizes.emplace_back(selectedItemHeight * 0.5 * INDICATOR_ZOOM_IN_SCALE);
155     CalculatePointCenterX(itemHalfSizes, 0, static_cast<float>(INDICATOR_PADDING_HOVER.ConvertToPx()),
156         static_cast<float>(INDICATOR_ITEM_SPACE.ConvertToPx()), currentIndex_);
157 
158     if (dotIndicatorModifier_->GetIsPressed()) {
159         dotIndicatorModifier_->SetIsPressed(false);
160         dotIndicatorModifier_->UpdateHoverAndPressConversionPaintProperty();
161     } else if (dotIndicatorModifier_->GetIsHover()) {
162         dotIndicatorModifier_->UpdateHoverPaintProperty(itemHalfSizes, vectorBlackPointCenterX_, longPointCenterX_);
163     } else {
164         dotIndicatorModifier_->UpdateNormalToHoverPaintProperty(
165             itemHalfSizes, vectorBlackPointCenterX_, longPointCenterX_);
166     }
167 
168     CalculateHoverIndex(itemHalfSizes);
169     if (dotIndicatorModifier_->GetNormalToHoverIndex() != hoverIndex_) {
170         dotIndicatorModifier_->SetHoverToNormalIndex(dotIndicatorModifier_->GetNormalToHoverIndex());
171         dotIndicatorModifier_->UpdateHoverToNormalPointDilateRatio();
172         dotIndicatorModifier_->SetNormalToHoverIndex(hoverIndex_);
173         dotIndicatorModifier_->UpdateNormalToHoverPointDilateRatio();
174     }
175     if (mouseClickIndex_ && mouseClickIndex_ != currentIndex_) {
176         if (currentIndex_ == itemCount_ - displayCount_ && !isLoop_ &&
177             mouseClickIndex_ > currentIndex_ && mouseClickIndex_ < itemCount_) {
178             CalculatePointCenterX(itemHalfSizes, 0, static_cast<float>(INDICATOR_PADDING_HOVER.ConvertToPx()),
179                 static_cast<float>(INDICATOR_ITEM_SPACE.ConvertToPx()), currentIndex_);
180         } else {
181             CalculatePointCenterX(itemHalfSizes, 0, static_cast<float>(INDICATOR_PADDING_HOVER.ConvertToPx()),
182                 static_cast<float>(INDICATOR_ITEM_SPACE.ConvertToPx()), mouseClickIndex_.value());
183         }
184         dotIndicatorModifier_->UpdateAllPointCenterXAnimation(
185             mouseClickIndex_ > currentIndex_, vectorBlackPointCenterX_, longPointCenterX_);
186         longPointIsHover_ = true;
187         mouseClickIndex_ = std::nullopt;
188     }
189     if (dotIndicatorModifier_->GetLongPointIsHover() != longPointIsHover_) {
190         dotIndicatorModifier_->SetLongPointIsHover(longPointIsHover_);
191         dotIndicatorModifier_->UpdateLongPointDilateRatio();
192     }
193 }
194 
PaintPressIndicator(const PaintWrapper * paintWrapper)195 void DotIndicatorPaintMethod::PaintPressIndicator(const PaintWrapper* paintWrapper)
196 {
197     CHECK_NULL_VOID(paintWrapper);
198     auto paintProperty = DynamicCast<DotIndicatorPaintProperty>(paintWrapper->GetPaintProperty());
199     CHECK_NULL_VOID(paintProperty);
200     auto swiperTheme = GetSwiperIndicatorTheme();
201     CHECK_NULL_VOID(swiperTheme);
202     // diameter calculation
203     auto itemWidth = static_cast<float>(paintProperty->GetItemWidthValue(swiperTheme->GetSize()).ConvertToPx());
204     auto itemHeight = static_cast<float>(paintProperty->GetItemHeightValue(swiperTheme->GetSize()).ConvertToPx());
205     auto selectedItemWidth = static_cast<float>(
206         paintProperty->GetSelectedItemWidthValue(swiperTheme->GetSize()).ConvertToPx());
207     auto selectedItemHeight = static_cast<float>(
208         paintProperty->GetSelectedItemHeightValue(swiperTheme->GetSize()).ConvertToPx());
209     // use radius calculation
210     auto itemHalfWidth = itemWidth * 0.5 * INDICATOR_ZOOM_IN_SCALE;
211     auto itemHalfHeight = itemHeight * 0.5 * INDICATOR_ZOOM_IN_SCALE;
212     auto selectedItemHalfWidth = selectedItemWidth * 0.5 * INDICATOR_ZOOM_IN_SCALE;
213     auto selectedItemHalfHeight = selectedItemHeight * 0.5 * INDICATOR_ZOOM_IN_SCALE;
214     LinearVector<float> itemHalfSizes;
215     itemHalfSizes.emplace_back(itemHalfWidth);
216     itemHalfSizes.emplace_back(itemHalfHeight);
217     itemHalfSizes.emplace_back(selectedItemHalfWidth);
218     itemHalfSizes.emplace_back(selectedItemHalfHeight);
219     CalculatePointCenterX(itemHalfSizes, 0, static_cast<float>(INDICATOR_PADDING_HOVER.ConvertToPx()),
220         static_cast<float>(INDICATOR_ITEM_SPACE.ConvertToPx()), currentIndex_);
221     if (dotIndicatorModifier_->GetIsPressed()) {
222         dotIndicatorModifier_->UpdatePressPaintProperty(itemHalfSizes, vectorBlackPointCenterX_, longPointCenterX_);
223     } else if (dotIndicatorModifier_->GetIsHover()) {
224         dotIndicatorModifier_->SetIsPressed(true);
225         dotIndicatorModifier_->UpdateHoverAndPressConversionPaintProperty();
226     } else {
227         dotIndicatorModifier_->UpdateNormalToPressPaintProperty(
228             itemHalfSizes, vectorBlackPointCenterX_, longPointCenterX_);
229     }
230 }
231 
CalculateNormalMargin(const LinearVector<float> & itemHalfSizes,const SizeF & frameSize)232 void DotIndicatorPaintMethod::CalculateNormalMargin(const LinearVector<float>& itemHalfSizes, const SizeF& frameSize)
233 {
234     // diameter calculation
235     auto itemWidth = itemHalfSizes[ITEM_HALF_WIDTH] * 2;
236     auto itemHeight = itemHalfSizes[ITEM_HALF_HEIGHT] * 2;
237     auto selectedItemWidth = itemHalfSizes[SELECTED_ITEM_HALF_WIDTH] * 2;
238     auto selectedItemHeight = itemHalfSizes[SELECTED_ITEM_HALF_HEIGHT] * 2;
239     auto allPointDiameterSum = itemWidth * static_cast<float>(itemCount_ + 1);
240     if (IsCustomSizeValue_) {
241         allPointDiameterSum = itemWidth * static_cast<float>(itemCount_ - 1) + selectedItemWidth;
242     }
243     auto allPointSpaceSum = static_cast<float>(INDICATOR_ITEM_SPACE.ConvertToPx()) * (itemCount_ - 1);
244     auto indicatorPadding = static_cast<float>(INDICATOR_PADDING_DEFAULT.ConvertToPx());
245     auto contentWidth = indicatorPadding + allPointDiameterSum + allPointSpaceSum + indicatorPadding;
246     auto contentHeight = indicatorPadding + itemHeight + indicatorPadding;
247     if (selectedItemHeight > itemHeight) {
248         contentHeight = indicatorPadding + selectedItemHeight + indicatorPadding;
249     }
250     float marginX = ((axis_ == Axis::HORIZONTAL ? frameSize.Width() : frameSize.Height()) - contentWidth) * 0.5;
251     float marginY = ((axis_ == Axis::HORIZONTAL ? frameSize.Height() : frameSize.Width()) - contentHeight) * 0.5;
252     normalMargin_.SetX(marginX);
253     normalMargin_.SetY(marginY);
254 }
255 
CalculatePointCenterX(const LinearVector<float> & itemHalfSizes,float margin,float padding,float space,int32_t index)256 void DotIndicatorPaintMethod::CalculatePointCenterX(
257     const LinearVector<float>& itemHalfSizes, float margin, float padding, float space, int32_t index)
258 {
259     float startCenterX = margin + padding;
260     float endCenterX = margin + padding;
261     if (Positive(turnPageRate_)) {
262         auto itemWidth = itemHalfSizes[ITEM_HALF_WIDTH] * TWOFOLD;
263         auto selectedItemWidth = itemHalfSizes[SELECTED_ITEM_HALF_WIDTH] * TWOFOLD;
264         float allPointDiameterSum = itemWidth * static_cast<float>(itemCount_ + 1);
265         if (IsCustomSizeValue_) {
266             allPointDiameterSum = itemWidth * static_cast<float>(itemCount_ - 1) + selectedItemWidth;
267         }
268         auto allPointSpaceSum = static_cast<float>(INDICATOR_ITEM_SPACE.ConvertToPx() * (itemCount_ - 1));
269         float rectWidth = padding + allPointDiameterSum + allPointSpaceSum + padding;
270         startCenterX = rectWidth - startCenterX;
271         endCenterX = rectWidth - endCenterX;
272         BackwardCalculation(itemHalfSizes, startCenterX, endCenterX, space, index);
273         return;
274     }
275     ForwardCalculation(itemHalfSizes, startCenterX, endCenterX, space, index);
276 }
277 
CalculatePointCenterX(const StarAndEndPointCenter & starAndEndPointCenter,const LinearVector<float> & startVectorBlackPointCenterX,const LinearVector<float> & endVectorBlackPointCenterX)278 void DotIndicatorPaintMethod::CalculatePointCenterX(const StarAndEndPointCenter& starAndEndPointCenter,
279     const LinearVector<float>& startVectorBlackPointCenterX, const LinearVector<float>& endVectorBlackPointCenterX)
280 {
281     float blackPointCenterMoveRate = CubicCurve(BLACK_POINT_CENTER_BEZIER_CURVE_VELOCITY, CENTER_BEZIER_CURVE_MASS,
282         CENTER_BEZIER_CURVE_STIFFNESS, CENTER_BEZIER_CURVE_DAMPING).MoveInternal(std::abs(turnPageRate_));
283     float longPointLeftCenterMoveRate = CubicCurve(turnPageRate_ > 0 ?
284         LONG_POINT_LEFT_CENTER_BEZIER_CURVE_VELOCITY : LONG_POINT_RIGHT_CENTER_BEZIER_CURVE_VELOCITY,
285         CENTER_BEZIER_CURVE_MASS, CENTER_BEZIER_CURVE_STIFFNESS,
286         CENTER_BEZIER_CURVE_DAMPING).MoveInternal(std::abs(turnPageRate_));
287     float longPointRightCenterMoveRate = CubicCurve(turnPageRate_ > 0 ?
288         LONG_POINT_RIGHT_CENTER_BEZIER_CURVE_VELOCITY : LONG_POINT_LEFT_CENTER_BEZIER_CURVE_VELOCITY,
289         CENTER_BEZIER_CURVE_MASS, CENTER_BEZIER_CURVE_STIFFNESS,
290         CENTER_BEZIER_CURVE_DAMPING).MoveInternal(std::abs(turnPageRate_));
291     vectorBlackPointCenterX_.resize(itemCount_);
292     for (int32_t i = 0; i < itemCount_; ++i) {
293         vectorBlackPointCenterX_[i] = startVectorBlackPointCenterX[i] +
294         (endVectorBlackPointCenterX[i] - startVectorBlackPointCenterX[i]) * blackPointCenterMoveRate;
295     }
296     longPointCenterX_.first = starAndEndPointCenter.startLongPointLeftCenterX +
297         (starAndEndPointCenter.endLongPointLeftCenterX - starAndEndPointCenter.startLongPointLeftCenterX) *
298         longPointLeftCenterMoveRate;
299     longPointCenterX_.second = starAndEndPointCenter.startLongPointRightCenterX +
300         (starAndEndPointCenter.endLongPointRightCenterX - starAndEndPointCenter.startLongPointRightCenterX) *
301         longPointRightCenterMoveRate;
302 }
303 
CalculateHoverIndex(const LinearVector<float> & itemHalfSizes)304 void DotIndicatorPaintMethod::CalculateHoverIndex(const LinearVector<float>& itemHalfSizes)
305 {
306     if (!isHover_) {
307         hoverIndex_ = std::nullopt;
308         longPointIsHover_ = false;
309         return;
310     }
311     for (size_t i = 0; i < vectorBlackPointCenterX_.size(); ++i) {
312         OffsetF center = { vectorBlackPointCenterX_[i], centerY_ };
313         if (isHoverPoint(hoverPoint_, center, center, itemHalfSizes)) {
314             hoverIndex_ = i;
315             break;
316         }
317     }
318 
319     OffsetF leftCenter = { longPointCenterX_.first, centerY_ };
320     OffsetF rightCenter = { longPointCenterX_.second, centerY_ };
321     longPointIsHover_ = isHoverPoint(hoverPoint_, leftCenter, rightCenter, itemHalfSizes);
322 }
323 
isHoverPoint(const PointF & hoverPoint,const OffsetF & leftCenter,const OffsetF & rightCenter,const LinearVector<float> & itemHalfSizes)324 bool DotIndicatorPaintMethod::isHoverPoint(
325     const PointF& hoverPoint, const OffsetF& leftCenter,
326     const OffsetF& rightCenter, const LinearVector<float>& itemHalfSizes)
327 {
328     float tempLeftCenterX = axis_ == Axis::HORIZONTAL ? leftCenter.GetX() : leftCenter.GetY();
329     float tempLeftCenterY = axis_ == Axis::HORIZONTAL ? leftCenter.GetY() : leftCenter.GetX();
330     float tempRightCenterX = axis_ == Axis::HORIZONTAL ? rightCenter.GetX() : rightCenter.GetY();
331     float tempRightCenterY = axis_ == Axis::HORIZONTAL ? rightCenter.GetY() : rightCenter.GetX();
332     float itemHalfWidth = itemHalfSizes[ITEM_HALF_WIDTH];
333     float itemHalfHeight = itemHalfSizes[ITEM_HALF_HEIGHT];
334     if (hoverIndex_ == currentIndex_) {
335         itemHalfWidth = itemHalfSizes[SELECTED_ITEM_HALF_WIDTH];
336         itemHalfHeight = itemHalfSizes[SELECTED_ITEM_HALF_HEIGHT];
337     }
338     return hoverPoint.GetX() >= (tempLeftCenterX - itemHalfWidth) && (hoverPoint.GetX() <=
339                 (tempRightCenterX + itemHalfWidth)) && (hoverPoint.GetY() >= (tempLeftCenterY - itemHalfHeight)) &&
340                 (hoverPoint.GetY() <= (tempRightCenterY + itemHalfHeight));
341 }
342 
UpdateBackground(const PaintWrapper * paintWrapper)343 void DotIndicatorPaintMethod::UpdateBackground(const PaintWrapper* paintWrapper)
344 {
345     CHECK_NULL_VOID(paintWrapper);
346     auto paintProperty = DynamicCast<DotIndicatorPaintProperty>(paintWrapper->GetPaintProperty());
347     CHECK_NULL_VOID(paintProperty);
348     auto swiperTheme = GetSwiperIndicatorTheme();
349     CHECK_NULL_VOID(swiperTheme);
350 
351     // diameter calculation
352     auto itemWidth = static_cast<float>(paintProperty->GetItemWidthValue(swiperTheme->GetSize()).ConvertToPx());
353     auto itemHeight = static_cast<float>(paintProperty->GetItemHeightValue(swiperTheme->GetSize()).ConvertToPx());
354     auto selectedItemWidth =
355         static_cast<float>(paintProperty->GetSelectedItemWidthValue(swiperTheme->GetSize()).ConvertToPx());
356     auto selectedItemHeight =
357         static_cast<float>(paintProperty->GetSelectedItemHeightValue(swiperTheme->GetSize()).ConvertToPx());
358     // use radius calculation
359     LinearVector<float> itemHalfSizes;
360     itemHalfSizes.emplace_back(itemWidth * 0.5f * INDICATOR_ZOOM_IN_SCALE);
361     itemHalfSizes.emplace_back(itemHeight * 0.5f * INDICATOR_ZOOM_IN_SCALE);
362     itemHalfSizes.emplace_back(selectedItemWidth * 0.5f * INDICATOR_ZOOM_IN_SCALE);
363     itemHalfSizes.emplace_back(selectedItemHeight * 0.5f * INDICATOR_ZOOM_IN_SCALE);
364     if (touchBottomType_ != TouchBottomType::NONE) {
365         float allPointDiameterSum = itemWidth * static_cast<float>(itemCount_ + 1);
366         if (IsCustomSizeValue_) {
367             allPointDiameterSum = itemWidth * static_cast<float>(itemCount_ - 1) + selectedItemWidth;
368         }
369         float allPointSpaceSum = static_cast<float>(INDICATOR_ITEM_SPACE.ConvertToPx()) * (itemCount_ - 1);
370         float padding = static_cast<float>(INDICATOR_PADDING_DEFAULT.ConvertToPx());
371         float rectWidth = padding + allPointDiameterSum + allPointSpaceSum + padding;
372         float newRectWidth =
373             rectWidth * (TOUCH_BOTTOM_BACKGROUND_WIDTH_MULTIPLE - TOUCH_BOTTOM_DOT_WIDTH_MULTIPLE * itemCount_);
374         auto changeValue = (newRectWidth - rectWidth) * touchBottomRate_;
375 
376         float space = static_cast<float>(INDICATOR_ITEM_SPACE.ConvertToPx());
377         if (itemCount_ > 1) {
378             space = (rectWidth + changeValue - padding * 2 - allPointDiameterSum) / (itemCount_ - 1);
379         }
380         CalculatePointCenterX(itemHalfSizes, 0, padding, space, currentIndex_);
381         if (touchBottomType_ == TouchBottomType::START) {
382             for (size_t index = 0; index < vectorBlackPointCenterX_.size(); index++) {
383                 vectorBlackPointCenterX_[index] = vectorBlackPointCenterX_[index] - changeValue;
384             }
385             longPointCenterX_.first = longPointCenterX_.first - changeValue;
386             longPointCenterX_.second = longPointCenterX_.second - changeValue;
387         }
388     }
389     dotIndicatorModifier_->UpdateTouchBottomAnimation(
390         touchBottomType_, vectorBlackPointCenterX_, longPointCenterX_, touchBottomRate_);
391 }
392 
ForwardCalculation(const LinearVector<float> & itemHalfSizes,float startCenterX,float endCenterX,float space,int32_t index)393 void DotIndicatorPaintMethod::ForwardCalculation(
394     const LinearVector<float>& itemHalfSizes, float startCenterX, float endCenterX, float space, int32_t index)
395 {
396     int32_t startCurrentIndex = index;
397     auto itemWidth = itemHalfSizes[ITEM_HALF_WIDTH] * TWOFOLD;
398     auto selectedItemWidth = itemHalfSizes[SELECTED_ITEM_HALF_WIDTH] * TWOFOLD;
399     StarAndEndPointCenter pointCenter;
400     // Calculate the data required for the current pages
401     LinearVector<float> startVectorBlackPointCenterX(itemCount_);
402     // Calculate the data required for subsequent pages
403     LinearVector<float> endVectorBlackPointCenterX(itemCount_);
404     int32_t endCurrentIndex = NearEqual(turnPageRate_, 0.0f) || turnPageRate_ <= -1.0f || turnPageRate_ >= 1.0f
405         ? endCurrentIndex = index : (turnPageRate_ < 0.0f ? index + 1 : index - 1);
406     if (endCurrentIndex == -1) {
407         endCurrentIndex = itemCount_ - 1;
408     } else if (endCurrentIndex == itemCount_) {
409         endCurrentIndex = 0;
410     }
411     for (int32_t i = 0; i < itemCount_; ++i) {
412         if (i != startCurrentIndex) {
413             startVectorBlackPointCenterX[i] = startCenterX + itemHalfSizes[ITEM_HALF_WIDTH];
414             startCenterX += itemWidth;
415         } else {
416             if (IsCustomSizeValue_) {
417                 startVectorBlackPointCenterX[i] = startCenterX + itemHalfSizes[SELECTED_ITEM_HALF_WIDTH];
418                 pointCenter.startLongPointLeftCenterX = startCenterX + itemHalfSizes[SELECTED_ITEM_HALF_WIDTH];
419                 pointCenter.startLongPointRightCenterX = pointCenter.startLongPointLeftCenterX;
420                 startCenterX += selectedItemWidth;
421             } else {
422                 startVectorBlackPointCenterX[i] = startCenterX + itemHalfSizes[SELECTED_ITEM_HALF_WIDTH];
423                 pointCenter.startLongPointLeftCenterX = startCenterX + itemHalfSizes[SELECTED_ITEM_HALF_WIDTH];
424                 pointCenter.startLongPointRightCenterX = pointCenter.startLongPointLeftCenterX + selectedItemWidth;
425                 startCenterX += selectedItemWidth * TWOFOLD;
426             }
427         }
428         if (i != endCurrentIndex) {
429             endVectorBlackPointCenterX[i] = endCenterX + itemHalfSizes[ITEM_HALF_WIDTH];
430             endCenterX += itemWidth;
431         } else {
432             if (IsCustomSizeValue_) {
433                 endVectorBlackPointCenterX[i] = endCenterX + itemHalfSizes[SELECTED_ITEM_HALF_WIDTH];
434                 pointCenter.endLongPointLeftCenterX = endCenterX + itemHalfSizes[SELECTED_ITEM_HALF_WIDTH];
435                 pointCenter.endLongPointRightCenterX = pointCenter.endLongPointLeftCenterX;
436                 endCenterX += selectedItemWidth;
437             } else {
438                 endVectorBlackPointCenterX[i] = endCenterX + itemHalfSizes[SELECTED_ITEM_HALF_WIDTH];
439                 pointCenter.endLongPointLeftCenterX = endCenterX + itemHalfSizes[SELECTED_ITEM_HALF_WIDTH];
440                 pointCenter.endLongPointRightCenterX = pointCenter.endLongPointLeftCenterX + selectedItemWidth;
441                 endCenterX += selectedItemWidth * TWOFOLD;
442             }
443         }
444         startCenterX += space;
445         endCenterX += space;
446     }
447     CalculatePointCenterX(pointCenter, startVectorBlackPointCenterX, endVectorBlackPointCenterX);
448 }
449 
BackwardCalculation(const LinearVector<float> & itemHalfSizes,float startCenterX,float endCenterX,float space,int32_t index)450 void DotIndicatorPaintMethod::BackwardCalculation(
451     const LinearVector<float>& itemHalfSizes, float startCenterX, float endCenterX, float space, int32_t index)
452 {
453     int32_t startCurrentIndex = index;
454     auto itemWidth = itemHalfSizes[ITEM_HALF_WIDTH] * TWOFOLD;
455     auto selectedItemWidth = itemHalfSizes[SELECTED_ITEM_HALF_WIDTH] * TWOFOLD;
456     StarAndEndPointCenter pointCenter;
457     // Calculate the data required for the current pages
458     LinearVector<float> startVectorBlackPointCenterX(itemCount_);
459     // Calculate the data required for subsequent pages
460     LinearVector<float> endVectorBlackPointCenterX(itemCount_);
461     int32_t endCurrentIndex = NearEqual(turnPageRate_, 0.0f) || turnPageRate_ <= -1.0f || turnPageRate_ >= 1.0f
462         ? endCurrentIndex = index : (turnPageRate_ < 0.0f ? index + 1 : index - 1);
463     if (endCurrentIndex == -1) {
464         endCurrentIndex = itemCount_ - 1;
465     } else if (endCurrentIndex == itemCount_) {
466         endCurrentIndex = 0;
467     }
468     for (int32_t i = itemCount_ - 1; i >= 0; --i) {
469         if (i != startCurrentIndex) {
470             startVectorBlackPointCenterX[i] = startCenterX - itemHalfSizes[ITEM_HALF_WIDTH];
471             startCenterX -= itemWidth;
472         } else {
473             if (IsCustomSizeValue_) {
474                 startVectorBlackPointCenterX[i] = startCenterX - itemHalfSizes[SELECTED_ITEM_HALF_WIDTH];
475                 pointCenter.startLongPointLeftCenterX = startCenterX - itemHalfSizes[SELECTED_ITEM_HALF_WIDTH];
476                 pointCenter.startLongPointRightCenterX = pointCenter.startLongPointLeftCenterX;
477                 startCenterX -= selectedItemWidth;
478             } else {
479                 startVectorBlackPointCenterX[i] = startCenterX - itemHalfSizes[SELECTED_ITEM_HALF_WIDTH];
480                 pointCenter.startLongPointRightCenterX = startCenterX - itemHalfSizes[SELECTED_ITEM_HALF_WIDTH];
481                 pointCenter.startLongPointLeftCenterX = pointCenter.startLongPointRightCenterX - selectedItemWidth;
482                 startCenterX -= selectedItemWidth * TWOFOLD;
483             }
484         }
485         if (i != endCurrentIndex) {
486             endVectorBlackPointCenterX[i] = endCenterX - itemHalfSizes[ITEM_HALF_WIDTH];
487             endCenterX -= itemWidth;
488         } else {
489             if (IsCustomSizeValue_) {
490                 endVectorBlackPointCenterX[i] = endCenterX - itemHalfSizes[SELECTED_ITEM_HALF_WIDTH];
491                 pointCenter.endLongPointLeftCenterX = endCenterX - itemHalfSizes[SELECTED_ITEM_HALF_WIDTH];
492                 pointCenter.endLongPointRightCenterX = pointCenter.endLongPointLeftCenterX;
493                 endCenterX -= selectedItemWidth;
494             } else {
495                 endVectorBlackPointCenterX[i] = endCenterX - itemHalfSizes[SELECTED_ITEM_HALF_WIDTH];
496                 pointCenter.endLongPointRightCenterX = endCenterX - itemHalfSizes[SELECTED_ITEM_HALF_WIDTH];
497                 pointCenter.endLongPointLeftCenterX = pointCenter.endLongPointRightCenterX - selectedItemWidth;
498                 endCenterX -= selectedItemWidth * TWOFOLD;
499             }
500         }
501         startCenterX -= space;
502         endCenterX -= space;
503     }
504     CalculatePointCenterX(pointCenter, startVectorBlackPointCenterX, endVectorBlackPointCenterX);
505 }
506 } // namespace OHOS::Ace::NG
507