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 "core/components/common/layout/constants.h"
19 #include "core/components/common/properties/color.h"
20 namespace OHOS::Ace::NG {
21 namespace {
22 // for indicator
23 constexpr float BLACK_POINT_CENTER_BEZIER_CURVE_VELOCITY = 0.4f;
24 constexpr float LONG_POINT_LEFT_CENTER_BEZIER_CURVE_VELOCITY = 0.2f;
25 constexpr float LONG_POINT_RIGHT_CENTER_BEZIER_CURVE_VELOCITY = 1.0f;
26 constexpr float CENTER_BEZIER_CURVE_MASS = 0.0f;
27 constexpr float CENTER_BEZIER_CURVE_STIFFNESS = 1.0f;
28 constexpr float CENTER_BEZIER_CURVE_DAMPING = 1.0f;
29 constexpr uint32_t ITEM_HALF_WIDTH = 0;
30 constexpr uint32_t ITEM_HALF_HEIGHT = 1;
31 constexpr uint32_t SELECTED_ITEM_HALF_WIDTH = 2;
32 constexpr uint32_t SELECTED_ITEM_HALF_HEIGHT = 3;
33 constexpr float TOUCH_BOTTOM_BACKGROUND_WIDTH_MULTIPLE = 1.225f;
34 constexpr float TOUCH_BOTTOM_DOT_WIDTH_MULTIPLE = 0.0125f;
35 constexpr float LONG_POINT_TAIL_RATIO = 0.5f;
36 constexpr float FIFTY_PERCENT = 0.5f;
37 constexpr float HALF_SELECTED_WIDTH = 2.0f;
38 constexpr float HALF_FLOAT = 0.5f;
39 constexpr int TWOFOLD = 2;
40 constexpr float HALF = 0.5f;
41 } // namespace
42
UpdateContentModifier(PaintWrapper * paintWrapper)43 void DotIndicatorPaintMethod::UpdateContentModifier(PaintWrapper* paintWrapper)
44 {
45 CHECK_NULL_VOID(dotIndicatorModifier_);
46 CHECK_NULL_VOID(paintWrapper);
47
48 auto pipelineContext = PipelineBase::GetCurrentContext();
49 CHECK_NULL_VOID(pipelineContext);
50 auto swiperTheme = pipelineContext->GetTheme<SwiperIndicatorTheme>();
51 CHECK_NULL_VOID(swiperTheme);
52
53 const auto& geometryNode = paintWrapper->GetGeometryNode();
54 CHECK_NULL_VOID(geometryNode);
55
56 auto paintProperty = DynamicCast<DotIndicatorPaintProperty>(paintWrapper->GetPaintProperty());
57 CHECK_NULL_VOID(paintProperty);
58 IsCustomSizeValue_ = paintProperty->GetIsCustomSizeValue(false);
59 dotIndicatorModifier_->SetAxis(axis_);
60 auto [currentIndex, currentIndexActual] = CalCurrentIndex();
61 dotIndicatorModifier_->SetCurrentIndex(currentIndex);
62 dotIndicatorModifier_->SetCurrentIndexActual(currentIndexActual);
63 dotIndicatorModifier_->SetUnselectedColor(paintProperty->GetColorValue(swiperTheme->GetColor()));
64 dotIndicatorModifier_->SetSelectedColor(paintProperty->GetSelectedColorValue(swiperTheme->GetSelectedColor()));
65 dotIndicatorModifier_->SetIndicatorMask(paintProperty->GetIndicatorMaskValue(false));
66 dotIndicatorModifier_->SetIsIndicatorCustomSize(IsCustomSizeValue_);
67 dotIndicatorModifier_->SetOffset(geometryNode->GetContentOffset());
68 dotIndicatorModifier_->SetIndicatorDotItemSpace(
69 paintProperty->GetSpaceValue(swiperTheme->GetIndicatorDotItemSpace()));
70
71 SizeF contentSize = geometryNode->GetFrameSize();
72 centerY_ = (axis_ == Axis::HORIZONTAL ? contentSize.Height() : contentSize.Width()) * 0.5;
73 dotIndicatorModifier_->SetCenterY(centerY_);
74 if (touchBottomType_ != TouchBottomType::NONE) {
75 if (!dotIndicatorModifier_->GetIsPressed()) {
76 PaintPressIndicator(paintWrapper);
77 dotIndicatorModifier_->SetIsPressed(true);
78 }
79 UpdateBackground(paintWrapper);
80 } else if (isPressed_) {
81 PaintPressIndicator(paintWrapper);
82 dotIndicatorModifier_->SetIsPressed(true);
83 } else if (isHover_) {
84 PaintHoverIndicator(paintWrapper);
85 dotIndicatorModifier_->SetIsHover(true);
86 } else {
87 PaintNormalIndicator(paintWrapper);
88 dotIndicatorModifier_->SetIsHover(false);
89 dotIndicatorModifier_->SetIsPressed(false);
90 }
91 }
92
CalCurrentIndex()93 std::pair<int32_t, int32_t> DotIndicatorPaintMethod::CalCurrentIndex()
94 {
95 totalItemCount_ = Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_EIGHTEEN) ?
96 totalItemCount_ : itemCount_;
97 if (isHorizontalAndRightToLeft_) {
98 if (isSwipeByGroup_) {
99 currentIndex_ = totalItemCount_ - 1 - currentIndex_;
100 } else {
101 currentIndex_ = itemCount_ - 1 - currentIndex_;
102 }
103 }
104 auto currentIndex = currentIndex_;
105 auto currentIndexActual = currentIndexActual_;
106 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_EIGHTEEN) && isSwipeByGroup_ &&
107 displayCount_ != 0) {
108 currentIndex = currentIndex_ / displayCount_;
109 currentIndexActual = currentIndexActual_ / displayCount_;
110 }
111 return { currentIndex, currentIndexActual };
112 }
113
NeedBottomAnimation() const114 bool DotIndicatorPaintMethod::NeedBottomAnimation() const
115 {
116 auto currentIndexActual = currentIndexActual_;
117 auto firstIndex = firstIndex_;
118 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_EIGHTEEN) && isSwipeByGroup_ &&
119 displayCount_ != 0) {
120 firstIndex /= displayCount_;
121 currentIndexActual /= displayCount_;
122 }
123 firstIndex = isHorizontalAndRightToLeft_ ? itemCount_ - 1 - firstIndex : firstIndex;
124 if (gestureState_ == GestureState::GESTURE_STATE_RELEASE_LEFT) {
125 if (touchBottomTypeLoop_ == TouchBottomTypeLoop::TOUCH_BOTTOM_TYPE_LOOP_LEFT) {
126 if (NearZero(touchBottomPageRate_)) {
127 return true;
128 }
129
130 if (currentIndexActual != firstIndex && std::abs(touchBottomPageRate_) < FIFTY_PERCENT) {
131 return false;
132 }
133
134 return true;
135 }
136
137 if (currentIndexActual == firstIndex && firstIndex == itemCount_ - 1 &&
138 std::abs(touchBottomPageRate_) > FIFTY_PERCENT) {
139 return true;
140 }
141 }
142
143 if (gestureState_ == GestureState::GESTURE_STATE_RELEASE_RIGHT) {
144 if (touchBottomTypeLoop_ == TouchBottomTypeLoop::TOUCH_BOTTOM_TYPE_LOOP_RIGHT) {
145 if (currentIndexActual == firstIndex && std::abs(touchBottomPageRate_) > FIFTY_PERCENT) {
146 return false;
147 }
148
149 return true;
150 }
151
152 if (currentIndexActual == 0 && firstIndex == itemCount_ - 1 &&
153 std::abs(touchBottomPageRate_) < FIFTY_PERCENT) {
154 return true;
155 }
156 }
157
158 return false;
159 }
160
GetLongPointAnimationStateSecondCenter(const PaintWrapper * paintWrapper,std::vector<std::pair<float,float>> & pointCenterX)161 void DotIndicatorPaintMethod::GetLongPointAnimationStateSecondCenter(
162 const PaintWrapper* paintWrapper, std::vector<std::pair<float, float>>& pointCenterX)
163 {
164 if (NeedBottomAnimation()) {
165 pointAnimationStage_ = PointAnimationStage::STATE_EXPAND_TO_LONG_POINT;
166 auto [longPointCenterX, _] = CalculateLongPointCenterX(paintWrapper);
167 pointAnimationStage_ = PointAnimationStage::STATE_SHRINKT_TO_BLACK_POINT;
168 pointCenterX.push_back(longPointCenterX);
169 }
170 }
171
UpdateNormalIndicator(LinearVector<float> & itemHalfSizes,const PaintWrapper * paintWrapper)172 void DotIndicatorPaintMethod::UpdateNormalIndicator(
173 LinearVector<float>& itemHalfSizes, const PaintWrapper* paintWrapper)
174 {
175 CHECK_NULL_VOID(dotIndicatorModifier_);
176 if (gestureState_ == GestureState::GESTURE_STATE_RELEASE_LEFT ||
177 gestureState_ == GestureState::GESTURE_STATE_RELEASE_RIGHT) {
178 std::vector<std::pair<float, float>> pointCenterX({ longPointCenterX_ });
179 GetLongPointAnimationStateSecondCenter(paintWrapper, pointCenterX);
180 dotIndicatorModifier_->PlayIndicatorAnimation(
181 vectorBlackPointCenterX_, pointCenterX, gestureState_, touchBottomTypeLoop_);
182 } else {
183 dotIndicatorModifier_->UpdateNormalPaintProperty(
184 normalMargin_, itemHalfSizes, vectorBlackPointCenterX_, longPointCenterX_);
185 }
186 }
187
PaintNormalIndicator(const PaintWrapper * paintWrapper)188 void DotIndicatorPaintMethod::PaintNormalIndicator(const PaintWrapper* paintWrapper)
189 {
190 CHECK_NULL_VOID(dotIndicatorModifier_);
191 auto [longPointCenterX, itemHalfSizes] = CalculateLongPointCenterX(paintWrapper);
192 longPointCenterX_ = longPointCenterX;
193
194 if (dotIndicatorModifier_->GetIsHover()) {
195 dotIndicatorModifier_->UpdateHoverToNormalPaintProperty(
196 normalMargin_, itemHalfSizes, vectorBlackPointCenterX_, longPointCenterX_);
197 } else if (dotIndicatorModifier_->GetIsPressed()) {
198 dotIndicatorModifier_->UpdatePressToNormalPaintProperty(
199 normalMargin_, itemHalfSizes, vectorBlackPointCenterX_, longPointCenterX_);
200 } else {
201 UpdateNormalIndicator(itemHalfSizes, paintWrapper);
202 }
203 }
204
PaintHoverIndicator(const PaintWrapper * paintWrapper)205 void DotIndicatorPaintMethod::PaintHoverIndicator(const PaintWrapper* paintWrapper)
206 {
207 CHECK_NULL_VOID(dotIndicatorModifier_);
208 CHECK_NULL_VOID(paintWrapper);
209 auto paintProperty = DynamicCast<DotIndicatorPaintProperty>(paintWrapper->GetPaintProperty());
210 CHECK_NULL_VOID(paintProperty);
211 auto indicatorTheme = GetSwiperIndicatorTheme();
212 CHECK_NULL_VOID(indicatorTheme);
213 // diameter calculation
214 auto itemWidth = static_cast<float>(paintProperty->GetItemWidthValue(indicatorTheme->GetSize()).ConvertToPx());
215 auto itemHeight = static_cast<float>(paintProperty->GetItemHeightValue(indicatorTheme->GetSize()).ConvertToPx());
216 auto selectedItemWidth =
217 static_cast<float>(paintProperty->GetSelectedItemWidthValue(indicatorTheme->GetSize()).ConvertToPx());
218 auto selectedItemHeight =
219 static_cast<float>(paintProperty->GetSelectedItemHeightValue(indicatorTheme->GetSize()).ConvertToPx());
220 // use radius calculation
221 LinearVector<float> itemHalfSizes;
222 float indicatorScale = indicatorTheme->GetIndicatorScale();
223 itemHalfSizes.emplace_back(itemWidth * HALF * indicatorScale);
224 itemHalfSizes.emplace_back(itemHeight * HALF * indicatorScale);
225 itemHalfSizes.emplace_back(selectedItemWidth * HALF * indicatorScale);
226 itemHalfSizes.emplace_back(selectedItemHeight * HALF * indicatorScale);
227 Dimension paddingSide = indicatorTheme->GetIndicatorPaddingDot();
228 Dimension indicatorDotItemSpace =
229 paintProperty->GetSpaceValue(indicatorTheme->GetIndicatorDotItemSpace());
230
231 longPointCenterX_ =
232 CalculatePointCenterX(itemHalfSizes, 0, static_cast<float>(paddingSide.ConvertToPx()),
233 static_cast<float>(indicatorDotItemSpace.ConvertToPx()), currentIndex_);
234 if (dotIndicatorModifier_->GetIsPressed()) {
235 dotIndicatorModifier_->SetIsPressed(false);
236 dotIndicatorModifier_->UpdateHoverAndPressConversionPaintProperty();
237 } else if (dotIndicatorModifier_->GetIsHover()) {
238 if (!mouseClickIndex_.has_value()) {
239 dotIndicatorModifier_->UpdateHoverPaintProperty(itemHalfSizes,
240 vectorBlackPointCenterX_, longPointCenterX_);
241 }
242 } else {
243 dotIndicatorModifier_->UpdateNormalToHoverPaintProperty(
244 itemHalfSizes, vectorBlackPointCenterX_, longPointCenterX_);
245 }
246
247 CalculateHoverIndex(itemHalfSizes);
248 if (dotIndicatorModifier_->GetNormalToHoverIndex() != hoverIndex_) {
249 dotIndicatorModifier_->SetHoverToNormalIndex(dotIndicatorModifier_->GetNormalToHoverIndex());
250 dotIndicatorModifier_->UpdateHoverToNormalPointDilateRatio();
251 dotIndicatorModifier_->SetNormalToHoverIndex(hoverIndex_);
252 dotIndicatorModifier_->UpdateNormalToHoverPointDilateRatio();
253 }
254
255 PaintHoverIndicator(itemHalfSizes, paddingSide, indicatorDotItemSpace);
256 }
257
CalculateMouseClickIndexOnRTL()258 int32_t DotIndicatorPaintMethod::CalculateMouseClickIndexOnRTL()
259 {
260 int32_t mouseClickIndex = 0;
261 if (!mouseClickIndex_) {
262 return mouseClickIndex;
263 }
264
265 if (isSwipeByGroup_) {
266 mouseClickIndex = totalItemCount_ - 1 - mouseClickIndex_.value();
267 } else {
268 mouseClickIndex = itemCount_ - 1 - mouseClickIndex_.value();
269 }
270
271 return mouseClickIndex;
272 }
273
PaintHoverIndicator(LinearVector<float> & itemHalfSizes,const Dimension paddingSide,const Dimension & indicatorDotItemSpace)274 void DotIndicatorPaintMethod::PaintHoverIndicator(LinearVector<float>& itemHalfSizes, const Dimension paddingSide,
275 const Dimension& indicatorDotItemSpace)
276 {
277 CHECK_NULL_VOID(dotIndicatorModifier_);
278 if (mouseClickIndex_) {
279 if (currentIndex_ == totalItemCount_ - displayCount_ && !isLoop_ && mouseClickIndex_ > currentIndex_ &&
280 mouseClickIndex_ < totalItemCount_) {
281 longPointCenterX_ = CalculatePointCenterX(itemHalfSizes, 0, static_cast<float>(paddingSide.ConvertToPx()),
282 static_cast<float>(indicatorDotItemSpace.ConvertToPx()), currentIndex_);
283 } else {
284 auto mouseClickIndex = isHorizontalAndRightToLeft_ ?
285 CalculateMouseClickIndexOnRTL() : mouseClickIndex_.value();
286 longPointCenterX_ = CalculatePointCenterX(itemHalfSizes, 0, static_cast<float>(paddingSide.ConvertToPx()),
287 static_cast<float>(indicatorDotItemSpace.ConvertToPx()), mouseClickIndex);
288 }
289 dotIndicatorModifier_->UpdateAllPointCenterXAnimation(
290 gestureState_, vectorBlackPointCenterX_, longPointCenterX_);
291 mouseClickIndex_ = std::nullopt;
292 }
293 if (dotIndicatorModifier_->GetLongPointIsHover() != longPointIsHover_) {
294 dotIndicatorModifier_->SetLongPointIsHover(longPointIsHover_);
295 dotIndicatorModifier_->UpdateLongPointDilateRatio();
296 }
297 }
298
PaintPressIndicator(const PaintWrapper * paintWrapper)299 void DotIndicatorPaintMethod::PaintPressIndicator(const PaintWrapper* paintWrapper)
300 {
301 CHECK_NULL_VOID(dotIndicatorModifier_);
302 CHECK_NULL_VOID(paintWrapper);
303 auto paintProperty = DynamicCast<DotIndicatorPaintProperty>(paintWrapper->GetPaintProperty());
304 CHECK_NULL_VOID(paintProperty);
305 auto indicatorTheme = GetSwiperIndicatorTheme();
306 CHECK_NULL_VOID(indicatorTheme);
307 // diameter calculation
308 auto itemWidth = static_cast<float>(paintProperty->GetItemWidthValue(indicatorTheme->GetSize()).ConvertToPx());
309 auto itemHeight = static_cast<float>(paintProperty->GetItemHeightValue(indicatorTheme->GetSize()).ConvertToPx());
310 auto selectedItemWidth =
311 static_cast<float>(paintProperty->GetSelectedItemWidthValue(indicatorTheme->GetSize()).ConvertToPx());
312 auto selectedItemHeight =
313 static_cast<float>(paintProperty->GetSelectedItemHeightValue(indicatorTheme->GetSize()).ConvertToPx());
314 // use radius calculation
315 float indicatorScale = indicatorTheme->GetIndicatorScale();
316 auto itemHalfWidth = itemWidth * HALF * indicatorScale;
317 auto itemHalfHeight = itemHeight * HALF * indicatorScale;
318 auto selectedItemHalfWidth = selectedItemWidth * HALF * indicatorScale;
319 auto selectedItemHalfHeight = selectedItemHeight * HALF * indicatorScale;
320 LinearVector<float> itemHalfSizes;
321 itemHalfSizes.emplace_back(itemHalfWidth);
322 itemHalfSizes.emplace_back(itemHalfHeight);
323 itemHalfSizes.emplace_back(selectedItemHalfWidth);
324 itemHalfSizes.emplace_back(selectedItemHalfHeight);
325 Dimension paddingSide = indicatorTheme->GetIndicatorPaddingDot();
326 Dimension indicatorDotItemSpace =
327 paintProperty->GetSpaceValue(indicatorTheme->GetIndicatorDotItemSpace());
328 longPointCenterX_ =
329 CalculatePointCenterX(itemHalfSizes, 0, static_cast<float>(paddingSide.ConvertToPx()),
330 static_cast<float>(indicatorDotItemSpace.ConvertToPx()), currentIndex_);
331 if (dotIndicatorModifier_->GetIsPressed()) {
332 dotIndicatorModifier_->UpdatePressPaintProperty(itemHalfSizes, vectorBlackPointCenterX_, longPointCenterX_);
333 } else if (dotIndicatorModifier_->GetIsHover()) {
334 dotIndicatorModifier_->SetIsPressed(true);
335 dotIndicatorModifier_->UpdateHoverAndPressConversionPaintProperty();
336 } else {
337 dotIndicatorModifier_->UpdateNormalToPressPaintProperty(
338 itemHalfSizes, vectorBlackPointCenterX_, longPointCenterX_);
339 }
340 }
341
CalculateNormalMargin(const LinearVector<float> & itemHalfSizes,const SizeF & frameSize,const int32_t displayCount,const Dimension & indicatorDotItemSpace,bool ignoreSize)342 void DotIndicatorPaintMethod::CalculateNormalMargin(const LinearVector<float>& itemHalfSizes,
343 const SizeF& frameSize, const int32_t displayCount, const Dimension& indicatorDotItemSpace, bool ignoreSize)
344 {
345 // diameter calculation
346 auto itemWidth = itemHalfSizes[ITEM_HALF_WIDTH] * 2;
347 auto itemHeight = itemHalfSizes[ITEM_HALF_HEIGHT] * 2;
348 auto selectedItemWidth = itemHalfSizes[SELECTED_ITEM_HALF_WIDTH] * 2;
349 auto selectedItemHeight = itemHalfSizes[SELECTED_ITEM_HALF_HEIGHT] * 2;
350 auto allPointDiameterSum = itemWidth * static_cast<float>(displayCount + 1);
351 if (IsCustomSizeValue_) {
352 allPointDiameterSum = itemWidth * static_cast<float>(displayCount - 1) + selectedItemWidth;
353 }
354 auto allPointSpaceSum = static_cast<float>(indicatorDotItemSpace.ConvertToPx()) * (displayCount - 1);
355 auto indicatorTheme = GetSwiperIndicatorTheme();
356 CHECK_NULL_VOID(indicatorTheme);
357 Dimension paddingSide = indicatorTheme->GetIndicatorPaddingDot();
358 auto indicatorPaddingSide = static_cast<float>(paddingSide.ConvertToPx());
359 auto contentWidth = indicatorPaddingSide + allPointDiameterSum + allPointSpaceSum + indicatorPaddingSide;
360 auto indicatorHeightPadding = indicatorTheme->GetIndicatorBgHeight().ConvertToPx();
361
362 auto contentHeight = indicatorHeightPadding + itemHeight + indicatorHeightPadding;
363 if (selectedItemHeight > itemHeight) {
364 contentHeight = indicatorHeightPadding + selectedItemHeight + indicatorHeightPadding;
365 }
366
367 float marginX = ((axis_ == Axis::HORIZONTAL ? frameSize.Width() : frameSize.Height()) - contentWidth) * 0.5;
368 float marginY = ((axis_ == Axis::HORIZONTAL ? frameSize.Height() : frameSize.Width()) - contentHeight) * 0.5;
369 normalMargin_.SetX(marginX);
370 normalMargin_.SetY(marginY);
371 }
372
CalculatePointCenterX(const LinearVector<float> & itemHalfSizes,float margin,float padding,float space,int32_t index)373 std::pair<float, float> DotIndicatorPaintMethod::CalculatePointCenterX(
374 const LinearVector<float>& itemHalfSizes, float margin, float padding, float space, int32_t index)
375 {
376 if (itemCount_ == 0) {
377 return { 0, 0 };
378 }
379 float startCenterX = margin + padding;
380 float endCenterX = margin + padding;
381 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_EIGHTEEN)) {
382 if (isSwipeByGroup_ && displayCount_ != 0) {
383 index /= displayCount_;
384 }
385 if (isPressed_ && isSwipeByGroup_) {
386 touchBottomTypeLoop_ = TouchBottomTypeLoop::TOUCH_BOTTOM_TYPE_LOOP_NONE;
387 }
388 }
389
390 if (Positive(turnPageRate_)) {
391 auto itemWidth = itemHalfSizes[ITEM_HALF_WIDTH] * TWOFOLD;
392 auto selectedItemWidth = itemHalfSizes[SELECTED_ITEM_HALF_WIDTH] * TWOFOLD;
393 float allPointDiameterSum = itemWidth * static_cast<float>(itemCount_ + 1);
394 if (IsCustomSizeValue_) {
395 allPointDiameterSum = itemWidth * static_cast<float>(itemCount_ - 1) + selectedItemWidth;
396 }
397 auto allPointSpaceSum = static_cast<float>(space * (itemCount_ - 1));
398
399 float rectWidth = padding + allPointDiameterSum + allPointSpaceSum + padding;
400 startCenterX = rectWidth - startCenterX;
401 endCenterX = rectWidth - endCenterX;
402 return BackwardCalculation(itemHalfSizes, startCenterX, endCenterX, space, index);
403 }
404 return ForwardCalculation(itemHalfSizes, startCenterX, endCenterX, space, index);
405 }
406
CalculateLongPointCenterX(const PaintWrapper * paintWrapper)407 std::tuple<std::pair<float, float>, LinearVector<float>> DotIndicatorPaintMethod::CalculateLongPointCenterX(
408 const PaintWrapper* paintWrapper)
409 {
410 std::tuple<std::pair<float, float>, LinearVector<float>> tmp;
411 CHECK_NULL_RETURN(paintWrapper, tmp);
412 const auto& geometryNode = paintWrapper->GetGeometryNode();
413 CHECK_NULL_RETURN(geometryNode, tmp);
414 auto paintProperty = DynamicCast<DotIndicatorPaintProperty>(paintWrapper->GetPaintProperty());
415 CHECK_NULL_RETURN(paintProperty, tmp);
416 auto indicatorTheme = GetSwiperIndicatorTheme();
417 CHECK_NULL_RETURN(indicatorTheme, tmp);
418 SizeF frameSize = geometryNode->GetFrameSize();
419 // diameter calculation
420 auto itemWidth = static_cast<float>(paintProperty->GetItemWidthValue(indicatorTheme->GetSize()).ConvertToPx());
421 auto itemHeight = static_cast<float>(paintProperty->GetItemHeightValue(indicatorTheme->GetSize()).ConvertToPx());
422 auto selectedItemWidth =
423 static_cast<float>(paintProperty->GetSelectedItemWidthValue(indicatorTheme->GetSize()).ConvertToPx());
424 auto selectedItemHeight =
425 static_cast<float>(paintProperty->GetSelectedItemHeightValue(indicatorTheme->GetSize()).ConvertToPx());
426 // use radius calculation
427 LinearVector<float> itemHalfSizes;
428 itemHalfSizes.emplace_back(itemWidth * 0.5);
429 itemHalfSizes.emplace_back(itemHeight * 0.5);
430 itemHalfSizes.emplace_back(selectedItemWidth * 0.5);
431 itemHalfSizes.emplace_back(selectedItemHeight * 0.5);
432
433 Dimension indicatorDotItemSpace =
434 paintProperty->GetSpaceValue(indicatorTheme->GetIndicatorDotItemSpace());
435 bool ignoreSize = paintProperty->GetIgnoreSizeValue(false);
436 CalculateNormalMargin(itemHalfSizes, frameSize, itemCount_, indicatorDotItemSpace, ignoreSize);
437 Dimension paddingSide = indicatorTheme->GetIndicatorPaddingDot();
438 auto longPointCenterX = CalculatePointCenterX(itemHalfSizes, normalMargin_.GetX(),
439 static_cast<float>(paddingSide.ConvertToPx()),
440 static_cast<float>(indicatorDotItemSpace.ConvertToPx()), currentIndex_);
441 return { longPointCenterX, itemHalfSizes };
442 }
443
GetMoveRate()444 std::tuple<float, float, float> DotIndicatorPaintMethod::GetMoveRate()
445 {
446 auto actualTurnPageRate = Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_EIGHTEEN) &&
447 isSwipeByGroup_ ? groupTurnPageRate_ : turnPageRate_;
448 float blackPointCenterMoveRate = CubicCurve(BLACK_POINT_CENTER_BEZIER_CURVE_VELOCITY, CENTER_BEZIER_CURVE_MASS,
449 CENTER_BEZIER_CURVE_STIFFNESS, CENTER_BEZIER_CURVE_DAMPING).MoveInternal(std::abs(actualTurnPageRate));
450 float longPointLeftCenterMoveRate = 0.0f;
451 float longPointRightCenterMoveRate = 0.0f;
452 if (isPressed_ && touchBottomTypeLoop_ == TouchBottomTypeLoop::TOUCH_BOTTOM_TYPE_LOOP_NONE) {
453 longPointLeftCenterMoveRate = CubicCurve(turnPageRate_ > 0 ? LONG_POINT_LEFT_CENTER_BEZIER_CURVE_VELOCITY :
454 LONG_POINT_RIGHT_CENTER_BEZIER_CURVE_VELOCITY, CENTER_BEZIER_CURVE_MASS, CENTER_BEZIER_CURVE_STIFFNESS,
455 CENTER_BEZIER_CURVE_DAMPING).MoveInternal(std::abs(turnPageRate_));
456 longPointRightCenterMoveRate = CubicCurve(turnPageRate_ > 0 ? LONG_POINT_RIGHT_CENTER_BEZIER_CURVE_VELOCITY :
457 LONG_POINT_LEFT_CENTER_BEZIER_CURVE_VELOCITY, CENTER_BEZIER_CURVE_MASS, CENTER_BEZIER_CURVE_STIFFNESS,
458 CENTER_BEZIER_CURVE_DAMPING).MoveInternal(std::abs(turnPageRate_));
459 } else if (gestureState_ == GestureState::GESTURE_STATE_RELEASE_LEFT ||
460 gestureState_ == GestureState::GESTURE_STATE_RELEASE_RIGHT) {
461 blackPointCenterMoveRate = 1;
462 longPointLeftCenterMoveRate = 1;
463 longPointRightCenterMoveRate = 1;
464 } else if (touchBottomTypeLoop_ == TouchBottomTypeLoop::TOUCH_BOTTOM_TYPE_LOOP_LEFT) {
465 auto rateAbs = 1.0f - std::abs(actualTurnPageRate);
466 // x0:0.33, y0:0, x1:0.67, y1:1
467 longPointLeftCenterMoveRate = longPointRightCenterMoveRate = CubicCurve(0.33, 0, 0.67, 1).MoveInternal(rateAbs);
468 } else if (touchBottomTypeLoop_ == TouchBottomTypeLoop::TOUCH_BOTTOM_TYPE_LOOP_RIGHT) {
469 auto rateAbs = std::abs(actualTurnPageRate);
470 // x0:0.33, y0:0, x1:0.67, y1:1
471 longPointLeftCenterMoveRate = longPointRightCenterMoveRate = CubicCurve(0.33, 0, 0.67, 1).MoveInternal(rateAbs);
472 } else if (gestureState_ == GestureState::GESTURE_STATE_FOLLOW_LEFT) {
473 longPointLeftCenterMoveRate =std::abs(actualTurnPageRate);
474 longPointRightCenterMoveRate = std::abs(actualTurnPageRate) +
475 ((1 - longPointLeftCenterMoveRate) * LONG_POINT_TAIL_RATIO);
476 } else if (gestureState_ == GestureState::GESTURE_STATE_FOLLOW_RIGHT) {
477 longPointRightCenterMoveRate = std::abs(actualTurnPageRate);
478 longPointLeftCenterMoveRate = std::abs(actualTurnPageRate) * LONG_POINT_TAIL_RATIO;
479 }
480 return { blackPointCenterMoveRate, longPointLeftCenterMoveRate, longPointRightCenterMoveRate };
481 }
482
CalculatePointCenterX(const StarAndEndPointCenter & starAndEndPointCenter,const LinearVector<float> & startVectorBlackPointCenterX,const LinearVector<float> & endVectorBlackPointCenterX)483 std::pair<float, float> DotIndicatorPaintMethod::CalculatePointCenterX(
484 const StarAndEndPointCenter& starAndEndPointCenter, const LinearVector<float>& startVectorBlackPointCenterX,
485 const LinearVector<float>& endVectorBlackPointCenterX)
486 {
487 const auto [blackPointCenterMoveRate, longPointLeftCenterMoveRate, longPointRightCenterMoveRate] = GetMoveRate();
488
489 vectorBlackPointCenterX_.resize(itemCount_);
490 for (int32_t i = 0; i < itemCount_; ++i) {
491 vectorBlackPointCenterX_[i] = startVectorBlackPointCenterX[i] +
492 (endVectorBlackPointCenterX[i] - startVectorBlackPointCenterX[i]) * blackPointCenterMoveRate;
493 }
494
495 std::pair<float, float> longPointCenterX;
496 longPointCenterX.first = starAndEndPointCenter.startLongPointLeftCenterX +
497 (starAndEndPointCenter.endLongPointLeftCenterX - starAndEndPointCenter.startLongPointLeftCenterX) *
498 longPointLeftCenterMoveRate;
499 longPointCenterX.second = starAndEndPointCenter.startLongPointRightCenterX +
500 (starAndEndPointCenter.endLongPointRightCenterX - starAndEndPointCenter.startLongPointRightCenterX) *
501 longPointRightCenterMoveRate;
502 if (isHorizontalAndRightToLeft_) {
503 longPointCenterX.first = starAndEndPointCenter.startLongPointLeftCenterX +
504 (starAndEndPointCenter.endLongPointLeftCenterX - starAndEndPointCenter.startLongPointLeftCenterX) *
505 longPointLeftCenterMoveRate;
506 longPointCenterX.second = starAndEndPointCenter.startLongPointRightCenterX +
507 (starAndEndPointCenter.endLongPointRightCenterX - starAndEndPointCenter.startLongPointRightCenterX) *
508 longPointRightCenterMoveRate;
509 }
510 return longPointCenterX;
511 }
512
CalculateHoverIndex(const LinearVector<float> & itemHalfSizes)513 void DotIndicatorPaintMethod::CalculateHoverIndex(const LinearVector<float>& itemHalfSizes)
514 {
515 CHECK_NULL_VOID(dotIndicatorModifier_);
516 if (!isHover_) {
517 hoverIndex_ = std::nullopt;
518 longPointIsHover_ = false;
519 return;
520 }
521 for (size_t i = 0; i < vectorBlackPointCenterX_.size(); ++i) {
522 OffsetF center = { vectorBlackPointCenterX_[i], centerY_ };
523 if (isHoverPoint(hoverPoint_, center, center, itemHalfSizes)) {
524 hoverIndex_ = i;
525 break;
526 }
527 }
528 auto longPointCenterX = dotIndicatorModifier_->GetLongPointCenterX();
529
530 OffsetF leftCenter = { longPointCenterX.first, centerY_ };
531 OffsetF rightCenter = { longPointCenterX.second, centerY_ };
532 longPointIsHover_ = isHoverPoint(hoverPoint_, leftCenter, rightCenter, itemHalfSizes);
533 }
534
isHoverPoint(const PointF & hoverPoint,const OffsetF & leftCenter,const OffsetF & rightCenter,const LinearVector<float> & itemHalfSizes)535 bool DotIndicatorPaintMethod::isHoverPoint(
536 const PointF& hoverPoint, const OffsetF& leftCenter,
537 const OffsetF& rightCenter, const LinearVector<float>& itemHalfSizes)
538 {
539 float tempLeftCenterX = axis_ == Axis::HORIZONTAL ? leftCenter.GetX() : leftCenter.GetY();
540 float tempLeftCenterY = axis_ == Axis::HORIZONTAL ? leftCenter.GetY() : leftCenter.GetX();
541 float tempRightCenterX = axis_ == Axis::HORIZONTAL ? rightCenter.GetX() : rightCenter.GetY();
542 float tempRightCenterY = axis_ == Axis::HORIZONTAL ? rightCenter.GetY() : rightCenter.GetX();
543 float itemHalfWidth = itemHalfSizes[ITEM_HALF_WIDTH];
544 float itemHalfHeight = itemHalfSizes[ITEM_HALF_HEIGHT];
545 if (hoverIndex_ == currentIndex_) {
546 itemHalfWidth = itemHalfSizes[SELECTED_ITEM_HALF_WIDTH];
547 itemHalfHeight = itemHalfSizes[SELECTED_ITEM_HALF_HEIGHT];
548 }
549 return hoverPoint.GetX() >= (tempLeftCenterX - itemHalfWidth) && (hoverPoint.GetX() <=
550 (tempRightCenterX + itemHalfWidth)) && (hoverPoint.GetY() >= (tempLeftCenterY - itemHalfHeight)) &&
551 (hoverPoint.GetY() <= (tempRightCenterY + itemHalfHeight));
552 }
553
UpdateBackground(const PaintWrapper * paintWrapper)554 void DotIndicatorPaintMethod::UpdateBackground(const PaintWrapper* paintWrapper)
555 {
556 CHECK_NULL_VOID(dotIndicatorModifier_);
557 CHECK_NULL_VOID(paintWrapper);
558 auto paintProperty = DynamicCast<DotIndicatorPaintProperty>(paintWrapper->GetPaintProperty());
559 CHECK_NULL_VOID(paintProperty);
560 auto indicatorTheme = GetSwiperIndicatorTheme();
561 CHECK_NULL_VOID(indicatorTheme);
562
563 // diameter calculation
564 auto itemWidth = static_cast<float>(paintProperty->GetItemWidthValue(indicatorTheme->GetSize()).ConvertToPx());
565 auto itemHeight = static_cast<float>(paintProperty->GetItemHeightValue(indicatorTheme->GetSize()).ConvertToPx());
566 auto selectedItemWidth =
567 static_cast<float>(paintProperty->GetSelectedItemWidthValue(indicatorTheme->GetSize()).ConvertToPx());
568 auto selectedItemHeight =
569 static_cast<float>(paintProperty->GetSelectedItemHeightValue(indicatorTheme->GetSize()).ConvertToPx());
570 // use radius calculation
571 LinearVector<float> itemHalfSizes;
572 float indicatorScale = indicatorTheme->GetIndicatorScale();
573 itemHalfSizes.emplace_back(itemWidth * HALF * indicatorScale);
574 itemHalfSizes.emplace_back(itemHeight * HALF * indicatorScale);
575 itemHalfSizes.emplace_back(selectedItemWidth * HALF * indicatorScale);
576 itemHalfSizes.emplace_back(selectedItemHeight * HALF * indicatorScale);
577 if (touchBottomType_ != TouchBottomType::NONE) {
578 Dimension indicatorDotItemSpace = paintProperty->GetSpaceValue(indicatorTheme->GetIndicatorDotItemSpace());
579 float allPointDiameterSum = itemWidth * static_cast<float>(itemCount_ + 1);
580 if (IsCustomSizeValue_) {
581 allPointDiameterSum = itemWidth * static_cast<float>(itemCount_ - 1) + selectedItemWidth;
582 }
583 float allPointSpaceSum = static_cast<float>(indicatorDotItemSpace.ConvertToPx()) * (itemCount_ - 1);
584 Dimension paddingSide = indicatorTheme->GetIndicatorPaddingDot();
585 float padding = static_cast<float>(paddingSide.ConvertToPx());
586 float rectWidth = padding + allPointDiameterSum + allPointSpaceSum + padding;
587 float newRectWidth =
588 rectWidth * (TOUCH_BOTTOM_BACKGROUND_WIDTH_MULTIPLE - TOUCH_BOTTOM_DOT_WIDTH_MULTIPLE * itemCount_);
589 auto changeValue = (newRectWidth - rectWidth) * touchBottomRate_;
590
591 float space = static_cast<float>(indicatorDotItemSpace.ConvertToPx());
592 if (itemCount_ > 1) {
593 space = (rectWidth + changeValue - padding * 2 - allPointDiameterSum) / (itemCount_ - 1);
594 }
595 longPointCenterX_ = CalculatePointCenterX(itemHalfSizes, 0, padding, space, currentIndex_);
596 if (touchBottomType_ == TouchBottomType::START) {
597 for (size_t index = 0; index < vectorBlackPointCenterX_.size(); index++) {
598 vectorBlackPointCenterX_[index] = vectorBlackPointCenterX_[index] - changeValue;
599 }
600 longPointCenterX_.first = longPointCenterX_.first - changeValue;
601 longPointCenterX_.second = longPointCenterX_.second - changeValue;
602 }
603 }
604 dotIndicatorModifier_->UpdateTouchBottomAnimation(
605 touchBottomType_, vectorBlackPointCenterX_, longPointCenterX_, touchBottomRate_);
606 }
607
GetIndexOnRTL(int32_t index)608 std::pair<int32_t, int32_t> DotIndicatorPaintMethod::GetIndexOnRTL(int32_t index)
609 {
610 auto actualTurnPageRate = turnPageRate_;
611 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_EIGHTEEN) &&
612 isSwipeByGroup_ && !NearZero(groupTurnPageRate_)) {
613 actualTurnPageRate = groupTurnPageRate_;
614 }
615
616 int32_t startCurrentIndex = index;
617 auto isInvalid = NearEqual(actualTurnPageRate, 0.0f) || LessOrEqualCustomPrecision(actualTurnPageRate, -1.0f) ||
618 GreatOrEqualCustomPrecision(actualTurnPageRate, 1.0f);
619 if (!isInvalid) {
620 startCurrentIndex = LessNotEqualCustomPrecision(actualTurnPageRate, 0.0f) ? index - 1 : index + 1;
621 }
622
623 if (startCurrentIndex <= -1) {
624 if (isLoop_) {
625 startCurrentIndex = itemCount_ - 1;
626 } else {
627 startCurrentIndex = 0;
628 if (index <= -1) {
629 index = 0;
630 }
631 }
632 }
633
634 return { startCurrentIndex, index };
635 }
636
GetIndex(int32_t index)637 std::pair<int32_t, int32_t> DotIndicatorPaintMethod::GetIndex(int32_t index)
638 {
639 if (mouseClickIndex_ || gestureState_ == GestureState::GESTURE_STATE_RELEASE_LEFT ||
640 gestureState_ == GestureState::GESTURE_STATE_RELEASE_RIGHT) {
641 turnPageRate_ = 0;
642 groupTurnPageRate_ = 0;
643 }
644
645 if (isHorizontalAndRightToLeft_ && !isPressed_) {
646 return GetIndexOnRTL(index);
647 }
648
649 auto actualTurnPageRate = turnPageRate_;
650 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_EIGHTEEN) &&
651 isSwipeByGroup_ && groupTurnPageRate_ != 0) {
652 actualTurnPageRate = groupTurnPageRate_;
653 }
654
655 // item may be invalid in auto linear scene
656 if (nextValidIndex_ >= 0) {
657 int32_t startCurrentIndex = index;
658 int32_t endCurrentIndex = NearEqual(turnPageRate_, 0.0f) || LessOrEqualCustomPrecision(turnPageRate_, -1.0f) ||
659 GreatOrEqualCustomPrecision(turnPageRate_, 1.0f)
660 ? index
661 : nextValidIndex_;
662 // reach edge scene
663 if (startCurrentIndex > endCurrentIndex) {
664 startCurrentIndex = currentIndexActual_;
665 endCurrentIndex = currentIndexActual_;
666 }
667 return { startCurrentIndex, endCurrentIndex };
668 }
669
670 int32_t startCurrentIndex = index;
671 int32_t endCurrentIndex = NearEqual(actualTurnPageRate, 0.0f) ||
672 LessOrEqualCustomPrecision(actualTurnPageRate, -1.0f) || GreatOrEqualCustomPrecision(actualTurnPageRate, 1.0f)
673 ? endCurrentIndex = index
674 : (LessNotEqualCustomPrecision(actualTurnPageRate, 0.0f) ? index + 1 : index - 1);
675 if (endCurrentIndex == -1) {
676 endCurrentIndex = itemCount_ - 1;
677 } else if (endCurrentIndex >= itemCount_) {
678 if (isLoop_) {
679 endCurrentIndex = 0;
680 } else {
681 if (startCurrentIndex >= itemCount_) {
682 startCurrentIndex = itemCount_ - 1;
683 }
684 endCurrentIndex = itemCount_ - 1;
685 }
686 }
687
688 return { startCurrentIndex, endCurrentIndex };
689 }
690
GetStartAndEndIndex(int32_t index)691 std::pair<int32_t, int32_t> DotIndicatorPaintMethod::GetStartAndEndIndex(int32_t index)
692 {
693 auto [startCurrentIndex, endCurrentIndex] = GetIndex(index);
694
695 if (pointAnimationStage_ == PointAnimationStage::STATE_EXPAND_TO_LONG_POINT &&
696 gestureState_ == GestureState::GESTURE_STATE_RELEASE_LEFT &&
697 touchBottomTypeLoop_ == TouchBottomTypeLoop::TOUCH_BOTTOM_TYPE_LOOP_LEFT) {
698 endCurrentIndex = startCurrentIndex;
699 return { startCurrentIndex, endCurrentIndex };
700 } else if (pointAnimationStage_ == PointAnimationStage::STATE_EXPAND_TO_LONG_POINT &&
701 gestureState_ == GestureState::GESTURE_STATE_RELEASE_RIGHT &&
702 touchBottomTypeLoop_ == TouchBottomTypeLoop::TOUCH_BOTTOM_TYPE_LOOP_RIGHT) {
703 endCurrentIndex = startCurrentIndex = 0;
704 return { startCurrentIndex, endCurrentIndex };
705 }
706
707 auto actualTurnPageRate = Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_EIGHTEEN) &&
708 isSwipeByGroup_ ? groupTurnPageRate_ : turnPageRate_;
709 if (touchBottomTypeLoop_ != TouchBottomTypeLoop::TOUCH_BOTTOM_TYPE_LOOP_NONE && Negative(actualTurnPageRate)) {
710 if (std::abs(actualTurnPageRate) >= FIFTY_PERCENT) {
711 return { endCurrentIndex, endCurrentIndex };
712 }
713
714 return { startCurrentIndex, startCurrentIndex };
715 }
716
717 return { startCurrentIndex, endCurrentIndex };
718 }
719
AdjustPointCenterXForTouchBottomNew(StarAndEndPointCenter & pointCenter,LinearVector<float> & endVectorBlackPointCenterX,int32_t endCurrentIndex,float selectedItemWidth)720 bool DotIndicatorPaintMethod::AdjustPointCenterXForTouchBottomNew(StarAndEndPointCenter& pointCenter,
721 LinearVector<float>& endVectorBlackPointCenterX, int32_t endCurrentIndex, float selectedItemWidth)
722 {
723 auto pageRate = std::abs(touchBottomPageRate_);
724 bool releaseLeftBottom = (gestureState_ == GestureState::GESTURE_STATE_RELEASE_LEFT &&
725 touchBottomTypeLoop_ == TouchBottomTypeLoop::TOUCH_BOTTOM_TYPE_LOOP_LEFT);
726 bool releaseRightBottom = (gestureState_ == GestureState::GESTURE_STATE_RELEASE_RIGHT &&
727 touchBottomTypeLoop_ == TouchBottomTypeLoop::TOUCH_BOTTOM_TYPE_LOOP_RIGHT);
728 if ((releaseLeftBottom && (!NearZero(touchBottomPageRate_) && pageRate <= FIFTY_PERCENT)) ||
729 (releaseRightBottom && pageRate >= FIFTY_PERCENT)) {
730 return true;
731 }
732
733 bool dragLeftBottom = (gestureState_ == GestureState::GESTURE_STATE_FOLLOW_LEFT &&
734 touchBottomTypeLoop_ == TouchBottomTypeLoop::TOUCH_BOTTOM_TYPE_LOOP_LEFT);
735 bool dragRightBottom = (gestureState_ == GestureState::GESTURE_STATE_FOLLOW_RIGHT &&
736 touchBottomTypeLoop_ == TouchBottomTypeLoop::TOUCH_BOTTOM_TYPE_LOOP_RIGHT);
737 if (dragLeftBottom && (!NearZero(touchBottomPageRate_) && pageRate <= FIFTY_PERCENT)) {
738 pointCenter.startLongPointLeftCenterX = pointCenter.startLongPointRightCenterX =
739 endVectorBlackPointCenterX[endCurrentIndex];
740 pointCenter.endLongPointLeftCenterX =
741 endVectorBlackPointCenterX[endCurrentIndex] - selectedItemWidth / HALF_SELECTED_WIDTH;
742 pointCenter.endLongPointRightCenterX =
743 endVectorBlackPointCenterX[endCurrentIndex] + selectedItemWidth / HALF_SELECTED_WIDTH;
744 return true;
745 }
746
747 if (dragRightBottom && pageRate >= FIFTY_PERCENT) {
748 pointCenter.startLongPointLeftCenterX = pointCenter.startLongPointRightCenterX = endVectorBlackPointCenterX[0];
749 pointCenter.endLongPointLeftCenterX = endVectorBlackPointCenterX[0] - selectedItemWidth / HALF_SELECTED_WIDTH;
750 pointCenter.endLongPointRightCenterX = endVectorBlackPointCenterX[0] + selectedItemWidth / HALF_SELECTED_WIDTH;
751 return true;
752 }
753
754 return false;
755 }
756
AdjustPointCenterXForTouchBottom(StarAndEndPointCenter & pointCenter,LinearVector<float> & endVectorBlackPointCenterX,int32_t startCurrentIndex,int32_t endCurrentIndex,float selectedItemWidth,int32_t index)757 void DotIndicatorPaintMethod::AdjustPointCenterXForTouchBottom(StarAndEndPointCenter& pointCenter,
758 LinearVector<float>& endVectorBlackPointCenterX, int32_t startCurrentIndex, int32_t endCurrentIndex,
759 float selectedItemWidth, int32_t index)
760 {
761 if (AdjustPointCenterXForTouchBottomNew(
762 pointCenter, endVectorBlackPointCenterX, endCurrentIndex, selectedItemWidth)) {
763 return;
764 }
765
766 if (Container::GreatOrEqualAPITargetVersion(PlatformVersion::VERSION_EIGHTEEN) && isSwipeByGroup_ && !isLoop_) {
767 return;
768 }
769
770 auto [startIndex, endIndex] = GetIndex(index);
771 if (touchBottomTypeLoop_ == TouchBottomTypeLoop::TOUCH_BOTTOM_TYPE_LOOP_LEFT &&
772 pointAnimationStage_ != PointAnimationStage::STATE_EXPAND_TO_LONG_POINT &&
773 (!(endIndex == startIndex && startIndex != 0) ||
774 (gestureState_ == GestureState::GESTURE_STATE_RELEASE_RIGHT ||
775 gestureState_ == GestureState::GESTURE_STATE_RELEASE_LEFT))) {
776 pointCenter.endLongPointRightCenterX = pointCenter.endLongPointLeftCenterX = endVectorBlackPointCenterX[0];
777 } else if (touchBottomTypeLoop_ == TouchBottomTypeLoop::TOUCH_BOTTOM_TYPE_LOOP_RIGHT &&
778 pointAnimationStage_ != PointAnimationStage::STATE_EXPAND_TO_LONG_POINT) {
779 pointCenter.endLongPointRightCenterX = pointCenter.endLongPointLeftCenterX =
780 endVectorBlackPointCenterX[startCurrentIndex];
781 }
782
783 if (pointAnimationStage_ == PointAnimationStage::STATE_EXPAND_TO_LONG_POINT &&
784 gestureState_ == GestureState::GESTURE_STATE_RELEASE_LEFT &&
785 touchBottomTypeLoop_ == TouchBottomTypeLoop::TOUCH_BOTTOM_TYPE_LOOP_LEFT) {
786 pointCenter.startLongPointRightCenterX = endVectorBlackPointCenterX[endCurrentIndex];
787 pointCenter.endLongPointLeftCenterX =
788 endVectorBlackPointCenterX[endCurrentIndex] - (selectedItemWidth / HALF_SELECTED_WIDTH);
789 } else if (pointAnimationStage_ == PointAnimationStage::STATE_EXPAND_TO_LONG_POINT &&
790 gestureState_ == GestureState::GESTURE_STATE_RELEASE_RIGHT &&
791 touchBottomTypeLoop_ == TouchBottomTypeLoop::TOUCH_BOTTOM_TYPE_LOOP_RIGHT) {
792 pointCenter.startLongPointRightCenterX = endVectorBlackPointCenterX[0];
793 pointCenter.endLongPointLeftCenterX = endVectorBlackPointCenterX[0] - (selectedItemWidth / HALF_SELECTED_WIDTH);
794 }
795 }
796
ForwardCalculation(const LinearVector<float> & itemHalfSizes,float startCenterX,float endCenterX,float space,int32_t index)797 std::pair<float, float> DotIndicatorPaintMethod::ForwardCalculation(
798 const LinearVector<float>& itemHalfSizes, float startCenterX, float endCenterX, float space, int32_t index)
799 {
800 auto itemWidth = itemHalfSizes[ITEM_HALF_WIDTH] * TWOFOLD;
801 auto selectedItemWidth = itemHalfSizes[SELECTED_ITEM_HALF_WIDTH] * TWOFOLD;
802 auto itemHalfWidth = itemHalfSizes[SELECTED_ITEM_HALF_WIDTH];
803 if (IsCustomSizeValue_) {
804 selectedItemWidth = itemHalfSizes[SELECTED_ITEM_HALF_WIDTH];
805 itemHalfWidth = itemHalfSizes[SELECTED_ITEM_HALF_WIDTH] * HALF_FLOAT;
806 }
807 StarAndEndPointCenter pointCenter;
808 // Calculate the data required for the current pages
809 LinearVector<float> startVectorBlackPointCenterX(itemCount_);
810 // Calculate the data required for subsequent pages
811 LinearVector<float> endVectorBlackPointCenterX(itemCount_);
812
813 auto [startCurrentIndex, endCurrentIndex] = GetStartAndEndIndex(index);
814 for (int32_t i = 0; i < itemCount_; ++i) {
815 if (i != startCurrentIndex) {
816 startVectorBlackPointCenterX[i] = startCenterX + itemHalfSizes[ITEM_HALF_WIDTH];
817 startCenterX += itemWidth;
818 } else {
819 startVectorBlackPointCenterX[i] = startCenterX + selectedItemWidth;
820 pointCenter.startLongPointLeftCenterX = startCenterX + itemHalfWidth;
821 pointCenter.startLongPointRightCenterX = pointCenter.startLongPointLeftCenterX + selectedItemWidth;
822 startCenterX += selectedItemWidth * TWOFOLD;
823 }
824 if (i != endCurrentIndex) {
825 endVectorBlackPointCenterX[i] = endCenterX + itemHalfSizes[ITEM_HALF_WIDTH];
826 endCenterX += itemWidth;
827 } else {
828 endVectorBlackPointCenterX[i] = endCenterX + selectedItemWidth;
829 pointCenter.endLongPointLeftCenterX = endCenterX + itemHalfWidth;
830 pointCenter.endLongPointRightCenterX = pointCenter.endLongPointLeftCenterX + selectedItemWidth;
831 endCenterX += selectedItemWidth * TWOFOLD;
832 }
833 startCenterX += space;
834 endCenterX += space;
835 }
836 AdjustPointCenterXForTouchBottom(
837 pointCenter, endVectorBlackPointCenterX, startCurrentIndex, endCurrentIndex, selectedItemWidth, index);
838 return CalculatePointCenterX(pointCenter, startVectorBlackPointCenterX, endVectorBlackPointCenterX);
839 }
840
BackwardCalculation(const LinearVector<float> & itemHalfSizes,float startCenterX,float endCenterX,float space,int32_t index)841 std::pair<float, float> DotIndicatorPaintMethod::BackwardCalculation(
842 const LinearVector<float>& itemHalfSizes, float startCenterX, float endCenterX, float space, int32_t index)
843 {
844 int32_t startCurrentIndex = index;
845 auto itemWidth = itemHalfSizes[ITEM_HALF_WIDTH] * TWOFOLD;
846 auto selectedItemWidth = itemHalfSizes[SELECTED_ITEM_HALF_WIDTH] * TWOFOLD;
847 auto itemHalfWidth = itemHalfSizes[SELECTED_ITEM_HALF_WIDTH];
848 if (IsCustomSizeValue_) {
849 selectedItemWidth = itemHalfSizes[SELECTED_ITEM_HALF_WIDTH];
850 itemHalfWidth = itemHalfSizes[SELECTED_ITEM_HALF_WIDTH] * HALF_FLOAT;
851 }
852 StarAndEndPointCenter pointCenter;
853 // Calculate the data required for the current pages
854 LinearVector<float> startVectorBlackPointCenterX(itemCount_);
855 // Calculate the data required for subsequent pages
856 LinearVector<float> endVectorBlackPointCenterX(itemCount_);
857 int32_t endCurrentIndex = NearEqual(turnPageRate_, 0.0f) || turnPageRate_ <= -1.0f || turnPageRate_ >= 1.0f
858 ? endCurrentIndex = index : (turnPageRate_ < 0.0f ? index + 1 : index - 1);
859 if (endCurrentIndex == -1) {
860 endCurrentIndex = itemCount_ - 1;
861 } else if (endCurrentIndex == itemCount_) {
862 endCurrentIndex = 0;
863 }
864 for (int32_t i = itemCount_ - 1; i >= 0; --i) {
865 if (i != startCurrentIndex) {
866 startVectorBlackPointCenterX[i] = startCenterX - itemHalfSizes[ITEM_HALF_WIDTH];
867 startCenterX -= itemWidth;
868 } else {
869 startVectorBlackPointCenterX[i] = startCenterX - itemHalfWidth;
870 pointCenter.startLongPointRightCenterX = startCenterX - itemHalfWidth;
871 pointCenter.startLongPointLeftCenterX = pointCenter.startLongPointRightCenterX - selectedItemWidth;
872 startCenterX -= selectedItemWidth * TWOFOLD;
873 }
874 if (i != endCurrentIndex) {
875 endVectorBlackPointCenterX[i] = endCenterX - itemHalfSizes[ITEM_HALF_WIDTH];
876 endCenterX -= itemWidth;
877 } else {
878 endVectorBlackPointCenterX[i] = endCenterX - itemHalfWidth;
879 pointCenter.endLongPointRightCenterX = endCenterX - itemHalfWidth;
880 pointCenter.endLongPointLeftCenterX = pointCenter.endLongPointRightCenterX - selectedItemWidth;
881 endCenterX -= selectedItemWidth * TWOFOLD;
882 }
883 startCenterX -= space;
884 endCenterX -= space;
885 }
886 return CalculatePointCenterX(pointCenter, startVectorBlackPointCenterX, endVectorBlackPointCenterX);
887 }
888 } // namespace OHOS::Ace::NG
889