• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "core/components_ng/pattern/swiper_indicator/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     if (GetIndicatorType() == SwiperIndicatorType::DIGIT) {
56         UpdateDigitalIndicator();
57     } else {
58         host->Clean();
59     }
60 
61     if (dotIndicatorModifier_) {
62         dotIndicatorModifier_->StopAnimation();
63     }
64 
65     InitIndicatorEvent();
66 }
InitIndicatorEvent()67 void SwiperIndicatorPattern::InitIndicatorEvent()
68 {
69     auto host = GetHost();
70     CHECK_NULL_VOID(host);
71     RegisterIndicatorChangeEvent();
72     auto gestureHub = host->GetOrCreateGestureEventHub();
73     CHECK_NULL_VOID(gestureHub);
74     if (GetIndicatorType() == SwiperIndicatorType::DOT) {
75         InitClickEvent(gestureHub);
76         InitHoverMouseEvent();
77         InitTouchEvent(gestureHub);
78         InitLongPressEvent(gestureHub);
79     } else {
80         if (clickEvent_) {
81             gestureHub->RemoveClickEvent(clickEvent_);
82             clickEvent_ = nullptr;
83         }
84     }
85 }
86 
UpdateDigitalIndicator()87 void SwiperIndicatorPattern::UpdateDigitalIndicator()
88 {
89     auto host = GetHost();
90     CHECK_NULL_VOID(host);
91     RefPtr<FrameNode> firstTextNode;
92     RefPtr<FrameNode> lastTextNode;
93     auto layoutProperty = host->GetLayoutProperty<SwiperIndicatorLayoutProperty>();
94     CHECK_NULL_VOID(layoutProperty);
95     if (host->GetChildren().size() == INDICATOR_HAS_CHILD) {
96         firstTextNode = DynamicCast<FrameNode>(host->GetFirstChild());
97         lastTextNode = DynamicCast<FrameNode>(host->GetLastChild());
98     } else {
99         host->Clean();
100         firstTextNode = FrameNode::CreateFrameNode(
101             V2::TEXT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<TextPattern>());
102         lastTextNode = FrameNode::CreateFrameNode(
103             V2::TEXT_ETS_TAG, ElementRegister::GetInstance()->MakeUniqueId(), AceType::MakeRefPtr<TextPattern>());
104     }
105     UpdateTextContent(layoutProperty, firstTextNode, lastTextNode);
106     host->AddChild(firstTextNode);
107     host->AddChild(lastTextNode);
108 }
109 
RegisterIndicatorChangeEvent()110 void SwiperIndicatorPattern::RegisterIndicatorChangeEvent()
111 {
112     auto host = GetHost();
113     CHECK_NULL_VOID(host);
114 
115     RefPtr<SwiperPattern> swiperPattern = GetSwiperPattern();
116     CHECK_NULL_VOID(swiperPattern);
117     auto swiperEventHub = swiperPattern->GetEventHub<SwiperEventHub>();
118     CHECK_NULL_VOID(swiperEventHub);
119     swiperEventHub->SetIndicatorOnChange(
120         [weak = AceType::WeakClaim(RawPtr(host)), context = AceType::WeakClaim(this)]() {
121             auto pipeline = PipelineContext::GetCurrentContextSafely();
122             CHECK_NULL_VOID(pipeline);
123             pipeline->AddAfterLayoutTask([weak, context]() {
124                 auto indicator = weak.Upgrade();
125                 CHECK_NULL_VOID(indicator);
126                 auto textContext = context.Upgrade();
127                 CHECK_NULL_VOID(textContext);
128                 if (textContext->GetIndicatorType() == SwiperIndicatorType::DIGIT) {
129                     RefPtr<FrameNode> firstTextNode;
130                     RefPtr<FrameNode> lastTextNode;
131                     auto layoutProperty = indicator->GetLayoutProperty<SwiperIndicatorLayoutProperty>();
132                     firstTextNode = DynamicCast<FrameNode>(indicator->GetFirstChild());
133                     lastTextNode = DynamicCast<FrameNode>(indicator->GetLastChild());
134                     textContext->UpdateTextContent(layoutProperty, firstTextNode, lastTextNode);
135                 }
136                 indicator->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
137             });
138             pipeline->RequestFrame();
139         });
140     swiperEventHub->SetIndicatorIndexChangeEvent(
141         [weak = AceType::WeakClaim(RawPtr(host)), context = AceType::WeakClaim(this)](int32_t index) {
142         auto indicator = weak.Upgrade();
143         CHECK_NULL_VOID(indicator);
144         auto pipeline = indicator->GetContext();
145         CHECK_NULL_VOID(pipeline);
146         auto pattern = context.Upgrade();
147         CHECK_NULL_VOID(pattern);
148         pattern->FireIndicatorIndexChangeEvent(index);
149     });
150 }
151 
OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper> & dirty,const DirtySwapConfig & config)152 bool SwiperIndicatorPattern::OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config)
153 {
154     CHECK_NULL_RETURN(config.frameSizeChange, false);
155     return true;
156 }
157 
InitClickEvent(const RefPtr<GestureEventHub> & gestureHub)158 void SwiperIndicatorPattern::InitClickEvent(const RefPtr<GestureEventHub>& gestureHub)
159 {
160     CHECK_NULL_VOID(!clickEvent_);
161     auto clickTask = [weak = WeakClaim(this)](const GestureEvent& info) {
162         auto pattern = weak.Upgrade();
163         CHECK_NULL_VOID(pattern);
164         pattern->HandleClick(info);
165     };
166     clickEvent_ = MakeRefPtr<ClickEvent>(std::move(clickTask));
167     gestureHub->AddClickEvent(clickEvent_);
168 }
169 
HandleClick(const GestureEvent & info)170 void SwiperIndicatorPattern::HandleClick(const GestureEvent& info)
171 {
172     if (info.GetSourceDevice() == SourceType::KEYBOARD) {
173         return;
174     }
175 
176     if (info.GetSourceDevice() == SourceType::MOUSE) {
177         isClicked_ = true;
178         HandleMouseClick(info);
179     } else {
180         HandleTouchClick(info);
181     }
182 }
183 
HandleMouseClick(const GestureEvent &)184 void SwiperIndicatorPattern::HandleMouseClick(const GestureEvent& /* info */)
185 {
186     if (isRepeatClicked_) {
187         return;
188     }
189     GetMouseClickIndex();
190     CHECK_NULL_VOID(mouseClickIndex_);
191     SwipeTo(mouseClickIndex_);
192     auto host = GetHost();
193     CHECK_NULL_VOID(host);
194     host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
195 }
196 
HandleTouchClick(const GestureEvent & info)197 void SwiperIndicatorPattern::HandleTouchClick(const GestureEvent& info)
198 {
199     auto host = GetHost();
200     CHECK_NULL_VOID(host);
201     auto paintProperty = host->GetPaintProperty<DotIndicatorPaintProperty>();
202     CHECK_NULL_VOID(paintProperty);
203     auto pipeline = PipelineBase::GetCurrentContext();
204     CHECK_NULL_VOID(pipeline);
205     auto theme = pipeline->GetTheme<SwiperIndicatorTheme>();
206     CHECK_NULL_VOID(theme);
207     auto itemWidth = paintProperty->GetItemWidthValue(theme->GetSize()).ConvertToPx();
208     auto selectedItemWidth = paintProperty->GetSelectedItemWidthValue(theme->GetSize()).ConvertToPx();
209     if (Negative(itemWidth) || Negative(selectedItemWidth)) {
210         itemWidth = theme->GetSize().ConvertToPx();
211         selectedItemWidth = theme->GetSize().ConvertToPx();
212     }
213 
214     auto isRtl = IsHorizontalAndRightToLeft();
215     auto currentIndex = GetCurrentIndex();
216     auto margin = HandleTouchClickMargin();
217     auto lengthBeforeCurrentIndex = margin + INDICATOR_PADDING_DEFAULT.ConvertToPx() +
218                                     (INDICATOR_ITEM_SPACE.ConvertToPx() + itemWidth) * currentIndex;
219     auto lengthWithCurrentIndex = lengthBeforeCurrentIndex + selectedItemWidth;
220     auto axis = GetDirection();
221     auto mainClickOffset = axis == Axis::HORIZONTAL ? info.GetLocalLocation().GetX() : info.GetLocalLocation().GetY();
222     if (mainClickOffset < lengthBeforeCurrentIndex) {
223         isRtl ? ShowNext() : ShowPrevious();
224     } else if (mainClickOffset > lengthWithCurrentIndex) {
225         isRtl ? ShowPrevious() : ShowNext();
226     }
227 }
228 
InitHoverMouseEvent()229 void SwiperIndicatorPattern::InitHoverMouseEvent()
230 {
231     auto host = GetHost();
232     CHECK_NULL_VOID(host);
233     auto eventHub = host->GetEventHub<EventHub>();
234     CHECK_NULL_VOID(eventHub);
235     auto inputHub = eventHub->GetOrCreateInputEventHub();
236     CHECK_NULL_VOID(inputHub);
237 
238     auto hoverTask = [weak = WeakClaim(this)](bool isHover, HoverInfo& info) {
239         auto pattern = weak.Upgrade();
240         if (pattern && info.GetSourceDevice() != SourceType::TOUCH) {
241             pattern->HandleHoverEvent(isHover);
242         }
243     };
244 
245     if (!hoverEvent_) {
246         hoverEvent_ = MakeRefPtr<InputEvent>(std::move(hoverTask));
247         inputHub->AddOnHoverEvent(hoverEvent_);
248     }
249 
250     auto mouseEvent = [weak = WeakClaim(this)](MouseInfo& info) {
251         auto pattern = weak.Upgrade();
252         if (pattern) {
253             pattern->HandleMouseEvent(info);
254         }
255     };
256     if (mouseEvent_) {
257         inputHub->RemoveOnMouseEvent(mouseEvent_);
258     }
259     mouseEvent_ = MakeRefPtr<InputEvent>(std::move(mouseEvent));
260     inputHub->AddOnMouseEvent(mouseEvent_);
261 }
262 
HandleMouseEvent(const MouseInfo & info)263 void SwiperIndicatorPattern::HandleMouseEvent(const MouseInfo& info)
264 {
265     if (info.GetSourceDevice() == SourceType::TOUCH) {
266         return;
267     }
268     auto mouseOffsetX = static_cast<float>(info.GetLocalLocation().GetX());
269     auto mouseOffsetY = static_cast<float>(info.GetLocalLocation().GetY());
270     auto mouseAction = info.GetAction();
271     if ((mouseAction == MouseAction::PRESS || mouseAction == MouseAction::RELEASE) &&
272         isClicked_ && NearEqual(hoverPoint_, PointF(mouseOffsetX, mouseOffsetY))) {
273         isRepeatClicked_ = true;
274         return;
275     }
276     isClicked_ = false;
277     isRepeatClicked_ = false;
278     auto host = GetHost();
279     CHECK_NULL_VOID(host);
280     hoverPoint_.SetX(mouseOffsetX);
281     hoverPoint_.SetY(mouseOffsetY);
282 
283     host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
284 }
285 
HandleHoverEvent(bool isHover)286 void SwiperIndicatorPattern::HandleHoverEvent(bool isHover)
287 {
288     if (isHover_ == isHover) {
289         return;
290     }
291 
292     isHover_ = isHover;
293     auto host = GetHost();
294     CHECK_NULL_VOID(host);
295     auto swiperNode = GetSwiperNode();
296     if (swiperNode) {
297         auto swiperPattern = swiperNode->GetPattern<SwiperPattern>();
298         CHECK_NULL_VOID(swiperPattern);
299         auto swiperLayoutProperty = swiperPattern->GetLayoutProperty<SwiperLayoutProperty>();
300         CHECK_NULL_VOID(swiperLayoutProperty);
301         if (swiperLayoutProperty->GetHoverShowValue(false) && !swiperPattern->GetIsAtHotRegion()) {
302             swiperPattern->ArrowHover(isHover_, HOVER_INDICATOR);
303         }
304     }
305     host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
306 }
307 
InitTouchEvent(const RefPtr<GestureEventHub> & gestureHub)308 void SwiperIndicatorPattern::InitTouchEvent(const RefPtr<GestureEventHub>& gestureHub)
309 {
310     if (touchEvent_) {
311         return;
312     }
313 
314     auto touchTask = [weak = WeakClaim(this)](const TouchEventInfo& info) {
315         auto pattern = weak.Upgrade();
316         if (pattern) {
317             pattern->HandleTouchEvent(info);
318         }
319     };
320 
321     if (touchEvent_) {
322         gestureHub->RemoveTouchEvent(touchEvent_);
323     }
324     touchEvent_ = MakeRefPtr<TouchEventImpl>(std::move(touchTask));
325     gestureHub->AddTouchEvent(touchEvent_);
326 
327     auto swiperNode = GetSwiperNode();
328     CHECK_NULL_VOID(swiperNode);
329     auto swiperPattern = swiperNode->GetPattern<SwiperPattern>();
330     CHECK_NULL_VOID(swiperPattern);
331     auto stopAnimationCb = [weak = WeakClaim(this)](bool ifImmediately) {
332         auto pattern = weak.Upgrade();
333         if (pattern) {
334             if (pattern->dotIndicatorModifier_) {
335                 pattern->dotIndicatorModifier_->StopAnimation(ifImmediately);
336             }
337 
338             if (pattern->overlongDotIndicatorModifier_) {
339                 pattern->overlongDotIndicatorModifier_->StopAnimation(ifImmediately);
340             }
341         }
342     };
343     swiperPattern->SetStopIndicatorAnimationCb(stopAnimationCb);
344 }
345 
HandleTouchEvent(const TouchEventInfo & info)346 void SwiperIndicatorPattern::HandleTouchEvent(const TouchEventInfo& info)
347 {
348     auto touchType = info.GetTouches().front().GetTouchType();
349     if (touchType == TouchType::UP) {
350         HandleTouchUp();
351         HandleDragEnd(0);
352         isPressed_ = false;
353     } else if (touchType == TouchType::CANCEL) {
354         HandleTouchUp();
355         HandleDragEnd(0);
356         isPressed_ = false;
357     }
358     if (isPressed_) {
359         HandleLongDragUpdate(info.GetTouches().front());
360     }
361 }
362 
HandleTouchDown()363 void SwiperIndicatorPattern::HandleTouchDown()
364 {
365     isPressed_ = true;
366     auto host = GetHost();
367     CHECK_NULL_VOID(host);
368     host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
369 }
370 
HandleTouchUp()371 void SwiperIndicatorPattern::HandleTouchUp()
372 {
373     isPressed_ = false;
374     auto host = GetHost();
375     CHECK_NULL_VOID(host);
376     host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
377 }
378 
GetMouseClickIndex()379 void SwiperIndicatorPattern::GetMouseClickIndex()
380 {
381     auto pipelineContext = PipelineBase::GetCurrentContext();
382     CHECK_NULL_VOID(pipelineContext);
383     auto swiperTheme = pipelineContext->GetTheme<SwiperIndicatorTheme>();
384     CHECK_NULL_VOID(swiperTheme);
385     auto host = GetHost();
386     CHECK_NULL_VOID(host);
387     auto paintProperty = host->GetPaintProperty<DotIndicatorPaintProperty>();
388     CHECK_NULL_VOID(paintProperty);
389     float itemWidthValue = static_cast<float>(paintProperty->GetItemWidthValue(swiperTheme->GetSize()).ConvertToPx());
390     float itemHeightValue = static_cast<float>(paintProperty->GetItemHeightValue(swiperTheme->GetSize()).ConvertToPx());
391     float selectedItemWidthValue =
392         static_cast<float>(paintProperty->GetSelectedItemWidthValue(swiperTheme->GetSize()).ConvertToPx() * 2);
393     paintProperty->GetIsCustomSizeValue(false) ? selectedItemWidthValue *= 0.5f : selectedItemWidthValue;
394     // diameter calculation
395     float itemWidth = itemWidthValue * INDICATOR_ZOOM_IN_SCALE;
396     float itemHeight = itemHeightValue * INDICATOR_ZOOM_IN_SCALE;
397     float selectedItemWidth = selectedItemWidthValue * INDICATOR_ZOOM_IN_SCALE;
398     float space = static_cast<float>(INDICATOR_ITEM_SPACE.ConvertToPx());
399     int32_t currentIndex = GetCurrentShownIndex();
400     int32_t itemCount = RealTotalCount();
401     int32_t loopCount = SwiperIndicatorUtils::CalcLoopCount(currentIndex, itemCount);
402     auto frameSize = host->GetGeometryNode()->GetFrameSize();
403     auto axis = GetDirection();
404     float centerX = static_cast<float>(INDICATOR_PADDING_DOT.ConvertToPx());
405     float centerY = ((axis == Axis::HORIZONTAL ? frameSize.Height() : frameSize.Width()) - itemHeight) * 0.5f;
406     PointF hoverPoint = axis == Axis::HORIZONTAL ? hoverPoint_ : PointF(hoverPoint_.GetY(), hoverPoint_.GetX());
407     int start = currentIndex >= 0 ? loopCount * itemCount : -(loopCount + 1) * itemCount;
408     int end = currentIndex >= 0 ? (loopCount + 1) * itemCount : -loopCount * itemCount;
409     if (IsHorizontalAndRightToLeft()) {
410         end = currentIndex >= 0 ? loopCount * itemCount - 1 : -(loopCount + 1) * itemCount - 1;
411         start = currentIndex >= 0 ? (loopCount + 1) * itemCount - 1 : -loopCount * itemCount - 1;
412     }
413     for (int32_t i = start; i != end; start > end ? --i : ++i) {
414         if (i != currentIndex) {
415             if (hoverPoint.GetX() >= centerX && hoverPoint.GetX() <= centerX + itemWidth &&
416                 hoverPoint.GetY() >= centerY && hoverPoint.GetY() <= centerY + itemHeight) {
417                 mouseClickIndex_ = i;
418                 break;
419             }
420             centerX += itemWidth + space;
421         } else {
422             centerX += selectedItemWidth + space;
423         }
424     }
425 }
426 
UpdateTextContent(const RefPtr<SwiperIndicatorLayoutProperty> & layoutProperty,const RefPtr<FrameNode> & firstTextNode,const RefPtr<FrameNode> & lastTextNode)427 void SwiperIndicatorPattern::UpdateTextContent(const RefPtr<SwiperIndicatorLayoutProperty>& layoutProperty,
428     const RefPtr<FrameNode>& firstTextNode, const RefPtr<FrameNode>& lastTextNode)
429 {
430     CHECK_NULL_VOID(layoutProperty);
431     CHECK_NULL_VOID(firstTextNode);
432     CHECK_NULL_VOID(lastTextNode);
433     auto pipeline = PipelineBase::GetCurrentContext();
434     CHECK_NULL_VOID(pipeline);
435     auto theme = pipeline->GetTheme<SwiperIndicatorTheme>();
436     firstTextNode->SetInternal();
437     lastTextNode->SetInternal();
438     auto firstTextLayoutProperty = firstTextNode->GetLayoutProperty<TextLayoutProperty>();
439     CHECK_NULL_VOID(firstTextLayoutProperty);
440     auto selectedFontColor =
441         layoutProperty->GetSelectedFontColorValue(theme->GetDigitalIndicatorTextStyle().GetTextColor());
442     auto selectedFontSize =
443         layoutProperty->GetSelectedFontSizeValue(theme->GetDigitalIndicatorTextStyle().GetFontSize());
444     if (!selectedFontSize.IsValid()) {
445         selectedFontSize = theme->GetDigitalIndicatorTextStyle().GetFontSize();
446     }
447     auto selectedFontWeight =
448         layoutProperty->GetSelectedFontWeightValue(theme->GetDigitalIndicatorTextStyle().GetFontWeight());
449     firstTextLayoutProperty->UpdateTextColor(selectedFontColor);
450     firstTextLayoutProperty->UpdateFontSize(selectedFontSize);
451     firstTextLayoutProperty->UpdateFontWeight(selectedFontWeight);
452     firstTextLayoutProperty->UpdateMaxFontScale(MAX_FONT_SCALE);
453     UpdateTextContentSub(layoutProperty, firstTextNode, lastTextNode);
454 }
455 
GetDisplayCurrentIndex() const456 int32_t SwiperIndicatorPattern::GetDisplayCurrentIndex() const
457 {
458     auto swiperNode = GetSwiperNode();
459     CHECK_NULL_RETURN(swiperNode, 0);
460     auto swiperPattern = swiperNode->GetPattern<SwiperPattern>();
461     CHECK_NULL_RETURN(swiperPattern, 0);
462     CHECK_NULL_RETURN(swiperPattern->RealTotalCount(), 0);
463     auto swiperLayoutProperty = swiperPattern->GetLayoutProperty<SwiperLayoutProperty>();
464     CHECK_NULL_RETURN(swiperLayoutProperty, 0);
465     auto currentIndex = swiperPattern->GetCurrentFirstIndex() + 1;
466     if (currentIndex > swiperPattern->RealTotalCount()) {
467         currentIndex = 1;
468     } else if (swiperLayoutProperty->HasIndex()) {
469         currentIndex = GetInitialIndex() + 1;
470         if (currentIndex > swiperPattern->RealTotalCount()) {
471             currentIndex = 1;
472         }
473     }
474 
475     return currentIndex;
476 }
477 
GetInitialIndex() const478 int32_t SwiperIndicatorPattern::GetInitialIndex() const
479 {
480     auto swiperNode = GetSwiperNode();
481     CHECK_NULL_RETURN(swiperNode, 0);
482     auto swiperPattern = swiperNode->GetPattern<SwiperPattern>();
483     CHECK_NULL_RETURN(swiperPattern, 0);
484     auto swiperLayoutProperty = swiperPattern->GetLayoutProperty<SwiperLayoutProperty>();
485     CHECK_NULL_RETURN(swiperLayoutProperty, 0);
486     auto currentIndex = swiperLayoutProperty->GetIndex().value_or(0);
487     if (swiperPattern->IsSwipeByGroup()) {
488         currentIndex = SwiperUtils::ComputePageIndex(currentIndex, swiperPattern->GetDisplayCount());
489     }
490 
491     return currentIndex;
492 }
493 
UpdateTextContentSub(const RefPtr<SwiperIndicatorLayoutProperty> & layoutProperty,const RefPtr<FrameNode> & firstTextNode,const RefPtr<FrameNode> & lastTextNode)494 void SwiperIndicatorPattern::UpdateTextContentSub(const RefPtr<SwiperIndicatorLayoutProperty>& layoutProperty,
495     const RefPtr<FrameNode>& firstTextNode, const RefPtr<FrameNode>& lastTextNode)
496 {
497     CHECK_NULL_VOID(layoutProperty);
498     CHECK_NULL_VOID(firstTextNode);
499     CHECK_NULL_VOID(lastTextNode);
500     auto pipeline = PipelineBase::GetCurrentContext();
501     CHECK_NULL_VOID(pipeline);
502     auto theme = pipeline->GetTheme<SwiperIndicatorTheme>();
503     CHECK_NULL_VOID(theme);
504     auto firstTextLayoutProperty = firstTextNode->GetLayoutProperty<TextLayoutProperty>();
505     CHECK_NULL_VOID(firstTextLayoutProperty);
506     auto lastTextLayoutProperty = lastTextNode->GetLayoutProperty<TextLayoutProperty>();
507     CHECK_NULL_VOID(lastTextLayoutProperty);
508     lastTextLayoutProperty->UpdateLayoutDirection(GetNonAutoLayoutDirection());
509 
510     std::string firstContent = "";
511     std::string lastContent = "";
512     GetTextContentSub(firstContent, lastContent);
513     firstTextLayoutProperty->UpdateContent(firstContent);
514     auto fontColor = layoutProperty->GetFontColorValue(theme->GetDigitalIndicatorTextStyle().GetTextColor());
515     auto fontSize = layoutProperty->GetFontSizeValue(theme->GetDigitalIndicatorTextStyle().GetFontSize());
516     if (!fontSize.IsValid()) {
517         fontSize = theme->GetDigitalIndicatorTextStyle().GetFontSize();
518     }
519     auto fontWeight = layoutProperty->GetFontWeightValue(theme->GetDigitalIndicatorTextStyle().GetFontWeight());
520     lastTextLayoutProperty->UpdateTextColor(fontColor);
521     lastTextLayoutProperty->UpdateFontSize(fontSize);
522     lastTextLayoutProperty->UpdateFontWeight(fontWeight);
523     lastTextLayoutProperty->UpdateContent(lastContent);
524     lastTextLayoutProperty->UpdateMaxFontScale(MAX_FONT_SCALE);
525     firstTextNode->MarkModifyDone();
526     firstTextNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT);
527     lastTextNode->MarkModifyDone();
528     lastTextNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE_SELF_AND_PARENT);
529 }
530 
HandleDragStart(const GestureEvent & info)531 void SwiperIndicatorPattern::HandleDragStart(const GestureEvent& info)
532 {
533     dragStartPoint_ =
534         PointF(static_cast<float>(info.GetLocalLocation().GetX()), static_cast<float>(info.GetLocalLocation().GetY()));
535 }
536 
HandleDragEnd(double dragVelocity)537 void SwiperIndicatorPattern::HandleDragEnd(double dragVelocity)
538 {
539     auto swiperNode = GetSwiperNode();
540     CHECK_NULL_VOID(swiperNode);
541     auto swiperPattern = swiperNode->GetPattern<SwiperPattern>();
542     CHECK_NULL_VOID(swiperPattern);
543     swiperPattern->SetTurnPageRate(0.0f);
544     auto swiperPaintProperty = swiperPattern->GetPaintProperty<SwiperPaintProperty>();
545     CHECK_NULL_VOID(swiperPaintProperty);
546     auto autoPlay = swiperPaintProperty->GetAutoPlay().value_or(false);
547     if (autoPlay) {
548         swiperPattern->SetIndicatorLongPress(false);
549         swiperPattern->StartAutoPlay();
550     }
551     auto host = GetHost();
552     CHECK_NULL_VOID(host);
553     touchBottomType_ = TouchBottomType::NONE;
554     host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
555 }
556 
SetIndicatorInteractive(bool isInteractive)557 void SwiperIndicatorPattern::SetIndicatorInteractive(bool isInteractive)
558 {
559     auto host = GetHost();
560     CHECK_NULL_VOID(host);
561     auto eventHub = host->GetEventHub<EventHub>();
562     CHECK_NULL_VOID(eventHub);
563     if (isInteractive) {
564         eventHub->SetEnabled(true);
565     } else {
566         eventHub->SetEnabled(false);
567     }
568 }
569 
CheckIsTouchBottom(const GestureEvent & info)570 bool SwiperIndicatorPattern::CheckIsTouchBottom(const GestureEvent& info)
571 {
572     auto swiperNode = GetSwiperNode();
573     CHECK_NULL_RETURN(swiperNode, false);
574     auto swiperPattern = swiperNode->GetPattern<SwiperPattern>();
575     CHECK_NULL_RETURN(swiperPattern, false);
576     auto currentIndex = swiperPattern->GetCurrentIndex();
577     auto childrenSize = swiperPattern->RealTotalCount();
578 
579     auto swiperLayoutProperty = swiperNode->GetLayoutProperty<SwiperLayoutProperty>();
580     CHECK_NULL_RETURN(swiperLayoutProperty, false);
581     auto displayCount = swiperLayoutProperty->GetDisplayCount().value_or(1);
582     auto isLoop = swiperLayoutProperty->GetLoop().value_or(true);
583     auto dragPoint =
584         PointF(static_cast<float>(info.GetLocalLocation().GetX()), static_cast<float>(info.GetLocalLocation().GetY()));
585     auto offset = dragPoint - dragStartPoint_;
586     auto touchOffset = GetDirection() == Axis::HORIZONTAL ? offset.GetX() : offset.GetY();
587     auto touchBottomRate = LessOrEqual(std::abs(touchOffset), INDICATOR_TOUCH_BOTTOM_MAX_DISTANCE.ConvertToPx())
588                                ? touchOffset / INDICATOR_TOUCH_BOTTOM_MAX_DISTANCE.ConvertToPx()
589                                : 1;
590 
591     swiperPattern->SetTurnPageRate(0);
592     swiperPattern->SetTouchBottomRate(std::abs(touchBottomRate));
593     TouchBottomType touchBottomType = TouchBottomType::NONE;
594 
595     if ((currentIndex <= 0) && !isLoop) {
596         if (Negative(info.GetMainDelta()) || NonPositive(touchOffset)) {
597             touchBottomType = TouchBottomType::START;
598         }
599     }
600 
601     if ((currentIndex >= childrenSize - displayCount) && !isLoop) {
602         if (Positive(info.GetMainDelta()) || NonNegative(touchOffset)) {
603             touchBottomType = TouchBottomType::END;
604         }
605     }
606 
607     touchBottomType_ = touchBottomType;
608     auto host = GetHost();
609     CHECK_NULL_RETURN(host, false);
610     host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
611 
612     return touchBottomType == TouchBottomType::NONE ? false : true;
613 }
614 
CheckIsTouchBottom(const TouchLocationInfo & info)615 bool SwiperIndicatorPattern::CheckIsTouchBottom(const TouchLocationInfo& info)
616 {
617     auto swiperNode = GetSwiperNode();
618     CHECK_NULL_RETURN(swiperNode, false);
619     auto swiperPattern = swiperNode->GetPattern<SwiperPattern>();
620     CHECK_NULL_RETURN(swiperPattern, false);
621     auto host = GetHost();
622     CHECK_NULL_RETURN(host, false);
623     auto currentIndex = swiperPattern->GetCurrentIndex();
624     auto childrenSize = swiperPattern->RealTotalCount();
625 
626     auto swiperLayoutProperty = swiperNode->GetLayoutProperty<SwiperLayoutProperty>();
627     CHECK_NULL_RETURN(swiperLayoutProperty, false);
628     auto displayCount = swiperLayoutProperty->GetDisplayCount().value_or(1);
629 
630     auto dragPoint =
631         PointF(static_cast<float>(info.GetLocalLocation().GetX()), static_cast<float>(info.GetLocalLocation().GetY()));
632     auto offset = dragPoint - dragStartPoint_;
633     auto touchOffset = swiperPattern->GetDirection() == Axis::HORIZONTAL ? offset.GetX() : offset.GetY();
634     auto touchBottomRate = LessOrEqual(std::abs(touchOffset), INDICATOR_TOUCH_BOTTOM_MAX_DISTANCE.ConvertToPx())
635                                ? touchOffset / INDICATOR_TOUCH_BOTTOM_MAX_DISTANCE.ConvertToPx()
636                                : 1;
637 
638     swiperPattern->SetTurnPageRate(0);
639     swiperPattern->SetTouchBottomRate(std::abs(touchBottomRate));
640     TouchBottomType touchBottomType = TouchBottomType::NONE;
641 
642     if (currentIndex <= 0) {
643         if (swiperPattern->IsHorizontalAndRightToLeft()) {
644             if (Positive(touchOffset)) {
645                 touchBottomType = TouchBottomType::END;
646             }
647         } else {
648             if (NonPositive(touchOffset)) {
649                 touchBottomType = TouchBottomType::START;
650             }
651         }
652     }
653 
654     if (currentIndex >= childrenSize - displayCount) {
655         if (swiperPattern->IsHorizontalAndRightToLeft()) {
656             if (NonPositive(touchOffset)) {
657                 touchBottomType = TouchBottomType::START;
658             }
659         } else {
660             if (Positive(touchOffset)) {
661                 touchBottomType = TouchBottomType::END;
662             }
663         }
664     }
665     touchBottomType_ = touchBottomType;
666     host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
667 
668     return touchBottomType == TouchBottomType::NONE ? false : true;
669 }
670 
InitLongPressEvent(const RefPtr<GestureEventHub> & gestureHub)671 void SwiperIndicatorPattern::InitLongPressEvent(const RefPtr<GestureEventHub>& gestureHub)
672 {
673     CHECK_NULL_VOID(!longPressEvent_);
674     auto longPressCallback = [weak = WeakClaim(this)](GestureEvent& info) {
675         auto pattern = weak.Upgrade();
676         CHECK_NULL_VOID(pattern);
677         pattern->HandleLongPress(info);
678     };
679     longPressEvent_ = MakeRefPtr<LongPressEvent>(std::move(longPressCallback));
680 
681     gestureHub->SetLongPressEvent(longPressEvent_, false, false, LONG_PRESS_DELAY);
682 }
683 
HandleLongPress(GestureEvent & info)684 void SwiperIndicatorPattern::HandleLongPress(GestureEvent& info)
685 {
686     HandleTouchDown();
687     HandleDragStart(info);
688 
689     auto swiperNode = GetSwiperNode();
690     CHECK_NULL_VOID(swiperNode);
691     auto swiperPattern = swiperNode->GetPattern<SwiperPattern>();
692     CHECK_NULL_VOID(swiperPattern);
693     auto swiperPaintProperty = swiperPattern->GetPaintProperty<SwiperPaintProperty>();
694     CHECK_NULL_VOID(swiperPaintProperty);
695     auto autoPlay = swiperPaintProperty->GetAutoPlay().value_or(false);
696     if (autoPlay) {
697         swiperPattern->SetIndicatorLongPress(true);
698         swiperPattern->StopTranslateAnimation();
699         swiperPattern->StopSpringAnimation();
700         swiperPattern->StopAutoPlay();
701     }
702 }
703 
HandleLongDragUpdate(const TouchLocationInfo & info)704 void SwiperIndicatorPattern::HandleLongDragUpdate(const TouchLocationInfo& info)
705 {
706     auto swiperNode = GetSwiperNode();
707     CHECK_NULL_VOID(swiperNode);
708     auto swiperPattern = swiperNode->GetPattern<SwiperPattern>();
709     CHECK_NULL_VOID(swiperPattern);
710     if (swiperPattern->IsIndicatorAnimatorRunning()) {
711         return;
712     }
713     auto swiperLayoutProperty = swiperNode->GetLayoutProperty<SwiperLayoutProperty>();
714     CHECK_NULL_VOID(swiperLayoutProperty);
715     auto displayCount = swiperLayoutProperty->GetDisplayCount().value_or(1);
716     if (swiperPattern->RealTotalCount() == displayCount) {
717         return;
718     }
719     if (CheckIsTouchBottom(info)) {
720         return;
721     }
722     auto dragPoint =
723         PointF(static_cast<float>(info.GetLocalLocation().GetX()), static_cast<float>(info.GetLocalLocation().GetY()));
724     auto offset = dragPoint - dragStartPoint_;
725     auto turnPageRateOffset = GetDirection() == Axis::HORIZONTAL ? offset.GetX() : offset.GetY();
726     if (LessNotEqual(std::abs(turnPageRateOffset), INDICATOR_DRAG_MIN_DISTANCE.ConvertToPx())) {
727         return;
728     }
729     if (swiperPattern->IsHorizontalAndRightToLeft()) {
730         turnPageRateOffset = -turnPageRateOffset;
731     }
732     auto turnPageRate = -(turnPageRateOffset / INDICATOR_DRAG_MAX_DISTANCE.ConvertToPx());
733     swiperPattern->SetTurnPageRate(turnPageRate);
734     if (std::abs(turnPageRate) >= 1) {
735         if (Positive(turnPageRateOffset)) {
736             swiperPattern->SwipeToWithoutAnimation(swiperPattern->GetCurrentIndex() + 1);
737         }
738         if (NonPositive(turnPageRateOffset)) {
739             swiperPattern->SwipeToWithoutAnimation(swiperPattern->GetCurrentIndex() - 1);
740         }
741 
742         dragStartPoint_ = dragPoint;
743     }
744 }
745 
HandleTouchClickMargin()746 float SwiperIndicatorPattern::HandleTouchClickMargin()
747 {
748     auto host = GetHost();
749     CHECK_NULL_RETURN(host, 0.0f);
750     auto paintProperty = host->GetPaintProperty<DotIndicatorPaintProperty>();
751     CHECK_NULL_RETURN(paintProperty, 0.0f);
752     auto pipeline = PipelineBase::GetCurrentContext();
753     CHECK_NULL_RETURN(pipeline, 0.0f);
754     auto theme = pipeline->GetTheme<SwiperIndicatorTheme>();
755     CHECK_NULL_RETURN(theme, 0.0f);
756     auto itemWidth = paintProperty->GetItemWidthValue(theme->GetSize()).ConvertToPx();
757     auto selectedItemWidth = paintProperty->GetSelectedItemWidthValue(theme->GetSize()).ConvertToPx();
758     if (Negative(itemWidth) || Negative(selectedItemWidth)) {
759         itemWidth = theme->GetSize().ConvertToPx();
760         selectedItemWidth = theme->GetSize().ConvertToPx();
761     }
762 
763     int32_t itemCount = RealTotalCount();
764     auto allPointDiameterSum = itemWidth * static_cast<float>(itemCount - 1) + selectedItemWidth;
765     auto allPointSpaceSum = static_cast<float>(INDICATOR_ITEM_SPACE.ConvertToPx() * (itemCount - 1));
766     auto indicatorPadding = static_cast<float>(INDICATOR_PADDING_DEFAULT.ConvertToPx());
767     auto contentWidth = indicatorPadding + allPointDiameterSum + allPointSpaceSum + indicatorPadding;
768     auto geometryNode = host->GetGeometryNode();
769     CHECK_NULL_RETURN(geometryNode, 0.0f);
770     auto frameSize = geometryNode->GetFrameSize();
771     auto axis = GetDirection();
772     return ((axis == Axis::HORIZONTAL ? frameSize.Width() : frameSize.Height()) - contentWidth) * 0.5f;
773 }
774 
DumpAdvanceInfo()775 void SwiperIndicatorPattern::DumpAdvanceInfo()
776 {
777     isHover_ ? DumpLog::GetInstance().AddDesc("isHover:true") : DumpLog::GetInstance().AddDesc("isHover:false");
778     isPressed_ ? DumpLog::GetInstance().AddDesc("isPressed:true") : DumpLog::GetInstance().AddDesc("isPressed:false");
779     isClicked_ ? DumpLog::GetInstance().AddDesc("isClicked:true") : DumpLog::GetInstance().AddDesc("isClicked:false");
780     isRepeatClicked_ ? DumpLog::GetInstance().AddDesc("isRepeatClicked:true")
781                      : DumpLog::GetInstance().AddDesc("isRepeatClicked:false");
782     switch (GetIndicatorType()) {
783         case SwiperIndicatorType::DOT: {
784             DumpLog::GetInstance().AddDesc("SwiperIndicatorType:DOT");
785             break;
786         }
787         case SwiperIndicatorType::DIGIT: {
788             DumpLog::GetInstance().AddDesc("SwiperIndicatorType:DIGIT");
789             break;
790         }
791         default: {
792             break;
793         }
794     }
795 }
796 
CreateOverlongDotIndicatorPaintMethod(RefPtr<SwiperPattern> swiperPattern)797 RefPtr<OverlengthDotIndicatorPaintMethod> SwiperIndicatorPattern::CreateOverlongDotIndicatorPaintMethod(
798     RefPtr<SwiperPattern> swiperPattern)
799 {
800     if (dotIndicatorModifier_) {
801         dotIndicatorModifier_->StopAnimation(true);
802         dotIndicatorModifier_->SetIsOverlong(true);
803     }
804 
805     if (!overlongDotIndicatorModifier_) {
806         overlongDotIndicatorModifier_ = AceType::MakeRefPtr<OverlengthDotIndicatorModifier>();
807     }
808 
809     overlongDotIndicatorModifier_->SetAnimationDuration(swiperPattern->GetDuration());
810     overlongDotIndicatorModifier_->SetLongPointHeadCurve(
811         swiperPattern->GetCurveIncludeMotion(), swiperPattern->GetMotionVelocity());
812 
813     auto swiperLayoutProperty = swiperPattern->GetLayoutProperty<SwiperLayoutProperty>();
814     CHECK_NULL_RETURN(swiperLayoutProperty, nullptr);
815     auto overlongPaintMethod = MakeRefPtr<OverlengthDotIndicatorPaintMethod>(overlongDotIndicatorModifier_);
816     auto paintMethodTemp = DynamicCast<DotIndicatorPaintMethod>(overlongPaintMethod);
817     SetDotIndicatorPaintMethodInfo(swiperPattern, paintMethodTemp, swiperLayoutProperty);
818     UpdateOverlongPaintMethod(swiperPattern, overlongPaintMethod);
819 
820     return overlongPaintMethod;
821 }
822 
CreateDotIndicatorPaintMethod(RefPtr<SwiperPattern> swiperPattern)823 RefPtr<DotIndicatorPaintMethod> SwiperIndicatorPattern::CreateDotIndicatorPaintMethod(
824     RefPtr<SwiperPattern> swiperPattern)
825 {
826     if (overlongDotIndicatorModifier_) {
827         overlongDotIndicatorModifier_->StopAnimation(true);
828         overlongDotIndicatorModifier_->SetMaxDisplayCount(0);
829     }
830 
831     if (!dotIndicatorModifier_) {
832         dotIndicatorModifier_ = AceType::MakeRefPtr<DotIndicatorModifier>();
833     }
834 
835     dotIndicatorModifier_->SetIsOverlong(false);
836     dotIndicatorModifier_->SetAnimationDuration(swiperPattern->GetDuration());
837     dotIndicatorModifier_->SetLongPointHeadCurve(
838         swiperPattern->GetCurveIncludeMotion(), swiperPattern->GetMotionVelocity());
839     auto swiperLayoutProperty = swiperPattern->GetLayoutProperty<SwiperLayoutProperty>();
840     CHECK_NULL_RETURN(swiperLayoutProperty, nullptr);
841     auto paintMethod = MakeRefPtr<DotIndicatorPaintMethod>(dotIndicatorModifier_);
842     SetDotIndicatorPaintMethodInfo(swiperPattern, paintMethod, swiperLayoutProperty);
843 
844     dotIndicatorModifier_->SetBoundsRect(CalcBoundsRect());
845 
846     return paintMethod;
847 }
848 
CalcBoundsRect() const849 RectF SwiperIndicatorPattern::CalcBoundsRect() const
850 {
851     auto swiperNode = GetSwiperNode();
852     CHECK_NULL_RETURN(swiperNode, RectF());
853     auto geometryNode = swiperNode->GetGeometryNode();
854     CHECK_NULL_RETURN(geometryNode, RectF());
855     auto host = GetHost();
856     CHECK_NULL_RETURN(host, RectF());
857     auto indicatorGeometryNode = host->GetGeometryNode();
858     CHECK_NULL_RETURN(indicatorGeometryNode, RectF());
859     auto boundsValue = (geometryNode->GetFrameSize().Width() - indicatorGeometryNode->GetFrameSize().Width()) * 0.5f;
860     auto boundsRectOriginX = -boundsValue;
861     auto boundsRectOriginY = 0.0f;
862     auto boundsRectWidth = geometryNode->GetFrameSize().Width();
863     auto boundsRectHeight = indicatorGeometryNode->GetFrameSize().Height();
864     auto swiperPattern = swiperNode->GetPattern<SwiperPattern>();
865     CHECK_NULL_RETURN(swiperPattern, RectF());
866     if (GetDirection() == Axis::VERTICAL) {
867         boundsValue = (geometryNode->GetFrameSize().Height() - indicatorGeometryNode->GetFrameSize().Height()) * 0.5f;
868         boundsRectOriginX = 0.0f;
869         boundsRectOriginY = -boundsValue;
870         boundsRectWidth = indicatorGeometryNode->GetFrameSize().Width();
871         boundsRectHeight = geometryNode->GetFrameSize().Height();
872     }
873     RectF boundsRect(boundsRectOriginX, boundsRectOriginY, boundsRectWidth, boundsRectHeight);
874 
875     return boundsRect;
876 }
877 
UpdateOverlongPaintMethod(const RefPtr<SwiperPattern> & swiperPattern,RefPtr<OverlengthDotIndicatorPaintMethod> & overlongPaintMethod)878 void SwiperIndicatorPattern::UpdateOverlongPaintMethod(
879     const RefPtr<SwiperPattern>& swiperPattern, RefPtr<OverlengthDotIndicatorPaintMethod>& overlongPaintMethod)
880 {
881     auto animationStartIndex = swiperPattern->GetLoopIndex(swiperPattern->GetCurrentIndex());
882     auto animationEndIndex = swiperPattern->GetLoopIndex(swiperPattern->GetCurrentFirstIndex());
883 
884     auto paintMethodTemp = DynamicCast<DotIndicatorPaintMethod>(overlongPaintMethod);
885     if (changeIndexWithAnimation_ && !changeIndexWithAnimation_.value()) {
886         animationStartIndex = startIndex_ ? startIndex_.value() : overlongDotIndicatorModifier_->GetAnimationEndIndex();
887         paintMethodTemp->SetGestureState(GestureState::GESTURE_STATE_NONE);
888     }
889 
890     if (jumpIndex_) {
891         paintMethodTemp->SetGestureState(GestureState::GESTURE_STATE_NONE);
892 
893         if (!changeIndexWithAnimation_) {
894             overlongDotIndicatorModifier_->StopAnimation(true);
895             overlongDotIndicatorModifier_->SetCurrentOverlongType(OverlongType::NONE);
896         }
897     }
898 
899     auto isSwiperTouchDown = swiperPattern->IsTouchDownOnOverlong();
900     auto isSwiperAnimationRunning =
901         swiperPattern->IsPropertyAnimationRunning() || swiperPattern->IsTranslateAnimationRunning();
902     auto keepStatus = !isSwiperTouchDown && !isSwiperAnimationRunning && animationStartIndex != animationEndIndex &&
903                       !changeIndexWithAnimation_;
904 
905     if (!changeIndexWithAnimation_ && gestureState_ == GestureState::GESTURE_STATE_NONE) {
906         keepStatus = true;
907     }
908 
909     auto bottomTouchLoop = swiperPattern->GetTouchBottomTypeLoop();
910     auto turnPageRateAbs = std::abs(swiperPattern->GetTurnPageRate());
911     auto totalCount = swiperPattern->RealTotalCount();
912     auto loopDrag = (animationStartIndex == 0 && animationEndIndex == totalCount - 1 && turnPageRateAbs < HALF_FLOAT &&
913                         turnPageRateAbs > 0.0f) ||
914                     (animationStartIndex == animationEndIndex && animationEndIndex == totalCount - 1 &&
915                         turnPageRateAbs > HALF_FLOAT);
916     auto nonLoopDrag = bottomTouchLoop == TouchBottomTypeLoop::TOUCH_BOTTOM_TYPE_LOOP_NONE &&
917                        ((gestureState_ == GestureState::GESTURE_STATE_FOLLOW_RIGHT && turnPageRateAbs > HALF_FLOAT) ||
918                            (gestureState_ == GestureState::GESTURE_STATE_FOLLOW_LEFT && turnPageRateAbs < HALF_FLOAT &&
919                                turnPageRateAbs > 0.0f));
920 
921     if (isSwiperTouchDown && (loopDrag || nonLoopDrag)) {
922         overlongDotIndicatorModifier_->UpdateCurrentStatus();
923     }
924 
925     overlongPaintMethod->SetMaxDisplayCount(swiperPattern->GetMaxDisplayCount());
926     overlongPaintMethod->SetKeepStatus(keepStatus);
927     overlongPaintMethod->SetAnimationStartIndex(animationStartIndex);
928     overlongPaintMethod->SetAnimationEndIndex(animationEndIndex);
929     overlongDotIndicatorModifier_->SetIsSwiperTouchDown(isSwiperTouchDown);
930     overlongDotIndicatorModifier_->SetBoundsRect(CalcBoundsRect());
931     changeIndexWithAnimation_.reset();
932     jumpIndex_.reset();
933     startIndex_.reset();
934 }
935 
ShowPrevious()936 void SwiperIndicatorPattern::ShowPrevious()
937 {
938     auto swiperPattern = GetSwiperPattern();
939     CHECK_NULL_VOID(swiperPattern);
940     swiperPattern->ShowPrevious();
941 }
942 
ShowNext()943 void SwiperIndicatorPattern::ShowNext()
944 {
945     auto swiperPattern = GetSwiperPattern();
946     CHECK_NULL_VOID(swiperPattern);
947     swiperPattern->ShowNext();
948 }
949 
ChangeIndex(int32_t index,bool useAnimation)950 void SwiperIndicatorPattern::ChangeIndex(int32_t index, bool useAnimation)
951 {
952     auto swiperPattern = GetSwiperPattern();
953     CHECK_NULL_VOID(swiperPattern);
954     swiperPattern->ChangeIndex(index, useAnimation);
955 }
956 
GetTouchCurrentIndex() const957 int32_t SwiperIndicatorPattern::GetTouchCurrentIndex() const
958 {
959     return GetCurrentIndex();
960 }
961 
GetCurrentIndex() const962 int32_t SwiperIndicatorPattern::GetCurrentIndex() const
963 {
964     auto swiperPattern = GetSwiperPattern();
965     CHECK_NULL_RETURN(swiperPattern, 0);
966     auto indicatorCount = swiperPattern->RealTotalCount();
967     auto currentIndex = swiperPattern->GetCurrentIndex();
968     auto isRtl = IsHorizontalAndRightToLeft();
969     if (isRtl) {
970         currentIndex = indicatorCount - 1 - currentIndex;
971     }
972     return currentIndex;
973 }
974 
GetCurrentShownIndex() const975 int32_t SwiperIndicatorPattern::GetCurrentShownIndex() const
976 {
977     auto swiperPattern = GetSwiperPattern();
978     CHECK_NULL_RETURN(swiperPattern, 0);
979     return swiperPattern->GetCurrentShownIndex();
980 }
981 
RealTotalCount() const982 int32_t SwiperIndicatorPattern::RealTotalCount() const
983 {
984     auto swiperPattern = GetSwiperPattern();
985     CHECK_NULL_RETURN(swiperPattern, 0);
986     return swiperPattern->RealTotalCount();
987 }
988 
GetDirection() const989 Axis SwiperIndicatorPattern::GetDirection() const
990 {
991     auto swiperPattern = GetSwiperPattern();
992     CHECK_NULL_RETURN(swiperPattern, Axis::HORIZONTAL);
993     return swiperPattern->GetDirection();
994 }
995 
IsHorizontalAndRightToLeft() const996 bool SwiperIndicatorPattern::IsHorizontalAndRightToLeft() const
997 {
998     auto swiperPattern = GetSwiperPattern();
999     CHECK_NULL_RETURN(swiperPattern, false);
1000     return swiperPattern->IsHorizontalAndRightToLeft();
1001 }
1002 
GetNonAutoLayoutDirection() const1003 TextDirection SwiperIndicatorPattern::GetNonAutoLayoutDirection() const
1004 {
1005     auto swiperPattern = GetSwiperPattern();
1006     CHECK_NULL_RETURN(swiperPattern, TextDirection::LTR);
1007     return swiperPattern->GetNonAutoLayoutDirection();
1008 }
1009 
IsLoop() const1010 bool SwiperIndicatorPattern::IsLoop() const
1011 {
1012     auto swiperPattern = GetSwiperPattern();
1013     CHECK_NULL_RETURN(swiperPattern, true);
1014     return swiperPattern->IsLoop();
1015 }
1016 
GetTextContentSub(std::string & firstContent,std::string & lastContent) const1017 void SwiperIndicatorPattern::GetTextContentSub(std::string& firstContent, std::string& lastContent) const
1018 {
1019     auto swiperPattern = GetSwiperPattern();
1020     CHECK_NULL_VOID(swiperPattern);
1021     auto currentIndex = GetDisplayCurrentIndex();
1022     bool isRtl = swiperPattern->GetNonAutoLayoutDirection() == TextDirection::RTL;
1023     firstContent = isRtl ? std::to_string(swiperPattern->RealTotalCount()) : std::to_string(currentIndex);
1024     lastContent = isRtl ? std::to_string(currentIndex) + "\\" : "/" + std::to_string(swiperPattern->RealTotalCount());
1025 }
1026 
SwipeTo(std::optional<int32_t> mouseClickIndex)1027 void SwiperIndicatorPattern::SwipeTo(std::optional<int32_t> mouseClickIndex)
1028 {
1029     auto swiperNode = GetSwiperNode();
1030     CHECK_NULL_VOID(swiperNode);
1031     auto swiperPattern = swiperNode->GetPattern<SwiperPattern>();
1032     CHECK_NULL_VOID(swiperPattern);
1033     if (swiperPattern->IsSwipeByGroup()) {
1034         auto clickPageIndex = SwiperUtils::ComputePageIndex(mouseClickIndex.value(), swiperPattern->GetDisplayCount());
1035         if (clickPageIndex == swiperPattern->GetCurrentIndex()) {
1036             mouseClickIndex_ = std::nullopt;
1037             return;
1038         }
1039         mouseClickIndex_ = clickPageIndex;
1040     }
1041     swiperPattern->SwipeTo(mouseClickIndex.value());
1042 }
1043 
GetDotCurrentOffset(OffsetF & offset,float indicatorWidth,float indicatorHeight)1044 bool SwiperIndicatorPattern::GetDotCurrentOffset(OffsetF& offset, float indicatorWidth, float indicatorHeight)
1045 {
1046     auto frameNode = GetHost();
1047     CHECK_NULL_RETURN(frameNode, true);
1048     auto swiperNode = GetSwiperNode();
1049     CHECK_NULL_RETURN(swiperNode, true);
1050     auto swiperLayoutProperty = swiperNode->GetLayoutProperty<SwiperLayoutProperty>();
1051     CHECK_NULL_RETURN(swiperLayoutProperty, true);
1052     auto indicatorlayoutProperty = frameNode->GetLayoutProperty<SwiperIndicatorLayoutProperty>();
1053     CHECK_NULL_RETURN(indicatorlayoutProperty, true);
1054 
1055     offset = SwiperIndicatorUtils::CalcIndicatrFrameOffSet(
1056         swiperLayoutProperty, indicatorlayoutProperty, indicatorWidth, indicatorHeight);
1057     return true;
1058 }
1059 
GetLoopIndex(int32_t originalIndex) const1060 int32_t SwiperIndicatorPattern::GetLoopIndex(int32_t originalIndex) const
1061 {
1062     auto realTotalCount = RealTotalCount();
1063     if (realTotalCount <= 0) {
1064         return originalIndex;
1065     }
1066     auto loopIndex = originalIndex;
1067     while (loopIndex < 0) {
1068         loopIndex = loopIndex + realTotalCount;
1069     }
1070     if (realTotalCount != 0) {
1071         loopIndex %= realTotalCount;
1072     }
1073     return loopIndex;
1074 }
1075 
IndicatorOnChange()1076 void SwiperIndicatorPattern::IndicatorOnChange()
1077 {
1078     auto host = GetHost();
1079     CHECK_NULL_VOID(host);
1080     auto pipeline = PipelineContext::GetCurrentContextSafely();
1081     CHECK_NULL_VOID(pipeline);
1082     pipeline->AddAfterLayoutTask([weak = AceType::WeakClaim(RawPtr(host)), context = AceType::WeakClaim(this)]() {
1083         auto indicator = weak.Upgrade();
1084         CHECK_NULL_VOID(indicator);
1085         auto textContext = context.Upgrade();
1086         CHECK_NULL_VOID(textContext);
1087         if (textContext->GetIndicatorType() == SwiperIndicatorType::DIGIT) {
1088             RefPtr<FrameNode> firstTextNode;
1089             RefPtr<FrameNode> lastTextNode;
1090             auto layoutProperty = indicator->GetLayoutProperty<SwiperIndicatorLayoutProperty>();
1091             firstTextNode = DynamicCast<FrameNode>(indicator->GetFirstChild());
1092             lastTextNode = DynamicCast<FrameNode>(indicator->GetLastChild());
1093             textContext->UpdateTextContent(layoutProperty, firstTextNode, lastTextNode);
1094         }
1095         indicator->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
1096     });
1097     pipeline->RequestFrame();
1098 }
1099 
GetDigitFrameSize(RefPtr<GeometryNode> & geoNode,SizeF & frameSize) const1100 bool SwiperIndicatorPattern::GetDigitFrameSize(RefPtr<GeometryNode>& geoNode, SizeF& frameSize) const
1101 {
1102     CHECK_NULL_RETURN(geoNode, false);
1103     frameSize = geoNode->GetMarginFrameSize();
1104     return true;
1105 }
1106 } // namespace OHOS::Ace::NG
1107