Files
graphic_ui/frameworks/components/ui_abstract_scroll.cpp
T
2021-03-11 18:38:06 +08:00

182 lines
5.6 KiB
C++
Executable File

/*
* 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.
*/
#include "components/ui_abstract_scroll.h"
namespace OHOS {
UIAbstractScroll::UIAbstractScroll()
: scrollBlankSize_(0),
reboundSize_(0),
maxScrollDistance_(0),
lastDeltaY_{0},
dragAccCoefficient_(DRAG_ACC_FACTOR),
swipeAccCoefficient_(0),
direction_(VERTICAL),
deltaYIndex_(0),
reserve_(0),
throwDrag_(false),
easingFunc_(EasingEquation::CubicEaseOut),
scrollAnimator_(&animatorCallback_, this, 0, true)
{
#if ENABLE_ROTATE_INPUT
rotateFactor_ = 1;
rotateThreshold_ = 1;
#endif
isViewGroup_ = true;
touchable_ = true;
draggable_ = true;
dragParentInstead_ = false;
AnimatorManager::GetInstance()->Add(&scrollAnimator_);
}
UIAbstractScroll::~UIAbstractScroll()
{
scrollAnimator_.Stop();
AnimatorManager::GetInstance()->Remove(&scrollAnimator_);
}
void UIAbstractScroll::MoveChildByOffset(int16_t offsetX, int16_t offsetY)
{
if ((offsetX == 0) && (offsetY == 0)) {
return;
}
UIView* view = GetChildrenHead();
int16_t x;
int16_t y;
while (view != nullptr) {
x = view->GetX() + offsetX;
y = view->GetY() + offsetY;
view->SetPosition(x, y);
view = view->GetNextSibling();
}
Invalidate();
}
int16_t UIAbstractScroll::GetMaxDeltaY() const
{
int16_t result = 0;
for (int16_t i = 0; i < MAX_DELTA_Y_SIZE; i++) {
if (result < MATH_ABS(lastDeltaY_[i])) {
result = MATH_ABS(lastDeltaY_[i]);
}
}
return result;
}
void UIAbstractScroll::StopAnimator()
{
scrollAnimator_.Stop();
animatorCallback_.RsetCallback();
isDragging_ = false;
}
bool UIAbstractScroll::DragThrowAnimator(Point currentPos, Point lastPos)
{
if (!throwDrag_ && (reboundSize_ == 0)) {
return false;
}
int16_t dragDistanceX = 0;
int16_t dragDistanceY = 0;
if (throwDrag_) {
CalculateDragDistance(currentPos, lastPos, dragDistanceX, dragDistanceY);
}
if (reboundSize_ != 0) {
CalculateReboundDistance(dragDistanceX, dragDistanceY);
}
StartAnimator(dragDistanceX, dragDistanceY);
return true;
}
void UIAbstractScroll::StartAnimator(int16_t dragDistanceX, int16_t dragDistanceY)
{
int16_t dragTimes = MATH_MAX(MATH_ABS(dragDistanceX), MATH_ABS(dragDistanceY)) / DRAG_TIMES_COEFFICIENT;
if (dragTimes < MIN_DRAG_TIMES) {
dragTimes = MIN_DRAG_TIMES;
}
animatorCallback_.SetDragStartValue(0, 0);
animatorCallback_.SetDragEndValue(dragDistanceX, dragDistanceY);
animatorCallback_.SetDragTimes(dragTimes * DRAG_ACC_FACTOR / GetDragACCLevel());
scrollAnimator_.Start();
}
void UIAbstractScroll::CalculateDragDistance(Point currentPos,
Point lastPos,
int16_t& dragDistanceX,
int16_t& dragDistanceY)
{
if ((direction_ == VERTICAL) || (direction_ == HORIZONTAL_AND_VERTICAL)) {
dragDistanceY = (currentPos.y - lastPos.y) * DRAG_DISTANCE_COEFFICIENT;
if (dragDistanceY > 0) {
dragDistanceY += GetMaxDeltaY() * GetSwipeACCLevel() / DRAG_ACC_FACTOR;
} else {
dragDistanceY -= GetMaxDeltaY() * GetSwipeACCLevel() / DRAG_ACC_FACTOR;
}
}
if ((direction_ == HORIZONTAL) || (direction_ == HORIZONTAL_AND_VERTICAL)) {
dragDistanceX = (currentPos.x - lastPos.x) * DRAG_DISTANCE_COEFFICIENT;
}
if (maxScrollDistance_ != 0) {
if (MATH_ABS(dragDistanceY) > maxScrollDistance_) {
int16_t calculatedValue = (dragDistanceY > 0) ? 1 : -1;
dragDistanceY = calculatedValue * maxScrollDistance_;
}
if (MATH_ABS(dragDistanceX) > maxScrollDistance_) {
int16_t calculatedValue = (dragDistanceX > 0) ? 1 : -1;
dragDistanceX = calculatedValue * maxScrollDistance_;
}
}
}
void UIAbstractScroll::ListAnimatorCallback::Callback(UIView* view)
{
if (view == nullptr) {
return;
}
curtTime_++;
UIAbstractScroll* scrollView = static_cast<UIAbstractScroll*>(view);
scrollView->isDragging_ = true;
if (curtTime_ <= dragTimes_) {
bool needStopX = false;
bool needStopY = false;
if (startValueY_ != endValueY_) {
int16_t actY = scrollView->easingFunc_(startValueY_, endValueY_, curtTime_, dragTimes_);
if (!scrollView->DragYInner(actY - previousValueY_)) {
needStopY = true;
}
previousValueY_ = actY;
} else {
needStopY = true;
}
if (startValueX_ != endValueX_) {
int16_t actX = scrollView->easingFunc_(startValueX_, endValueX_, curtTime_, dragTimes_);
if (!scrollView->DragXInner(actX - previousValueX_)) {
needStopX = true;
}
previousValueX_ = actX;
} else {
needStopX = true;
}
if (needStopX && needStopY) {
scrollView->StopAnimator();
}
} else {
scrollView->StopAnimator();
}
}
} // namespace OHOS