1a3e0fd82Sopenharmony_ci/*
2a3e0fd82Sopenharmony_ci * Copyright (c) 2020-2021 Huawei Device Co., Ltd.
3a3e0fd82Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4a3e0fd82Sopenharmony_ci * you may not use this file except in compliance with the License.
5a3e0fd82Sopenharmony_ci * You may obtain a copy of the License at
6a3e0fd82Sopenharmony_ci *
7a3e0fd82Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8a3e0fd82Sopenharmony_ci *
9a3e0fd82Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10a3e0fd82Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11a3e0fd82Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12a3e0fd82Sopenharmony_ci * See the License for the specific language governing permissions and
13a3e0fd82Sopenharmony_ci * limitations under the License.
14a3e0fd82Sopenharmony_ci */
15a3e0fd82Sopenharmony_ci
16a3e0fd82Sopenharmony_ci#include "components/ui_scroll_view.h"
17a3e0fd82Sopenharmony_ci
18a3e0fd82Sopenharmony_ci#include "components/ui_abstract_scroll_bar.h"
19a3e0fd82Sopenharmony_ci#include "dock/focus_manager.h"
20a3e0fd82Sopenharmony_ci#include "dock/vibrator_manager.h"
21a3e0fd82Sopenharmony_ci#include "draw/draw_rect.h"
22a3e0fd82Sopenharmony_ci#include "gfx_utils/graphic_log.h"
23a3e0fd82Sopenharmony_ci
24a3e0fd82Sopenharmony_cinamespace OHOS {
25a3e0fd82Sopenharmony_ciUIScrollView::UIScrollView() : scrollListener_(nullptr)
26a3e0fd82Sopenharmony_ci{
27a3e0fd82Sopenharmony_ci#if defined(ENABLE_ROTATE_INPUT) && ENABLE_ROTATE_INPUT
28a3e0fd82Sopenharmony_ci    rotateFactor_ = DEFAULT_SCROLL_VIEW_ROTATE_FACTOR;
29a3e0fd82Sopenharmony_ci    rotateThrowthreshold_ = SCROLLVIEW_ROTATE_THROW_THRESHOLD;
30a3e0fd82Sopenharmony_ci    rotateAccCoefficient_ = SCROLLVIEW_ROTATE_DISTANCE_COEFF;
31a3e0fd82Sopenharmony_ci#endif
32a3e0fd82Sopenharmony_ci#if defined(ENABLE_VIBRATOR) && ENABLE_VIBRATOR
33a3e0fd82Sopenharmony_ci    totalRotateLen_ = 0;
34a3e0fd82Sopenharmony_ci    lastVibratorRotateLen_ = 0;
35a3e0fd82Sopenharmony_ci#endif
36a3e0fd82Sopenharmony_ci#if defined(ENABLE_FOCUS_MANAGER) && ENABLE_FOCUS_MANAGER
37a3e0fd82Sopenharmony_ci    focusable_ = true;
38a3e0fd82Sopenharmony_ci#endif
39a3e0fd82Sopenharmony_ci    direction_ = HORIZONTAL_AND_VERTICAL;
40a3e0fd82Sopenharmony_ci}
41a3e0fd82Sopenharmony_ci
42a3e0fd82Sopenharmony_cibool UIScrollView::OnDragEvent(const DragEvent& event)
43a3e0fd82Sopenharmony_ci{
44a3e0fd82Sopenharmony_ci    if (scrollAnimator_.GetState() != Animator::STOP) {
45a3e0fd82Sopenharmony_ci        UIAbstractScroll::StopAnimator();
46a3e0fd82Sopenharmony_ci    }
47a3e0fd82Sopenharmony_ci    Drag(event);
48a3e0fd82Sopenharmony_ci    return UIView::OnDragEvent(event);
49a3e0fd82Sopenharmony_ci}
50a3e0fd82Sopenharmony_ci
51a3e0fd82Sopenharmony_cibool UIScrollView::OnDragEndEvent(const DragEvent& event)
52a3e0fd82Sopenharmony_ci{
53a3e0fd82Sopenharmony_ci    Point last = event.GetPreLastPoint();
54a3e0fd82Sopenharmony_ci    Point current = event.GetLastPoint();
55a3e0fd82Sopenharmony_ci    if ((last.x == current.x) && (last.y == current.y)) {
56a3e0fd82Sopenharmony_ci        last = current;
57a3e0fd82Sopenharmony_ci        current = event.GetCurrentPos();
58a3e0fd82Sopenharmony_ci    }
59a3e0fd82Sopenharmony_ci
60a3e0fd82Sopenharmony_ci    if (!DragThrowAnimator(current, last, event.GetDragDirection())) {
61a3e0fd82Sopenharmony_ci        if (scrollListener_ && (scrollListener_->GetScrollState() == OnScrollListener::SCROLL_STATE_MOVE)) {
62a3e0fd82Sopenharmony_ci            scrollListener_->OnScrollEnd();
63a3e0fd82Sopenharmony_ci            scrollListener_->SetScrollState(OnScrollListener::SCROLL_STATE_STOP);
64a3e0fd82Sopenharmony_ci        }
65a3e0fd82Sopenharmony_ci    }
66a3e0fd82Sopenharmony_ci    return UIView::OnDragEndEvent(event);
67a3e0fd82Sopenharmony_ci}
68a3e0fd82Sopenharmony_ci
69a3e0fd82Sopenharmony_civoid UIScrollView::Drag(const DragEvent& event)
70a3e0fd82Sopenharmony_ci{
71a3e0fd82Sopenharmony_ci    int16_t xDistance = event.GetDeltaX();
72a3e0fd82Sopenharmony_ci    int16_t yDistance = event.GetDeltaY();
73a3e0fd82Sopenharmony_ci
74a3e0fd82Sopenharmony_ci    if ((direction_ == HORIZONTAL || direction_ == HORIZONTAL_AND_VERTICAL) && xDistance != 0) {
75a3e0fd82Sopenharmony_ci        DragXInner(xDistance);
76a3e0fd82Sopenharmony_ci    }
77a3e0fd82Sopenharmony_ci    if ((direction_ == VERTICAL || direction_ == HORIZONTAL_AND_VERTICAL) && yDistance != 0) {
78a3e0fd82Sopenharmony_ci        RefreshDelta(yDistance);
79a3e0fd82Sopenharmony_ci        DragYInner(yDistance);
80a3e0fd82Sopenharmony_ci    }
81a3e0fd82Sopenharmony_ci}
82a3e0fd82Sopenharmony_ci
83a3e0fd82Sopenharmony_cibool UIScrollView::OnPressEvent(const PressEvent& event)
84a3e0fd82Sopenharmony_ci{
85a3e0fd82Sopenharmony_ci    StopAnimator();
86a3e0fd82Sopenharmony_ci    return UIView::OnPressEvent(event);
87a3e0fd82Sopenharmony_ci}
88a3e0fd82Sopenharmony_ci
89a3e0fd82Sopenharmony_ci#if defined(ENABLE_ROTATE_INPUT) && ENABLE_ROTATE_INPUT
90a3e0fd82Sopenharmony_cibool UIScrollView::OnRotateEvent(const RotateEvent& event)
91a3e0fd82Sopenharmony_ci{
92a3e0fd82Sopenharmony_ci    if (direction_ == HORIZONTAL_NOR_VERTICAL) {
93a3e0fd82Sopenharmony_ci        return UIView::OnRotateEvent(event);
94a3e0fd82Sopenharmony_ci    }
95a3e0fd82Sopenharmony_ci    int16_t rotateLen = static_cast<int16_t>(event.GetRotate() * rotateFactor_);
96a3e0fd82Sopenharmony_ci#if defined(ENABLE_VIBRATOR) && ENABLE_VIBRATOR
97a3e0fd82Sopenharmony_ci    bool lastIsEdge = false;
98a3e0fd82Sopenharmony_ci    Rect childRect = GetAllChildRelativeRect();
99a3e0fd82Sopenharmony_ci    SetIsEdge(lastIsEdge, childRect);
100a3e0fd82Sopenharmony_ci#endif
101a3e0fd82Sopenharmony_ci    RefreshRotate(rotateLen);
102a3e0fd82Sopenharmony_ci    if (direction_ == HORIZONTAL) {
103a3e0fd82Sopenharmony_ci        DragXInner(rotateLen);
104a3e0fd82Sopenharmony_ci    } else {
105a3e0fd82Sopenharmony_ci        DragYInner(rotateLen);
106a3e0fd82Sopenharmony_ci    }
107a3e0fd82Sopenharmony_ci#if defined(ENABLE_VIBRATOR) && ENABLE_VIBRATOR
108a3e0fd82Sopenharmony_ci    totalRotateLen_ += rotateLen;
109a3e0fd82Sopenharmony_ci    childRect = GetAllChildRelativeRect();
110a3e0fd82Sopenharmony_ci    bool isEdge = false;
111a3e0fd82Sopenharmony_ci    if (direction_ == HORIZONTAL) {
112a3e0fd82Sopenharmony_ci        if (childRect.GetLeft() - scrollBlankSize_ >= 0 || childRect.GetRight() + scrollBlankSize_ <= GetWidth()) {
113a3e0fd82Sopenharmony_ci            isEdge = true;
114a3e0fd82Sopenharmony_ci        }
115a3e0fd82Sopenharmony_ci    } else {
116a3e0fd82Sopenharmony_ci        if (childRect.GetTop() - scrollBlankSize_ >= 0 || childRect.GetBottom() + scrollBlankSize_ <= GetHeight()) {
117a3e0fd82Sopenharmony_ci            isEdge = true;
118a3e0fd82Sopenharmony_ci        }
119a3e0fd82Sopenharmony_ci    }
120a3e0fd82Sopenharmony_ci    VibratorFunc vibratorFunc = VibratorManager::GetInstance()->GetVibratorFunc();
121a3e0fd82Sopenharmony_ci    if (vibratorFunc != nullptr && !isEdge) {
122a3e0fd82Sopenharmony_ci        rotateLen = MATH_ABS(totalRotateLen_ - lastVibratorRotateLen_);
123a3e0fd82Sopenharmony_ci        if (rotateLen > DEFAULT_SCROLL_VIEW_VIBRATION_LEN) {
124a3e0fd82Sopenharmony_ci            uint16_t vibrationCnt = rotateLen / DEFAULT_SCROLL_VIEW_VIBRATION_LEN;
125a3e0fd82Sopenharmony_ci            for (uint16_t i = 0; i < vibrationCnt; i++) {
126a3e0fd82Sopenharmony_ci                GRAPHIC_LOGI("UIScrollView::OnRotateEvent calls TYPE_ONE vibrator");
127a3e0fd82Sopenharmony_ci                vibratorFunc(VibratorType::VIBRATOR_TYPE_ONE);
128a3e0fd82Sopenharmony_ci            }
129a3e0fd82Sopenharmony_ci            lastVibratorRotateLen_ = totalRotateLen_;
130a3e0fd82Sopenharmony_ci        }
131a3e0fd82Sopenharmony_ci    }
132a3e0fd82Sopenharmony_ci    if (vibratorFunc != nullptr && (!lastIsEdge && isEdge)) {
133a3e0fd82Sopenharmony_ci        GRAPHIC_LOGI("UIScrollView::OnRotateEvent calls TYPE_THREE vibrator");
134a3e0fd82Sopenharmony_ci        vibratorFunc(VibratorType::VIBRATOR_TYPE_THREE);
135a3e0fd82Sopenharmony_ci    }
136a3e0fd82Sopenharmony_ci#endif
137a3e0fd82Sopenharmony_ci    return UIView::OnRotateEvent(event);
138a3e0fd82Sopenharmony_ci}
139a3e0fd82Sopenharmony_ci
140a3e0fd82Sopenharmony_cibool UIScrollView::OnRotateEndEvent(const RotateEvent& event)
141a3e0fd82Sopenharmony_ci{
142a3e0fd82Sopenharmony_ci    if (direction_ == HORIZONTAL_NOR_VERTICAL) {
143a3e0fd82Sopenharmony_ci        return UIView::OnRotateEvent(event);
144a3e0fd82Sopenharmony_ci    }
145a3e0fd82Sopenharmony_ci    return UIAbstractScroll::OnRotateEndEvent(event);
146a3e0fd82Sopenharmony_ci}
147a3e0fd82Sopenharmony_ci
148a3e0fd82Sopenharmony_ci#if defined(ENABLE_VIBRATOR) && ENABLE_VIBRATOR
149a3e0fd82Sopenharmony_civoid UIScrollView::SetIsEdge(bool& lastIsEdge, Rect childRect)
150a3e0fd82Sopenharmony_ci{
151a3e0fd82Sopenharmony_ci    if (direction_ == HORIZONTAL) {
152a3e0fd82Sopenharmony_ci        if (childRect.GetLeft() - scrollBlankSize_ >= 0 || childRect.GetRight() + scrollBlankSize_ <= GetWidth()) {
153a3e0fd82Sopenharmony_ci            lastIsEdge = true;
154a3e0fd82Sopenharmony_ci        }
155a3e0fd82Sopenharmony_ci    } else {
156a3e0fd82Sopenharmony_ci        if (childRect.GetTop() - scrollBlankSize_ >= 0 || childRect.GetBottom() + scrollBlankSize_ <= GetHeight()) {
157a3e0fd82Sopenharmony_ci            lastIsEdge = true;
158a3e0fd82Sopenharmony_ci        }
159a3e0fd82Sopenharmony_ci    }
160a3e0fd82Sopenharmony_ci}
161a3e0fd82Sopenharmony_ci#endif
162a3e0fd82Sopenharmony_ci#endif
163a3e0fd82Sopenharmony_ci
164a3e0fd82Sopenharmony_civoid UIScrollView::ScrollBy(int16_t xDistance, int16_t yDistance)
165a3e0fd82Sopenharmony_ci{
166a3e0fd82Sopenharmony_ci    if ((direction_ == HORIZONTAL || direction_ == HORIZONTAL_AND_VERTICAL) && xDistance != 0) {
167a3e0fd82Sopenharmony_ci        DragXInner(xDistance);
168a3e0fd82Sopenharmony_ci    }
169a3e0fd82Sopenharmony_ci    if ((direction_ == VERTICAL || direction_ == HORIZONTAL_AND_VERTICAL) && yDistance != 0) {
170a3e0fd82Sopenharmony_ci        DragYInner(yDistance);
171a3e0fd82Sopenharmony_ci    }
172a3e0fd82Sopenharmony_ci    if ((scrollListener_ != nullptr) && (scrollListener_->GetScrollState() == OnScrollListener::SCROLL_STATE_MOVE)) {
173a3e0fd82Sopenharmony_ci        scrollListener_->OnScrollEnd();
174a3e0fd82Sopenharmony_ci        scrollListener_->SetScrollState(OnScrollListener::SCROLL_STATE_STOP);
175a3e0fd82Sopenharmony_ci    }
176a3e0fd82Sopenharmony_ci}
177a3e0fd82Sopenharmony_ci
178a3e0fd82Sopenharmony_cibool UIScrollView::DragXInner(int16_t distance)
179a3e0fd82Sopenharmony_ci{
180a3e0fd82Sopenharmony_ci    Rect childRect = GetAllChildRelativeRect();
181a3e0fd82Sopenharmony_ci    int16_t reboundSize = reboundSize_;
182a3e0fd82Sopenharmony_ci    if (scrollAnimator_.GetState() != Animator::STOP) {
183a3e0fd82Sopenharmony_ci        reboundSize = 0;
184a3e0fd82Sopenharmony_ci    }
185a3e0fd82Sopenharmony_ci
186a3e0fd82Sopenharmony_ci    if (childRect.GetWidth() <= (GetWidth() - (scrollBlankSize_ << 1)) ||
187a3e0fd82Sopenharmony_ci        !(direction_ == HORIZONTAL || direction_ == HORIZONTAL_AND_VERTICAL)) {
188a3e0fd82Sopenharmony_ci        return false;
189a3e0fd82Sopenharmony_ci    }
190a3e0fd82Sopenharmony_ci
191a3e0fd82Sopenharmony_ci    if (distance > 0) {
192a3e0fd82Sopenharmony_ci        if (childRect.GetLeft() > scrollBlankSize_ + reboundSize) {
193a3e0fd82Sopenharmony_ci            distance = 0;
194a3e0fd82Sopenharmony_ci        } else if ((childRect.GetLeft() + distance) > scrollBlankSize_ + reboundSize) {
195a3e0fd82Sopenharmony_ci            distance = scrollBlankSize_ - childRect.GetLeft() + reboundSize;
196a3e0fd82Sopenharmony_ci        }
197a3e0fd82Sopenharmony_ci    } else {
198a3e0fd82Sopenharmony_ci        int16_t childRight = childRect.GetRight();
199a3e0fd82Sopenharmony_ci        int16_t scrollWidth = GetWidth();
200a3e0fd82Sopenharmony_ci        if (childRight < scrollWidth - (scrollBlankSize_ + reboundSize)) {
201a3e0fd82Sopenharmony_ci            distance = 0;
202a3e0fd82Sopenharmony_ci        } else if (childRight + distance < scrollWidth - (scrollBlankSize_ + reboundSize)) {
203a3e0fd82Sopenharmony_ci            distance = scrollWidth - (scrollBlankSize_ + reboundSize) - childRight - 1;
204a3e0fd82Sopenharmony_ci        }
205a3e0fd82Sopenharmony_ci    }
206a3e0fd82Sopenharmony_ci
207a3e0fd82Sopenharmony_ci    return MoveOffset(distance, 0);
208a3e0fd82Sopenharmony_ci}
209a3e0fd82Sopenharmony_ci
210a3e0fd82Sopenharmony_cibool UIScrollView::DragYInner(int16_t distance)
211a3e0fd82Sopenharmony_ci{
212a3e0fd82Sopenharmony_ci    Rect childRect = GetAllChildRelativeRect();
213a3e0fd82Sopenharmony_ci    int16_t reboundSize = reboundSize_;
214a3e0fd82Sopenharmony_ci    if (scrollAnimator_.GetState() != Animator::STOP) {
215a3e0fd82Sopenharmony_ci        reboundSize = 0;
216a3e0fd82Sopenharmony_ci    }
217a3e0fd82Sopenharmony_ci
218a3e0fd82Sopenharmony_ci    if (childRect.GetHeight() <= (GetHeight() - (scrollBlankSize_ << 1)) ||
219a3e0fd82Sopenharmony_ci        !(direction_ == VERTICAL || direction_ == HORIZONTAL_AND_VERTICAL)) {
220a3e0fd82Sopenharmony_ci        return false;
221a3e0fd82Sopenharmony_ci    }
222a3e0fd82Sopenharmony_ci
223a3e0fd82Sopenharmony_ci    if (distance > 0) {
224a3e0fd82Sopenharmony_ci        if (childRect.GetTop() > scrollBlankSize_ + reboundSize) {
225a3e0fd82Sopenharmony_ci            distance = 0;
226a3e0fd82Sopenharmony_ci        } else if ((childRect.GetTop() + distance) > scrollBlankSize_ + reboundSize) {
227a3e0fd82Sopenharmony_ci            distance = scrollBlankSize_ - childRect.GetTop() + reboundSize;
228a3e0fd82Sopenharmony_ci        }
229a3e0fd82Sopenharmony_ci    } else {
230a3e0fd82Sopenharmony_ci        int16_t childBottom = childRect.GetBottom();
231a3e0fd82Sopenharmony_ci        int16_t scrollHeight = GetHeight();
232a3e0fd82Sopenharmony_ci        if (childBottom < scrollHeight - (scrollBlankSize_ + reboundSize)) {
233a3e0fd82Sopenharmony_ci            distance = 0;
234a3e0fd82Sopenharmony_ci        } else if (childBottom + distance < scrollHeight - (scrollBlankSize_ + reboundSize)) {
235a3e0fd82Sopenharmony_ci            distance = scrollHeight - (scrollBlankSize_ + reboundSize) - childBottom - 1;
236a3e0fd82Sopenharmony_ci        }
237a3e0fd82Sopenharmony_ci    }
238a3e0fd82Sopenharmony_ci
239a3e0fd82Sopenharmony_ci    return MoveOffset(0, distance);
240a3e0fd82Sopenharmony_ci}
241a3e0fd82Sopenharmony_ci
242a3e0fd82Sopenharmony_cibool UIScrollView::MoveOffset(int16_t offsetX, int16_t offsetY)
243a3e0fd82Sopenharmony_ci{
244a3e0fd82Sopenharmony_ci    if ((offsetX != 0) || (offsetY != 0)) {
245a3e0fd82Sopenharmony_ci        if ((scrollListener_ != nullptr) &&
246a3e0fd82Sopenharmony_ci            (scrollListener_->GetScrollState() == OnScrollListener::SCROLL_STATE_STOP)) {
247a3e0fd82Sopenharmony_ci            scrollListener_->OnScrollStart();
248a3e0fd82Sopenharmony_ci            scrollListener_->SetScrollState(OnScrollListener::SCROLL_STATE_MOVE);
249a3e0fd82Sopenharmony_ci        }
250a3e0fd82Sopenharmony_ci        UIAbstractScroll::MoveChildByOffset(offsetX, offsetY);
251a3e0fd82Sopenharmony_ci        if (xScrollBarVisible_ || yScrollBarVisible_) {
252a3e0fd82Sopenharmony_ci            RefreshScrollBar();
253a3e0fd82Sopenharmony_ci        }
254a3e0fd82Sopenharmony_ci        Invalidate();
255a3e0fd82Sopenharmony_ci        return true;
256a3e0fd82Sopenharmony_ci    }
257a3e0fd82Sopenharmony_ci    return false;
258a3e0fd82Sopenharmony_ci}
259a3e0fd82Sopenharmony_ci
260a3e0fd82Sopenharmony_civoid UIScrollView::RefreshScrollBar()
261a3e0fd82Sopenharmony_ci{
262a3e0fd82Sopenharmony_ci    Rect childrenRect = GetAllChildRelativeRect();
263a3e0fd82Sopenharmony_ci    /* calculate scrollBar's the proportion of foreground */
264a3e0fd82Sopenharmony_ci    int16_t totalLen = childrenRect.GetHeight() + 2 * scrollBlankSize_; // 2: two blank space on both sizes
265a3e0fd82Sopenharmony_ci    int16_t len = GetHeight();
266a3e0fd82Sopenharmony_ci    if (yScrollBarVisible_) {
267a3e0fd82Sopenharmony_ci        yScrollBar_->SetForegroundProportion(static_cast<float>(len) / totalLen);
268a3e0fd82Sopenharmony_ci        /* calculate scrolling progress */
269a3e0fd82Sopenharmony_ci        yScrollBar_->SetScrollProgress(static_cast<float>(scrollBlankSize_ - childrenRect.GetTop()) / (totalLen - len));
270a3e0fd82Sopenharmony_ci    }
271a3e0fd82Sopenharmony_ci    if (xScrollBarVisible_) {
272a3e0fd82Sopenharmony_ci        /* so do x-bar */
273a3e0fd82Sopenharmony_ci        totalLen = childrenRect.GetWidth() + 2 * scrollBlankSize_; // 2: two blank space on both sizes
274a3e0fd82Sopenharmony_ci        len = GetWidth();
275a3e0fd82Sopenharmony_ci        xScrollBar_->SetForegroundProportion(static_cast<float>(len) / totalLen);
276a3e0fd82Sopenharmony_ci        xScrollBar_->SetScrollProgress(static_cast<float>(scrollBlankSize_ - childrenRect.GetLeft()) /
277a3e0fd82Sopenharmony_ci                                       (totalLen - len));
278a3e0fd82Sopenharmony_ci    }
279a3e0fd82Sopenharmony_ci    RefreshAnimator();
280a3e0fd82Sopenharmony_ci}
281a3e0fd82Sopenharmony_ci
282a3e0fd82Sopenharmony_civoid UIScrollView::CalculateReboundDistance(int16_t& dragDistanceX, int16_t& dragDistanceY)
283a3e0fd82Sopenharmony_ci{
284a3e0fd82Sopenharmony_ci    Rect rect = GetAllChildRelativeRect();
285a3e0fd82Sopenharmony_ci    int16_t top = rect.GetTop();
286a3e0fd82Sopenharmony_ci    int16_t bottom = rect.GetBottom();
287a3e0fd82Sopenharmony_ci    int16_t scrollHeight = GetHeight();
288a3e0fd82Sopenharmony_ci    int16_t left = rect.GetLeft();
289a3e0fd82Sopenharmony_ci    int16_t right = rect.GetRight();
290a3e0fd82Sopenharmony_ci    int16_t scrollWidth = GetWidth();
291a3e0fd82Sopenharmony_ci    if (scrollBlankSize_ < top) {
292a3e0fd82Sopenharmony_ci        dragDistanceY = scrollBlankSize_ - top;
293a3e0fd82Sopenharmony_ci    } else if (bottom < scrollHeight - 1) {
294a3e0fd82Sopenharmony_ci        dragDistanceY = scrollHeight - scrollBlankSize_ - bottom - 1;
295a3e0fd82Sopenharmony_ci    }
296a3e0fd82Sopenharmony_ci
297a3e0fd82Sopenharmony_ci    if (scrollBlankSize_ < left) {
298a3e0fd82Sopenharmony_ci        dragDistanceX = scrollBlankSize_ - left;
299a3e0fd82Sopenharmony_ci    } else if (right < scrollWidth - 1) {
300a3e0fd82Sopenharmony_ci        dragDistanceX = scrollWidth - scrollBlankSize_ - right - 1;
301a3e0fd82Sopenharmony_ci    }
302a3e0fd82Sopenharmony_ci}
303a3e0fd82Sopenharmony_ci
304a3e0fd82Sopenharmony_civoid UIScrollView::StopAnimator()
305a3e0fd82Sopenharmony_ci{
306a3e0fd82Sopenharmony_ci    if ((scrollListener_ != nullptr) && (scrollListener_->GetScrollState() == OnScrollListener::SCROLL_STATE_MOVE)) {
307a3e0fd82Sopenharmony_ci        scrollListener_->OnScrollEnd();
308a3e0fd82Sopenharmony_ci        scrollListener_->SetScrollState(OnScrollListener::SCROLL_STATE_STOP);
309a3e0fd82Sopenharmony_ci    }
310a3e0fd82Sopenharmony_ci    UIAbstractScroll::StopAnimator();
311a3e0fd82Sopenharmony_ci}
312a3e0fd82Sopenharmony_ci} // namespace OHOS
313