void ScrollView::processAutoScrolling(float deltaTime) { // Make auto scroll shorter if it needs to deaccelerate. float brakingFactor = (isNecessaryAutoScrollBrake() ? OUT_OF_BOUNDARY_BREAKING_FACTOR : 1); // Elapsed time _autoScrollAccumulatedTime += deltaTime * (1 / brakingFactor); // Calculate the progress percentage float percentage = MIN(1, _autoScrollAccumulatedTime / _autoScrollTotalTime); if(_autoScrollAttenuate) { // Use quintic(5th degree) polynomial percentage = tweenfunc::quintEaseOut(percentage); } // Calculate the new position Vec2 newPosition = _autoScrollStartPosition + (_autoScrollTargetDelta * percentage); bool reachedEnd = std::abs(percentage - 1) <= this->getAutoScrollStopEpsilon(); if (reachedEnd) { newPosition = _autoScrollStartPosition + _autoScrollTargetDelta; } if(_bounceEnabled) { // The new position is adjusted if out of boundary newPosition = _autoScrollBrakingStartPosition + (newPosition - _autoScrollBrakingStartPosition) * brakingFactor; } else { // Don't let go out of boundary Vec2 moveDelta = newPosition - getInnerContainerPosition(); Vec2 outOfBoundary = getHowMuchOutOfBoundary(moveDelta); if (!fltEqualZero(outOfBoundary)) { newPosition += outOfBoundary; reachedEnd = true; } } // Finish auto scroll if it ended if(reachedEnd) { _autoScrolling = false; dispatchEvent(SCROLLVIEW_EVENT_AUTOSCROLL_ENDED, EventType::AUTOSCROLL_ENDED); } moveInnerContainer(newPosition - getInnerContainerPosition(), reachedEnd); }
void ScrollView::scrollChildren(const Vec2& deltaMove) { Vec2 realMove = deltaMove; if(_bounceEnabled) { // If the position of the inner container is out of the boundary, the offsets should be divided by two. Vec2 outOfBoundary = getHowMuchOutOfBoundary(); realMove.x *= (outOfBoundary.x == 0 ? 1 : 0.5f); realMove.y *= (outOfBoundary.y == 0 ? 1 : 0.5f); } if(!_bounceEnabled) { Vec2 outOfBoundary = getHowMuchOutOfBoundary(realMove); realMove += outOfBoundary; } bool scrolledToLeft = false; bool scrolledToRight = false; bool scrolledToTop = false; bool scrolledToBottom = false; if (realMove.y > 0.0f) // up { float icBottomPos = _innerContainer->getBottomBoundary(); if (icBottomPos + realMove.y >= _bottomBoundary) { scrolledToBottom = true; } } else if (realMove.y < 0.0f) // down { float icTopPos = _innerContainer->getTopBoundary(); if (icTopPos + realMove.y <= _topBoundary) { scrolledToTop = true; } } if (realMove.x < 0.0f) // left { float icRightPos = _innerContainer->getRightBoundary(); if (icRightPos + realMove.x <= _rightBoundary) { scrolledToRight = true; } } else if (realMove.x > 0.0f) // right { float icLeftPos = _innerContainer->getLeftBoundary(); if (icLeftPos + realMove.x >= _leftBoundary) { scrolledToLeft = true; } } moveInnerContainer(realMove, false); if(realMove.x != 0 || realMove.y != 0) { processScrollingEvent(); } if(scrolledToBottom) { processScrollEvent(MoveDirection::BOTTOM, false); } if(scrolledToTop) { processScrollEvent(MoveDirection::TOP, false); } if(scrolledToLeft) { processScrollEvent(MoveDirection::LEFT, false); } if(scrolledToRight) { processScrollEvent(MoveDirection::RIGHT, false); } }
void ScrollView::jumpToDestination(const Vec2 &des) { _autoScrolling = false; moveInnerContainer(des - getInnerContainerPosition(), true); }