• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021 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_SCROLL_RENDER_SCROLL_H
17 #define FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_SCROLL_RENDER_SCROLL_H
18 
19 #include <utility>
20 
21 #include "base/geometry/axis.h"
22 #include "base/memory/ace_type.h"
23 #include "core/animation/curve.h"
24 #include "core/components/common/properties/scroll_bar.h"
25 #include "core/components/refresh/render_refresh.h"
26 #include "core/components/scroll/scroll_bar_controller.h"
27 #include "core/components/scroll/scroll_component.h"
28 #include "core/components/scroll/scroll_edge_effect.h"
29 #include "core/components/scroll/scroll_position_controller.h"
30 #include "core/gestures/raw_recognizer.h"
31 #include "core/pipeline/base/render_node.h"
32 
33 namespace OHOS::Ace {
34 
35 enum class ScrollType {
36     SCROLL_INDEX = 0,
37     SCROLL_PAGE_DOWN,
38     SCROLL_PAGE_UP,
39     SCROLL_BOTTOM,
40     SCROLL_TOP,
41 };
42 
43 class RenderScroll : public RenderNode {
44     DECLARE_ACE_TYPE(RenderScroll, RenderNode)
45 
46 public:
47     ~RenderScroll() override;
48 
49     static double CalculateFriction(double gamma);
50     static double CalculateOffsetByFriction(double extentOffset, double delta, double friction);
51 
52     virtual void JumpToIndex(int32_t index, int32_t source = SCROLL_FROM_JUMP);
53     virtual void ScrollToEdge(ScrollEdgeType scrollEdgeType, bool smooth);
54     virtual bool ScrollPage(bool reverse, bool smooth, const std::function<void()>& onFinish = nullptr);
55     virtual void JumpToPosition(double position, int32_t source = SCROLL_FROM_JUMP);
56     // notify start position in global main axis
NotifyDragStart(double startPosition)57     virtual void NotifyDragStart(double startPosition) {};
58     // notify drag offset in global main axis
NotifyDragUpdate(double dragOffset,int32_t source)59     virtual void NotifyDragUpdate(double dragOffset, int32_t source) {};
ProcessScrollOverCallback(double velocity)60     virtual void ProcessScrollOverCallback(double velocity) {};
61     void AnimateTo(double position, float duration, const RefPtr<Curve>& curve, bool limitDuration = true,
62         const std::function<void()>& onFinish = nullptr);
63     bool AnimateToTarget(const ComposeId& targetId, float duration, const RefPtr<Curve>& curve,
64         bool limitDuration = true, const std::function<void()>& onFinish = nullptr);
65     void ScrollBy(double pixelX, double pixelY, bool smooth, const std::function<void()>& onFinish = nullptr);
66 
67     double GetCurrentPosition() const;
68     bool UpdateOffset(Offset& delta, int32_t source);
69     bool ScrollPageByChild(Offset& delta, int32_t source) override;
70     double GetEstimatedHeight();
71     void OnChildAdded(const RefPtr<RenderNode>& child) override;
72 
73     void UpdateTouchRect() override;
74 
GetFixPositionOnWatch(double destination,double current)75     virtual double GetFixPositionOnWatch(double destination, double current)
76     {
77         return destination;
78     }
79 
IsAtTop()80     bool IsAtTop() const
81     {
82         return LessOrEqual(GetMainOffset(currentOffset_), 0.0);
83     }
84 
IsAtBottom()85     bool IsAtBottom() const
86     {
87         auto outViewportSize = mainScrollExtent_ - GetMainSize(viewPort_);
88         bool atBottom = GreatOrEqual(GetMainOffset(currentOffset_), outViewportSize);
89         return LessOrEqual(outViewportSize, 0.0) || (atBottom && ReachMaxCount());
90     }
91 
IsScrollStop()92     bool IsScrollStop() const
93     {
94         return (scrollable_ ? scrollable_->IsMotionStop() : true) && (animator_ ? (!animator_->IsRunning()) : true);
95     }
96 
97     bool CanScrollVertically(const Offset& delta);
98     bool ScrollPageCheck(Offset& delta, int32_t source);
99 
GetMainOffset(const Offset & offset)100     double GetMainOffset(const Offset& offset) const
101     {
102         return axis_ == Axis::HORIZONTAL ? offset.GetX() : offset.GetY();
103     }
104 
GetMainSize(const Size & size)105     double GetMainSize(const Size& size) const
106     {
107         return axis_ == Axis::HORIZONTAL ? size.Width() : size.Height();
108     }
109 
GetViewPort()110     Size GetViewPort() const
111     {
112         return viewPort_;
113     }
114 
GetCrossSize(const Size & size)115     double GetCrossSize(const Size& size) const
116     {
117         return axis_ == Axis::HORIZONTAL ? size.Height() : size.Width();
118     }
119 
GetAxis()120     Axis GetAxis() const
121     {
122         return axis_;
123     }
124 
IsRowReverse()125     bool IsRowReverse()
126     {
127         return axis_ == Axis::HORIZONTAL && rightToLeft_;
128     }
129 
ReachMaxCount()130     virtual bool ReachMaxCount() const
131     {
132         return true;
133     }
134 
GetMainScrollExtent()135     virtual double GetMainScrollExtent() const
136     {
137         return mainScrollExtent_;
138     }
139 
SetScrollPage(bool scrollPage)140     void SetScrollPage(bool scrollPage)
141     {
142         scrollPage_ = scrollPage;
143     }
144 
GetBarDisappearFlag()145     int32_t GetBarDisappearFlag() const
146     {
147         return scrollBarOpacity_;
148     }
149 
GetCurrentOffset()150     Offset GetCurrentOffset() const
151     {
152         return currentOffset_;
153     }
154 
GetLastOffset()155     const Offset& GetLastOffset() const
156     {
157         return lastOffset_;
158     }
159 
SetNeedMove(bool needMove)160     void SetNeedMove(bool needMove)
161     {
162         moveStatus_.second = moveStatus_.first;
163         moveStatus_.first = needMove;
164     }
165 
166     virtual void HandleRotate(double rotateValue, bool isVertical);
167 
168     void HandleScrollOverByBar(double velocity);
169 
SetMainScrollExtentForBar(double value)170     void SetMainScrollExtentForBar(double value)
171     {
172         scrollBarExtent_ = value;
173     }
174 
GetScrollBar()175     RefPtr<ScrollBar> GetScrollBar() const
176     {
177         return scrollBar_;
178     }
179 
GetScrollBarOutBoundaryExtent()180     double GetScrollBarOutBoundaryExtent() const
181     {
182         return scrollBarOutBoundaryExtent_;
183     }
184 
IsSpringMotionRunning()185     bool IsSpringMotionRunning() const
186     {
187         return scrollable_ ? scrollable_->IsSpringMotionRunning() : false;
188     }
189 
190     virtual bool IsOutOfBottomBoundary();
191 
192     virtual bool IsOutOfTopBoundary();
193 
194     virtual bool HandleCrashTop();
195     virtual bool HandleCrashBottom();
196 
SetIsFromRotate(bool isRotate)197     void SetIsFromRotate(bool isRotate)
198     {
199         isFromRotate_ = isRotate;
200     }
201 
IsFromRotate()202     bool IsFromRotate()
203     {
204         return isFromRotate_;
205     }
206 
207     void HandleAxisEvent(const AxisEvent& event) override;
208 
209     bool IsAxisScrollable(AxisDirection direction) override;
210 
211     WeakPtr<RenderNode> CheckAxisNode() override;
212 
213 protected:
214     explicit RenderScroll();
215 
216     void ResetEdgeEffect();
217     void ResetScrollable();
218     bool ValidateOffset(int32_t source);
219     void DoJump(double position, int32_t source = SCROLL_FROM_JUMP);
220     void Update(const RefPtr<Component>& component) override;
221     void InitScrollBar(const RefPtr<ScrollBar>& scrollBar);
222     void InitScrollBarProxy();
223 
AdjustTouchRestrict(TouchRestrict & touchRestrict)224     virtual void AdjustTouchRestrict(TouchRestrict& touchRestrict) {};
225 
226     Edge padding_;
227     Axis axis_ = Axis::FREE;
228     std::pair<bool, bool> moveStatus_;
229     Offset currentBottomOffset_;
230     Offset currentOffset_;
231     double currentDeltaInMain_ = 0.0;
232     Offset correctedDelta_;
233     Offset lastOffset_;
234     double overScroll_ = 0.0;
235     double mainScrollExtent_ = 0.0;
236     double outBoundaryExtent_ = 0.0;
237     double estimatedHeight_ = 0.0;
238     double moveDistance_ = 0.0;
239     bool scrollPage_ = false;
240     bool isFromRotate_ = false;
241     RefPtr<ScrollPositionController> positionController_;
242     RefPtr<ScrollEdgeEffect> scrollEffect_;
243     RefPtr<Scrollable> scrollable_;
244 
245     RefPtr<ScrollBar> scrollBar_;
246     bool inLinkRefresh_ = false;
247     WeakPtr<RenderRefresh> refreshParent_;
248     bool rightToLeft_ = false;
249     bool enable_ = true;
250     bool isRoot_ = false;
251 
252     // used for scrollBar
253     double scrollBarExtent_ = 0.0;
254     double scrollBarOutBoundaryExtent_ = 0.0;
255     bool scrollBarExtentFlag_ = false;
256     int32_t scrollBarOpacity_ = 0;
257 
258     double friction_ = 0.0;
259     RefPtr<SpringProperty> springProperty_;
260     RefPtr<ScrollBarProxy> scrollBarProxy_;
261 
262 private:
263     bool IsOutOfBoundary();
264     bool IsCrashBottom();
265     bool IsCrashTop();
266     void Initialize();
267     void AdjustOffset(Offset& delta, int32_t source);
268     void OnTouchTestHit(
269         const Offset& coordinateOffset, const TouchRestrict& touchRestrict, TouchTestResult& result) override;
270     void HandleScrollPosition(double scrollX, double scrollY, int32_t scrollState) const;
271     void SetEdgeEffectAttribute();
272     bool HandleRefreshEffect(Offset& delta, int32_t source);
273     void ResetScrollEventCallBack();
274     void HandleScrollEffect();
275     void SetBarCallBack(bool isVertical);
276     void HandleScrollBarEnd();
277     void HandleScrollBarOutBoundary();
278     void OnReachStart() const;
279     void OnReachEnd() const;
280     void OnReachTop() const;
281     void OnReachBottom() const;
282 
283     using OnReachFunc = std::function<void(const std::string&)>;
284     OnReachFunc onReachStart_;
285     OnReachFunc onReachEnd_;
286     OnReachFunc onReachTop_;
287     OnReachFunc onReachBottom_;
288 
289     RefPtr<Animator> animator_;
290     RefPtr<RawRecognizer> touchRecognizer_;
291 };
292 
293 } // namespace OHOS::Ace
294 
295 #endif // FOUNDATION_ACE_FRAMEWORKS_CORE_COMPONENTS_SCROLL_RENDER_SCROLL_H
296