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