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