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 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SWIPER_SWIPER_PATTERN_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SWIPER_SWIPER_PATTERN_H 18 19 #include <functional> 20 #include <optional> 21 #include <vector> 22 23 #include "base/geometry/axis.h" 24 #include "base/geometry/ng/offset_t.h" 25 #include "base/memory/referenced.h" 26 #include "core/components/common/layout/constants.h" 27 #include "core/components/swiper/swiper_controller.h" 28 #include "core/components/swiper/swiper_indicator_theme.h" 29 #include "core/components_ng/base/frame_scene_status.h" 30 #include "core/components_ng/event/event_hub.h" 31 #include "core/components_ng/event/input_event.h" 32 #include "core/components_ng/pattern/pattern.h" 33 #include "core/components_ng/pattern/scrollable/nestable_scroll_container.h" 34 #include "core/components_ng/pattern/swiper/swiper_accessibility_property.h" 35 #include "core/components_ng/pattern/swiper/swiper_event_hub.h" 36 #include "core/components_ng/pattern/swiper/swiper_layout_algorithm.h" 37 #include "core/components_ng/pattern/swiper/swiper_layout_property.h" 38 #include "core/components_ng/pattern/swiper/swiper_model.h" 39 #include "core/components_ng/pattern/swiper/swiper_paint_method.h" 40 #include "core/components_ng/pattern/swiper/swiper_paint_property.h" 41 #include "core/components_ng/pattern/tabs/tab_content_transition_proxy.h" 42 #include "core/components_v2/inspector/utils.h" 43 44 namespace OHOS::Ace::NG { 45 class SwiperPattern : public NestableScrollContainer { 46 DECLARE_ACE_TYPE(SwiperPattern, NestableScrollContainer); 47 48 public: 49 using CustomContentTransitionPtr = std::shared_ptr<std::function<TabContentAnimatedTransition(int32_t, int32_t)>>; 50 51 SwiperPattern(); 52 ~SwiperPattern() override = default; 53 IsAtomicNode()54 bool IsAtomicNode() const override 55 { 56 return false; 57 } 58 ShouldDelayChildPressedState()59 bool ShouldDelayChildPressedState() const override 60 { 61 return true; 62 } 63 64 void RegisterScrollingListener(const RefPtr<ScrollingListener> listener) override; 65 void FireAndCleanScrollingListener() override; 66 void CleanScrollingListener() override; 67 UsResRegion()68 bool UsResRegion() override 69 { 70 return false; 71 } 72 CreateLayoutProperty()73 RefPtr<LayoutProperty> CreateLayoutProperty() override 74 { 75 return MakeRefPtr<SwiperLayoutProperty>(); 76 } 77 CreatePaintProperty()78 RefPtr<PaintProperty> CreatePaintProperty() override 79 { 80 return MakeRefPtr<SwiperPaintProperty>(); 81 } 82 CreateAccessibilityProperty()83 RefPtr<AccessibilityProperty> CreateAccessibilityProperty() override 84 { 85 return MakeRefPtr<SwiperAccessibilityProperty>(); 86 } 87 88 RefPtr<LayoutAlgorithm> CreateLayoutAlgorithm() override; 89 CreateNodePaintMethod()90 RefPtr<NodePaintMethod> CreateNodePaintMethod() override 91 { 92 auto layoutProperty = GetLayoutProperty<SwiperLayoutProperty>(); 93 CHECK_NULL_RETURN(layoutProperty, nullptr); 94 const auto& paddingProperty = layoutProperty->GetPaddingProperty(); 95 bool needClipPadding = paddingProperty != nullptr; 96 bool needPaintFade = !IsLoop() && GetEdgeEffect() == EdgeEffect::FADE && !NearZero(fadeOffset_); 97 auto paintMethod = MakeRefPtr<SwiperPaintMethod>(GetDirection(), fadeOffset_); 98 paintMethod->SetNeedPaintFade(needPaintFade); 99 paintMethod->SetNeedClipPadding(needClipPadding); 100 return paintMethod; 101 } 102 CreateEventHub()103 RefPtr<EventHub> CreateEventHub() override 104 { 105 return MakeRefPtr<SwiperEventHub>(); 106 } 107 ToJsonValue(std::unique_ptr<JsonValue> & json)108 void ToJsonValue(std::unique_ptr<JsonValue>& json) const override 109 { 110 Pattern::ToJsonValue(json); 111 json->Put("currentIndex", currentIndex_); 112 json->Put("currentOffset", currentOffset_); 113 json->Put("uiCastJumpIndex", uiCastJumpIndex_.value_or(-1)); 114 115 if (indicatorIsBoolean_) { 116 return; 117 } 118 119 auto indicatorType = GetIndicatorType(); 120 if (indicatorType == SwiperIndicatorType::DOT) { 121 json->Put("indicator", GetDotIndicatorStyle().c_str()); 122 } else { 123 json->Put("indicator", GetDigitIndicatorStyle().c_str()); 124 } 125 } 126 FromJson(const std::unique_ptr<JsonValue> & json)127 void FromJson(const std::unique_ptr<JsonValue>& json) override 128 { 129 currentIndex_ = json->GetInt("currentIndex"); 130 auto currentOffset = json->GetDouble("currentOffset"); 131 auto jumpIndex = json->GetInt("uiCastJumpIndex"); 132 if (currentOffset != currentOffset_) { 133 auto delta = currentOffset - currentOffset_; 134 UpdateCurrentOffset(delta); 135 } else if (jumpIndex >= 0) { 136 jumpIndex_ = jumpIndex; 137 MarkDirtyNodeSelf(); 138 } 139 Pattern::FromJson(json); 140 } 141 GetDotIndicatorStyle()142 std::string GetDotIndicatorStyle() const 143 { 144 auto swiperParameters = GetSwiperParameters(); 145 CHECK_NULL_RETURN(swiperParameters, ""); 146 auto jsonValue = JsonUtil::Create(true); 147 jsonValue->Put("left", swiperParameters_->dimLeft.value_or(0.0_vp).ToString().c_str()); 148 jsonValue->Put("top", swiperParameters_->dimTop.value_or(0.0_vp).ToString().c_str()); 149 jsonValue->Put("right", swiperParameters_->dimRight.value_or(0.0_vp).ToString().c_str()); 150 jsonValue->Put("bottom", swiperParameters_->dimBottom.value_or(0.0_vp).ToString().c_str()); 151 jsonValue->Put("itemWidth", swiperParameters_->itemWidth.value_or(6.0_vp).ToString().c_str()); 152 jsonValue->Put("itemHeight", swiperParameters_->itemHeight.value_or(6.0_vp).ToString().c_str()); 153 jsonValue->Put("selectedItemWidth", swiperParameters_->selectedItemWidth.value_or(6.0_vp).ToString().c_str()); 154 jsonValue->Put("selectedItemHeight", swiperParameters_->selectedItemHeight.value_or(6.0_vp).ToString().c_str()); 155 jsonValue->Put("selectedColor", 156 swiperParameters_->selectedColorVal.value_or(Color::FromString("#ff007dff")).ColorToString().c_str()); 157 jsonValue->Put( 158 "color", swiperParameters_->colorVal.value_or(Color::FromString("#19182431")).ColorToString().c_str()); 159 jsonValue->Put("mask", swiperParameters_->maskValue ? "true" : "false"); 160 return jsonValue->ToString(); 161 } 162 GetDigitIndicatorStyle()163 std::string GetDigitIndicatorStyle() const 164 { 165 auto swiperParameters = GetSwiperDigitalParameters(); 166 CHECK_NULL_RETURN(swiperParameters, ""); 167 auto jsonValue = JsonUtil::Create(true); 168 auto pipelineContext = PipelineBase::GetCurrentContext(); 169 CHECK_NULL_RETURN(pipelineContext, ""); 170 auto swiperIndicatorTheme = pipelineContext->GetTheme<SwiperIndicatorTheme>(); 171 CHECK_NULL_RETURN(swiperIndicatorTheme, ""); 172 jsonValue->Put("left", swiperDigitalParameters_->dimLeft.value_or(0.0_vp).ToString().c_str()); 173 jsonValue->Put("top", swiperDigitalParameters_->dimTop.value_or(0.0_vp).ToString().c_str()); 174 jsonValue->Put("right", swiperDigitalParameters_->dimRight.value_or(0.0_vp).ToString().c_str()); 175 jsonValue->Put("bottom", swiperDigitalParameters_->dimBottom.value_or(0.0_vp).ToString().c_str()); 176 jsonValue->Put("fontSize", swiperDigitalParameters_->fontSize 177 .value_or(swiperIndicatorTheme->GetDigitalIndicatorTextStyle().GetFontSize()) 178 .ToString() 179 .c_str()); 180 jsonValue->Put("fontColor", swiperDigitalParameters_->fontColor 181 .value_or(swiperIndicatorTheme->GetDigitalIndicatorTextStyle().GetTextColor()) 182 .ColorToString() 183 .c_str()); 184 jsonValue->Put("fontWeight", 185 V2::ConvertWrapFontWeightToStirng(swiperDigitalParameters_->fontWeight.value_or(FontWeight::NORMAL)) 186 .c_str()); 187 jsonValue->Put( 188 "selectedFontSize", swiperDigitalParameters_->selectedFontSize 189 .value_or(swiperIndicatorTheme->GetDigitalIndicatorTextStyle().GetFontSize()) 190 .ToString() 191 .c_str()); 192 jsonValue->Put( 193 "selectedFontColor", swiperDigitalParameters_->selectedFontColor 194 .value_or(swiperIndicatorTheme->GetDigitalIndicatorTextStyle().GetTextColor()) 195 .ColorToString() 196 .c_str()); 197 jsonValue->Put("selectedFontWeight", 198 V2::ConvertWrapFontWeightToStirng(swiperDigitalParameters_->selectedFontWeight.value_or(FontWeight::NORMAL)) 199 .c_str()); 200 return jsonValue->ToString(); 201 } 202 GetCurrentShownIndex()203 int32_t GetCurrentShownIndex() const 204 { 205 return IsLoop() ? currentIndex_ : GetLoopIndex(currentIndex_); 206 } 207 GetSwiperController()208 RefPtr<SwiperController> GetSwiperController() const 209 { 210 return swiperController_; 211 } 212 SetSwiperController(const RefPtr<SwiperController> & swiperController)213 void SetSwiperController(const RefPtr<SwiperController>& swiperController) 214 { 215 swiperController_ = swiperController; 216 InitSwiperController(); 217 } 218 GetCurrentFirstIndex()219 int32_t GetCurrentFirstIndex() const 220 { 221 return currentFirstIndex_; 222 } 223 GetCurrentIndex()224 int32_t GetCurrentIndex() 225 { 226 return GetLoopIndex(currentIndex_); 227 } 228 GetTurnPageRate()229 float GetTurnPageRate() const 230 { 231 return turnPageRate_; 232 } 233 GetGestureState()234 GestureState GetGestureState() 235 { 236 auto gestureState = gestureState_; 237 if (gestureState_ == GestureState::GESTURE_STATE_RELEASE_LEFT || 238 gestureState_ == GestureState::GESTURE_STATE_RELEASE_RIGHT) { 239 gestureState_ = GestureState::GESTURE_STATE_NONE; 240 } 241 242 return gestureState; 243 } 244 GetTouchBottomTypeLoop()245 TouchBottomTypeLoop GetTouchBottomTypeLoop() const 246 { 247 return touchBottomType_; 248 } 249 IsIndicatorAnimatorRunning()250 bool IsIndicatorAnimatorRunning() const 251 { 252 return indicatorAnimationIsRunning_; 253 } 254 SetTurnPageRate(float turnPageRate)255 void SetTurnPageRate(float turnPageRate) 256 { 257 turnPageRate_ = turnPageRate; 258 } 259 GetTouchBottomRate()260 float GetTouchBottomRate() const 261 { 262 return touchBottomRate_; 263 } 264 SetTouchBottomRate(float touchBottomRate)265 void SetTouchBottomRate(float touchBottomRate) 266 { 267 touchBottomRate_ = touchBottomRate; 268 } 269 GetController()270 RefPtr<Animator> GetController() 271 { 272 return controller_; 273 } 274 SetIndicatorDoingAnimation(bool indicatorDoingAnimation)275 void SetIndicatorDoingAnimation(bool indicatorDoingAnimation) 276 { 277 indicatorDoingAnimation_ = indicatorDoingAnimation; 278 } 279 280 void UpdateCurrentOffset(float offset); 281 /** 282 * @brief Checks if the given offset exceeds the bounds of the swiper container and triggers overScroll. 283 * 284 * @param offset The offset to check. 285 * @return True if overScroll is triggered, false otherwise. 286 */ 287 bool CheckOverScroll(float offset); 288 289 /** 290 * @brief Applies spring effect to the over-scrolling of the swiper. 291 * 292 * @param offset The offset of the swiper. 293 * @return true if the spring effect is applied successfully, false otherwise. 294 */ 295 bool SpringOverScroll(float offset); 296 297 void CheckMarkDirtyNodeForRenderIndicator(float additionalOffset = 0.0f); 298 299 int32_t TotalCount() const; 300 301 Axis GetDirection() const; 302 GetFocusPattern()303 FocusPattern GetFocusPattern() const override 304 { 305 return { FocusType::SCOPE, true }; 306 } 307 GetScopeFocusAlgorithm()308 ScopeFocusAlgorithm GetScopeFocusAlgorithm() override 309 { 310 return ScopeFocusAlgorithm(direction_ != Axis::HORIZONTAL, true, ScopeType::OTHERS, 311 [wp = WeakClaim(this)]( 312 FocusStep step, const WeakPtr<FocusHub>& currFocusNode, WeakPtr<FocusHub>& nextFocusNode) { 313 auto swiper = wp.Upgrade(); 314 if (swiper) { 315 nextFocusNode = swiper->GetNextFocusNode(step, currFocusNode); 316 } 317 }); 318 } 319 UpdateChangeEvent(ChangeEvent && event)320 void UpdateChangeEvent(ChangeEvent&& event) 321 { 322 if (!changeEvent_) { 323 changeEvent_ = std::make_shared<ChangeEvent>(event); 324 auto eventHub = GetEventHub<SwiperEventHub>(); 325 CHECK_NULL_VOID(eventHub); 326 eventHub->AddOnChangeEvent(changeEvent_); 327 } else { 328 (*changeEvent_).swap(event); 329 } 330 } 331 UpdateOnChangeEvent(ChangeEvent && event)332 void UpdateOnChangeEvent(ChangeEvent&& event) 333 { 334 if (!onIndexChangeEvent_) { 335 onIndexChangeEvent_ = std::make_shared<ChangeEvent>(event); 336 auto eventHub = GetEventHub<SwiperEventHub>(); 337 CHECK_NULL_VOID(eventHub); 338 eventHub->AddOnChangeEvent(onIndexChangeEvent_); 339 } else { 340 (*onIndexChangeEvent_).swap(event); 341 } 342 } 343 UpdateAnimationStartEvent(AnimationStartEvent && event)344 void UpdateAnimationStartEvent(AnimationStartEvent&& event) 345 { 346 if (!animationStartEvent_) { 347 animationStartEvent_ = std::make_shared<AnimationStartEvent>(event); 348 auto eventHub = GetEventHub<SwiperEventHub>(); 349 CHECK_NULL_VOID(eventHub); 350 eventHub->AddAnimationStartEvent(animationStartEvent_); 351 } else { 352 (*animationStartEvent_).swap(event); 353 } 354 } 355 UpdateAnimationEndEvent(AnimationEndEvent && event)356 void UpdateAnimationEndEvent(AnimationEndEvent&& event) 357 { 358 if (!animationEndEvent_) { 359 animationEndEvent_ = std::make_shared<AnimationEndEvent>(event); 360 auto eventHub = GetEventHub<SwiperEventHub>(); 361 CHECK_NULL_VOID(eventHub); 362 eventHub->AddAnimationEndEvent(animationEndEvent_); 363 } else { 364 (*animationEndEvent_).swap(event); 365 } 366 } 367 SetSwiperParameters(const SwiperParameters & swiperParameters)368 void SetSwiperParameters(const SwiperParameters& swiperParameters) 369 { 370 swiperParameters_ = std::make_shared<SwiperParameters>(swiperParameters); 371 } 372 SetSwiperDigitalParameters(const SwiperDigitalParameters & swiperDigitalParameters)373 void SetSwiperDigitalParameters(const SwiperDigitalParameters& swiperDigitalParameters) 374 { 375 swiperDigitalParameters_ = std::make_shared<SwiperDigitalParameters>(swiperDigitalParameters); 376 } 377 378 void ShowNext(); 379 void ShowPrevious(); 380 void SwipeTo(int32_t index); 381 382 void OnVisibleChange(bool isVisible) override; 383 GetStartIndex()384 int32_t GetStartIndex() const 385 { 386 return startIndex_; 387 } 388 GetEndIndex()389 int32_t GetEndIndex() const 390 { 391 return endIndex_; 392 } 393 HasIndicatorNode()394 bool HasIndicatorNode() const 395 { 396 return indicatorId_.has_value(); 397 } 398 HasLeftButtonNode()399 bool HasLeftButtonNode() const 400 { 401 return leftButtonId_.has_value(); 402 } 403 HasRightButtonNode()404 bool HasRightButtonNode() const 405 { 406 return rightButtonId_.has_value(); 407 } 408 GetIndicatorId()409 int32_t GetIndicatorId() 410 { 411 if (!indicatorId_.has_value()) { 412 indicatorId_ = ElementRegister::GetInstance()->MakeUniqueId(); 413 } 414 return indicatorId_.value(); 415 } 416 GetLeftButtonId()417 int32_t GetLeftButtonId() 418 { 419 if (!leftButtonId_.has_value()) { 420 leftButtonId_ = ElementRegister::GetInstance()->MakeUniqueId(); 421 } 422 return leftButtonId_.value(); 423 } 424 GetRightButtonId()425 int32_t GetRightButtonId() 426 { 427 if (!rightButtonId_.has_value()) { 428 rightButtonId_ = ElementRegister::GetInstance()->MakeUniqueId(); 429 } 430 return rightButtonId_.value(); 431 } 432 RemoveIndicatorNode()433 void RemoveIndicatorNode() 434 { 435 CHECK_NULL_VOID(HasIndicatorNode()); 436 auto swiperNode = GetHost(); 437 CHECK_NULL_VOID(swiperNode); 438 swiperNode->RemoveChildAtIndex(swiperNode->GetChildIndexById(GetIndicatorId())); 439 indicatorId_ = std::nullopt; 440 } 441 RemoveLeftButtonNode()442 void RemoveLeftButtonNode() 443 { 444 CHECK_NULL_VOID(HasLeftButtonNode()); 445 auto swiperNode = GetHost(); 446 CHECK_NULL_VOID(swiperNode); 447 swiperNode->RemoveChildAtIndex(swiperNode->GetChildIndexById(GetLeftButtonId())); 448 leftButtonId_ = std::nullopt; 449 } 450 RemoveRightButtonNode()451 void RemoveRightButtonNode() 452 { 453 CHECK_NULL_VOID(HasRightButtonNode()); 454 auto swiperNode = GetHost(); 455 CHECK_NULL_VOID(swiperNode); 456 swiperNode->RemoveChildAtIndex(swiperNode->GetChildIndexById(GetRightButtonId())); 457 rightButtonId_ = std::nullopt; 458 } 459 460 SwiperIndicatorType GetIndicatorType() const; 461 IsIndicatorCustomSize()462 bool IsIndicatorCustomSize() const 463 { 464 return IsCustomSize_; 465 } 466 SetIsIndicatorCustomSize(bool IsCustomSize)467 void SetIsIndicatorCustomSize(bool IsCustomSize) 468 { 469 IsCustomSize_ = IsCustomSize; 470 } 471 SetIndicatorIsBoolean(bool isBoolean)472 void SetIndicatorIsBoolean(bool isBoolean) 473 { 474 indicatorIsBoolean_ = isBoolean; 475 } 476 SetNestedScroll(const NestedScrollOptions & nestedOpt)477 void SetNestedScroll(const NestedScrollOptions& nestedOpt) 478 { 479 enableNestedScroll_ = nestedOpt.NeedParent(); 480 } 481 GetIsAtHotRegion()482 bool GetIsAtHotRegion() const 483 { 484 return isAtHotRegion_; 485 } 486 HasSurfaceChangedCallback()487 bool HasSurfaceChangedCallback() 488 { 489 return surfaceChangedCallbackId_.has_value(); 490 } 491 UpdateSurfaceChangedCallbackId(int32_t id)492 void UpdateSurfaceChangedCallbackId(int32_t id) 493 { 494 surfaceChangedCallbackId_ = id; 495 } 496 SetIndicatorLongPress(bool isIndicatorLongPress)497 void SetIndicatorLongPress(bool isIndicatorLongPress) 498 { 499 isIndicatorLongPress_ = isIndicatorLongPress; 500 } SetCachedCount(int32_t cachedCount)501 void SetCachedCount(int32_t cachedCount) 502 { 503 if (cachedCount_.has_value() && cachedCount_.value() != cachedCount) { 504 SetLazyLoadFeature(true); 505 } 506 cachedCount_ = cachedCount; 507 } 508 SetFinishCallbackType(FinishCallbackType finishCallbackType)509 void SetFinishCallbackType(FinishCallbackType finishCallbackType) 510 { 511 finishCallbackType_ = finishCallbackType; 512 } 513 GetFinishCallbackType()514 FinishCallbackType GetFinishCallbackType() const 515 { 516 return finishCallbackType_; 517 } 518 SetStopIndicatorAnimationCb(const std::function<void (void)> & stopCallback)519 void SetStopIndicatorAnimationCb(const std::function<void(void)>& stopCallback) 520 { 521 stopIndicatorAnimationFunc_ = std::move(stopCallback); 522 } 523 524 std::shared_ptr<SwiperParameters> GetSwiperParameters() const; 525 std::shared_ptr<SwiperDigitalParameters> GetSwiperDigitalParameters() const; 526 527 void ArrowHover(bool hoverFlag); 528 bool IsLoop() const; 529 bool IsEnabled() const; 530 void OnWindowShow() override; 531 void OnWindowHide() override; 532 std::string ProvideRestoreInfo() override; 533 void OnRestoreInfo(const std::string& restoreInfo) override; 534 bool IsAutoFill() const; 535 void OnTouchTestHit(SourceType hitTestType) override; 536 void SwipeToWithoutAnimation(int32_t index); 537 void StopAutoPlay(); 538 void StartAutoPlay(); 539 void StopTranslateAnimation(); 540 void StopSpringAnimation(); 541 void DumpAdvanceInfo() override; 542 int32_t GetLoopIndex(int32_t originalIndex) const; 543 int32_t GetDuration() const; 544 RefPtr<Curve> GetCurveIncludeMotion(); 545 void OnCustomContentTransition(int32_t toIndex); 546 void OnCustomAnimationFinish(int32_t fromIndex, int32_t toIndex, bool hasOnChanged); 547 SetCustomAnimationToIndex(int32_t toIndex)548 void SetCustomAnimationToIndex(int32_t toIndex) 549 { 550 customAnimationToIndex_ = toIndex; 551 } 552 GetCustomAnimationToIndex()553 std::optional<int32_t> GetCustomAnimationToIndex() const 554 { 555 return customAnimationToIndex_; 556 } 557 SetCustomContentTransition(std::function<TabContentAnimatedTransition (int32_t,int32_t)> && event)558 void SetCustomContentTransition(std::function<TabContentAnimatedTransition(int32_t, int32_t)>&& event) 559 { 560 onCustomContentTransition_ = 561 std::make_shared<std::function<TabContentAnimatedTransition(int32_t, int32_t)>>(event); 562 } 563 GetCustomContentTransition()564 CustomContentTransitionPtr GetCustomContentTransition() const 565 { 566 return onCustomContentTransition_; 567 } 568 569 void SetSwiperEventCallback(bool disableSwipe); 570 void UpdateSwiperPanEvent(bool disableSwipe); 571 bool IsUseCustomAnimation() const; GetMotionVelocity()572 float GetMotionVelocity() 573 { 574 return motionVelocity_; 575 } 576 SetTabsPaddingAndBorder(const PaddingPropertyF & tabsPaddingAndBorder)577 void SetTabsPaddingAndBorder(const PaddingPropertyF& tabsPaddingAndBorder) 578 { 579 tabsPaddingAndBorder_ = tabsPaddingAndBorder; 580 } 581 582 bool ContentWillChange(int32_t comingIndex); 583 bool ContentWillChange(int32_t currentIndex, int32_t comingIndex); 584 bool CheckSwiperPanEvent(const GestureEvent& info); InitIndexCanChangeMap()585 void InitIndexCanChangeMap() 586 { 587 indexCanChangeMap_.clear(); 588 } 589 590 int32_t RealTotalCount() const; 591 bool IsSwipeByGroup() const; 592 int32_t GetDisplayCount() const; 593 int32_t GetCachedCount() const; 594 GetNextValidIndex()595 int32_t GetNextValidIndex() const 596 { 597 return nextValidIndex_; 598 } 599 void UpdateNextValidIndex(); 600 601 private: 602 void OnModifyDone() override; 603 void OnAfterModifyDone() override; 604 void OnAttachToFrameNode() override; 605 void OnDetachFromFrameNode(FrameNode* node) override; 606 void InitSurfaceChangedCallback(); 607 bool OnDirtyLayoutWrapperSwap(const RefPtr<LayoutWrapper>& dirty, const DirtySwapConfig& config) override; 608 609 // Init pan recognizer to move items when drag update, play translate animation when drag end. 610 void InitPanEvent(const RefPtr<GestureEventHub>& gestureHub); 611 void AddPanEvent(const RefPtr<GestureEventHub>& gestureHub, GestureEventFunc && actionStart, 612 GestureEventFunc && actionUpdate, GestureEventFunc && actionEnd, GestureEventNoParameter && actionCancel); 613 614 // Init touch event, stop animation when touch down. 615 void InitTouchEvent(const RefPtr<GestureEventHub>& gestureHub); 616 void InitHoverMouseEvent(); 617 // Init on key event 618 void InitOnFocusInternal(const RefPtr<FocusHub>& focusHub); 619 void HandleFocusInternal(); 620 void InitOnKeyEvent(const RefPtr<FocusHub>& focusHub); 621 bool OnKeyEvent(const KeyEvent& event); 622 void FlushFocus(const RefPtr<FrameNode>& curShowFrame); 623 WeakPtr<FocusHub> GetNextFocusNode(FocusStep step, const WeakPtr<FocusHub>& currentFocusNode); 624 625 // Init controller of swiper, controller support showNext, showPrevious and finishAnimation interface. 626 void InitSwiperController(); 627 628 // Init indicator 629 void InitIndicator(); 630 void InitArrow(); 631 632 void HandleDragStart(const GestureEvent& info); 633 void HandleDragUpdate(const GestureEvent& info); 634 void HandleDragEnd(double dragVelocity); 635 636 void HandleTouchEvent(const TouchEventInfo& info); 637 void HandleTouchDown(const TouchLocationInfo& locationInfo); 638 void HandleTouchUp(); 639 640 void HandleMouseEvent(const MouseInfo& info); 641 void PlayTranslateAnimation( 642 float startPos, float endPos, int32_t nextIndex, bool restartAutoPlay = false, float velocity = 0.0f); 643 void PlaySpringAnimation(double dragVelocity); 644 void PlayFadeAnimation(); 645 646 // use property animation feature 647 void PlayPropertyTranslateAnimation( 648 float translate, int32_t nextIndex, float velocity = 0.0f, bool stopAutoPlay = false); 649 void StopPropertyTranslateAnimation(bool isFinishAnimation, bool isBeforeCreateLayoutWrapper = false); 650 void UpdateOffsetAfterPropertyAnimation(float offset); 651 void OnPropertyTranslateAnimationFinish(const OffsetF& offset); 652 void PlayIndicatorTranslateAnimation(float translate); 653 654 // Implement of swiper controller 655 656 void FinishAnimation(); 657 void StopFadeAnimation(); 658 659 bool IsOutOfBoundary(float mainOffset = 0.0f) const; 660 bool AutoLinearIsOutOfBoundary(float mainOffset) const; 661 float GetDistanceToEdge() const; 662 float MainSize() const; 663 float GetMainContentSize() const; 664 void FireChangeEvent() const; 665 void FireAnimationStartEvent(int32_t currentIndex, int32_t nextIndex, const AnimationCallbackInfo& info) const; 666 void FireAnimationEndEvent(int32_t currentIndex, const AnimationCallbackInfo& info) const; 667 void FireGestureSwipeEvent(int32_t currentIndex, const AnimationCallbackInfo& info) const; 668 669 float GetItemSpace() const; 670 float GetPrevMargin() const; 671 float GetNextMargin() const; 672 float CalculateVisibleSize() const; 673 int32_t CurrentIndex() const; 674 int32_t CalculateDisplayCount() const; 675 int32_t CalculateCount( 676 float contentWidth, float minSize, float margin, float gutter, float swiperPadding = 0.0f) const; 677 int32_t GetInterval() const; 678 RefPtr<Curve> GetCurve() const; 679 EdgeEffect GetEdgeEffect() const; 680 bool IsAutoPlay() const; 681 bool IsDisableSwipe() const; 682 bool IsShowIndicator() const; 683 float GetTranslateLength() const; 684 std::pair<int32_t, SwiperItemInfo> GetFirstItemInfoInVisibleArea() const; 685 std::pair<int32_t, SwiperItemInfo> GetLastItemInfoInVisibleArea() const; 686 std::pair<int32_t, SwiperItemInfo> GetSecondItemInfoInVisibleArea() const; 687 void OnIndexChange(); 688 bool IsOutOfHotRegion(const PointF& dragPoint) const; 689 void SaveDotIndicatorProperty(const RefPtr<FrameNode>& indicatorNode); 690 void SaveDigitIndicatorProperty(const RefPtr<FrameNode>& indicatorNode); 691 void PostTranslateTask(uint32_t delayTime); 692 void RegisterVisibleAreaChange(); 693 bool NeedAutoPlay() const; 694 void OnTranslateFinish(int32_t nextIndex, bool restartAutoPlay, bool isFinishAnimation, bool forceStop = false); 695 bool IsShowArrow() const; 696 void SaveArrowProperty(const RefPtr<FrameNode>& arrowNode); 697 RefPtr<FocusHub> GetFocusHubChild(std::string childFrameName); 698 WeakPtr<FocusHub> PreviousFocus(const RefPtr<FocusHub>& curFocusNode); 699 WeakPtr<FocusHub> NextFocus(const RefPtr<FocusHub>& curFocusNode); 700 void SetAccessibilityAction(); 701 bool NeedStartAutoPlay() const; 702 void CheckAndSetArrowHoverState(const PointF& mousePoint); 703 RectF GetArrowFrameRect(const int32_t index) const; 704 float GetCustomPropertyOffset() const; 705 float GetCurrentFirstIndexStartPos() const; 706 void UpdateAnimationProperty(float velocity); 707 void TriggerAnimationEndOnForceStop(); 708 void TriggerAnimationEndOnSwipeToLeft(); 709 void TriggerAnimationEndOnSwipeToRight(); 710 void TriggerEventOnFinish(int32_t nextIndex); 711 bool IsVisibleChildrenSizeLessThanSwiper(); 712 void BeforeCreateLayoutWrapper() override; 713 714 void SetLazyLoadFeature(bool useLazyLoad) const; 715 void SetLazyForEachLongPredict(bool useLazyLoad) const; 716 void SetLazyLoadIsLoop() const; 717 int32_t ComputeNextIndexByVelocity(float velocity, bool onlyDistance = false) const; 718 void UpdateCurrentIndex(int32_t index); 719 void OnSpringAnimationStart(float velocity); 720 void OnSpringAndFadeAnimationFinish(); 721 void OnFadeAnimationStart(); 722 int32_t TotalDisPlayCount() const; 723 void StopAndResetSpringAnimation(); 724 void OnLoopChange(); 725 void StopSpringAnimationAndFlushImmediately(); 726 void UpdateItemRenderGroup(bool itemRenderGroup); 727 void MarkDirtyNodeSelf(); 728 void ResetAndUpdateIndexOnAnimationEnd(int32_t nextIndex); 729 int32_t GetLoopIndex(int32_t index, int32_t childrenSize) const; 730 bool IsAutoLinear() const; 731 bool AutoLinearAnimationNeedReset(float translate) const; 732 void OnAnimationTranslateZero(int32_t nextIndex, bool stopAutoPlay); 733 void UpdateDragFRCSceneInfo(float speed, SceneStatus sceneStatus); 734 void AdjustCurrentIndexOnSwipePage(int32_t index); 735 void TriggerCustomContentTransitionEvent(int32_t fromIndex, int32_t toIndex); 736 /** 737 * @brief Preprocess drag delta when received from DragUpdate event. 738 * 739 * Drag offset in Swiper can't go beyond a full page. Apply the restriction through this function. 740 * 741 * @param delta 742 * @param mainSize content length along the main axis. 743 * @param deltaSum accumulated delta in the current drag event. 744 */ 745 static void ProcessDelta(float& delta, float mainSize, float deltaSum); 746 747 /** 748 * @brief Stops animations when the scroll starts. 749 * 750 * @param flushImmediately Whether to flush layout immediately. 751 */ 752 void StopAnimationOnScrollStart(bool flushImmediately); 753 /** 754 * @brief Checks if the animation is currently running. 755 * 756 * @return true if the animation is running, false otherwise. 757 */ 758 inline bool AnimationRunning() const; 759 760 /** 761 * NestableScrollContainer implementations 762 * ============================================================ 763 */ GetAxis()764 Axis GetAxis() const override 765 { 766 return GetDirection(); 767 } 768 769 /** 770 * @brief Closes gap to the edge, called before Swiper transfers extra offset to parent/child to ensure that Swiper 771 * actually reaches the edge. 772 * 773 * @param offset The scroll offset from DragUpdate. 774 */ 775 void CloseTheGap(float offset); 776 777 ScrollResult HandleScroll(float offset, int32_t source, NestedState state) override; 778 ScrollResult HandleScrollSelfFirst(float offset, int32_t source, NestedState state); 779 780 bool HandleScrollVelocity(float velocity) override; 781 782 void OnScrollStartRecursive(float position) override; 783 void OnScrollEndRecursive(const std::optional<float>& velocity) override; 784 785 /** 786 * @brief Notifies the parent component that the scroll has started at the specified position. 787 * 788 * @param position The position where the scroll has started. 789 */ 790 void NotifyParentScrollStart(float position); 791 /** 792 * @brief Notifies the parent NestableScrollContainer that the scroll has ended. 793 */ 794 void NotifyParentScrollEnd(); 795 796 inline bool ChildFirst(NestedState state); 797 void HandleTouchBottomLoop(); 798 void CalculateGestureState(float additionalOffset, float currentTurnPageRate, int32_t preFirstIndex); 799 void StopIndicatorAnimation(); 800 RefPtr<FrameNode> GetCurrentFrameNode(int32_t currentIndex) const; 801 bool FadeOverScroll(float offset); 802 int32_t ComputeSwipePageNextIndex(float velocity, bool onlyDistance = false) const; 803 int32_t ComputePageIndex(int32_t index) const; 804 void UpdateIndexOnAnimationStop(); 805 void UpdateIndexOnSwipePageStop(int32_t pauseTargetIndex); 806 void AdjustCurrentFocusIndex(); 807 bool IsContentFocused(); 808 809 int32_t CheckTargetIndex(int32_t targetIndex, bool isForceBackward = false); 810 811 void PreloadItems(const std::set<int32_t>& indexSet); 812 void DoPreloadItems(const std::set<int32_t>& indexSet, int32_t errorCode); 813 void FirePreloadFinishEvent(int32_t errorCode); 814 815 WeakPtr<NestableScrollContainer> parent_; 816 /** 817 * ============================================================ 818 * End of NestableScrollContainer implementations 819 */ 820 821 RefPtr<PanEvent> panEvent_; 822 RefPtr<TouchEventImpl> touchEvent_; 823 RefPtr<InputEvent> hoverEvent_; 824 825 // Control translate animation when drag end. 826 RefPtr<Animator> controller_; 827 828 // Control spring animation when drag beyond boundary and drag end. 829 std::shared_ptr<AnimationUtils::Animation> springAnimation_; 830 831 // Control fade animation when drag beyond boundary and drag end. 832 std::shared_ptr<AnimationUtils::Animation> fadeAnimation_; 833 834 // Control translate animation for indicator. 835 std::shared_ptr<AnimationUtils::Animation> indicatorAnimation_; 836 837 bool indicatorAnimationIsRunning_ = false; 838 839 // stop indicator animation callback 840 std::function<void(void)> stopIndicatorAnimationFunc_; 841 842 RefPtr<SwiperController> swiperController_; 843 RefPtr<InputEvent> mouseEvent_; 844 845 bool enableNestedScroll_ = false; 846 bool isLastIndicatorFocused_ = false; 847 int32_t startIndex_ = 0; 848 int32_t endIndex_ = 0; 849 int32_t currentIndex_ = 0; 850 int32_t oldIndex_ = 0; 851 int32_t nextIndex_ = 0; 852 853 PanDirection panDirection_; 854 855 float currentOffset_ = 0.0f; 856 float fadeOffset_ = 0.0f; 857 float turnPageRate_ = 0.0f; 858 GestureState gestureState_ = GestureState::GESTURE_STATE_INIT; 859 TouchBottomTypeLoop touchBottomType_ = TouchBottomTypeLoop::TOUCH_BOTTOM_TYPE_LOOP_NONE; 860 float touchBottomRate_ = 1.0f; 861 float currentIndexOffset_ = 0.0f; 862 int32_t gestureSwipeIndex_ = 0; 863 int32_t currentFirstIndex_ = 0; 864 int32_t nextValidIndex_ = 0; 865 int32_t currentFocusIndex_ = 0; 866 867 bool moveDirection_ = false; 868 bool indicatorDoingAnimation_ = false; 869 bool isInit_ = true; 870 bool hasVisibleChangeRegistered_ = false; 871 bool isVisible_ = true; 872 bool isVisibleArea_ = true; 873 bool isWindowShow_ = true; 874 bool IsCustomSize_ = false; 875 bool indicatorIsBoolean_ = true; 876 bool isAtHotRegion_ = false; 877 bool isDragging_ = false; 878 bool needTurn_ = false; 879 /** 880 * @brief Indicates whether the child NestableScrollContainer is currently scrolling and affecting Swiper. 881 */ 882 bool childScrolling_ = false; 883 bool isTouchDown_ = false; 884 std::optional<bool> preLoop_; 885 886 Axis direction_ = Axis::HORIZONTAL; 887 888 ChangeEventPtr changeEvent_; 889 ChangeEventPtr onIndexChangeEvent_; 890 AnimationStartEventPtr animationStartEvent_; 891 AnimationEndEventPtr animationEndEvent_; 892 893 mutable std::shared_ptr<SwiperParameters> swiperParameters_; 894 mutable std::shared_ptr<SwiperDigitalParameters> swiperDigitalParameters_; 895 896 WeakPtr<FrameNode> lastWeakShowNode_; 897 898 CancelableCallback<void()> translateTask_; 899 900 std::optional<int32_t> indicatorId_; 901 std::optional<int32_t> leftButtonId_; 902 std::optional<int32_t> rightButtonId_; 903 std::optional<SwiperIndicatorType> lastSwiperIndicatorType_; 904 905 float startMainPos_ = 0.0f; 906 float endMainPos_ = 0.0f; 907 float contentMainSize_ = 0.0f; 908 float contentCrossSize_ = 0.0f; 909 bool crossMatchChild_ = false; 910 911 std::optional<int32_t> uiCastJumpIndex_; 912 std::optional<int32_t> jumpIndex_; 913 std::optional<int32_t> targetIndex_; 914 std::optional<int32_t> preTargetIndex_; 915 std::optional<int32_t> pauseTargetIndex_; 916 std::optional<int32_t> oldChildrenSize_; 917 std::optional<float> placeItemWidth_; 918 float currentDelta_ = 0.0f; 919 // cumulated delta in a single drag event 920 float mainDeltaSum_ = 0.0f; 921 SwiperLayoutAlgorithm::PositionMap itemPosition_; 922 std::optional<float> velocity_; 923 float motionVelocity_ = 0.0f; 924 bool isFinishAnimation_ = false; 925 bool mainSizeIsMeasured_ = false; 926 bool isNeedResetPrevMarginAndNextMargin_ = false; 927 bool usePropertyAnimation_ = false; 928 bool springAnimationIsRunning_ = false; 929 bool isTouchDownSpringAnimation_ = false; 930 int32_t propertyAnimationIndex_ = -1; 931 bool isUserFinish_ = true; 932 bool isVoluntarilyClear_ = false; 933 bool isIndicatorLongPress_ = false; 934 bool stopIndicatorAnimation_ = true; 935 bool isTouchPad_ = false; 936 bool fadeAnimationIsRunning_ = false; 937 bool autoLinearReachBoundary = false; 938 bool needAdjustIndex_ = false; 939 940 std::optional<int32_t> cachedCount_; 941 942 std::optional<int32_t> surfaceChangedCallbackId_; 943 SwiperLayoutAlgorithm::PositionMap itemPositionInAnimation_; 944 945 WindowSizeChangeReason windowSizeChangeReason_ = WindowSizeChangeReason::UNDEFINED; 946 std::vector<RefPtr<ScrollingListener>> scrollingListener_; 947 FinishCallbackType finishCallbackType_ = FinishCallbackType::REMOVED; 948 949 CustomContentTransitionPtr onCustomContentTransition_; 950 std::set<int32_t> indexsInAnimation_; 951 std::set<int32_t> needUnmountIndexs_; 952 std::optional<int32_t> customAnimationToIndex_; 953 RefPtr<TabContentTransitionProxy> currentProxyInAnimation_; 954 PaddingPropertyF tabsPaddingAndBorder_; 955 std::map<int32_t, bool> indexCanChangeMap_; 956 }; 957 } // namespace OHOS::Ace::NG 958 959 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SWIPER_SWIPER_PATTERN_H 960