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