• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2020-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 /**
17  * @addtogroup UI_Components
18  * @{
19  *
20  * @brief Defines UI components such as buttons, texts, images, lists, and progress bars.
21  *
22  * @since 1.0
23  * @version 1.0
24  */
25 
26 /**
27  * @file ui_abstract_scroll.h
28  *
29  * @brief Declares the base class used to define the attributes of a scroll. The <b>UIList</b>, <b>UIScrollView</b>, and
30  *        <b>UISwipeView</b> inherit from this class.
31  *
32  * @since 1.0
33  * @version 1.0
34  */
35 
36 #ifndef GRAPHIC_LITE_UI_ABSTRACT_SCROLL_H
37 #define GRAPHIC_LITE_UI_ABSTRACT_SCROLL_H
38 
39 #include "animator/animator.h"
40 #include "animator/easing_equation.h"
41 #include "components/ui_view_group.h"
42 
43 namespace OHOS {
44 class BarEaseInOutAnimator;
45 class UIAbstractScrollBar;
46 /**
47  * @brief Defines the attributes of a scroll, including the scroll direction, blank size of a scroll view, velocity and
48  *        effects of a scroll animation.
49  *
50  * @since 1.0
51  * @version 1.0
52  */
53 class UIAbstractScroll : public UIViewGroup {
54 public:
55     /**
56      * @brief A constructor used to create a <b>UIAbstractScroll</b> instance.
57      *
58      * @since 1.0
59      * @version 1.0
60      */
61     UIAbstractScroll();
62 
63     /**
64      * @brief A destructor used to delete the <b>UIAbstractScroll</b> instance.
65      *
66      * @since 1.0
67      * @version 1.0
68      */
69     virtual ~UIAbstractScroll();
70 
71     /**
72      * @brief Obtains the view type.
73      * @return Returns the view type, as defined in {@link UIViewType}.
74      * @since 1.0
75      * @version 1.0
76      */
GetViewType()77     UIViewType GetViewType() const override
78     {
79         return UI_ABSTRACT_SCROLL;
80     }
81 
82     /**
83      * @brief Sets the blank size for this scroll view.
84      *
85      *
86      * @param value Indicates the blank size to set. The default value is <b>0</b>. Taking a vertical scroll as an
87      *              example, the value <b>0</b> indicates that the head node can only scroll downwards the top of the
88      *              view and the tail node scroll upwards the bottom; the value <b>10</b> indicates that the head node
89      *              can continue scrolling down by 10 pixels after it reaches the top of the view.
90      * @since 1.0
91      * @version 1.0
92      */
SetScrollBlankSize(uint16_t size)93     void SetScrollBlankSize(uint16_t size)
94     {
95         scrollBlankSize_ = size;
96     }
97 
98     /**
99      * @brief Sets the maximum scroll distance after a finger lifts the screen.
100      *
101      * @param distance Indicates the maximum scroll distance to set. The default value is <b>0</b>, indicating that the
102      *                 scroll distance is not limited.
103      * @since 1.0
104      * @version 1.0
105      */
SetMaxScrollDistance(uint16_t distance)106     void SetMaxScrollDistance(uint16_t distance)
107     {
108         maxScrollDistance_ = distance;
109     }
110 
111     /**
112      * @brief Sets the rebound size, which is the distance a knob moves after being released when it reaches the end of
113      *        a scrollbar.
114      *
115      * @param size Indicates the rebound size to set.
116      * @since 1.0
117      * @version 1.0
118      */
SetReboundSize(uint16_t size)119     void SetReboundSize(uint16_t size)
120     {
121         reboundSize_ = size;
122     }
123 
124     /**
125      * @brief Obtains the maximum scroll distance after a finger lifts the screen.
126      *
127      * @return Returns the maximum scroll distance. The default value is <b>0</b>, indicating that the scroll distance
128      * is not limited.
129      * @since 1.0
130      * @version 1.0
131      */
GetMaxScrollDistance()132     uint16_t GetMaxScrollDistance() const
133     {
134         return maxScrollDistance_;
135     }
136 
137     /**
138      * @brief Sets the easing function that specifies a scroll animation after a finger lifts the screen.
139      *
140      * @param func Indicates the easing function to set. The default function is {@link EasingEquation::CubicEaseOut}.
141      *             For details, see {@link EasingEquation}.
142      * @since 1.0
143      * @version 1.0
144      */
SetDragFunc(EasingFunc func)145     void SetDragFunc(EasingFunc func)
146     {
147         easingFunc_ = func;
148     }
149 
150     /**
151      * @brief Sets whether to continue scrolling after a finger lifts the screen.
152      *
153      * @param throwDrag Specifies whether to continue scrolling after a finger lifts the screen. <b>true</b> indicates
154      *                  the scroll continues, and <b>false</b> indicates the scroll stops immediately after a finger
155      *                  lifts.
156      * @since 1.0
157      * @version 1.0
158      */
SetThrowDrag(bool throwDrag)159     void SetThrowDrag(bool throwDrag)
160     {
161         throwDrag_ = throwDrag;
162     }
163 
164     /**
165      * @brief Moves the position of all child views.
166      *
167      * @param offsetX Indicates the offset distance by which a child view is moved on the x-axis.
168      * @param offsetY Indicates the offset distance by which a child view is moved on the y-axis.
169      * @since 1.0
170      * @version 1.0
171      */
172     void MoveChildByOffset(int16_t offsetX, int16_t offsetY) override;
173 
174     /**
175      * @brief Sets the drag acceleration.
176      *
177      * @param value Indicates the drag acceleration to set. The default value is <b>10</b>. A larger drag acceleration
178      *              indicates a higher inertial scroll velocity.
179      * @since 1.0
180      * @version 1.0
181      */
SetDragACCLevel(uint16_t value)182     void SetDragACCLevel(uint16_t value)
183     {
184         if (value != 0) {
185             dragAccCoefficient_ = value;
186         }
187     }
188 
189     /**
190      * @brief Obtains the drag acceleration.
191      *
192      * @return Returns the drag acceleration.
193      * @since 1.0
194      * @version 1.0
195      */
GetDragACCLevel()196     uint8_t GetDragACCLevel() const
197     {
198         return dragAccCoefficient_;
199     }
200 
201     /**
202      * @brief Sets the compensation distance after a finger lifts the screen.
203      *
204      * @param value Indicates the compensation distance to set. The default value is <b>0</b>.
205      * @since 1.0
206      * @version 1.0
207      */
SetSwipeACCLevel(uint16_t value)208     void SetSwipeACCLevel(uint16_t value)
209     {
210         swipeAccCoefficient_ = value;
211     }
212 
213     /**
214      * @brief Obtains the compensation distance after a finger lifts the screen.
215      *
216      * @return Returns the compensation distance.
217      * @since 1.0
218      * @version 1.0
219      */
GetSwipeACCLevel()220     uint8_t GetSwipeACCLevel() const
221     {
222         return swipeAccCoefficient_;
223     }
224 
225 #if ENABLE_ROTATE_INPUT
226     /**
227      * @brief Sets coefficient for rotation dragthrow animation. The view will roll farther with larger coeffcient.
228      *
229      * @param value Indicates the coefficient to set. The default value is <b>0</b>.
230      * @since 1.0
231      * @version 1.0
232      */
SetRotateACCLevel(uint8_t value)233     void SetRotateACCLevel(uint8_t value)
234     {
235         rotateAccCoefficient_ = value;
236     }
237 
238     /**
239      * @brief Obtains the coefficient for rotation drag throw animation.
240      *
241      * @return Returns the coefficient for rotation drag throw animation.
242      * @since 1.0
243      * @version 1.0
244      */
GetRotateACCLevel()245     uint8_t GetRotateACCLevel() const
246     {
247         return rotateAccCoefficient_;
248     }
249 
250     /**
251      * @brief Obtains the rotation factor.
252      *
253      * @return Returns the rotation factor.
254      * @since 5.0
255      * @version 3.0
256      */
GetRotateFactor()257     float GetRotateFactor() const
258     {
259         return rotateFactor_;
260     }
261 
262     /**
263      * @brief Sets the rotation factor.
264      *
265      * @param factor Indicates the rotation factor to set.
266      * @since 5.0
267      * @version 3.0
268      */
SetRotateFactor(float factor)269     void SetRotateFactor(float factor)
270     {
271         if (MATH_ABS(factor) > MAX_ROTATE_FACTOR) {
272             rotateFactor_ = (factor > 0) ? MAX_ROTATE_FACTOR : -MAX_ROTATE_FACTOR;
273             return;
274         }
275         rotateFactor_ = factor;
276     }
277 
278     /**
279      * @brief Sets threshold for rotation drag throw animation. The view will roll easier with larger threshold.
280      *
281      * @param threshold Indicates the rotation factor to set.
282      *
283      * @since 6
284      */
SetRotateThrowThreshold(uint8_t threshold)285     void SetRotateThrowThreshold(uint8_t threshold)
286     {
287         if (threshold == 0) {
288             return;
289         }
290         rotateThrowthreshold_ = threshold;
291     }
292 
293     bool OnRotateStartEvent(const RotateEvent& event) override;
294 
295     bool OnRotateEvent(const RotateEvent& event) override;
296 
297     bool OnRotateEndEvent(const RotateEvent& event) override;
298 #endif
299 
300     void SetXScrollBarVisible(bool visible);
301 
302     void SetYScrollBarVisible(bool visible);
303 
SetScrollBarSide(uint8_t side)304     void SetScrollBarSide(uint8_t side)
305     {
306         scrollBarSide_ = side;
307     }
308 
SetScrollBarCenter(const Point & center)309     void SetScrollBarCenter(const Point& center)
310     {
311         scrollBarCenter_ = center;
312         scrollBarCenterSetFlag_ = true;
313     }
314 
315     /**
316      * @brief Sets the list direction.
317      *
318      * @param direction Indicates the list direction, either {@link HORIZONTAL} or {@link VERTICAL}.
319      * @since 1.0
320      * @version 1.0
321      */
SetDirection(uint8_t direction)322     void SetDirection(uint8_t direction)
323     {
324         direction_ = direction;
325     }
326 
327     /**
328      * @brief Obtains the list direction.
329      * @return Returns the list direction, either {@link HORIZONTAL} or {@link VERTICAL}.
330      * @since 1.0
331      * @version 1.0
332      */
GetDirection()333     uint8_t GetDirection() const
334     {
335         return direction_;
336     }
337 
338     void OnPostDraw(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea) override;
339 
340     static constexpr uint8_t HORIZONTAL = 0;
341     static constexpr uint8_t VERTICAL = 1;
342 
343 protected:
344     static constexpr uint8_t HORIZONTAL_AND_VERTICAL = 2;
345     static constexpr uint8_t HORIZONTAL_NOR_VERTICAL = 3;
346     /* calculate drag throw distance, last drag distance in one tick * DRAG_DISTANCE_COEFFICIENT */
347     static constexpr uint8_t DRAG_DISTANCE_COEFFICIENT = 5;
348     /* calculate drag throw times, drag distance / DRAG_TIMES_COEFFICIENT */
349     static constexpr uint8_t DRAG_TIMES_COEFFICIENT = 18;
350     /* the minimum duration of the swipe animator */
351     static constexpr uint8_t MIN_DRAG_TIMES = 5;
352     /* acceleration calculation coefficient */
353     static constexpr uint8_t DRAG_ACC_FACTOR = 10;
354     /* the maximum number of historical drag data */
355     static constexpr uint8_t MAX_DELTA_SIZE = 3;
356 
357     static constexpr uint16_t SCROLL_BAR_WIDTH = 4;
358     static constexpr uint8_t MAX_ROTATE_FACTOR = 128;
359 
360     class ListAnimatorCallback : public AnimatorCallback {
361     public:
ListAnimatorCallback()362         ListAnimatorCallback()
363             : curtTime_(0),
364               dragTimes_(0),
365               startValueX_(0),
366               endValueX_(0),
367               previousValueX_(0),
368               startValueY_(0),
369               endValueY_(0),
370               previousValueY_(0)
371         {
372         }
373 
~ListAnimatorCallback()374         virtual ~ListAnimatorCallback() {}
375 
SetDragTimes(uint16_t times)376         void SetDragTimes(uint16_t times)
377         {
378             dragTimes_ = times;
379         }
380 
SetDragStartValue(int16_t startValueX,int16_t startValueY)381         void SetDragStartValue(int16_t startValueX, int16_t startValueY)
382         {
383             startValueX_ = startValueX;
384             previousValueX_ = startValueX;
385             startValueY_ = startValueY;
386             previousValueY_ = startValueY;
387         }
388 
SetDragEndValue(int16_t endValueX,int16_t endValueY)389         void SetDragEndValue(int16_t endValueX, int16_t endValueY)
390         {
391             endValueX_ = endValueX;
392             endValueY_ = endValueY;
393         }
394 
ResetCallback()395         void ResetCallback()
396         {
397             curtTime_ = 0;
398             dragTimes_ = 0;
399             startValueX_ = 0;
400             endValueX_ = 0;
401             startValueY_ = 0;
402             endValueY_ = 0;
403         }
404 
405         virtual void Callback(UIView* view) override;
406 
407         uint16_t curtTime_;
408         uint16_t dragTimes_;
409         int16_t startValueX_;
410         int16_t endValueX_;
411         int16_t previousValueX_;
412         int16_t startValueY_;
413         int16_t endValueY_;
414         int16_t previousValueY_;
415     };
416 
417     bool DragThrowAnimator(Point currentPos, Point lastPos, uint8_t dragDirection, bool dragBack = true);
418 
419     virtual void StopAnimator();
420 
421     virtual bool DragXInner(int16_t distance) = 0;
422 
423     virtual bool DragYInner(int16_t distance) = 0;
424 
RefreshDelta(int16_t distance)425     void RefreshDelta(int16_t distance)
426     {
427         lastDelta_[deltaIndex_ % MAX_DELTA_SIZE] = distance;
428         deltaIndex_++;
429     }
430 
431     void InitDelta();
432 
RefreshRotate(int16_t distance)433     void RefreshRotate(int16_t distance)
434     {
435         lastRotate_[rotateIndex_ % MAX_DELTA_SIZE] = distance;
436         rotateIndex_++;
437     }
438 
439     void InitRotate();
440 
441     virtual void CalculateDragDistance(Point currentPos,
442                                        Point lastPos,
443                                        uint8_t dragDirection,
444                                        int16_t& dragDistanceX,
445                                        int16_t& dragDistanceY);
446 
447     void StartAnimator(int16_t dragDistanceX, int16_t dragDistanceY);
448 
CalculateReboundDistance(int16_t & dragDistanceX,int16_t & dragDistanceY)449     virtual void CalculateReboundDistance(int16_t& dragDistanceX, int16_t& dragDistanceY){};
450 
451     int16_t GetMaxDelta() const;
452 
453     int16_t GetMaxRotate() const;
454 
455     void RefreshAnimator();
456 
FixDistance(int16_t & distanceX,int16_t & distanceY)457     virtual void FixDistance(int16_t& distanceX, int16_t& distanceY) {}
458 
459     uint16_t scrollBlankSize_ = 0;
460     uint16_t reboundSize_ = 0;
461     uint16_t maxScrollDistance_ = 0;
462     int16_t lastDelta_[MAX_DELTA_SIZE] = {0};
463     int16_t lastRotate_[MAX_DELTA_SIZE] = {0};
464     uint8_t dragAccCoefficient_ = DRAG_ACC_FACTOR;
465     uint8_t swipeAccCoefficient_ = 0;
466     uint8_t direction_ : 2;
467     uint8_t deltaIndex_ : 2;
468     uint8_t rotateIndex_ : 2;
469     uint8_t reserve_ : 2;
470     bool throwDrag_ = false;
471     EasingFunc easingFunc_;
472     ListAnimatorCallback animatorCallback_;
473     Animator scrollAnimator_;
474 #if ENABLE_ROTATE_INPUT
475     uint8_t rotateAccCoefficient_ = 0;
476     float rotateFactor_;
477     uint8_t rotateThrowthreshold_;
478     bool isRotating_;
479 #endif
480     bool yScrollBarVisible_ = false;
481     UIAbstractScrollBar* yScrollBar_ = nullptr;
482     bool xScrollBarVisible_ = false;
483     UIAbstractScrollBar* xScrollBar_ = nullptr;
484     uint8_t scrollBarSide_;
485     Point scrollBarCenter_;
486     bool scrollBarCenterSetFlag_;
487     bool dragBack_ = true;
488 #if DEFAULT_ANIMATION
489     friend class BarEaseInOutAnimator;
490     BarEaseInOutAnimator* barEaseInOutAnimator_ = nullptr;
491 #endif
492 };
493 } // namespace OHOS
494 #endif // GRAPHIC_LITE_UI_ABSTRACT_SCROLL_H
495