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