/* * Copyright (c) 2020-2021 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * @addtogroup UI_Components * @{ * * @brief Defines UI components such as buttons, texts, images, lists, and progress bars. * * @since 1.0 * @version 1.0 */ /** * @file ui_abstract_scroll.h * * @brief Declares the base class used to define the attributes of a scroll. The <b>UIList</b>, <b>UIScrollView</b>, and * <b>UISwipeView</b> inherit from this class. * * @since 1.0 * @version 1.0 */ #ifndef GRAPHIC_LITE_UI_ABSTRACT_SCROLL_H #define GRAPHIC_LITE_UI_ABSTRACT_SCROLL_H #include "animator/animator.h" #include "animator/easing_equation.h" #include "components/ui_view_group.h" namespace OHOS { class BarEaseInOutAnimator; class UIAbstractScrollBar; /** * @brief Defines the attributes of a scroll, including the scroll direction, blank size of a scroll view, velocity and * effects of a scroll animation. * * @since 1.0 * @version 1.0 */ class UIAbstractScroll : public UIViewGroup { public: /** * @brief A constructor used to create a <b>UIAbstractScroll</b> instance. * * @since 1.0 * @version 1.0 */ UIAbstractScroll(); /** * @brief A destructor used to delete the <b>UIAbstractScroll</b> instance. * * @since 1.0 * @version 1.0 */ virtual ~UIAbstractScroll(); /** * @brief Obtains the view type. * @return Returns the view type, as defined in {@link UIViewType}. * @since 1.0 * @version 1.0 */ UIViewType GetViewType() const override { return UI_ABSTRACT_SCROLL; } /** * @brief Sets the blank size for this scroll view. * * * @param value Indicates the blank size to set. The default value is <b>0</b>. Taking a vertical scroll as an * example, the value <b>0</b> indicates that the head node can only scroll downwards the top of the * view and the tail node scroll upwards the bottom; the value <b>10</b> indicates that the head node * can continue scrolling down by 10 pixels after it reaches the top of the view. * @since 1.0 * @version 1.0 */ void SetScrollBlankSize(uint16_t size) { scrollBlankSize_ = size; } /** * @brief Get the blank size for this scroll view. * * @return Returns the blank size for this scroll view */ uint16_t GetScrollBlankSize() const { return scrollBlankSize_; } /** * @brief Sets the maximum scroll distance after a finger lifts the screen. * * @param distance Indicates the maximum scroll distance to set. The default value is <b>0</b>, indicating that the * scroll distance is not limited. * @since 1.0 * @version 1.0 */ void SetMaxScrollDistance(uint16_t distance) { maxScrollDistance_ = distance; } /** * @brief Sets the rebound size, which is the distance a knob moves after being released when it reaches the end of * a scrollbar. * * @param size Indicates the rebound size to set. * @since 1.0 * @version 1.0 */ void SetReboundSize(uint16_t size) { reboundSize_ = size; } /** * @brief Get the rebound size, which is the distance a knob moves after being released when it reaches the end of * a scrollbar. * * @return Returns the rebound size. */ uint16_t GetReboundSize() const { return reboundSize_; } /** * @brief Obtains the maximum scroll distance after a finger lifts the screen. * * @return Returns the maximum scroll distance. The default value is <b>0</b>, indicating that the scroll distance * is not limited. * @since 1.0 * @version 1.0 */ uint16_t GetMaxScrollDistance() const { return maxScrollDistance_; } /** * @brief Sets the easing function that specifies a scroll animation after a finger lifts the screen. * * @param func Indicates the easing function to set. The default function is {@link EasingEquation::CubicEaseOut}. * For details, see {@link EasingEquation}. * @since 1.0 * @version 1.0 */ void SetDragFunc(EasingFunc func) { easingFunc_ = func; } /** * @brief Get the easing function that specifies a scroll animation after a finger lifts the screen. * * @param func Returns the easing function to set. The default function is {@link EasingEquation::CubicEaseOut}. * For details, see {@link EasingEquation}. */ EasingFunc GetDragFunc() const { return easingFunc_; } /** * @brief Sets whether to continue scrolling after a finger lifts the screen. * * @param throwDrag Specifies whether to continue scrolling after a finger lifts the screen. <b>true</b> indicates * the scroll continues, and <b>false</b> indicates the scroll stops immediately after a finger * lifts. * @since 1.0 * @version 1.0 */ void SetThrowDrag(bool throwDrag) { throwDrag_ = throwDrag; } /** * @brief Moves the position of all child views. * * @param offsetX Indicates the offset distance by which a child view is moved on the x-axis. * @param offsetY Indicates the offset distance by which a child view is moved on the y-axis. * @since 1.0 * @version 1.0 */ void MoveChildByOffset(int16_t offsetX, int16_t offsetY) override; /** * @brief Sets the drag acceleration. * * @param value Indicates the drag acceleration to set. The default value is <b>10</b>. A larger drag acceleration * indicates a higher inertial scroll velocity. * @since 1.0 * @version 1.0 */ void SetDragACCLevel(uint16_t value) { if (value != 0) { dragAccCoefficient_ = value; } } /** * @brief Obtains the drag acceleration. * * @return Returns the drag acceleration. * @since 1.0 * @version 1.0 */ uint8_t GetDragACCLevel() const { return dragAccCoefficient_; } /** * @brief Sets the compensation distance after a finger lifts the screen. * * @param value Indicates the compensation distance to set. The default value is <b>0</b>. * @since 1.0 * @version 1.0 */ void SetSwipeACCLevel(uint16_t value) { swipeAccCoefficient_ = value; } /** * @brief Obtains the compensation distance after a finger lifts the screen. * * @return Returns the compensation distance. * @since 1.0 * @version 1.0 */ uint8_t GetSwipeACCLevel() const { return swipeAccCoefficient_; } #if ENABLE_ROTATE_INPUT /** * @brief Sets coefficient for rotation dragthrow animation. The view will roll farther with larger coeffcient. * * @param value Indicates the coefficient to set. The default value is <b>0</b>. * @since 1.0 * @version 1.0 */ void SetRotateACCLevel(uint8_t value) { rotateAccCoefficient_ = value; } /** * @brief Obtains the coefficient for rotation drag throw animation. * * @return Returns the coefficient for rotation drag throw animation. * @since 1.0 * @version 1.0 */ uint8_t GetRotateACCLevel() const { return rotateAccCoefficient_; } /** * @brief Obtains the rotation factor. * * @return Returns the rotation factor. * @since 5.0 * @version 3.0 */ float GetRotateFactor() const { return rotateFactor_; } /** * @brief Sets the rotation factor. * * @param factor Indicates the rotation factor to set. * @since 5.0 * @version 3.0 */ void SetRotateFactor(float factor) { if (MATH_ABS(factor) > MAX_ROTATE_FACTOR) { rotateFactor_ = (factor > 0) ? MAX_ROTATE_FACTOR : -MAX_ROTATE_FACTOR; return; } rotateFactor_ = factor; } /** * @brief Sets threshold for rotation drag throw animation. The view will roll easier with larger threshold. * * @param threshold Indicates the rotation factor to set. * * @since 6 */ void SetRotateThrowThreshold(uint8_t threshold) { if (threshold == 0) { return; } rotateThrowthreshold_ = threshold; } /** * @brief Get threshold for rotation drag throw animation. The view will roll easier with larger threshold. * * @param Returns the threshold for rotation drag throw animation. The view will roll easier with larger threshold. * */ uint8_t GetRotateThrowThreshold() const { return rotateThrowthreshold_; } bool OnRotateStartEvent(const RotateEvent& event) override; bool OnRotateEvent(const RotateEvent& event) override; bool OnRotateEndEvent(const RotateEvent& event) override; #endif void SetXScrollBarVisible(bool visible); void SetYScrollBarVisible(bool visible); void SetScrollBarSide(uint8_t side) { scrollBarSide_ = side; } /** * @brief Get ScrollBarSide. * * @param Returns the scrollBarSide_. * */ uint8_t GetScrollBarSide() { return scrollBarSide_; } void SetScrollBarCenter(const Point& center) { scrollBarCenter_ = center; scrollBarCenterSetFlag_ = true; } /** * @brief Get scrollBarCenter. * * @param Returns the scrollBarCenter_. * */ Point GetScrollBarCenter() { return scrollBarCenter_; } /** * @brief Sets the list direction. * * @param direction Indicates the list direction, either {@link HORIZONTAL} or {@link VERTICAL}. * @since 1.0 * @version 1.0 */ void SetDirection(uint8_t direction) { direction_ = direction; } /** * @brief Obtains the list direction. * @return Returns the list direction, either {@link HORIZONTAL} or {@link VERTICAL}. * @since 1.0 * @version 1.0 */ uint8_t GetDirection() const { return direction_; } void OnPostDraw(BufferInfo& gfxDstBuffer, const Rect& invalidatedArea) override; static constexpr uint8_t HORIZONTAL = 0; static constexpr uint8_t VERTICAL = 1; protected: static constexpr uint8_t HORIZONTAL_AND_VERTICAL = 2; static constexpr uint8_t HORIZONTAL_NOR_VERTICAL = 3; /* calculate drag throw distance, last drag distance in one tick * DRAG_DISTANCE_COEFFICIENT */ static constexpr uint8_t DRAG_DISTANCE_COEFFICIENT = 5; /* calculate drag throw times, drag distance / DRAG_TIMES_COEFFICIENT */ static constexpr uint8_t DRAG_TIMES_COEFFICIENT = 18; /* the minimum duration of the swipe animator */ static constexpr uint8_t MIN_DRAG_TIMES = 5; /* acceleration calculation coefficient */ static constexpr uint8_t DRAG_ACC_FACTOR = 10; /* the maximum number of historical drag data */ static constexpr uint8_t MAX_DELTA_SIZE = 3; static constexpr uint16_t SCROLL_BAR_WIDTH = 4; static constexpr uint8_t MAX_ROTATE_FACTOR = 128; class ListAnimatorCallback : public AnimatorCallback { public: ListAnimatorCallback() : curtTime_(0), dragTimes_(0), startValueX_(0), endValueX_(0), previousValueX_(0), startValueY_(0), endValueY_(0), previousValueY_(0) { } virtual ~ListAnimatorCallback() {} void SetDragTimes(uint16_t times) { dragTimes_ = times; } void SetDragStartValue(int16_t startValueX, int16_t startValueY) { startValueX_ = startValueX; previousValueX_ = startValueX; startValueY_ = startValueY; previousValueY_ = startValueY; } void SetDragEndValue(int16_t endValueX, int16_t endValueY) { endValueX_ = endValueX; endValueY_ = endValueY; } void ResetCallback() { curtTime_ = 0; dragTimes_ = 0; startValueX_ = 0; endValueX_ = 0; startValueY_ = 0; endValueY_ = 0; } void Callback(UIView* view) override; uint16_t curtTime_; uint16_t dragTimes_; int16_t startValueX_; int16_t endValueX_; int16_t previousValueX_; int16_t startValueY_; int16_t endValueY_; int16_t previousValueY_; }; bool DragThrowAnimator(Point currentPos, Point lastPos, uint8_t dragDirection, bool dragBack = true); virtual void StopAnimator(); virtual bool DragXInner(int16_t distance) = 0; virtual bool DragYInner(int16_t distance) = 0; void RefreshDelta(int16_t distance) { lastDelta_[deltaIndex_ % MAX_DELTA_SIZE] = distance; deltaIndex_++; } void InitDelta(); void RefreshRotate(int16_t distance) { lastRotate_[rotateIndex_ % MAX_DELTA_SIZE] = distance; rotateIndex_++; } void InitRotate(); virtual void CalculateDragDistance(Point currentPos, Point lastPos, uint8_t dragDirection, int16_t& dragDistanceX, int16_t& dragDistanceY); void StartAnimator(int16_t dragDistanceX, int16_t dragDistanceY); virtual void CalculateReboundDistance(int16_t& dragDistanceX, int16_t& dragDistanceY) {} int16_t GetMaxDelta() const; int16_t GetMaxRotate() const; void RefreshAnimator(); virtual void FixDistance(int16_t& distanceX, int16_t& distanceY) {} uint16_t scrollBlankSize_ = 0; uint16_t reboundSize_ = 0; uint16_t maxScrollDistance_ = 0; int16_t lastDelta_[MAX_DELTA_SIZE] = {0}; int16_t lastRotate_[MAX_DELTA_SIZE] = {0}; uint8_t dragAccCoefficient_ = DRAG_ACC_FACTOR; uint8_t swipeAccCoefficient_ = 0; uint8_t direction_ : 2; uint8_t deltaIndex_ : 2; uint8_t rotateIndex_ : 2; uint8_t reserve_ : 2; bool throwDrag_ = false; EasingFunc easingFunc_; ListAnimatorCallback animatorCallback_; Animator scrollAnimator_; #if ENABLE_ROTATE_INPUT uint8_t rotateAccCoefficient_ = 0; float rotateFactor_; uint8_t rotateThrowthreshold_; bool isRotating_; #endif bool yScrollBarVisible_ = false; UIAbstractScrollBar* yScrollBar_ = nullptr; bool xScrollBarVisible_ = false; UIAbstractScrollBar* xScrollBar_ = nullptr; uint8_t scrollBarSide_; Point scrollBarCenter_; bool scrollBarCenterSetFlag_; bool dragBack_ = true; #if DEFAULT_ANIMATION friend class BarEaseInOutAnimator; BarEaseInOutAnimator* barEaseInOutAnimator_ = nullptr; #endif }; } // namespace OHOS #endif // GRAPHIC_LITE_UI_ABSTRACT_SCROLL_H