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