• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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