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/indicator_common/swiper_indicator_pattern.h"
17
18 #include "base/log/dump_log.h"
19 #include "base/utils/utils.h"
20 #include "core/components_ng/base/frame_node.h"
21 #include "core/components_ng/pattern/swiper/swiper_pattern.h"
22 #include "core/components_ng/pattern/swiper/swiper_utils.h"
23 #include "core/event/ace_events.h"
24 #include "core/event/mouse_event.h"
25 #include "core/pipeline_ng/pipeline_context.h"
26
27 namespace OHOS::Ace::NG {
28 namespace {
29 constexpr Dimension INDICATOR_PADDING_DOT = 12.0_vp;
30 constexpr float INDICATOR_ZOOM_IN_SCALE = 1.33f;
31 constexpr Dimension INDICATOR_ITEM_SPACE = 8.0_vp;
32 constexpr Dimension INDICATOR_PADDING_DEFAULT = 12.0_vp;
33 constexpr uint32_t INDICATOR_HAS_CHILD = 2;
34 constexpr Dimension INDICATOR_DRAG_MIN_DISTANCE = 4.0_vp;
35 constexpr Dimension INDICATOR_DRAG_MAX_DISTANCE = 18.0_vp;
36 constexpr Dimension INDICATOR_TOUCH_BOTTOM_MAX_DISTANCE = 80.0_vp;
37 constexpr int32_t LONG_PRESS_DELAY = 300;
38 constexpr float HALF_FLOAT = 0.5f;
39 constexpr float MAX_FONT_SCALE = 2.0f;
40 } // namespace
41
OnAttachToFrameNode()42 void SwiperIndicatorPattern::OnAttachToFrameNode()
43 {
44 auto host = GetHost();
45 CHECK_NULL_VOID(host);
46 host->GetRenderContext()->SetClipToBounds(true);
47 }
48
OnModifyDone()49 void SwiperIndicatorPattern::OnModifyDone()
50 {
51 Pattern::OnModifyDone();
52 auto host = GetHost();
53 CHECK_NULL_VOID(host);
54
55 auto swiperNode = GetSwiperNode();
56 CHECK_NULL_VOID(swiperNode);
57 auto swiperPattern = swiperNode->GetPattern<SwiperPattern>();
58 CHECK_NULL_VOID(swiperPattern);
59 swiperIndicatorType_ = swiperPattern->GetIndicatorType();
60 if (swiperIndicatorType_ == SwiperIndicatorType::DIGIT) {
61 RefPtr<FrameNode> firstTextNode;
62 RefPtr<FrameNode> lastTextNode;
63 auto layoutProperty = host->GetLayoutProperty<SwiperIndicatorLayoutProperty>();
64 CHECK_NULL_VOID(layoutProperty);
65 if (host->GetChildren().size() == INDICATOR_HAS_CHILD) {
66 firstTextNode = DynamicCast<FrameNode>(host->GetFirstChild());
67 lastTextNode = DynamicCast<FrameNode>(host->GetLastChild());
68 } else {
69 host->Clean();
70 firstTextNode = FrameNode::CreateFrameNode(
71 V2::TEXT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<TextPattern>());
72 lastTextNode = FrameNode::CreateFrameNode(
73 V2::TEXT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<TextPattern>());
74 }
75 UpdateTextContent(layoutProperty, firstTextNode, lastTextNode);
76 host->AddChild(firstTextNode);
77 host->AddChild(lastTextNode);
78 } else {
79 host->Clean();
80 }
81
82 if (dotIndicatorModifier_) {
83 dotIndicatorModifier_->StopAnimation();
84 }
85
86 auto swiperEventHub = swiperPattern->GetEventHub<SwiperEventHub>();
87 CHECK_NULL_VOID(swiperEventHub);
88
89 swiperEventHub->SetIndicatorOnChange(
90 [weak = AceType::WeakClaim(RawPtr(host)), context = AceType::WeakClaim(this)]() {
91 auto pipeline = PipelineContext::GetCurrentContextSafely();
92 CHECK_NULL_VOID(pipeline);
93 pipeline->AddAfterLayoutTask([weak, context]() {
94 auto indicator = weak.Upgrade();
95 CHECK_NULL_VOID(indicator);
96 auto textContext = context.Upgrade();
97 CHECK_NULL_VOID(textContext);
98 if (textContext->swiperIndicatorType_ == SwiperIndicatorType::DIGIT) {
99 RefPtr<FrameNode> firstTextNode;
100 RefPtr<FrameNode> lastTextNode;
101 auto layoutProperty = indicator->GetLayoutProperty<SwiperIndicatorLayoutProperty>();
102 firstTextNode = DynamicCast<FrameNode>(indicator->GetFirstChild());
103 lastTextNode = DynamicCast<FrameNode>(indicator->GetLastChild());
104 textContext->UpdateTextContent(layoutProperty, firstTextNode, lastTextNode);
105 }
106 indicator->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
107 });
108 pipeline->RequestFrame();
109 });
110 auto swiperLayoutProperty = swiperPattern->GetLayoutProperty<SwiperLayoutProperty>();
111 CHECK_NULL_VOID(swiperLayoutProperty);
112 if (swiperLayoutProperty->GetIndicatorTypeValue(SwiperIndicatorType::DOT) == SwiperIndicatorType::DOT) {
113 auto gestureHub = host->GetOrCreateGestureEventHub();
114 CHECK_NULL_VOID(gestureHub);
115 InitClickEvent(gestureHub);
116 InitHoverMouseEvent();
117 InitTouchEvent(gestureHub);
118 InitLongPressEvent(gestureHub);
119 }
120 }
121
OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper> & dirty,const DirtySwapConfig & config)122 bool SwiperIndicatorPattern::OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config)
123 {
124 CHECK_NULL_RETURN(config.frameSizeChange, false);
125 return true;
126 }
127
InitClickEvent(const RefPtr<GestureEventHub> & gestureHub)128 void SwiperIndicatorPattern::InitClickEvent(const RefPtr<GestureEventHub>& gestureHub)
129 {
130 CHECK_NULL_VOID(!clickEvent_);
131 auto clickTask = [weak = WeakClaim(this)](const GestureEvent& info) {
132 auto pattern = weak.Upgrade();
133 CHECK_NULL_VOID(pattern);
134 pattern->HandleClick(info);
135 };
136 clickEvent_ = MakeRefPtr<ClickEvent>(std::move(clickTask));
137 gestureHub->AddClickEvent(clickEvent_);
138 }
139
HandleClick(const GestureEvent & info)140 void SwiperIndicatorPattern::HandleClick(const GestureEvent& info)
141 {
142 if (info.GetSourceDevice() == SourceType::KEYBOARD) {
143 return;
144 }
145
146 if (info.GetSourceDevice() == SourceType::MOUSE) {
147 isClicked_ = true;
148 HandleMouseClick(info);
149 } else {
150 HandleTouchClick(info);
151 }
152 }
153
HandleMouseClick(const GestureEvent &)154 void SwiperIndicatorPattern::HandleMouseClick(const GestureEvent& /* info */)
155 {
156 if (isRepeatClicked_) {
157 return;
158 }
159 GetMouseClickIndex();
160 CHECK_NULL_VOID(mouseClickIndex_);
161 auto swiperNode = GetSwiperNode();
162 CHECK_NULL_VOID(swiperNode);
163 auto swiperPattern = swiperNode->GetPattern<SwiperPattern>();
164 CHECK_NULL_VOID(swiperPattern);
165
166 if (swiperPattern->IsSwipeByGroup()) {
167 auto clickPageIndex = SwiperUtils::ComputePageIndex(mouseClickIndex_.value(), swiperPattern->GetDisplayCount());
168 if (clickPageIndex == swiperPattern->GetCurrentIndex()) {
169 mouseClickIndex_ = std::nullopt;
170 return;
171 }
172
173 mouseClickIndex_ = clickPageIndex;
174 }
175
176 swiperPattern->SwipeTo(mouseClickIndex_.value());
177 auto host = GetHost();
178 CHECK_NULL_VOID(host);
179 host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
180 }
181
HandleTouchClick(const GestureEvent & info)182 void SwiperIndicatorPattern::HandleTouchClick(const GestureEvent& info)
183 {
184 auto host = GetHost();
185 CHECK_NULL_VOID(host);
186 auto paintProperty = host->GetPaintProperty<DotIndicatorPaintProperty>();
187 CHECK_NULL_VOID(paintProperty);
188 auto pipeline = PipelineBase::GetCurrentContext();
189 CHECK_NULL_VOID(pipeline);
190 auto theme = pipeline->GetTheme<SwiperIndicatorTheme>();
191 CHECK_NULL_VOID(theme);
192 auto itemWidth = paintProperty->GetItemWidthValue(theme->GetSize()).ConvertToPx();
193 auto selectedItemWidth = paintProperty->GetSelectedItemWidthValue(theme->GetSize()).ConvertToPx();
194 if (Negative(itemWidth) || Negative(selectedItemWidth)) {
195 itemWidth = theme->GetSize().ConvertToPx();
196 selectedItemWidth = theme->GetSize().ConvertToPx();
197 }
198 auto swiperNode = GetSwiperNode();
199 CHECK_NULL_VOID(swiperNode);
200 auto swiperPattern = swiperNode->GetPattern<SwiperPattern>();
201 CHECK_NULL_VOID(swiperPattern);
202
203 auto isRtl = swiperPattern->GetNonAutoLayoutDirection() == TextDirection::RTL;
204 auto indicatorCount = swiperPattern->RealTotalCount();
205 auto currentIndex = swiperPattern->GetCurrentIndex();
206 if (isRtl) {
207 currentIndex = indicatorCount - 1 - currentIndex;
208 }
209
210 auto margin = HandleTouchClickMargin();
211 auto lengthBeforeCurrentIndex = margin + INDICATOR_PADDING_DEFAULT.ConvertToPx() +
212 (INDICATOR_ITEM_SPACE.ConvertToPx() + itemWidth) * currentIndex;
213 auto lengthWithCurrentIndex = lengthBeforeCurrentIndex + selectedItemWidth;
214 auto axis = swiperPattern->GetDirection();
215 auto mainClickOffset = axis == Axis::HORIZONTAL ? info.GetLocalLocation().GetX() : info.GetLocalLocation().GetY();
216 if (mainClickOffset < lengthBeforeCurrentIndex) {
217 isRtl ? swiperPattern->ShowNext() : swiperPattern->ShowPrevious();
218 } else if (mainClickOffset > lengthWithCurrentIndex) {
219 isRtl ? swiperPattern->ShowPrevious() : swiperPattern->ShowNext();
220 }
221 }
222
InitHoverMouseEvent()223 void SwiperIndicatorPattern::InitHoverMouseEvent()
224 {
225 auto host = GetHost();
226 CHECK_NULL_VOID(host);
227 auto eventHub = host->GetEventHub<EventHub>();
228 CHECK_NULL_VOID(eventHub);
229 auto inputHub = eventHub->GetOrCreateInputEventHub();
230 CHECK_NULL_VOID(inputHub);
231
232 auto hoverTask = [weak = WeakClaim(this)](bool isHover, HoverInfo& info) {
233 auto pattern = weak.Upgrade();
234 if (pattern && info.GetSourceDevice() != SourceType::TOUCH) {
235 pattern->HandleHoverEvent(isHover);
236 }
237 };
238
239 if (!hoverEvent_) {
240 hoverEvent_ = MakeRefPtr<InputEvent>(std::move(hoverTask));
241 inputHub->AddOnHoverEvent(hoverEvent_);
242 }
243
244 auto mouseEvent = [weak = WeakClaim(this)](MouseInfo& info) {
245 auto pattern = weak.Upgrade();
246 if (pattern) {
247 pattern->HandleMouseEvent(info);
248 }
249 };
250 if (mouseEvent_) {
251 inputHub->RemoveOnMouseEvent(mouseEvent_);
252 }
253 mouseEvent_ = MakeRefPtr<InputEvent>(std::move(mouseEvent));
254 inputHub->AddOnMouseEvent(mouseEvent_);
255 }
256
HandleMouseEvent(const MouseInfo & info)257 void SwiperIndicatorPattern::HandleMouseEvent(const MouseInfo& info)
258 {
259 if (info.GetSourceDevice() == SourceType::TOUCH) {
260 return;
261 }
262 auto mouseOffsetX = static_cast<float>(info.GetLocalLocation().GetX());
263 auto mouseOffsetY = static_cast<float>(info.GetLocalLocation().GetY());
264 auto mouseAction = info.GetAction();
265 if ((mouseAction == MouseAction::PRESS || mouseAction == MouseAction::RELEASE) &&
266 isClicked_ && NearEqual(hoverPoint_, PointF(mouseOffsetX, mouseOffsetY))) {
267 isRepeatClicked_ = true;
268 return;
269 }
270 isClicked_ = false;
271 isRepeatClicked_ = false;
272 auto host = GetHost();
273 CHECK_NULL_VOID(host);
274 hoverPoint_.SetX(mouseOffsetX);
275 hoverPoint_.SetY(mouseOffsetY);
276
277 host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
278 }
279
HandleHoverEvent(bool isHover)280 void SwiperIndicatorPattern::HandleHoverEvent(bool isHover)
281 {
282 if (isHover_ == isHover) {
283 return;
284 }
285
286 isHover_ = isHover;
287 auto host = GetHost();
288 CHECK_NULL_VOID(host);
289 auto swiperNode = GetSwiperNode();
290 CHECK_NULL_VOID(swiperNode);
291 auto swiperPattern = swiperNode->GetPattern<SwiperPattern>();
292 CHECK_NULL_VOID(swiperPattern);
293 auto swiperLayoutProperty = swiperPattern->GetLayoutProperty<SwiperLayoutProperty>();
294 CHECK_NULL_VOID(swiperLayoutProperty);
295 if (swiperLayoutProperty->GetHoverShowValue(false) && !swiperPattern->GetIsAtHotRegion()) {
296 swiperPattern->ArrowHover(isHover_);
297 }
298 host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
299 }
300
InitTouchEvent(const RefPtr<GestureEventHub> & gestureHub)301 void SwiperIndicatorPattern::InitTouchEvent(const RefPtr<GestureEventHub>& gestureHub)
302 {
303 if (touchEvent_) {
304 return;
305 }
306
307 auto touchTask = [weak = WeakClaim(this)](const TouchEventInfo& info) {
308 auto pattern = weak.Upgrade();
309 if (pattern) {
310 pattern->HandleTouchEvent(info);
311 }
312 };
313
314 if (touchEvent_) {
315 gestureHub->RemoveTouchEvent(touchEvent_);
316 }
317 touchEvent_ = MakeRefPtr<TouchEventImpl>(std::move(touchTask));
318 gestureHub->AddTouchEvent(touchEvent_);
319
320 auto swiperNode = GetSwiperNode();
321 CHECK_NULL_VOID(swiperNode);
322 auto swiperPattern = swiperNode->GetPattern<SwiperPattern>();
323 CHECK_NULL_VOID(swiperPattern);
324 auto stopAnimationCb = [weak = WeakClaim(this)](bool ifImmediately) {
325 auto pattern = weak.Upgrade();
326 if (pattern) {
327 if (pattern->dotIndicatorModifier_) {
328 pattern->dotIndicatorModifier_->StopAnimation(ifImmediately);
329 }
330
331 if (pattern->overlongDotIndicatorModifier_) {
332 pattern->overlongDotIndicatorModifier_->StopAnimation(ifImmediately);
333 }
334 }
335 };
336 swiperPattern->SetStopIndicatorAnimationCb(stopAnimationCb);
337 }
338
HandleTouchEvent(const TouchEventInfo & info)339 void SwiperIndicatorPattern::HandleTouchEvent(const TouchEventInfo& info)
340 {
341 auto touchType = info.GetTouches().front().GetTouchType();
342 if (touchType == TouchType::UP) {
343 HandleTouchUp();
344 HandleDragEnd(0);
345 isPressed_ = false;
346 } else if (touchType == TouchType::CANCEL) {
347 HandleTouchUp();
348 HandleDragEnd(0);
349 isPressed_ = false;
350 }
351 if (isPressed_) {
352 HandleLongDragUpdate(info.GetTouches().front());
353 }
354 }
355
HandleTouchDown()356 void SwiperIndicatorPattern::HandleTouchDown()
357 {
358 isPressed_ = true;
359 auto host = GetHost();
360 CHECK_NULL_VOID(host);
361 host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
362 }
363
HandleTouchUp()364 void SwiperIndicatorPattern::HandleTouchUp()
365 {
366 isPressed_ = false;
367 auto host = GetHost();
368 CHECK_NULL_VOID(host);
369 host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
370 }
371
GetMouseClickIndex()372 void SwiperIndicatorPattern::GetMouseClickIndex()
373 {
374 auto pipelineContext = PipelineBase::GetCurrentContext();
375 CHECK_NULL_VOID(pipelineContext);
376 auto swiperTheme = pipelineContext->GetTheme<SwiperIndicatorTheme>();
377 CHECK_NULL_VOID(swiperTheme);
378 auto host = GetHost();
379 CHECK_NULL_VOID(host);
380 auto paintProperty = host->GetPaintProperty<DotIndicatorPaintProperty>();
381 CHECK_NULL_VOID(paintProperty);
382 auto swiperNode = GetSwiperNode();
383 CHECK_NULL_VOID(swiperNode);
384 auto swiperPattern = swiperNode->GetPattern<SwiperPattern>();
385 CHECK_NULL_VOID(swiperPattern);
386 float itemWidthValue = static_cast<float>(paintProperty->GetItemWidthValue(swiperTheme->GetSize()).ConvertToPx());
387 float itemHeightValue = static_cast<float>(paintProperty->GetItemHeightValue(swiperTheme->GetSize()).ConvertToPx());
388 float selectedItemWidthValue =
389 static_cast<float>(paintProperty->GetSelectedItemWidthValue(swiperTheme->GetSize()).ConvertToPx() * 2);
390 paintProperty->GetIsCustomSizeValue(false) ? selectedItemWidthValue *= 0.5f : selectedItemWidthValue;
391 // diameter calculation
392 float itemWidth = itemWidthValue * INDICATOR_ZOOM_IN_SCALE;
393 float itemHeight = itemHeightValue * INDICATOR_ZOOM_IN_SCALE;
394 float selectedItemWidth = selectedItemWidthValue * INDICATOR_ZOOM_IN_SCALE;
395 float space = static_cast<float>(INDICATOR_ITEM_SPACE.ConvertToPx());
396 int32_t currentIndex = swiperPattern->GetCurrentShownIndex();
397 int32_t itemCount = swiperPattern->RealTotalCount();
398 int32_t loopCount = SwiperIndicatorUtils::CalcLoopCount(currentIndex, itemCount);
399 auto frameSize = host->GetGeometryNode()->GetFrameSize();
400 auto axis = swiperPattern->GetDirection();
401 float centerX = static_cast<float>(INDICATOR_PADDING_DOT.ConvertToPx());
402 float centerY = ((axis == Axis::HORIZONTAL ? frameSize.Height() : frameSize.Width()) - itemHeight) * 0.5f;
403 PointF hoverPoint = axis == Axis::HORIZONTAL ? hoverPoint_ : PointF(hoverPoint_.GetY(), hoverPoint_.GetX());
404 int start = currentIndex >= 0 ? loopCount * itemCount : -(loopCount + 1) * itemCount;
405 int end = currentIndex >= 0 ? (loopCount + 1) * itemCount : -loopCount * itemCount;
406 if (swiperPattern->IsHorizontalAndRightToLeft()) {
407 end = currentIndex >= 0 ? loopCount * itemCount - 1 : -(loopCount + 1) * itemCount - 1;
408 start = currentIndex >= 0 ? (loopCount + 1) * itemCount - 1 : -loopCount * itemCount - 1;
409 }
410 for (int32_t i = start; i != end; start > end ? --i : ++i) {
411 if (i != currentIndex) {
412 if (hoverPoint.GetX() >= centerX && hoverPoint.GetX() <= centerX + itemWidth &&
413 hoverPoint.GetY() >= centerY && hoverPoint.GetY() <= centerY + itemHeight) {
414 mouseClickIndex_ = i;
415 break;
416 }
417 centerX += itemWidth + space;
418 } else {
419 centerX += selectedItemWidth + space;
420 }
421 }
422 }
423
UpdateTextContent(const RefPtr<SwiperIndicatorLayoutProperty> & layoutProperty,const RefPtr<FrameNode> & firstTextNode,const RefPtr<FrameNode> & lastTextNode)424 void SwiperIndicatorPattern::UpdateTextContent(const RefPtr<SwiperIndicatorLayoutProperty>& layoutProperty,
425 const RefPtr<FrameNode>& firstTextNode, const RefPtr<FrameNode>& lastTextNode)
426 {
427 CHECK_NULL_VOID(layoutProperty);
428 CHECK_NULL_VOID(firstTextNode);
429 CHECK_NULL_VOID(lastTextNode);
430 auto pipeline = PipelineBase::GetCurrentContext();
431 CHECK_NULL_VOID(pipeline);
432 auto theme = pipeline->GetTheme<SwiperIndicatorTheme>();
433 firstTextNode->SetInternal();
434 lastTextNode->SetInternal();
435 auto firstTextLayoutProperty = firstTextNode->GetLayoutProperty<TextLayoutProperty>();
436 CHECK_NULL_VOID(firstTextLayoutProperty);
437 auto selectedFontColor =
438 layoutProperty->GetSelectedFontColorValue(theme->GetDigitalIndicatorTextStyle().GetTextColor());
439 auto selectedFontSize =
440 layoutProperty->GetSelectedFontSizeValue(theme->GetDigitalIndicatorTextStyle().GetFontSize());
441 if (!selectedFontSize.IsValid()) {
442 selectedFontSize = theme->GetDigitalIndicatorTextStyle().GetFontSize();
443 }
444 auto selectedFontWeight =
445 layoutProperty->GetSelectedFontWeightValue(theme->GetDigitalIndicatorTextStyle().GetFontWeight());
446 firstTextLayoutProperty->UpdateTextColor(selectedFontColor);
447 firstTextLayoutProperty->UpdateFontSize(selectedFontSize);
448 firstTextLayoutProperty->UpdateFontWeight(selectedFontWeight);
449 firstTextLayoutProperty->UpdateMaxFontScale(MAX_FONT_SCALE);
450 UpdateTextContentSub(layoutProperty, firstTextNode, lastTextNode);
451 }
452
GetDisplayCurrentIndex() const453 int32_t SwiperIndicatorPattern::GetDisplayCurrentIndex() const
454 {
455 auto swiperNode = GetSwiperNode();
456 CHECK_NULL_RETURN(swiperNode, 0);
457 auto swiperPattern = swiperNode->GetPattern<SwiperPattern>();
458 CHECK_NULL_RETURN(swiperPattern, 0);
459 CHECK_NULL_RETURN(swiperPattern->RealTotalCount(), 0);
460 auto swiperLayoutProperty = swiperPattern->GetLayoutProperty<SwiperLayoutProperty>();
461 CHECK_NULL_RETURN(swiperLayoutProperty, 0);
462 auto currentIndex = swiperPattern->GetCurrentFirstIndex() + 1;
463 if (currentIndex > swiperPattern->RealTotalCount()) {
464 currentIndex = 1;
465 } else if (swiperLayoutProperty->HasIndex()) {
466 currentIndex = GetCurrentIndex() + 1;
467 if (currentIndex > swiperPattern->RealTotalCount()) {
468 currentIndex = 1;
469 }
470 }
471
472 return currentIndex;
473 }
474
GetCurrentIndex() const475 int32_t SwiperIndicatorPattern::GetCurrentIndex() const
476 {
477 auto swiperNode = GetSwiperNode();
478 CHECK_NULL_RETURN(swiperNode, 0);
479 auto swiperPattern = swiperNode->GetPattern<SwiperPattern>();
480 CHECK_NULL_RETURN(swiperPattern, 0);
481 auto swiperLayoutProperty = swiperPattern->GetLayoutProperty<SwiperLayoutProperty>();
482 CHECK_NULL_RETURN(swiperLayoutProperty, 0);
483 auto currentIndex = swiperLayoutProperty->GetIndex().value_or(0);
484 if (swiperPattern->IsSwipeByGroup()) {
485 currentIndex = SwiperUtils::ComputePageIndex(currentIndex, swiperPattern->GetDisplayCount());
486 }
487
488 return currentIndex;
489 }
490
UpdateTextContentSub(const RefPtr<SwiperIndicatorLayoutProperty> & layoutProperty,const RefPtr<FrameNode> & firstTextNode,const RefPtr<FrameNode> & lastTextNode)491 void SwiperIndicatorPattern::UpdateTextContentSub(const RefPtr<SwiperIndicatorLayoutProperty>& layoutProperty,
492 const RefPtr<FrameNode>& firstTextNode, const RefPtr<FrameNode>& lastTextNode)
493 {
494 CHECK_NULL_VOID(layoutProperty);
495 CHECK_NULL_VOID(firstTextNode);
496 CHECK_NULL_VOID(lastTextNode);
497 auto swiperNode = GetSwiperNode();
498 CHECK_NULL_VOID(swiperNode);
499 auto pipeline = PipelineBase::GetCurrentContext();
500 CHECK_NULL_VOID(pipeline);
501 auto swiperPattern = swiperNode->GetPattern<SwiperPattern>();
502 CHECK_NULL_VOID(swiperPattern);
503 auto swiperLayoutProperty = swiperPattern->GetLayoutProperty<SwiperLayoutProperty>();
504 CHECK_NULL_VOID(swiperLayoutProperty);
505 auto currentIndex = GetDisplayCurrentIndex();
506 auto lastTextLayoutProperty = lastTextNode->GetLayoutProperty<TextLayoutProperty>();
507 CHECK_NULL_VOID(lastTextLayoutProperty);
508 lastTextLayoutProperty->UpdateLayoutDirection(swiperPattern->GetNonAutoLayoutDirection());
509 bool isRtl = swiperPattern->GetNonAutoLayoutDirection() == TextDirection::RTL;
510 std::string firstContent = isRtl ? std::to_string(swiperPattern->RealTotalCount()) : std::to_string(currentIndex);
511 std::string lastContent = isRtl ? std::to_string(currentIndex) + "\\" :
512 "/" + std::to_string(swiperPattern->RealTotalCount());
513
514 auto firstTextLayoutProperty = firstTextNode->GetLayoutProperty<TextLayoutProperty>();
515 CHECK_NULL_VOID(firstTextLayoutProperty);
516 firstTextLayoutProperty->UpdateContent(firstContent);
517 auto theme = pipeline->GetTheme<SwiperIndicatorTheme>();
518 CHECK_NULL_VOID(theme);
519 auto fontColor = layoutProperty->GetFontColorValue(theme->GetDigitalIndicatorTextStyle().GetTextColor());
520 auto fontSize = layoutProperty->GetFontSizeValue(theme->GetDigitalIndicatorTextStyle().GetFontSize());
521 if (!fontSize.IsValid()) {
522 fontSize = theme->GetDigitalIndicatorTextStyle().GetFontSize();
523 }
524 auto fontWeight = layoutProperty->GetFontWeightValue(theme->GetDigitalIndicatorTextStyle().GetFontWeight());
525 lastTextLayoutProperty->UpdateTextColor(fontColor);
526 lastTextLayoutProperty->UpdateFontSize(fontSize);
527 lastTextLayoutProperty->UpdateFontWeight(fontWeight);
528 lastTextLayoutProperty->UpdateContent(lastContent);
529 lastTextLayoutProperty->UpdateMaxFontScale(MAX_FONT_SCALE);
530 firstTextNode->MarkModifyDone();
531 firstTextNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT);
532 lastTextNode->MarkModifyDone();
533 lastTextNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT);
534 }
535
HandleDragStart(const GestureEvent & info)536 void SwiperIndicatorPattern::HandleDragStart(const GestureEvent& info)
537 {
538 dragStartPoint_ =
539 PointF(static_cast<float>(info.GetLocalLocation().GetX()), static_cast<float>(info.GetLocalLocation().GetY()));
540 }
541
HandleDragEnd(double dragVelocity)542 void SwiperIndicatorPattern::HandleDragEnd(double dragVelocity)
543 {
544 auto swiperNode = GetSwiperNode();
545 CHECK_NULL_VOID(swiperNode);
546 auto swiperPattern = swiperNode->GetPattern<SwiperPattern>();
547 CHECK_NULL_VOID(swiperPattern);
548 swiperPattern->SetTurnPageRate(0.0f);
549 auto swiperPaintProperty = swiperPattern->GetPaintProperty<SwiperPaintProperty>();
550 CHECK_NULL_VOID(swiperPaintProperty);
551 auto autoPlay = swiperPaintProperty->GetAutoPlay().value_or(false);
552 if (autoPlay) {
553 swiperPattern->SetIndicatorLongPress(false);
554 swiperPattern->StartAutoPlay();
555 }
556 auto host = GetHost();
557 CHECK_NULL_VOID(host);
558 touchBottomType_ = TouchBottomType::NONE;
559 host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
560 }
561
SetIndicatorInteractive(bool isInteractive)562 void SwiperIndicatorPattern::SetIndicatorInteractive(bool isInteractive)
563 {
564 auto host = GetHost();
565 CHECK_NULL_VOID(host);
566 auto eventHub = host->GetEventHub<EventHub>();
567 CHECK_NULL_VOID(eventHub);
568 if (isInteractive) {
569 eventHub->SetEnabled(true);
570 } else {
571 eventHub->SetEnabled(false);
572 }
573 }
574
CheckIsTouchBottom(const GestureEvent & info)575 bool SwiperIndicatorPattern::CheckIsTouchBottom(const GestureEvent& info)
576 {
577 auto swiperNode = GetSwiperNode();
578 CHECK_NULL_RETURN(swiperNode, false);
579 auto swiperPattern = swiperNode->GetPattern<SwiperPattern>();
580 CHECK_NULL_RETURN(swiperPattern, false);
581 auto currentIndex = swiperPattern->GetCurrentIndex();
582 auto childrenSize = swiperPattern->RealTotalCount();
583
584 auto swiperLayoutProperty = swiperNode->GetLayoutProperty<SwiperLayoutProperty>();
585 CHECK_NULL_RETURN(swiperLayoutProperty, false);
586 auto displayCount = swiperLayoutProperty->GetDisplayCount().value_or(1);
587 auto isLoop = swiperLayoutProperty->GetLoop().value_or(true);
588 auto dragPoint =
589 PointF(static_cast<float>(info.GetLocalLocation().GetX()), static_cast<float>(info.GetLocalLocation().GetY()));
590 auto offset = dragPoint - dragStartPoint_;
591 auto touchOffset = swiperPattern->GetDirection() == Axis::HORIZONTAL ? offset.GetX() : offset.GetY();
592 auto touchBottomRate = LessOrEqual(std::abs(touchOffset), INDICATOR_TOUCH_BOTTOM_MAX_DISTANCE.ConvertToPx())
593 ? touchOffset / INDICATOR_TOUCH_BOTTOM_MAX_DISTANCE.ConvertToPx()
594 : 1;
595
596 swiperPattern->SetTurnPageRate(0);
597 swiperPattern->SetTouchBottomRate(std::abs(touchBottomRate));
598 TouchBottomType touchBottomType = TouchBottomType::NONE;
599
600 if ((currentIndex <= 0) && !isLoop) {
601 if (Negative(info.GetMainDelta()) || NonPositive(touchOffset)) {
602 touchBottomType = TouchBottomType::START;
603 }
604 }
605
606 if ((currentIndex >= childrenSize - displayCount) && !isLoop) {
607 if (Positive(info.GetMainDelta()) || NonNegative(touchOffset)) {
608 touchBottomType = TouchBottomType::END;
609 }
610 }
611
612 touchBottomType_ = touchBottomType;
613 auto host = GetHost();
614 CHECK_NULL_RETURN(host, false);
615 host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
616
617 return touchBottomType == TouchBottomType::NONE ? false : true;
618 }
619
CheckIsTouchBottom(const TouchLocationInfo & info)620 bool SwiperIndicatorPattern::CheckIsTouchBottom(const TouchLocationInfo& info)
621 {
622 auto swiperNode = GetSwiperNode();
623 CHECK_NULL_RETURN(swiperNode, false);
624 auto swiperPattern = swiperNode->GetPattern<SwiperPattern>();
625 CHECK_NULL_RETURN(swiperPattern, false);
626 auto host = GetHost();
627 CHECK_NULL_RETURN(host, false);
628 auto currentIndex = swiperPattern->GetCurrentIndex();
629 auto childrenSize = swiperPattern->RealTotalCount();
630
631 auto swiperLayoutProperty = swiperNode->GetLayoutProperty<SwiperLayoutProperty>();
632 CHECK_NULL_RETURN(swiperLayoutProperty, false);
633 auto displayCount = swiperLayoutProperty->GetDisplayCount().value_or(1);
634
635 auto dragPoint =
636 PointF(static_cast<float>(info.GetLocalLocation().GetX()), static_cast<float>(info.GetLocalLocation().GetY()));
637 auto offset = dragPoint - dragStartPoint_;
638 auto touchOffset = swiperPattern->GetDirection() == Axis::HORIZONTAL ? offset.GetX() : offset.GetY();
639 auto touchBottomRate = LessOrEqual(std::abs(touchOffset), INDICATOR_TOUCH_BOTTOM_MAX_DISTANCE.ConvertToPx())
640 ? touchOffset / INDICATOR_TOUCH_BOTTOM_MAX_DISTANCE.ConvertToPx()
641 : 1;
642
643 swiperPattern->SetTurnPageRate(0);
644 swiperPattern->SetTouchBottomRate(std::abs(touchBottomRate));
645 TouchBottomType touchBottomType = TouchBottomType::NONE;
646
647 if (currentIndex <= 0) {
648 if (swiperPattern->IsHorizontalAndRightToLeft()) {
649 if (Positive(touchOffset)) {
650 touchBottomType = TouchBottomType::END;
651 }
652 } else {
653 if (NonPositive(touchOffset)) {
654 touchBottomType = TouchBottomType::START;
655 }
656 }
657 }
658
659 if (currentIndex >= childrenSize - displayCount) {
660 if (swiperPattern->IsHorizontalAndRightToLeft()) {
661 if (NonPositive(touchOffset)) {
662 touchBottomType = TouchBottomType::START;
663 }
664 } else {
665 if (Positive(touchOffset)) {
666 touchBottomType = TouchBottomType::END;
667 }
668 }
669 }
670 touchBottomType_ = touchBottomType;
671 host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
672
673 return touchBottomType == TouchBottomType::NONE ? false : true;
674 }
675
InitLongPressEvent(const RefPtr<GestureEventHub> & gestureHub)676 void SwiperIndicatorPattern::InitLongPressEvent(const RefPtr<GestureEventHub>& gestureHub)
677 {
678 CHECK_NULL_VOID(!longPressEvent_);
679 auto longPressCallback = [weak = WeakClaim(this)](GestureEvent& info) {
680 auto pattern = weak.Upgrade();
681 CHECK_NULL_VOID(pattern);
682 pattern->HandleLongPress(info);
683 };
684 longPressEvent_ = MakeRefPtr<LongPressEvent>(std::move(longPressCallback));
685
686 gestureHub->SetLongPressEvent(longPressEvent_, false, false, LONG_PRESS_DELAY);
687 }
688
HandleLongPress(GestureEvent & info)689 void SwiperIndicatorPattern::HandleLongPress(GestureEvent& info)
690 {
691 HandleTouchDown();
692 HandleDragStart(info);
693
694 auto swiperNode = GetSwiperNode();
695 CHECK_NULL_VOID(swiperNode);
696 auto swiperPattern = swiperNode->GetPattern<SwiperPattern>();
697 CHECK_NULL_VOID(swiperPattern);
698 auto swiperPaintProperty = swiperPattern->GetPaintProperty<SwiperPaintProperty>();
699 CHECK_NULL_VOID(swiperPaintProperty);
700 auto autoPlay = swiperPaintProperty->GetAutoPlay().value_or(false);
701 if (autoPlay) {
702 swiperPattern->SetIndicatorLongPress(true);
703 swiperPattern->StopTranslateAnimation();
704 swiperPattern->StopSpringAnimation();
705 swiperPattern->StopAutoPlay();
706 }
707 }
708
HandleLongDragUpdate(const TouchLocationInfo & info)709 void SwiperIndicatorPattern::HandleLongDragUpdate(const TouchLocationInfo& info)
710 {
711 auto swiperNode = GetSwiperNode();
712 CHECK_NULL_VOID(swiperNode);
713 auto swiperPattern = swiperNode->GetPattern<SwiperPattern>();
714 CHECK_NULL_VOID(swiperPattern);
715 if (swiperPattern->IsIndicatorAnimatorRunning()) {
716 return;
717 }
718 auto swiperLayoutProperty = swiperNode->GetLayoutProperty<SwiperLayoutProperty>();
719 CHECK_NULL_VOID(swiperLayoutProperty);
720 auto displayCount = swiperLayoutProperty->GetDisplayCount().value_or(1);
721 if (swiperPattern->RealTotalCount() == displayCount) {
722 return;
723 }
724 if (CheckIsTouchBottom(info)) {
725 return;
726 }
727 auto dragPoint =
728 PointF(static_cast<float>(info.GetLocalLocation().GetX()), static_cast<float>(info.GetLocalLocation().GetY()));
729 auto offset = dragPoint - dragStartPoint_;
730 auto turnPageRateOffset = swiperPattern->GetDirection() == Axis::HORIZONTAL ? offset.GetX() : offset.GetY();
731 if (LessNotEqual(std::abs(turnPageRateOffset), INDICATOR_DRAG_MIN_DISTANCE.ConvertToPx())) {
732 return;
733 }
734 if (swiperPattern->IsHorizontalAndRightToLeft()) {
735 turnPageRateOffset = -turnPageRateOffset;
736 }
737 auto turnPageRate = -(turnPageRateOffset / INDICATOR_DRAG_MAX_DISTANCE.ConvertToPx());
738 swiperPattern->SetTurnPageRate(turnPageRate);
739 if (std::abs(turnPageRate) >= 1) {
740 if (Positive(turnPageRateOffset)) {
741 swiperPattern->SwipeToWithoutAnimation(swiperPattern->GetCurrentIndex() + 1);
742 }
743 if (NonPositive(turnPageRateOffset)) {
744 swiperPattern->SwipeToWithoutAnimation(swiperPattern->GetCurrentIndex() - 1);
745 }
746
747 dragStartPoint_ = dragPoint;
748 }
749 }
750
HandleTouchClickMargin()751 float SwiperIndicatorPattern::HandleTouchClickMargin()
752 {
753 auto host = GetHost();
754 CHECK_NULL_RETURN(host, 0.0f);
755 auto paintProperty = host->GetPaintProperty<DotIndicatorPaintProperty>();
756 CHECK_NULL_RETURN(paintProperty, 0.0f);
757 auto pipeline = PipelineBase::GetCurrentContext();
758 CHECK_NULL_RETURN(pipeline, 0.0f);
759 auto theme = pipeline->GetTheme<SwiperIndicatorTheme>();
760 CHECK_NULL_RETURN(theme, 0.0f);
761 auto itemWidth = paintProperty->GetItemWidthValue(theme->GetSize()).ConvertToPx();
762 auto selectedItemWidth = paintProperty->GetSelectedItemWidthValue(theme->GetSize()).ConvertToPx();
763 if (Negative(itemWidth) || Negative(selectedItemWidth)) {
764 itemWidth = theme->GetSize().ConvertToPx();
765 selectedItemWidth = theme->GetSize().ConvertToPx();
766 }
767 auto swiperNode = GetSwiperNode();
768 CHECK_NULL_RETURN(swiperNode, 0.0f);
769 auto swiperPattern = swiperNode->GetPattern<SwiperPattern>();
770 int32_t itemCount = swiperPattern->RealTotalCount();
771 auto allPointDiameterSum = itemWidth * static_cast<float>(itemCount - 1) + selectedItemWidth;
772 auto allPointSpaceSum = static_cast<float>(INDICATOR_ITEM_SPACE.ConvertToPx() * (itemCount - 1));
773 auto indicatorPadding = static_cast<float>(INDICATOR_PADDING_DEFAULT.ConvertToPx());
774 auto contentWidth = indicatorPadding + allPointDiameterSum + allPointSpaceSum + indicatorPadding;
775 auto geometryNode = host->GetGeometryNode();
776 CHECK_NULL_RETURN(geometryNode, 0.0f);
777 auto frameSize = geometryNode->GetFrameSize();
778 auto axis = swiperPattern->GetDirection();
779 return ((axis == Axis::HORIZONTAL ? frameSize.Width() : frameSize.Height()) - contentWidth) * 0.5f;
780 }
781
DumpAdvanceInfo()782 void SwiperIndicatorPattern::DumpAdvanceInfo()
783 {
784 isHover_ ? DumpLog::GetInstance().AddDesc("isHover:true") : DumpLog::GetInstance().AddDesc("isHover:false");
785 isPressed_ ? DumpLog::GetInstance().AddDesc("isPressed:true") : DumpLog::GetInstance().AddDesc("isPressed:false");
786 isClicked_ ? DumpLog::GetInstance().AddDesc("isClicked:true") : DumpLog::GetInstance().AddDesc("isClicked:false");
787 isRepeatClicked_ ? DumpLog::GetInstance().AddDesc("isRepeatClicked:true")
788 : DumpLog::GetInstance().AddDesc("isRepeatClicked:false");
789 switch (swiperIndicatorType_) {
790 case SwiperIndicatorType::DOT: {
791 DumpLog::GetInstance().AddDesc("SwiperIndicatorType:DOT");
792 break;
793 }
794 case SwiperIndicatorType::DIGIT: {
795 DumpLog::GetInstance().AddDesc("SwiperIndicatorType:DIGIT");
796 break;
797 }
798 default: {
799 break;
800 }
801 }
802 }
803
CreateOverlongDotIndicatorPaintMethod(RefPtr<SwiperPattern> swiperPattern)804 RefPtr<OverlengthDotIndicatorPaintMethod> SwiperIndicatorPattern::CreateOverlongDotIndicatorPaintMethod(
805 RefPtr<SwiperPattern> swiperPattern)
806 {
807 if (dotIndicatorModifier_) {
808 dotIndicatorModifier_->StopAnimation(true);
809 dotIndicatorModifier_->SetIsOverlong(true);
810 }
811
812 if (!overlongDotIndicatorModifier_) {
813 overlongDotIndicatorModifier_ = AceType::MakeRefPtr<OverlengthDotIndicatorModifier>();
814 }
815
816 overlongDotIndicatorModifier_->SetAnimationDuration(swiperPattern->GetDuration());
817 overlongDotIndicatorModifier_->SetLongPointHeadCurve(
818 swiperPattern->GetCurveIncludeMotion(), swiperPattern->GetMotionVelocity());
819
820 auto swiperLayoutProperty = swiperPattern->GetLayoutProperty<SwiperLayoutProperty>();
821 CHECK_NULL_RETURN(swiperLayoutProperty, nullptr);
822 auto overlongPaintMethod = MakeRefPtr<OverlengthDotIndicatorPaintMethod>(overlongDotIndicatorModifier_);
823 auto paintMethodTemp = DynamicCast<DotIndicatorPaintMethod>(overlongPaintMethod);
824 SetDotIndicatorPaintMethodInfo(swiperPattern, paintMethodTemp, swiperLayoutProperty);
825 UpdateOverlongPaintMethod(swiperPattern, overlongPaintMethod);
826
827 return overlongPaintMethod;
828 }
829
CreateDotIndicatorPaintMethod(RefPtr<SwiperPattern> swiperPattern)830 RefPtr<DotIndicatorPaintMethod> SwiperIndicatorPattern::CreateDotIndicatorPaintMethod(
831 RefPtr<SwiperPattern> swiperPattern)
832 {
833 if (overlongDotIndicatorModifier_) {
834 overlongDotIndicatorModifier_->StopAnimation(true);
835 overlongDotIndicatorModifier_->SetMaxDisplayCount(0);
836 }
837
838 if (!dotIndicatorModifier_) {
839 dotIndicatorModifier_ = AceType::MakeRefPtr<DotIndicatorModifier>();
840 }
841
842 dotIndicatorModifier_->SetIsOverlong(false);
843 dotIndicatorModifier_->SetAnimationDuration(swiperPattern->GetDuration());
844 dotIndicatorModifier_->SetLongPointHeadCurve(
845 swiperPattern->GetCurveIncludeMotion(), swiperPattern->GetMotionVelocity());
846 auto swiperLayoutProperty = swiperPattern->GetLayoutProperty<SwiperLayoutProperty>();
847 CHECK_NULL_RETURN(swiperLayoutProperty, nullptr);
848 auto paintMethod = MakeRefPtr<DotIndicatorPaintMethod>(dotIndicatorModifier_);
849 SetDotIndicatorPaintMethodInfo(swiperPattern, paintMethod, swiperLayoutProperty);
850
851 dotIndicatorModifier_->SetBoundsRect(CalcBoundsRect());
852
853 return paintMethod;
854 }
855
CalcBoundsRect() const856 RectF SwiperIndicatorPattern::CalcBoundsRect() const
857 {
858 auto swiperNode = GetSwiperNode();
859 CHECK_NULL_RETURN(swiperNode, RectF());
860 auto geometryNode = swiperNode->GetGeometryNode();
861 CHECK_NULL_RETURN(geometryNode, RectF());
862 auto host = GetHost();
863 CHECK_NULL_RETURN(host, RectF());
864 auto indicatorGeometryNode = host->GetGeometryNode();
865 CHECK_NULL_RETURN(indicatorGeometryNode, RectF());
866 auto boundsValue = (geometryNode->GetFrameSize().Width() - indicatorGeometryNode->GetFrameSize().Width()) * 0.5f;
867 auto boundsRectOriginX = -boundsValue;
868 auto boundsRectOriginY = 0.0f;
869 auto boundsRectWidth = geometryNode->GetFrameSize().Width();
870 auto boundsRectHeight = indicatorGeometryNode->GetFrameSize().Height();
871 auto swiperPattern = swiperNode->GetPattern<SwiperPattern>();
872 CHECK_NULL_RETURN(swiperPattern, RectF());
873 if (swiperPattern->GetDirection() == Axis::VERTICAL) {
874 boundsValue = (geometryNode->GetFrameSize().Height() - indicatorGeometryNode->GetFrameSize().Height()) * 0.5f;
875 boundsRectOriginX = 0.0f;
876 boundsRectOriginY = -boundsValue;
877 boundsRectWidth = indicatorGeometryNode->GetFrameSize().Width();
878 boundsRectHeight = geometryNode->GetFrameSize().Height();
879 }
880 RectF boundsRect(boundsRectOriginX, boundsRectOriginY, boundsRectWidth, boundsRectHeight);
881
882 return boundsRect;
883 }
884
UpdateOverlongPaintMethod(const RefPtr<SwiperPattern> & swiperPattern,RefPtr<OverlengthDotIndicatorPaintMethod> & overlongPaintMethod)885 void SwiperIndicatorPattern::UpdateOverlongPaintMethod(
886 const RefPtr<SwiperPattern>& swiperPattern, RefPtr<OverlengthDotIndicatorPaintMethod>& overlongPaintMethod)
887 {
888 auto animationStartIndex = swiperPattern->GetLoopIndex(swiperPattern->GetCurrentIndex());
889 auto animationEndIndex = swiperPattern->GetLoopIndex(swiperPattern->GetCurrentFirstIndex());
890
891 auto paintMethodTemp = DynamicCast<DotIndicatorPaintMethod>(overlongPaintMethod);
892 if (changeIndexWithAnimation_ && !changeIndexWithAnimation_.value()) {
893 animationStartIndex = startIndex_ ? startIndex_.value() : overlongDotIndicatorModifier_->GetAnimationEndIndex();
894 paintMethodTemp->SetGestureState(GestureState::GESTURE_STATE_NONE);
895 }
896
897 if (jumpIndex_) {
898 paintMethodTemp->SetGestureState(GestureState::GESTURE_STATE_NONE);
899
900 if (!changeIndexWithAnimation_) {
901 overlongDotIndicatorModifier_->StopAnimation(true);
902 overlongDotIndicatorModifier_->SetCurrentOverlongType(OverlongType::NONE);
903 }
904 }
905
906 auto isSwiperTouchDown = swiperPattern->IsTouchDownOnOverlong();
907 auto isSwiperAnimationRunning =
908 swiperPattern->IsPropertyAnimationRunning() || swiperPattern->IsTranslateAnimationRunning();
909 auto keepStatus = !isSwiperTouchDown && !isSwiperAnimationRunning && animationStartIndex != animationEndIndex &&
910 !changeIndexWithAnimation_;
911
912 if (!changeIndexWithAnimation_ && gestureState_ == GestureState::GESTURE_STATE_NONE) {
913 keepStatus = true;
914 }
915
916 auto bottomTouchLoop = swiperPattern->GetTouchBottomTypeLoop();
917 auto turnPageRateAbs = std::abs(swiperPattern->GetTurnPageRate());
918 auto totalCount = swiperPattern->RealTotalCount();
919 auto loopDrag = (animationStartIndex == 0 && animationEndIndex == totalCount - 1 && turnPageRateAbs < HALF_FLOAT &&
920 turnPageRateAbs > 0.0f) ||
921 (animationStartIndex == animationEndIndex && animationEndIndex == totalCount - 1 &&
922 turnPageRateAbs > HALF_FLOAT);
923 auto nonLoopDrag = bottomTouchLoop == TouchBottomTypeLoop::TOUCH_BOTTOM_TYPE_LOOP_NONE &&
924 ((gestureState_ == GestureState::GESTURE_STATE_FOLLOW_RIGHT && turnPageRateAbs > HALF_FLOAT) ||
925 (gestureState_ == GestureState::GESTURE_STATE_FOLLOW_LEFT && turnPageRateAbs < HALF_FLOAT &&
926 turnPageRateAbs > 0.0f));
927
928 if (isSwiperTouchDown && (loopDrag || nonLoopDrag)) {
929 overlongDotIndicatorModifier_->UpdateCurrentStatus();
930 }
931
932 overlongPaintMethod->SetMaxDisplayCount(swiperPattern->GetMaxDisplayCount());
933 overlongPaintMethod->SetKeepStatus(keepStatus);
934 overlongPaintMethod->SetAnimationStartIndex(animationStartIndex);
935 overlongPaintMethod->SetAnimationEndIndex(animationEndIndex);
936 overlongDotIndicatorModifier_->SetIsSwiperTouchDown(isSwiperTouchDown);
937 overlongDotIndicatorModifier_->SetBoundsRect(CalcBoundsRect());
938 changeIndexWithAnimation_.reset();
939 jumpIndex_.reset();
940 startIndex_.reset();
941 }
942 } // namespace OHOS::Ace::NG
943