• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024 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/indicator_pattern.h"
17 
18 namespace OHOS::Ace::NG {
19 namespace {
20 constexpr Dimension INDICATOR_DRAG_MIN_DISTANCE = 4.0_vp;
21 constexpr Dimension INDICATOR_DRAG_MAX_DISTANCE = 18.0_vp;
22 constexpr Dimension INDICATOR_TOUCH_BOTTOM_MAX_DISTANCE = 80.0_vp;
23 constexpr Dimension INDICATOR_BORDER_RADIUS = 16.0_vp;
24 constexpr float DEFAULT_COUNT = 2.0f;
25 } // namespace
26 
IndicatorPattern()27 IndicatorPattern::IndicatorPattern()
28 {
29     indicatorController_ = MakeRefPtr<IndicatorController>();
30     InitIndicatorController();
31 }
32 
InitIndicatorController()33 void IndicatorPattern::InitIndicatorController()
34 {
35     indicatorController_->SetShowNextImpl([weak = WeakClaim(this)]() {
36         auto indicator = weak.Upgrade();
37         CHECK_NULL_VOID(indicator);
38         indicator->ShowNext();
39     });
40 
41     indicatorController_->SetShowPrevImpl([weak = WeakClaim(this)]() {
42         auto indicator = weak.Upgrade();
43         CHECK_NULL_VOID(indicator);
44         indicator->ShowPrevious();
45     });
46 
47     indicatorController_->SetChangeIndexImpl([weak = WeakClaim(this)](int32_t index, bool useAnimation) {
48         auto indicator = weak.Upgrade();
49         CHECK_NULL_VOID(indicator);
50         indicator->ChangeIndex(index, useAnimation);
51     });
52 }
53 
SetSwiperDigitalParameters(const SwiperDigitalParameters & swiperDigitalParameters)54 void IndicatorPattern::SetSwiperDigitalParameters(const SwiperDigitalParameters& swiperDigitalParameters)
55 {
56     swiperDigitalParameters_ = std::make_shared<SwiperDigitalParameters>(swiperDigitalParameters);
57 }
58 
GetIndicatorTypeFromProperty() const59 SwiperIndicatorType IndicatorPattern::GetIndicatorTypeFromProperty() const
60 {
61     auto swiperIndicatorLayoutProperty = GetLayoutProperty<SwiperIndicatorLayoutProperty>();
62     CHECK_NULL_RETURN(swiperIndicatorLayoutProperty, SwiperIndicatorType::DOT);
63     return swiperIndicatorLayoutProperty->GetIndicatorTypeValue(SwiperIndicatorType::DOT);
64 }
65 
GetInitialIndexFromProperty() const66 int32_t IndicatorPattern::GetInitialIndexFromProperty() const
67 {
68     auto swiperIndicatorLayoutProperty = GetLayoutProperty<SwiperIndicatorLayoutProperty>();
69     CHECK_NULL_RETURN(swiperIndicatorLayoutProperty, 0);
70     return swiperIndicatorLayoutProperty->GetInitialIndex().value_or(0);
71 }
72 
GetDirectionFromProperty() const73 Axis IndicatorPattern::GetDirectionFromProperty() const
74 {
75     auto swiperIndicatorLayoutProperty = GetLayoutProperty<SwiperIndicatorLayoutProperty>();
76     CHECK_NULL_RETURN(swiperIndicatorLayoutProperty, Axis::HORIZONTAL);
77     return swiperIndicatorLayoutProperty->GetDirection().value_or(Axis::HORIZONTAL);
78 }
79 
GetCountFromProperty() const80 int32_t IndicatorPattern::GetCountFromProperty() const
81 {
82     auto swiperIndicatorLayoutProperty = GetLayoutProperty<SwiperIndicatorLayoutProperty>();
83     CHECK_NULL_RETURN(swiperIndicatorLayoutProperty, DEFAULT_COUNT);
84     return swiperIndicatorLayoutProperty->GetCount().value_or(DEFAULT_COUNT);
85 }
86 
IsLoopFromProperty() const87 bool IndicatorPattern::IsLoopFromProperty() const
88 {
89     auto swiperIndicatorLayoutProperty = GetLayoutProperty<SwiperIndicatorLayoutProperty>();
90     CHECK_NULL_RETURN(swiperIndicatorLayoutProperty, true);
91     return swiperIndicatorLayoutProperty->GetLoop().value_or(true);
92 }
93 
FireChangeEvent() const94 void IndicatorPattern::FireChangeEvent() const
95 {
96     auto indicatorEventHub = GetEventHub<IndicatorEventHub>();
97     CHECK_NULL_VOID(indicatorEventHub);
98     indicatorEventHub->FireChangeEvent(GetLoopIndex(GetCurrentIndex()));
99 }
100 
FireIndicatorIndexChangeEvent(int32_t index) const101 void IndicatorPattern::FireIndicatorIndexChangeEvent(int32_t index) const
102 {
103     auto indicatorEventHub = GetEventHub<IndicatorEventHub>();
104     CHECK_NULL_VOID(indicatorEventHub);
105     indicatorEventHub->FireChangeEvent(GetLoopIndex(index));
106 }
107 
GetSwiperParameters()108 std::shared_ptr<SwiperParameters> IndicatorPattern::GetSwiperParameters()
109 {
110     if (swiperParameters_ == nullptr) {
111         swiperParameters_ = std::make_shared<SwiperParameters>();
112         auto pipelineContext = GetContext();
113         CHECK_NULL_RETURN(pipelineContext, swiperParameters_);
114         auto swiperIndicatorTheme = pipelineContext->GetTheme<SwiperIndicatorTheme>();
115         CHECK_NULL_RETURN(swiperIndicatorTheme, swiperParameters_);
116         swiperParameters_->itemWidth = swiperIndicatorTheme->GetSize();
117         swiperParameters_->itemHeight = swiperIndicatorTheme->GetSize();
118         swiperParameters_->selectedItemWidth = swiperIndicatorTheme->GetSize();
119         swiperParameters_->selectedItemHeight = swiperIndicatorTheme->GetSize();
120         swiperParameters_->maskValue = false;
121         swiperParameters_->colorVal = swiperIndicatorTheme->GetColor();
122         swiperParameters_->selectedColorVal = swiperIndicatorTheme->GetSelectedColor();
123         swiperParameters_->dimSpace = swiperIndicatorTheme->GetIndicatorDotItemSpace();
124     }
125     return swiperParameters_;
126 }
127 
GetSwiperDigitalParameters()128 std::shared_ptr<SwiperDigitalParameters> IndicatorPattern::GetSwiperDigitalParameters()
129 {
130     if (swiperDigitalParameters_ == nullptr) {
131         swiperDigitalParameters_ = std::make_shared<SwiperDigitalParameters>();
132         auto pipelineContext = GetContext();
133         CHECK_NULL_RETURN(pipelineContext, swiperDigitalParameters_);
134         auto swiperIndicatorTheme = pipelineContext->GetTheme<SwiperIndicatorTheme>();
135         swiperDigitalParameters_->fontColor = swiperIndicatorTheme->GetDigitalIndicatorTextStyle().GetTextColor();
136         swiperDigitalParameters_->selectedFontColor =
137             swiperIndicatorTheme->GetDigitalIndicatorTextStyle().GetTextColor();
138         swiperDigitalParameters_->fontSize = swiperIndicatorTheme->GetDigitalIndicatorTextStyle().GetFontSize();
139         swiperDigitalParameters_->selectedFontSize = swiperIndicatorTheme->GetDigitalIndicatorTextStyle().GetFontSize();
140         swiperDigitalParameters_->fontWeight = swiperIndicatorTheme->GetDigitalIndicatorTextStyle().GetFontWeight();
141         swiperDigitalParameters_->selectedFontWeight =
142             swiperIndicatorTheme->GetDigitalIndicatorTextStyle().GetFontWeight();
143     }
144     return swiperDigitalParameters_;
145 }
146 
SaveDigitIndicatorProperty()147 void IndicatorPattern::SaveDigitIndicatorProperty()
148 {
149     auto indicatorNode = GetHost();
150     CHECK_NULL_VOID(indicatorNode);
151     auto layoutProperty = indicatorNode->GetLayoutProperty<SwiperIndicatorLayoutProperty>();
152     CHECK_NULL_VOID(layoutProperty);
153     auto pipelineContext = indicatorNode->GetContext();
154     CHECK_NULL_VOID(pipelineContext);
155     auto swiperIndicatorTheme = pipelineContext->GetTheme<SwiperIndicatorTheme>();
156     auto swiperDigitalParameters = GetSwiperDigitalParameters();
157     CHECK_NULL_VOID(swiperDigitalParameters);
158     layoutProperty->ResetIndicatorLayoutStyle();
159     if (swiperDigitalParameters->dimLeft.has_value()) {
160         layoutProperty->UpdateLeft(swiperDigitalParameters->dimLeft.value());
161     }
162     if (swiperDigitalParameters->dimTop.has_value()) {
163         layoutProperty->UpdateTop(swiperDigitalParameters->dimTop.value());
164     }
165     if (swiperDigitalParameters->dimRight.has_value()) {
166         layoutProperty->UpdateRight(swiperDigitalParameters->dimRight.value());
167     }
168     if (swiperDigitalParameters->dimBottom.has_value()) {
169         layoutProperty->UpdateBottom(swiperDigitalParameters->dimBottom.value());
170     }
171     layoutProperty->UpdateFontColor(swiperDigitalParameters->fontColor.value_or(
172         swiperIndicatorTheme->GetDigitalIndicatorTextStyle().GetTextColor()));
173     layoutProperty->UpdateSelectedFontColor(swiperDigitalParameters->selectedFontColor.value_or(
174         swiperIndicatorTheme->GetDigitalIndicatorTextStyle().GetTextColor()));
175     layoutProperty->UpdateFontSize(
176         swiperDigitalParameters->fontSize.value_or(swiperIndicatorTheme->GetDigitalIndicatorTextStyle().GetFontSize()));
177     layoutProperty->UpdateSelectedFontSize(swiperDigitalParameters->selectedFontSize.value_or(
178         swiperIndicatorTheme->GetDigitalIndicatorTextStyle().GetFontSize()));
179     layoutProperty->UpdateFontWeight(swiperDigitalParameters->fontWeight.value_or(
180         swiperIndicatorTheme->GetDigitalIndicatorTextStyle().GetFontWeight()));
181     layoutProperty->UpdateSelectedFontWeight(swiperDigitalParameters->selectedFontWeight.value_or(
182         swiperIndicatorTheme->GetDigitalIndicatorTextStyle().GetFontWeight()));
183     ResetDotModifier();
184 }
185 
SaveDotIndicatorProperty()186 void IndicatorPattern::SaveDotIndicatorProperty()
187 {
188     auto indicatorNode = GetHost();
189     CHECK_NULL_VOID(indicatorNode);
190     auto layoutProperty = indicatorNode->GetLayoutProperty<SwiperIndicatorLayoutProperty>();
191     CHECK_NULL_VOID(layoutProperty);
192     auto swiperParameters = GetSwiperParameters();
193     CHECK_NULL_VOID(swiperParameters);
194     layoutProperty->ResetIndicatorLayoutStyle();
195     if (swiperParameters->dimLeft.has_value()) {
196         layoutProperty->UpdateLeft(swiperParameters->dimLeft.value());
197     }
198     if (swiperParameters->dimTop.has_value()) {
199         layoutProperty->UpdateTop(swiperParameters->dimTop.value());
200     }
201     if (swiperParameters->dimRight.has_value()) {
202         layoutProperty->UpdateRight(swiperParameters->dimRight.value());
203     }
204     if (swiperParameters->dimBottom.has_value()) {
205         layoutProperty->UpdateBottom(swiperParameters->dimBottom.value());
206     }
207 
208     bool isRtl = GetNonAutoLayoutDirection() == TextDirection::RTL;
209     if (swiperParameters->dimStart.has_value()) {
210         auto dimValue = swiperParameters->dimStart.value();
211         isRtl ? layoutProperty->UpdateRight(dimValue) : layoutProperty->UpdateLeft(dimValue);
212     }
213     if (swiperParameters->dimEnd.has_value()) {
214         auto dimValue = swiperParameters->dimEnd.value();
215         isRtl ? layoutProperty->UpdateLeft(dimValue) : layoutProperty->UpdateRight(dimValue);
216     }
217     if (swiperParameters->dimSpace.has_value()) {
218         layoutProperty->UpdateSpace(swiperParameters->dimSpace.value());
219     }
220     UpdatePaintProperty();
221 }
222 
UpdatePaintProperty()223 void IndicatorPattern::UpdatePaintProperty()
224 {
225     auto indicatorNode = GetHost();
226     CHECK_NULL_VOID(indicatorNode);
227     auto paintProperty = indicatorNode->GetPaintProperty<DotIndicatorPaintProperty>();
228     CHECK_NULL_VOID(paintProperty);
229     auto pipelineContext = indicatorNode->GetContext();
230     CHECK_NULL_VOID(pipelineContext);
231     auto swiperIndicatorTheme = pipelineContext->GetTheme<SwiperIndicatorTheme>();
232     CHECK_NULL_VOID(swiperIndicatorTheme);
233     auto swiperParameters = GetSwiperParameters();
234     CHECK_NULL_VOID(swiperParameters);
235     paintProperty->UpdateItemWidth(swiperParameters->itemWidth.value_or(swiperIndicatorTheme->GetSize()));
236     paintProperty->UpdateItemHeight(swiperParameters->itemHeight.value_or(swiperIndicatorTheme->GetSize()));
237     paintProperty->UpdateSelectedItemWidth(
238         swiperParameters->selectedItemWidth.value_or(swiperIndicatorTheme->GetSize()));
239     paintProperty->UpdateSelectedItemHeight(
240         swiperParameters->selectedItemHeight.value_or(swiperIndicatorTheme->GetSize()));
241     paintProperty->UpdateIndicatorMask(swiperParameters->maskValue.value_or(false));
242     paintProperty->UpdateColor(swiperParameters->colorVal.value_or(swiperIndicatorTheme->GetColor()));
243     paintProperty->UpdateSelectedColor(
244         swiperParameters->selectedColorVal.value_or(swiperIndicatorTheme->GetSelectedColor()));
245     paintProperty->UpdateIsCustomSize(isCustomSize_);
246     paintProperty->UpdateSpace(swiperParameters->dimSpace.value_or(swiperIndicatorTheme->GetIndicatorDotItemSpace()));
247     indicatorNode->MarkDirtyNode(PROPERTY_UPDATE_MEASURE);
248     indicatorNode->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
249 }
250 
OnModifyDone()251 void IndicatorPattern::OnModifyDone()
252 {
253     if (!hasSetInitialIndex_) {
254         hasSetInitialIndex_ = true;
255         auto initialIndex = GetInitialIndexFromProperty();
256         if ((initialIndex < 0) || (initialIndex >= RealTotalCount())) {
257             initialIndex = 0;
258         }
259         currentIndexInSingleMode_ = initialIndex;
260     }
261     if (currentIndexInSingleMode_ > RealTotalCount() - 1) {
262         currentIndexInSingleMode_ = 0;
263     }
264     auto indicatorNode = GetHost();
265     CHECK_NULL_VOID(indicatorNode);
266     if (GetIndicatorType() == SwiperIndicatorType::DOT) {
267         SaveDotIndicatorProperty();
268     } else {
269         SaveDigitIndicatorProperty();
270     }
271 
272     auto renderContext = indicatorNode->GetRenderContext();
273     CHECK_NULL_VOID(renderContext);
274     BorderRadiusProperty radius;
275     auto commonRadiusValue = renderContext->GetBorderRadius();
276     if (commonRadiusValue.has_value()) {
277         radius.UpdateWithCheck(commonRadiusValue.value());
278     } else {
279         radius.SetRadius(INDICATOR_BORDER_RADIUS);
280     }
281     renderContext->UpdateBorderRadius(radius);
282     auto focusHub = indicatorNode->GetFocusHub();
283     if (focusHub) {
284         InitOnKeyEvent(focusHub);
285     }
286     SwiperIndicatorPattern::OnModifyDone();
287 }
288 
InitOnKeyEvent(const RefPtr<FocusHub> & focusHub)289 void IndicatorPattern::InitOnKeyEvent(const RefPtr<FocusHub>& focusHub)
290 {
291     auto onKeyEvent = [wp = WeakClaim(this)](const KeyEvent& event) -> bool {
292         auto pattern = wp.Upgrade();
293         if (pattern) {
294             return pattern->OnKeyEvent(event);
295         }
296         return false;
297     };
298     focusHub->SetOnKeyEventInternal(std::move(onKeyEvent));
299 }
300 
OnKeyEvent(const KeyEvent & event)301 bool IndicatorPattern::OnKeyEvent(const KeyEvent& event)
302 {
303     if (event.action != KeyAction::DOWN) {
304         return false;
305     }
306     if ((GetDirection() == Axis::HORIZONTAL &&
307             event.code == (IsHorizontalAndRightToLeft() ? KeyCode::KEY_DPAD_RIGHT : KeyCode::KEY_DPAD_LEFT)) ||
308         (GetDirection() == Axis::VERTICAL && event.code == KeyCode::KEY_DPAD_UP)) {
309         ShowPrevious();
310         return true;
311     }
312     if ((GetDirection() == Axis::HORIZONTAL &&
313             event.code == (IsHorizontalAndRightToLeft() ? KeyCode::KEY_DPAD_LEFT : KeyCode::KEY_DPAD_RIGHT)) ||
314         (GetDirection() == Axis::VERTICAL && event.code == KeyCode::KEY_DPAD_DOWN)) {
315         ShowNext();
316         return true;
317     }
318     return false;
319 }
320 
GetDotCurrentOffset(OffsetF & offset,float indicatorWidth,float indicatorHeight)321 bool IndicatorPattern::GetDotCurrentOffset(OffsetF& offset, float indicatorWidth, float indicatorHeight)
322 {
323     return false;
324 }
325 
GetDigitFrameSize(RefPtr<GeometryNode> & geoNode,SizeF & frameSize) const326 bool IndicatorPattern::GetDigitFrameSize(RefPtr<GeometryNode>& geoNode, SizeF& frameSize) const
327 {
328     CHECK_NULL_RETURN(geoNode, false);
329     frameSize = geoNode->GetFrameSize();
330     return true;
331 }
332 
OnIndexChangeInSingleMode(int32_t index)333 void IndicatorPattern::OnIndexChangeInSingleMode(int32_t index)
334 {
335     if (!IsLoop() || IsHover() || IsPressed()) {
336         singleIndicatorTouchBottomTypeLoop_ = TouchBottomTypeLoop::TOUCH_BOTTOM_TYPE_LOOP_NONE;
337         if (index >= RealTotalCount()) {
338             SetCurrentIndexInSingleMode(RealTotalCount() - 1);
339             return;
340         } else if (index < 0) {
341             SetCurrentIndexInSingleMode(0);
342             return;
343         }
344     }
345     SetCurrentIndexInSingleMode(GetLoopIndex(index));
346     FireChangeEvent();
347     SwiperIndicatorPattern::IndicatorOnChange();
348 }
349 
ShowPrevious()350 void IndicatorPattern::ShowPrevious()
351 {
352     if (GetBindSwiperNode()) {
353         return SwiperIndicatorPattern::ShowPrevious();
354     }
355 
356     singleIndicatorTouchBottomTypeLoop_ = TouchBottomTypeLoop::TOUCH_BOTTOM_TYPE_LOOP_NONE;
357     if (IsHorizontalAndRightToLeft()) {
358         singleGestureState_ = GestureState::GESTURE_STATE_RELEASE_RIGHT;
359         if (IsLoop() && GetCurrentIndex() == 0) {
360             singleIndicatorTouchBottomTypeLoop_ = TouchBottomTypeLoop::TOUCH_BOTTOM_TYPE_LOOP_RIGHT;
361         }
362     } else {
363         singleGestureState_ = GestureState::GESTURE_STATE_RELEASE_LEFT;
364         if (IsLoop() && GetCurrentIndex() == 0) {
365             singleIndicatorTouchBottomTypeLoop_ = TouchBottomTypeLoop::TOUCH_BOTTOM_TYPE_LOOP_LEFT;
366         }
367     }
368     auto dotIndicatorModifier = GetDotIndicatorModifier();
369     if (dotIndicatorModifier && !dotIndicatorModifier->GetIsBottomAnimationFinished()) {
370         dotIndicatorModifier->FinishAnimationToTargetImmediately(dotIndicatorModifier->GetTargetCenter());
371     }
372     lastIndex_ = GetCurrentIndex();
373     OnIndexChangeInSingleMode(GetCurrentIndex() - 1);
374 }
375 
ShowNext()376 void IndicatorPattern::ShowNext()
377 {
378     if (GetBindSwiperNode()) {
379         return SwiperIndicatorPattern::ShowNext();
380     }
381     singleIndicatorTouchBottomTypeLoop_ = TouchBottomTypeLoop::TOUCH_BOTTOM_TYPE_LOOP_NONE;
382     if (IsHorizontalAndRightToLeft()) {
383         singleGestureState_ = GestureState::GESTURE_STATE_RELEASE_LEFT;
384         if (IsLoop() && GetCurrentIndex() == (RealTotalCount() - 1)) {
385             singleIndicatorTouchBottomTypeLoop_ = TouchBottomTypeLoop::TOUCH_BOTTOM_TYPE_LOOP_LEFT;
386         }
387     } else {
388         singleGestureState_ = GestureState::GESTURE_STATE_RELEASE_RIGHT;
389         if (IsLoop() && GetCurrentIndex() == (RealTotalCount() - 1)) {
390             singleIndicatorTouchBottomTypeLoop_ = TouchBottomTypeLoop::TOUCH_BOTTOM_TYPE_LOOP_RIGHT;
391         }
392     }
393     auto dotIndicatorModifier = GetDotIndicatorModifier();
394     if (dotIndicatorModifier && !dotIndicatorModifier->GetIsBottomAnimationFinished()) {
395         dotIndicatorModifier->FinishAnimationToTargetImmediately(dotIndicatorModifier->GetTargetCenter());
396     }
397     lastIndex_ = GetCurrentIndex();
398     OnIndexChangeInSingleMode(GetCurrentIndex() + 1);
399 }
400 
ChangeIndex(int32_t index,bool useAnimation)401 void IndicatorPattern::ChangeIndex(int32_t index, bool useAnimation)
402 {
403     if (GetBindSwiperNode()) {
404         return SwiperIndicatorPattern::ChangeIndex(index, useAnimation);
405     }
406     if ((index < 0) || (index >= RealTotalCount())) {
407         index = 0;
408     }
409 
410     if (useAnimation) {
411         if (GetLoopIndex(GetCurrentIndex()) > GetLoopIndex(index)) {
412             singleGestureState_ = GestureState::GESTURE_STATE_RELEASE_LEFT;
413         } else if (GetLoopIndex(GetCurrentIndex()) < GetLoopIndex(index)) {
414             singleGestureState_ = GestureState::GESTURE_STATE_RELEASE_RIGHT;
415         }
416     } else {
417         singleGestureState_ = GestureState::GESTURE_STATE_INIT;
418     }
419     auto dotIndicatorModifier = GetDotIndicatorModifier();
420     if (dotIndicatorModifier) {
421         dotIndicatorModifier->StopAnimation();
422     }
423     OnIndexChangeInSingleMode(index);
424 }
425 
GetCurrentIndex() const426 int32_t IndicatorPattern::GetCurrentIndex() const
427 {
428     if (GetBindSwiperNode()) {
429         return SwiperIndicatorPattern::GetCurrentIndex();
430     }
431     return currentIndexInSingleMode_;
432 }
433 
GetCurrentShownIndex() const434 int32_t IndicatorPattern::GetCurrentShownIndex() const
435 {
436     if (GetBindSwiperNode()) {
437         return SwiperIndicatorPattern::GetCurrentShownIndex();
438     }
439     return currentIndexInSingleMode_;
440 }
441 
DisplayIndicatorTotalCount() const442 int32_t IndicatorPattern::DisplayIndicatorTotalCount() const
443 {
444     if (GetBindSwiperNode()) {
445         return SwiperIndicatorPattern::DisplayIndicatorTotalCount();
446     }
447     return GetCountFromProperty();
448 }
449 
RealTotalCount() const450 int32_t IndicatorPattern::RealTotalCount() const
451 {
452     if (GetBindSwiperNode()) {
453         return SwiperIndicatorPattern::RealTotalCount();
454     }
455     return GetCountFromProperty();
456 }
457 
GetDirection() const458 Axis IndicatorPattern::GetDirection() const
459 {
460     if (GetBindSwiperNode()) {
461         return SwiperIndicatorPattern::GetDirection();
462     }
463     return GetDirectionFromProperty();
464 }
465 
IsHorizontalAndRightToLeft() const466 bool IndicatorPattern::IsHorizontalAndRightToLeft() const
467 {
468     if (GetBindSwiperNode()) {
469         return SwiperIndicatorPattern::IsHorizontalAndRightToLeft();
470     }
471     return GetDirection() == Axis::HORIZONTAL && GetNonAutoLayoutDirection() == TextDirection::RTL;
472 }
473 
GetNonAutoLayoutDirection() const474 TextDirection IndicatorPattern::GetNonAutoLayoutDirection() const
475 {
476     if (GetBindSwiperNode()) {
477         return SwiperIndicatorPattern::GetNonAutoLayoutDirection();
478     }
479     auto host = GetHost();
480     CHECK_NULL_RETURN(host, TextDirection::LTR);
481     CHECK_NULL_RETURN(host->GetLayoutProperty(), TextDirection::LTR);
482     return host->GetLayoutProperty()->GetNonAutoLayoutDirection();
483 }
484 
IsLoop() const485 bool IndicatorPattern::IsLoop() const
486 {
487     if (GetBindSwiperNode()) {
488         return SwiperIndicatorPattern::IsLoop();
489     }
490     return IsLoopFromProperty();
491 }
492 
GetTextContentSub(std::string & firstContent,std::string & lastContent) const493 void IndicatorPattern::GetTextContentSub(std::string& firstContent, std::string& lastContent) const
494 {
495     if (GetBindSwiperNode()) {
496         return SwiperIndicatorPattern::GetTextContentSub(firstContent, lastContent);
497     }
498     // If the mode is set to single mode, the initial information is taken from the Indicator component
499     // interface.
500     auto currentIndex = GetLoopIndex(GetCurrentIndex()) + 1;
501     bool isRtl = GetNonAutoLayoutDirection() == TextDirection::RTL;
502     firstContent = isRtl ? std::to_string(GetCountFromProperty()) : std::to_string(currentIndex);
503     lastContent = isRtl ? std::to_string(currentIndex) + "\\" : "/" + std::to_string(GetCountFromProperty());
504 }
505 
SwipeTo(std::optional<int32_t> mouseClickIndex)506 void IndicatorPattern::SwipeTo(std::optional<int32_t> mouseClickIndex)
507 {
508     if (GetBindSwiperNode()) {
509         return SwiperIndicatorPattern::SwipeTo(mouseClickIndex);
510     }
511     if (mouseClickIndex) {
512         OnIndexChangeInSingleMode(mouseClickIndex.value());
513     }
514 }
515 
CheckIsTouchBottom(const TouchLocationInfo & info)516 bool IndicatorPattern::CheckIsTouchBottom(const TouchLocationInfo& info)
517 {
518     auto host = GetHost();
519     CHECK_NULL_RETURN(host, false);
520     auto currentIndex = GetCurrentIndex();
521     auto dragPoint =
522         PointF(static_cast<float>(info.GetLocalLocation().GetX()), static_cast<float>(info.GetLocalLocation().GetY()));
523     float touchBottomRate = 0.0;
524     float touchOffset = 0.0;
525     auto offset = dragPoint - GetDragStartPoint();
526     touchOffset = GetDirection() == Axis::HORIZONTAL ? offset.GetX() : offset.GetY();
527     touchBottomRate = LessOrEqual(std::abs(touchOffset), INDICATOR_TOUCH_BOTTOM_MAX_DISTANCE.ConvertToPx())
528                             ? touchOffset / INDICATOR_TOUCH_BOTTOM_MAX_DISTANCE.ConvertToPx() : 1;
529     touchBottomRate_ = std::abs(touchBottomRate);
530     TouchBottomType touchBottomType = TouchBottomType::NONE;
531     if (currentIndex <= 0) {
532         if (IsHorizontalAndRightToLeft()) {
533             if (Positive(touchOffset)) {
534                 touchBottomType = TouchBottomType::END;
535             }
536         } else {
537             if (NonPositive(touchOffset)) {
538                 touchBottomType = TouchBottomType::START;
539             }
540         }
541     }
542     if (currentIndex >= RealTotalCount() - 1) {
543         if (IsHorizontalAndRightToLeft()) {
544             if (NonPositive(touchOffset)) {
545                 touchBottomType = TouchBottomType::START;
546             }
547         } else {
548             if (Positive(touchOffset)) {
549                 touchBottomType = TouchBottomType::END;
550             }
551         }
552     }
553     SetTouchBottomType(touchBottomType);
554     host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
555     return touchBottomType == TouchBottomType::NONE ? false : true;
556 }
557 
HandleDragEnd(double dragVelocity)558 void IndicatorPattern::HandleDragEnd(double dragVelocity)
559 {
560     auto host = GetHost();
561     CHECK_NULL_VOID(host);
562     SetTouchBottomType(TouchBottomType::NONE);
563     host->MarkDirtyNode(PROPERTY_UPDATE_RENDER);
564 }
565 
HandleLongDragUpdate(const TouchLocationInfo & info)566 void IndicatorPattern::HandleLongDragUpdate(const TouchLocationInfo& info)
567 {
568     if (GetBindSwiperNode()) {
569         return SwiperIndicatorPattern::HandleLongDragUpdate(info);
570     }
571     if (CheckIsTouchBottom(info)) {
572         return;
573     }
574     float turnPageRate = 0.0;
575     float turnPageRateOffset = 0.0;
576     auto dragPoint =
577         PointF(static_cast<float>(info.GetLocalLocation().GetX()), static_cast<float>(info.GetLocalLocation().GetY()));
578 
579     auto offset = dragPoint - GetDragStartPoint();
580     turnPageRateOffset = GetDirection() == Axis::HORIZONTAL ? offset.GetX() : offset.GetY();
581     if (LessNotEqual(std::abs(turnPageRateOffset), INDICATOR_DRAG_MIN_DISTANCE.ConvertToPx())) {
582         return;
583     }
584     turnPageRate = -(turnPageRateOffset / INDICATOR_DRAG_MAX_DISTANCE.ConvertToPx());
585     if (IsHorizontalAndRightToLeft()) {
586         turnPageRateOffset = -turnPageRateOffset;
587     }
588     if (std::abs(turnPageRate) >= 1) {
589         if (Positive(turnPageRateOffset)) {
590             ShowNext();
591         }
592         if (NonPositive(turnPageRateOffset)) {
593             ShowPrevious();
594         }
595         SetDragStartPoint(dragPoint);
596     }
597 }
598 
GetTouchCurrentIndex() const599 int32_t IndicatorPattern::GetTouchCurrentIndex() const
600 {
601     if (GetBindSwiperNode()) {
602         return SwiperIndicatorPattern::GetTouchCurrentIndex();
603     }
604 
605     auto currentIndex = GetCurrentIndex();
606     auto isRtl = IsHorizontalAndRightToLeft();
607     if (isRtl) {
608         currentIndex = RealTotalCount() - 1 - currentIndex;
609     }
610 
611     return currentIndex;
612 }
613 
CalMouseClickIndexStartAndEnd(int32_t itemCount,int32_t currentIndex)614 std::pair<int32_t, int32_t> IndicatorPattern::CalMouseClickIndexStartAndEnd(
615     int32_t itemCount, int32_t currentIndex)
616 {
617     if (GetBindSwiperNode()) {
618         return SwiperIndicatorPattern::CalMouseClickIndexStartAndEnd(itemCount, currentIndex);
619     }
620 
621     int32_t loopCount = SwiperIndicatorUtils::CalcLoopCount(currentIndex, itemCount);
622     int32_t start = currentIndex >= 0 ? loopCount * itemCount : -(loopCount + 1) * itemCount;
623     int32_t end = currentIndex >= 0 ? (loopCount + 1) * itemCount : -loopCount * itemCount;
624     if (IsHorizontalAndRightToLeft()) {
625         end = currentIndex >= 0 ? loopCount * itemCount - 1 : -(loopCount + 1) * itemCount - 1;
626         start = currentIndex >= 0 ? (loopCount + 1) * itemCount - 1 : -loopCount * itemCount - 1;
627     }
628     return { start, end };
629 }
630 } // namespace OHOS::Ace::NG
631