1 /* 2 * Copyright (c) 2023-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 #ifndef FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SCROLLABLE_SCROLLABLE_PATTERN_H 17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SCROLLABLE_SCROLLABLE_PATTERN_H 18 19 #include <cmath> 20 #include <vector> 21 22 #include "base/geometry/axis.h" 23 #include "core/animation/select_motion.h" 24 #include "core/animation/spring_curve.h" 25 #include "core/animation/bezier_variable_velocity_motion.h" 26 #include "core/animation/velocity_motion.h" 27 #include "core/components_ng/base/frame_scene_status.h" 28 #include "core/components_ng/event/drag_event.h" 29 #include "core/components_ng/pattern/navigation/nav_bar_pattern.h" 30 #include "core/components_ng/pattern/overlay/sheet_presentation_pattern.h" 31 #include "core/components_ng/pattern/pattern.h" 32 #include "core/components_ng/pattern/scroll/inner/scroll_bar.h" 33 #include "core/components_ng/pattern/scroll/inner/scroll_bar_overlay_modifier.h" 34 #include "core/components_ng/pattern/scroll_bar/proxy/scroll_bar_proxy.h" 35 #include "core/components_ng/pattern/scrollable/nestable_scroll_container.h" 36 #include "core/components_ng/pattern/scrollable/refresh_coordination.h" 37 #include "core/components_ng/pattern/scrollable/scrollable_controller.h" 38 #include "core/components_ng/pattern/scrollable/scrollable_coordination_event.h" 39 #include "core/components_ng/pattern/scrollable/scrollable_paint_method.h" 40 #include "core/components_ng/pattern/scrollable/scrollable_paint_property.h" 41 #include "core/components_ng/pattern/scrollable/scrollable_properties.h" 42 #include "core/components_ng/render/animation_utils.h" 43 #include "core/event/mouse_event.h" 44 #include "core/components_ng/event/scrollable_event.h" 45 #include "core/event/statusbar/statusbar_event_proxy.h" 46 namespace OHOS::Ace::NG { 47 class InspectorFilter; 48 #ifndef WEARABLE_PRODUCT 49 constexpr double FRICTION = 0.6; 50 constexpr double API11_FRICTION = 0.7; 51 constexpr double API12_FRICTION = 0.75; 52 constexpr double MAX_VELOCITY = 9000.0; 53 #else 54 constexpr double FRICTION = 0.9; 55 constexpr double MAX_VELOCITY = 5000.0; 56 #endif 57 constexpr float SPRING_ACCURACY = 0.1f; 58 enum class ModalSheetCoordinationMode : char { 59 UNKNOWN = 0, 60 SHEET_SCROLL = 1, 61 SCROLLABLE_SCROLL = 2, 62 }; 63 struct ScrollOffsetAbility { 64 std::function<bool(float)> scrollFunc = nullptr; 65 Axis axis = Axis::VERTICAL; 66 float contentStartOffset = 0.0f; 67 float contentEndOffset = 0.0f; 68 }; 69 class ScrollablePattern : public NestableScrollContainer, public virtual StatusBarClickListener { 70 DECLARE_ACE_TYPE(ScrollablePattern, NestableScrollContainer); 71 72 public: 73 ScrollablePattern(); 74 ScrollablePattern(EdgeEffect edgeEffect, bool alwaysEnabled); 75 ~ScrollablePattern()76 ~ScrollablePattern() 77 { 78 UnRegister2DragDropManager(); 79 if (scrollBarProxy_) { 80 scrollBarProxy_->UnRegisterNestScrollableNode(AceType::WeakClaim(this)); 81 } 82 } 83 IsAtomicNode()84 bool IsAtomicNode() const override 85 { 86 return false; 87 } 88 89 RefPtr<PaintProperty> CreatePaintProperty() override; 90 91 void CreateAnalyzerOverlay(const RefPtr<FrameNode> node); 92 93 void UpdateFadingEdge(const RefPtr<ScrollablePaintMethod>& paint); 94 95 void ToJsonValue(std::unique_ptr<JsonValue>& json, const InspectorFilter& filter) const override; 96 void OnWindowHide() override; 97 98 // scrollable GetAxis()99 Axis GetAxis() const override 100 { 101 return axis_; 102 } 103 IsReverse()104 virtual bool IsReverse() const 105 { 106 if (GetAxis() != Axis::HORIZONTAL) { 107 return false; 108 } 109 auto host = GetHost(); 110 CHECK_NULL_RETURN(host, false); 111 auto layoutProperty = host->GetLayoutProperty<LayoutProperty>(); 112 CHECK_NULL_RETURN(layoutProperty, false); 113 auto layoutDirection = layoutProperty->GetNonAutoLayoutDirection(); 114 return (layoutDirection == TextDirection::RTL); 115 }; 116 ShouldDelayChildPressedState()117 virtual bool ShouldDelayChildPressedState() const override 118 { 119 return true; 120 } 121 122 void RegisterScrollingListener(const RefPtr<ScrollingListener> listener) override; 123 void FireAndCleanScrollingListener() override; 124 void CleanScrollingListener() override; 125 126 void SetAxis(Axis axis); 127 virtual bool UpdateCurrentOffset(float delta, int32_t source) = 0; IsScrollable()128 virtual bool IsScrollable() const 129 { 130 return false; 131 } 132 virtual bool IsAtTop() const = 0; 133 virtual bool IsAtBottom() const = 0; IsFadingBottom()134 virtual bool IsFadingBottom() const 135 { 136 return !IsAtBottom(); 137 } OutBoundaryCallback()138 virtual bool OutBoundaryCallback() 139 { 140 return IsOutOfBoundary(); 141 } 142 143 virtual bool IsOutOfBoundary(bool useCurrentDelta = true) 144 { 145 return false; 146 } 147 148 virtual void OnTouchDown(const TouchEventInfo& info); 149 150 void AddScrollEvent(); GetScrollableEvent()151 RefPtr<ScrollableEvent> GetScrollableEvent() 152 { 153 return scrollableEvent_; 154 } 155 virtual bool OnScrollCallback(float offset, int32_t source); 156 virtual void OnScrollStartCallback(); 157 virtual void FireOnScrollStart(); FireOnReachStart(const OnReachEvent & onReachStart)158 virtual void FireOnReachStart(const OnReachEvent& onReachStart) {} FireOnReachEnd(const OnReachEvent & onReachEnd)159 virtual void FireOnReachEnd(const OnReachEvent& onReachEnd) {} ScrollableIdle()160 bool ScrollableIdle() 161 { 162 return !scrollableEvent_ || scrollableEvent_->Idle(); 163 } SetScrollEnabled(bool enabled)164 void SetScrollEnabled(bool enabled) 165 { 166 CHECK_NULL_VOID(scrollableEvent_); 167 bool bNest = false; 168 if (scrollBarProxy_) { 169 bNest = scrollBarProxy_->IsNestScroller(); 170 } 171 172 if (enabled || bNest) { 173 enabled = true; 174 scrollableEvent_->SetAxis(axis_); 175 } else { 176 scrollableEvent_->SetAxis(Axis::NONE); 177 } 178 scrollableEvent_->SetEnabled(enabled); 179 180 if (scrollBarProxy_) { 181 scrollBarProxy_->SetScrollEnabled(enabled, AceType::WeakClaim(this)); 182 } 183 } 184 GetScrollEnabled()185 bool GetScrollEnabled() const 186 { 187 CHECK_NULL_RETURN(scrollableEvent_, false); 188 return scrollableEvent_->GetEnabled(); 189 } 190 191 RefPtr<GestureEventHub> GetGestureHub(); 192 RefPtr<InputEventHub> GetInputHub(); 193 194 // edgeEffect GetScrollEdgeEffect()195 const RefPtr<ScrollEdgeEffect>& GetScrollEdgeEffect() const 196 { 197 return scrollEffect_; 198 } 199 bool HandleEdgeEffect(float offset, int32_t source, const SizeF& size); 200 void HandleFadeEffect(float offset, int32_t source, const SizeF& size, 201 bool isNotPositiveScrollableDistance); SetEdgeEffectCallback(const RefPtr<ScrollEdgeEffect> & scrollEffect)202 virtual void SetEdgeEffectCallback(const RefPtr<ScrollEdgeEffect>& scrollEffect) {} IsRestrictBoundary()203 bool IsRestrictBoundary() 204 { 205 return !scrollEffect_ || scrollEffect_->IsRestrictBoundary(); 206 } 207 208 // scrollBar 209 virtual void UpdateScrollBarOffset() = 0; 210 void SetScrollBar(const std::unique_ptr<ScrollBarProperty>& property); 211 void SetScrollBar(DisplayMode displayMode); 212 void SetScrollBarProxy(const RefPtr<ScrollBarProxy>& scrollBarProxy); 213 void CreateScrollBarOverlayModifier(); 214 GetScrollableDistance()215 float GetScrollableDistance() const 216 { 217 return estimatedHeight_; 218 } 219 GetBarOffset()220 float GetBarOffset() const 221 { 222 return barOffset_; 223 } 224 GetScrollBarOutBoundaryExtent()225 double GetScrollBarOutBoundaryExtent() const 226 { 227 return scrollBarOutBoundaryExtent_; 228 } 229 SetScrollBarOutBoundaryExtent(float scrollBarOutBoundaryExtent)230 void SetScrollBarOutBoundaryExtent(float scrollBarOutBoundaryExtent) 231 { 232 scrollBarOutBoundaryExtent_ = scrollBarOutBoundaryExtent; 233 } 234 235 void HandleScrollBarOutBoundary(float scrollBarOutBoundaryExtent); 236 GetMainSize(const SizeF & size)237 double GetMainSize(const SizeF& size) const 238 { 239 return axis_ == Axis::HORIZONTAL ? size.Width() : size.Height(); 240 } 241 IsScrollableStopped()242 bool IsScrollableStopped() const 243 { 244 CHECK_NULL_RETURN(scrollableEvent_, true); 245 auto scrollable = scrollableEvent_->GetScrollable(); 246 CHECK_NULL_RETURN(scrollable, true); 247 return scrollable->IsStopped(); 248 } 249 GetIsDragging()250 bool GetIsDragging() const 251 { 252 CHECK_NULL_RETURN(scrollableEvent_, false); 253 auto scrollable = scrollableEvent_->GetScrollable(); 254 CHECK_NULL_RETURN(scrollable, false); 255 return scrollable->GetIsDragging(); 256 } 257 StopScrollable()258 void StopScrollable() 259 { 260 CHECK_NULL_VOID(scrollableEvent_); 261 auto scrollable = scrollableEvent_->GetScrollable(); 262 CHECK_NULL_VOID(scrollable); 263 scrollable->StopScrollable(); 264 } 265 StartScrollSnapMotion(float scrollSnapDelta,float scrollSnapVelocity)266 void StartScrollSnapMotion(float scrollSnapDelta, float scrollSnapVelocity) 267 { 268 CHECK_NULL_VOID(scrollableEvent_); 269 auto scrollable = scrollableEvent_->GetScrollable(); 270 CHECK_NULL_VOID(scrollable); 271 scrollable->ProcessScrollSnapSpringMotion(scrollSnapDelta, scrollSnapVelocity); 272 } 273 IsScrollableSpringEffect()274 bool IsScrollableSpringEffect() const 275 { 276 CHECK_NULL_RETURN(scrollEffect_, false); 277 return scrollEffect_->IsSpringEffect(); 278 } 279 SetCoordEventNeedSpringEffect(bool IsCoordEventNeedSpring)280 void SetCoordEventNeedSpringEffect(bool IsCoordEventNeedSpring) 281 { 282 isCoordEventNeedSpring_ = IsCoordEventNeedSpring; 283 } 284 285 void GetParentNavigation(); 286 void GetParentModalSheet(); 287 288 /** 289 * @brief Return the portion of delta that's in overScroll range. 290 * 291 * @param delta incoming offset change. 292 * @return the portion of delta in overScroll range. Both top overScroll and bottom overScroll. 293 */ GetOverScrollOffset(double delta)294 virtual OverScrollOffset GetOverScrollOffset(double delta) const 295 { 296 return { 0, 0 }; 297 } 298 OnScrollSnapCallback(double targetOffset,double velocity)299 virtual bool OnScrollSnapCallback(double targetOffset, double velocity) 300 { 301 return false; 302 } 303 StartScrollBarAnimatorByProxy()304 void StartScrollBarAnimatorByProxy() 305 { 306 if (scrollBarProxy_) { 307 scrollBarProxy_->StartScrollBarAnimator(); 308 } 309 310 for (auto proxy : nestScrollBarProxy_) { 311 auto scrollBarProxy = proxy.Upgrade(); 312 CHECK_NULL_CONTINUE(scrollBarProxy); 313 scrollBarProxy->StartScrollBarAnimator(); 314 } 315 } 316 StopScrollBarAnimatorByProxy()317 void StopScrollBarAnimatorByProxy() 318 { 319 if (scrollBarProxy_) { 320 scrollBarProxy_->StopScrollBarAnimator(); 321 } 322 323 for (auto proxy : nestScrollBarProxy_) { 324 auto scrollBarProxy = proxy.Upgrade(); 325 CHECK_NULL_CONTINUE(scrollBarProxy); 326 scrollBarProxy->StopScrollBarAnimator(); 327 } 328 } 329 330 void SetFriction(double friction); 331 GetFriction()332 double GetFriction() const 333 { 334 return friction_; 335 } 336 337 void SetMaxFlingVelocity(double max); 338 GetMaxFlingVelocity()339 double GetMaxFlingVelocity() const 340 { 341 CHECK_NULL_RETURN(scrollableEvent_, 0.0); 342 auto scrollable = scrollableEvent_->GetScrollable(); 343 CHECK_NULL_RETURN(scrollable, 0.0); 344 return scrollable->GetMaxFlingVelocity(); 345 } 346 347 virtual void StopAnimate(); 348 AnimateRunning()349 bool AnimateRunning() const 350 { 351 return (animator_ && animator_->IsRunning()) || !isAnimationStop_; 352 } AnimateStoped()353 bool AnimateStoped() const 354 { 355 return (!animator_ || animator_->IsStopped()) && isAnimationStop_; 356 } 357 AbortScrollAnimator()358 void AbortScrollAnimator() 359 { 360 if (animator_ && !animator_->IsStopped()) { 361 scrollAbort_ = true; 362 animator_->Stop(); 363 } 364 if (!isAnimationStop_) { 365 scrollAbort_ = true; 366 StopAnimation(springAnimation_); 367 StopAnimation(curveAnimation_); 368 } 369 } GetScrollAbort()370 bool GetScrollAbort() const 371 { 372 return scrollAbort_; 373 } SetScrollAbort(bool abort)374 void SetScrollAbort(bool abort) 375 { 376 scrollAbort_ = abort; 377 } 378 void PlaySpringAnimation(float position, float velocity, float mass, float stiffness, float damping, 379 bool useTotalOffset = true); 380 void PlayCurveAnimation(float position, float duration, const RefPtr<Curve>& curve, bool canOverScroll); GetTotalOffset()381 virtual float GetTotalOffset() const 382 { 383 return 0.0f; 384 } GetContentStartOffset()385 virtual float GetContentStartOffset() const 386 { 387 return 0.0f; 388 } 389 // main size of all children GetTotalHeight()390 virtual float GetTotalHeight() const 391 { 392 return 0.0f; 393 } OnAnimateStop()394 virtual void OnAnimateStop() {} 395 virtual void ScrollTo(float position); 396 virtual void AnimateTo( 397 float position, float duration, const RefPtr<Curve>& curve, bool smooth, bool canOverScroll = false, 398 bool useTotalOffset = true); CanOverScroll(int32_t source)399 virtual bool CanOverScroll(int32_t source) 400 { 401 auto canOverScroll = (IsScrollableSpringEffect() && source != SCROLL_FROM_AXIS && source != SCROLL_FROM_BAR && 402 IsScrollable() && (!ScrollableIdle() || animateOverScroll_ || animateCanOverScroll_)); 403 if (canOverScroll != lastCanOverScroll_) { 404 lastCanOverScroll_ = canOverScroll; 405 AddScrollableFrameInfo(source); 406 } 407 return canOverScroll; 408 } 409 void MarkSelectedItems(); 410 bool ShouldSelectScrollBeStopped(); 411 void UpdateMouseStart(float offset); 412 413 // scrollSnap CalePredictSnapOffset(float delta,float dragDistance,float velocity)414 virtual std::optional<float> CalePredictSnapOffset(float delta, float dragDistance, float velocity) 415 { 416 std::optional<float> predictSnapPosition; 417 return predictSnapPosition; 418 } 419 NeedScrollSnapToSide(float delta)420 virtual bool NeedScrollSnapToSide(float delta) 421 { 422 return false; 423 } 424 SetScrollSource(int32_t scrollSource)425 void SetScrollSource(int32_t scrollSource) 426 { 427 if (scrollSource == SCROLL_FROM_JUMP || scrollSource == SCROLL_FROM_FOCUS_JUMP) { 428 if (scrollBar_ && scrollBar_->IsScrollable() && scrollBarOverlayModifier_) { 429 scrollBarOverlayModifier_->SetOpacity(UINT8_MAX); 430 scrollBar_->ScheduleDisappearDelayTask(); 431 } 432 StopScrollBarAnimatorByProxy(); 433 StartScrollBarAnimatorByProxy(); 434 } 435 if (scrollSource == SCROLL_FROM_NONE) { 436 if (lastScrollSource_ != scrollSource_) { 437 AddScrollableFrameInfo(scrollSource_); 438 } 439 lastScrollSource_ = scrollSource_; 440 } 441 scrollSource_ = scrollSource; 442 } 443 GetScrollSource()444 int32_t GetScrollSource() const 445 { 446 return scrollSource_; 447 } 448 GetCurrentVelocity()449 float GetCurrentVelocity() const 450 { 451 return currentVelocity_; 452 } 453 454 ScrollState GetScrollState() const; 455 456 static ScrollState GetScrollState(int32_t scrollSource); 457 458 static ScrollSource ConvertScrollSource(int32_t source); 459 CalculateFriction(float gamma)460 static float CalculateFriction(float gamma) 461 { 462 constexpr float RATIO = 1.848f; 463 if (GreatOrEqual(gamma, 1.0)) { 464 gamma = 1.0f; 465 } 466 return exp(-RATIO * gamma); 467 } 468 virtual float GetMainContentSize() const; 469 SupportScrollToIndex()470 virtual bool SupportScrollToIndex() const 471 { 472 return true; 473 } 474 GetDefaultScrollAlign()475 virtual ScrollAlign GetDefaultScrollAlign() const 476 { 477 return ScrollAlign::START; 478 } 479 480 virtual void ScrollToIndex(int32_t index, bool smooth = false, ScrollAlign align = ScrollAlign::START, 481 std::optional<float> extraOffset = std::nullopt) 482 {} 483 SetExtraOffset(std::optional<float> extraOffset)484 void SetExtraOffset(std::optional<float> extraOffset) 485 { 486 extraOffset_ = extraOffset; 487 } 488 GetExtraOffset()489 const std::optional<float>& GetExtraOffset() const 490 { 491 return extraOffset_; 492 } 493 ResetExtraOffset()494 void ResetExtraOffset() 495 { 496 extraOffset_.reset(); 497 } 498 499 virtual void ScrollToEdge(ScrollEdgeType scrollEdgeType, bool smooth); 500 GetScrollEdgeType()501 virtual ScrollEdgeType GetScrollEdgeType() const 502 { 503 return ScrollEdgeType::SCROLL_NONE; 504 } 505 SetScrollEdgeType(ScrollEdgeType scrollEdgeType)506 virtual void SetScrollEdgeType(ScrollEdgeType scrollEdgeType) {} 507 508 virtual void Fling(double flingVelocity); 509 SetPositionController(RefPtr<ScrollableController> control)510 void SetPositionController(RefPtr<ScrollableController> control) 511 { 512 positionController_ = control; 513 if (control) { 514 control->SetScrollPattern(AceType::WeakClaim(this)); 515 } 516 } 517 GetOrCreatePositionController()518 RefPtr<ScrollableController> GetOrCreatePositionController() 519 { 520 if (!positionController_) { 521 auto controller = AceType::MakeRefPtr<NG::ScrollableController>(); 522 SetPositionController(controller); 523 } 524 return positionController_; 525 } 526 GetItemRect(int32_t index)527 virtual Rect GetItemRect(int32_t index) const 528 { 529 return Rect(); 530 }; 531 GetItemIndex(double x,double y)532 virtual int32_t GetItemIndex(double x, double y) const 533 { 534 return -1; 535 } 536 SetEdgeEffect(EdgeEffect edgeEffect,bool alwaysEnabled)537 void SetEdgeEffect(EdgeEffect edgeEffect, bool alwaysEnabled) 538 { 539 edgeEffect_ = edgeEffect; 540 edgeEffectAlwaysEnabled_ = alwaysEnabled; 541 } 542 GetEdgeEffect()543 EdgeEffect GetEdgeEffect() 544 { 545 return edgeEffect_; 546 } 547 GetAlwaysEnabled()548 bool GetAlwaysEnabled() const 549 { 550 return edgeEffectAlwaysEnabled_; 551 } 552 SetAlwaysEnabled(bool alwaysEnabled)553 void SetAlwaysEnabled(bool alwaysEnabled) 554 { 555 edgeEffectAlwaysEnabled_ = alwaysEnabled; 556 } 557 IsScrollableAnimationNotRunning()558 bool IsScrollableAnimationNotRunning() 559 { 560 if (scrollableEvent_) { 561 auto scrollable = scrollableEvent_->GetScrollable(); 562 if (scrollable) { 563 return scrollable->IsAnimationNotRunning(); 564 } 565 return false; 566 } 567 return false; 568 } 569 GetFinalPosition()570 float GetFinalPosition() const 571 { 572 return finalPosition_; 573 } 574 void HandleOnDragStatusCallback( 575 const DragEventType& dragEventType, const RefPtr<NotifyDragEvent>& notifyDragEvent) override; 576 IsScrollableSpringMotionRunning()577 bool IsScrollableSpringMotionRunning() 578 { 579 CHECK_NULL_RETURN(scrollableEvent_, false); 580 auto scrollable = scrollableEvent_->GetScrollable(); 581 CHECK_NULL_RETURN(scrollable, false); 582 return scrollable->IsSpringMotionRunning(); 583 } 584 IsScrollSnap()585 virtual bool IsScrollSnap() 586 { 587 // When setting snap or enablePaging in scroll, the PARENT_FIRST in nestedScroll_ is invalid 588 return false; 589 } 590 SetNeedLinked(bool needLinked)591 void SetNeedLinked(bool needLinked) 592 { 593 needLinked_ = needLinked; 594 } 595 SetAnimateCanOverScroll(bool animateCanOverScroll)596 void SetAnimateCanOverScroll(bool animateCanOverScroll) 597 { 598 bool isScrollable = !(IsAtBottom() && IsAtTop() && !GetAlwaysEnabled()); 599 animateCanOverScroll_ = isScrollable && animateCanOverScroll; 600 } 601 GetVisibleSelectedItems()602 virtual std::vector<RefPtr<FrameNode>> GetVisibleSelectedItems() 603 { 604 std::vector<RefPtr<FrameNode>> children; 605 return children; 606 } 607 void InitScrollBarGestureEvent(); 608 609 virtual void InitScrollBarClickEvent(); 610 void HandleClickEvent(); 611 void InitScrollBarMouseEvent(); 612 virtual void ScrollPage( 613 bool reverse, bool smooth = false, AccessibilityScrollType scrollType = AccessibilityScrollType::SCROLL_FULL); 614 void PrintOffsetLog(AceLogTag tag, int32_t id, double finalOffset); 615 616 void CheckRestartSpring(bool sizeDiminished, bool needNestedScrolling = true); 617 GetScrollablePanDirection()618 Axis GetScrollablePanDirection() 619 { 620 CHECK_NULL_RETURN(scrollableEvent_, Axis::NONE); 621 auto scrollable = scrollableEvent_->GetScrollable(); 622 CHECK_NULL_RETURN(scrollable, Axis::NONE); 623 return scrollable->GetPanDirection(); 624 } 625 626 void AddEventsFiredInfo(ScrollableEventType eventType); 627 628 void AddScrollableFrameInfo(int32_t scrollSource); 629 630 void GetEdgeEffectDumpInfo(); 631 632 void GetAxisDumpInfo(); 633 634 void GetPanDirectionDumpInfo(); 635 636 void GetPaintPropertyDumpInfo(); 637 638 void GetEventDumpInfo(); 639 640 void DumpAdvanceInfo() override; 641 SetScrollToSafeAreaHelper(bool isScrollToSafeAreaHelper)642 void SetScrollToSafeAreaHelper(bool isScrollToSafeAreaHelper) 643 { 644 isScrollToSafeAreaHelper_ = isScrollToSafeAreaHelper; 645 } 646 IsScrollToSafeAreaHelper()647 bool IsScrollToSafeAreaHelper() const 648 { 649 return isScrollToSafeAreaHelper_; 650 } 651 GetScrollOffsetAbility()652 virtual ScrollOffsetAbility GetScrollOffsetAbility() 653 { 654 return { nullptr, Axis::NONE }; 655 } 656 GetScrollIndexAbility()657 virtual std::function<bool(int32_t)> GetScrollIndexAbility() 658 { 659 return nullptr; 660 } 661 662 void ScrollAtFixedVelocity(float velocity); 663 664 PositionMode GetPositionMode(); 665 666 void HandleMoveEventInComp(const PointF& point); 667 void HandleLeaveHotzoneEvent(); SetHotZoneScrollCallback(std::function<void (void)> && func)668 void SetHotZoneScrollCallback(std::function<void(void)>&& func) 669 { 670 hotZoneScrollCallback_ = func; 671 } 672 673 void OnCollectClickTarget(const OffsetF& coordinateOffset, const GetEventTargetImpl& getEventTargetImpl, 674 TouchTestResult& result, const RefPtr<FrameNode>& frameNode, const RefPtr<TargetComponent>& targetComponent, 675 ResponseLinkResult& responseLinkResult); 676 677 virtual void SetAccessibilityAction(); GetScrollBarProxy()678 RefPtr<NG::ScrollBarProxy> GetScrollBarProxy() const 679 { 680 return scrollBarProxy_; 681 } 682 683 virtual void OnAttachToMainTree() override; 684 685 void AddNestScrollBarProxy(const WeakPtr<ScrollBarProxy>& scrollBarProxy); 686 687 void SetParentNestedScroll(RefPtr<ScrollablePattern>& parentPattern); 688 689 void SearchAndSetParentNestedScroll(const RefPtr<FrameNode>& node); 690 691 void UnsetParentNestedScroll(RefPtr<ScrollablePattern>& parentPattern); 692 693 void SearchAndUnsetParentNestedScroll(const RefPtr<FrameNode>& node); 694 695 void DeleteNestScrollBarProxy(const WeakPtr<ScrollBarProxy>& scrollBarProxy); 696 SetUseTotalOffset(bool useTotalOffset)697 void SetUseTotalOffset(bool useTotalOffset) 698 { 699 useTotalOffset_ = useTotalOffset; 700 } 701 GetNestedScrolling()702 bool GetNestedScrolling() const 703 { 704 CHECK_NULL_RETURN(scrollableEvent_, false); 705 auto scrollable = scrollableEvent_->GetScrollable(); 706 CHECK_NULL_RETURN(scrollable, false); 707 return scrollable->GetNestedScrolling(); 708 } 709 710 void ScrollEndCallback(bool nestedScroll, float velocity); 711 GetChildrenExpandedSize()712 virtual SizeF GetChildrenExpandedSize() 713 { 714 return SizeF(); 715 } 716 717 SizeF GetViewSizeMinusPadding(); 718 719 void SetBackToTop(bool backToTop); GetBackToTop()720 bool GetBackToTop() const 721 { 722 return backToTop_; 723 } 724 void OnStatusBarClick() override; 725 726 protected: 727 void SuggestOpIncGroup(bool flag); 728 void OnDetachFromFrameNode(FrameNode* frameNode) override; 729 GetDefaultScrollBarDisplayMode()730 virtual DisplayMode GetDefaultScrollBarDisplayMode() const 731 { 732 return DisplayMode::AUTO; 733 } GetScrollBar()734 RefPtr<ScrollBar> GetScrollBar() const 735 { 736 return scrollBar_; 737 } 738 void UpdateScrollBarRegion(float offset, float estimatedHeight, Size viewPort, Offset viewOffset); 739 740 EdgeEffect GetEdgeEffect() const; SetEdgeEffect()741 void SetEdgeEffect() 742 { 743 SetEdgeEffect(edgeEffect_); 744 } 745 746 virtual void FireOnScroll(float finalOffset, OnScrollEvent& onScroll) const; 747 748 void FireObserverOnTouch(const TouchEventInfo& info); 749 void FireObserverOnPanActionEnd(GestureEvent& info); 750 void FireObserverOnReachStart(); 751 void FireObserverOnReachEnd(); 752 void FireObserverOnScrollStart(); 753 void FireObserverOnScrollStop(); 754 void FireObserverOnDidScroll(float finalOffset); 755 756 virtual void OnScrollStop(const OnScrollStopEvent& onScrollStop); 757 758 float FireOnWillScroll(float offset) const; 759 760 // select with mouse 761 struct ItemSelectedStatus { 762 std::function<void(bool)> onSelected; 763 std::function<void(bool)> selectChangeEvent; 764 RectF rect; 765 bool selected = false; FireSelectChangeEventItemSelectedStatus766 void FireSelectChangeEvent(bool isSelected) 767 { 768 if (selected == isSelected) { 769 return; 770 } 771 selected = isSelected; 772 if (onSelected) { 773 onSelected(isSelected); 774 } 775 if (selectChangeEvent) { 776 selectChangeEvent(isSelected); 777 } 778 } 779 }; 780 void InitMouseEvent(); 781 void UninitMouseEvent(); 782 void DrawSelectedZone(const RectF& selectedZone); 783 void ClearSelectedZone(); 784 bool multiSelectable_ = false; 785 bool isMouseEventInit_ = false; 786 OffsetF mouseStartOffset_; 787 float totalOffsetOfMousePressed_ = 0.0f; 788 std::unordered_map<int32_t, ItemSelectedStatus> itemToBeSelected_; 789 bool animateOverScroll_ = false; 790 bool animateCanOverScroll_ = false; 791 GetScrollBarOverlayModifier()792 RefPtr<ScrollBarOverlayModifier> GetScrollBarOverlayModifier() const 793 { 794 return scrollBarOverlayModifier_; 795 } 796 SetScrollBarOverlayModifier(RefPtr<ScrollBarOverlayModifier> scrollBarOverlayModifier)797 void SetScrollBarOverlayModifier(RefPtr<ScrollBarOverlayModifier> scrollBarOverlayModifier) 798 { 799 scrollBarOverlayModifier_ = scrollBarOverlayModifier; 800 } 801 // just for hold ScrollableController 802 RefPtr<ScrollableController> positionController_; 803 804 bool scrollStop_ = false; 805 806 // for onReachStart of the first layout 807 bool isInitialized_ = false; 808 809 void Register2DragDropManager(); 810 SetScrollOriginChild(const WeakPtr<NestableScrollContainer> & scrollOriginChild)811 void SetScrollOriginChild(const WeakPtr<NestableScrollContainer>& scrollOriginChild) 812 { 813 scrollOriginChild_ = scrollOriginChild; 814 } 815 GetScrollOriginChild()816 RefPtr<NestableScrollContainer> GetScrollOriginChild() 817 { 818 return scrollOriginChild_.Upgrade(); 819 } 820 821 void SetCanOverScroll(bool val); 822 bool GetCanOverScroll() const; 823 bool lastCanOverScroll_ = false; 824 825 void CheckScrollBarOff(); 826 827 private: OnScrollEndCallback()828 virtual void OnScrollEndCallback() {}; 829 830 void RegisterScrollBarEventTask(); 831 bool OnScrollPosition(double& offset, int32_t source); 832 void ProcessNavBarReactOnStart(); 833 float ProcessNavBarReactOnUpdate(float offset); 834 void ProcessNavBarReactOnEnd(); 835 void InitSpringOffsetProperty(); 836 void InitCurveOffsetProperty(); 837 void OnAnimateFinish(); 838 void StopAnimation(std::shared_ptr<AnimationUtils::Animation> animation); 839 void PauseAnimation(std::shared_ptr<AnimationUtils::Animation> animation); 840 void InitOption(AnimationOption &option, float duration, const RefPtr<Curve>& curve); 841 float GetScrollDelta(float offset, bool& stopAnimation); 842 843 void OnAttachToFrameNode() override; 844 void AttachAnimatableProperty(RefPtr<Scrollable> scrollable); 845 void InitTouchEvent(const RefPtr<GestureEventHub>& gestureHub); 846 void RegisterWindowStateChangedCallback(); 847 848 // select with mouse MultiSelectWithoutKeyboard(const RectF & selectedZone)849 virtual void MultiSelectWithoutKeyboard(const RectF& selectedZone) {}; ClearMultiSelect()850 virtual void ClearMultiSelect() {}; IsItemSelected(const GestureEvent & info)851 virtual bool IsItemSelected(const GestureEvent& info) 852 { 853 return false; 854 } 855 void ClearInvisibleItemsSelectedStatus(); 856 void HandleInvisibleItemsSelectedStatus(const RectF& selectedZone); 857 void HandleDragStart(const GestureEvent& info); 858 void HandleDragUpdate(const GestureEvent& info); 859 void HandleDragEnd(); 860 void SelectWithScroll(); 861 RectF ComputeSelectedZone(const OffsetF& startOffset, const OffsetF& endOffset); 862 float GetOutOfScrollableOffset() const; 863 virtual float GetOffsetWithLimit(float offset) const; 864 void LimitMouseEndOffset(); 865 void UpdateBorderRadius(); 866 867 /****************************************************************************** 868 * NestableScrollContainer implementations 869 */ 870 ScrollResult HandleScroll( 871 float offset, int32_t source, NestedState state = NestedState::GESTURE, float velocity = 0.f) override; 872 bool HandleScrollVelocity(float velocity, const RefPtr<NestableScrollContainer>& child = nullptr) override; 873 874 void RemainVelocityToChild(float remainVelocity) override; NestedScrollOutOfBoundary()875 bool NestedScrollOutOfBoundary() override 876 { 877 return OutBoundaryCallback(); 878 } 879 void UpdateNestedScrollVelocity(float offset, NestedState state); 880 float GetNestedScrollVelocity(); 881 882 void OnScrollEndRecursive(const std::optional<float>& velocity) override; 883 void OnScrollEndRecursiveInner(const std::optional<float>& velocity); 884 void OnScrollStartRecursive(WeakPtr<NestableScrollContainer> child, float position, float velocity = 0.f) override; 885 void OnScrollStartRecursiveInner(WeakPtr<NestableScrollContainer> child, float position, float velocity = 0.f); 886 void OnScrollDragEndRecursive() override; 887 void StopScrollAnimation() override; 888 889 ScrollResult HandleScrollParentFirst(float& offset, int32_t source, NestedState state); 890 ScrollResult HandleScrollSelfFirst(float& offset, int32_t source, NestedState state); 891 ScrollResult HandleScrollSelfOnly(float& offset, int32_t source, NestedState state); 892 ScrollResult HandleScrollParallel(float& offset, int32_t source, NestedState state); 893 bool HandleOutBoundary(float& offset, int32_t source, NestedState state, ScrollResult& result); 894 895 void ExecuteScrollFrameBegin(float& mainDelta, ScrollState state); 896 897 void OnScrollEnd(); 898 void ProcessSpringEffect(float velocity, bool needRestart = false); 899 void SetEdgeEffect(EdgeEffect edgeEffect); 900 901 // Scrollable::UpdateScrollPosition 902 bool HandleScrollImpl(float offset, int32_t source); 903 void NotifyMoved(bool value); 904 905 /* 906 * End of NestableScrollContainer implementations 907 *******************************************************************************/ 908 909 bool HandleOverScroll(float velocity); 910 bool HandleScrollableOverScroll(float velocity); 911 CreateRefreshCoordination()912 void CreateRefreshCoordination() 913 { 914 if (!refreshCoordination_) { 915 auto host = GetHost(); 916 CHECK_NULL_VOID(host); 917 refreshCoordination_ = AceType::MakeRefPtr<RefreshCoordination>(host); 918 } 919 } 920 float GetVelocity() const; 921 bool NeedSplitScroll(OverScrollOffset& overOffsets, int32_t source); 922 RefreshCoordinationMode CoordinateWithRefresh(double& offset, int32_t source, bool isAtTop); 923 bool CoordinateWithNavigation(double& offset, int32_t source, bool isAtTop); 924 void NotifyFRCSceneInfo(const std::string& scene, double velocity, SceneStatus sceneStatus); 925 ModalSheetCoordinationMode CoordinateWithSheet(double& offset, int32_t source, bool isAtTop); 926 bool NeedCoordinateScrollWithNavigation(double offset, int32_t source, const OverScrollOffset& overOffsets); 927 void SetUiDvsyncSwitch(bool on); 928 void SetNestedScrolling(bool nestedScrolling); 929 930 Axis axis_ = Axis::VERTICAL; 931 RefPtr<ScrollableEvent> scrollableEvent_; 932 RefPtr<TouchEventImpl> touchEvent_; 933 RefPtr<ScrollEdgeEffect> scrollEffect_; 934 RefPtr<RefreshCoordination> refreshCoordination_; 935 int32_t scrollSource_ = SCROLL_FROM_NONE; 936 int32_t lastScrollSource_ = SCROLL_FROM_NONE; 937 // scrollBar 938 RefPtr<ScrollBar> scrollBar_; 939 RefPtr<NG::ScrollBarProxy> scrollBarProxy_; 940 std::list<WeakPtr<NG::ScrollBarProxy>> nestScrollBarProxy_; 941 RefPtr<ScrollBarOverlayModifier> scrollBarOverlayModifier_; 942 float barOffset_ = 0.0f; 943 float estimatedHeight_ = 0.0f; 944 bool isReactInParentMovement_ = false; 945 bool isRefreshInReactive_ = false; // true if Refresh component is ready to receive scroll offset. 946 bool isSheetInReactive_ = false; 947 bool isCoordEventNeedSpring_ = true; 948 double scrollBarOutBoundaryExtent_ = 0.0; 949 double friction_ = 0.0; 950 double maxFlingVelocity_ = MAX_VELOCITY; 951 // scroller 952 RefPtr<Animator> animator_; 953 bool scrollAbort_ = false; 954 bool isAnimateOverScroll_ = false; 955 bool isScrollToSafeAreaHelper_ = true; 956 bool inScrollingStatus_ = false; 957 bool switchOnStatus_ = false; 958 959 float startPercent_ = 0.0f; 960 float endPercent_ = 1.0f; 961 void UpdateFadeInfo( 962 bool isFadingTop, bool isFadingBottom, float fadeFrameSize, const RefPtr<ScrollablePaintMethod>& paint); 963 964 // select with mouse 965 enum SelectDirection { SELECT_DOWN, SELECT_UP, SELECT_NONE }; 966 SelectDirection selectDirection_ = SELECT_NONE; 967 bool mousePressed_ = false; 968 bool canMultiSelect_ = false; 969 OffsetF mouseEndOffset_; 970 OffsetF mousePressOffset_; 971 OffsetF lastMouseStart_; 972 GestureEvent lastMouseMove_; 973 RefPtr<SelectMotion> selectMotion_; 974 RefPtr<PanEvent> boxSelectPanEvent_; 975 976 RefPtr<NavBarPattern> navBarPattern_; 977 RefPtr<SheetPresentationPattern> sheetPattern_; 978 std::vector<RefPtr<ScrollingListener>> scrollingListener_; 979 980 EdgeEffect edgeEffect_ = EdgeEffect::NONE; 981 bool edgeEffectAlwaysEnabled_ = false; 982 bool needLinked_ = true; 983 984 RefPtr<NodeAnimatablePropertyFloat> springOffsetProperty_; 985 RefPtr<NodeAnimatablePropertyFloat> curveOffsetProperty_; 986 std::shared_ptr<AnimationUtils::Animation> springAnimation_; 987 std::shared_ptr<AnimationUtils::Animation> curveAnimation_; 988 uint64_t lastVsyncTime_ = 0; 989 bool isAnimationStop_ = true; // graphic animation flag 990 bool isClickAnimationStop_ = false; // interrupt scrolling after click statubar. 991 float currentVelocity_ = 0.0f; 992 float lastPosition_ = 0.0f; 993 float finalPosition_ = 0.0f; 994 bool useTotalOffset_ = true; 995 bool animateToTraceFlag_ = false; 996 std::optional<float> extraOffset_; 997 998 RefPtr<Animator> hotzoneAnimator_; 999 float lastHonezoneOffsetPct_ = 0.0f; 1000 RefPtr<BezierVariableVelocityMotion> velocityMotion_; 1001 RefPtr<VelocityMotion> fixedVelocityMotion_; 1002 std::function<void(void)> hotZoneScrollCallback_; 1003 void UnRegister2DragDropManager(); 1004 float IsInHotZone(const PointF& point); 1005 void HotZoneScroll(const float offset); 1006 void StopHotzoneScroll(); 1007 void HandleHotZone(const DragEventType& dragEventType, const RefPtr<NotifyDragEvent>& notifyDragEvent); 1008 bool isVertical() const; 1009 Offset locationInfo_; 1010 WeakPtr<NestableScrollContainer> scrollOriginChild_; 1011 float nestedScrollVelocity_ = 0.0f; 1012 uint64_t nestedScrollTimestamp_ = 0; 1013 bool prevHasFadingEdge_ = false; 1014 1015 RefPtr<ClickRecognizer> clickRecognizer_; 1016 // dump info 1017 std::list<ScrollableEventsFiredInfo> eventsFiredInfos_; 1018 std::list<ScrollableFrameInfo> scrollableFrameInfos_; 1019 RefPtr<InputEvent> mouseEvent_; 1020 bool isMousePressed_ = false; 1021 bool backToTop_ = false; 1022 }; 1023 } // namespace OHOS::Ace::NG 1024 1025 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_NG_PATTERNS_SCROLL_SCROLL_PATTERN_H 1026