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