From c70c923674208cf17f4c7c59544dbf1e5b3b1d33 Mon Sep 17 00:00:00 2001 From: Neo Kim Date: Sun, 21 Jun 2015 18:22:21 +0900 Subject: [PATCH 1/4] Separate the inertia scroll from auto scroll. And implement auto scroll and bounce back as one logic. The bounce back movement is one of auto scroll feature. --- cocos/ui/UIScrollView.cpp | 613 ++++++++++++++++++++------------------ cocos/ui/UIScrollView.h | 63 ++-- 2 files changed, 352 insertions(+), 324 deletions(-) diff --git a/cocos/ui/UIScrollView.cpp b/cocos/ui/UIScrollView.cpp index 3744984268..3c731e54a5 100644 --- a/cocos/ui/UIScrollView.cpp +++ b/cocos/ui/UIScrollView.cpp @@ -25,6 +25,8 @@ THE SOFTWARE. #include "ui/UIScrollView.h" #include "2d/CCTweenFunction.h" +#include "CCDirector.h" + NS_CC_BEGIN namespace ui { @@ -55,6 +57,13 @@ char* time() snprintf(LOG_BUFFER + nCurrentLength, nBufferLength - nCurrentLength, ".%03ld", lMilliseconds); return LOG_BUFFER; } + +inline long long getTimestamp() +{ + struct timeval tv; + gettimeofday (&tv, NULL); + return tv.tv_sec * 1000 + tv.tv_usec / 1000; +} const Vec2 SCROLLDIR_UP(0.0f, 1.0f); const Vec2 SCROLLDIR_DOWN(0.0f, -1.0f); @@ -70,21 +79,22 @@ _topBoundary(0.0f), _bottomBoundary(0.0f), _leftBoundary(0.0f), _rightBoundary(0.0f), -_autoScroll(false), -_autoScrollAddUpTime(0.0f), -_autoScrollOriginalSpeed(0.0f), -_autoScrollAcceleration(-1000.0f), -_isAutoScrollSpeedAttenuated(false), -_needCheckAutoScrollDestination(false), +_inertiaScrollEnabled(true), +_inertiaScrolling(false), +//_inertiaScrollAddUpTime(0.0f), +//_inertiaScrollOriginalSpeed(0.0f), +//_inertiaScrollAcceleration(-1000.0f), +//_inertiaScrollSpeedAttenuated(false), +//_needCheckInertiaScrollDestination(false), _bePressed(false), _slidTime(0.0f), _childFocusCancelOffset(5.0f), +_autoScrolling(false), _bounceEnabled(false), _bouncingBack(false), -_bounceBackAttenuate(true), -_bounceBackDuration(0), -_bounceBackAccumulatedTime(0), -_inertiaScrollEnabled(true), +_autoScrollAttenuate(true), +_autoScrollDuration(0), +_autoScrollAccumulatedTime(0), _scrollViewEventListener(nullptr), _scrollViewEventSelector(nullptr), _eventCallback(nullptr) @@ -289,54 +299,54 @@ void ScrollView::moveChildren(float offsetX, float offsetY) _innerContainer->setPosition(position); } -void ScrollView::autoScrollChildren(float dt) +void ScrollView::inertiaScrollChildren(float dt) { - float lastTime = _autoScrollAddUpTime; - _autoScrollAddUpTime += dt; - if (_isAutoScrollSpeedAttenuated) - { - float nowSpeed = _autoScrollOriginalSpeed + _autoScrollAcceleration * _autoScrollAddUpTime; - if (nowSpeed <= 0.0f) - { - stopAutoScrollChildren(); - startBounceBackIfNeeded(); - } - else - { - float timeParam = lastTime * 2 + dt; - float offset = (_autoScrollOriginalSpeed + _autoScrollAcceleration * timeParam * 0.5f) * dt; - float offsetX = offset * _autoScrollDir.x; - float offsetY = offset * _autoScrollDir.y; - if (!scrollChildren(offsetX, offsetY)) - { - stopAutoScrollChildren(); - startBounceBackIfNeeded(); - } - } - } - else - { - if (_needCheckAutoScrollDestination) - { - float xOffset = _autoScrollDir.x * dt * _autoScrollOriginalSpeed; - float yOffset = _autoScrollDir.y * dt * _autoScrollOriginalSpeed; - bool notDone = checkCustomScrollDestination(&xOffset, &yOffset); - bool scrollCheck = scrollChildren(xOffset, yOffset); - if (!notDone || !scrollCheck) - { - stopAutoScrollChildren(); - startBounceBackIfNeeded(); - } - } - else - { - if (!scrollChildren(_autoScrollDir.x * dt * _autoScrollOriginalSpeed, _autoScrollDir.y * dt * _autoScrollOriginalSpeed)) - { - stopAutoScrollChildren(); - startBounceBackIfNeeded(); - } - } - } +// float lastTime = _inertiaScrollAddUpTime; +// _inertiaScrollAddUpTime += dt; +// if (_inertiaScrollSpeedAttenuated) +// { +// float nowSpeed = _inertiaScrollOriginalSpeed + _inertiaScrollAcceleration * _inertiaScrollAddUpTime; +// if (nowSpeed <= 0.0f) +// { +// stopInertiaScroll(); +// startBounceBackIfNeeded(); +// } +// else +// { +// float timeParam = lastTime * 2 + dt; +// float offset = (_inertiaScrollOriginalSpeed + _inertiaScrollAcceleration * timeParam * 0.5f) * dt; +// float offsetX = offset * _inertiaScrollDir.x; +// float offsetY = offset * _inertiaScrollDir.y; +// if (!scrollChildren(offsetX, offsetY)) +// { +// stopInertiaScroll(); +// startBounceBackIfNeeded(); +// } +// } +// } +// else +// { +// if (_needCheckInertiaScrollDestination) +// { +// float xOffset = _inertiaScrollDir.x * dt * _inertiaScrollOriginalSpeed; +// float yOffset = _inertiaScrollDir.y * dt * _inertiaScrollOriginalSpeed; +// bool notDone = checkCustomScrollDestination(&xOffset, &yOffset); +// bool scrollCheck = scrollChildren(xOffset, yOffset); +// if (!notDone || !scrollCheck) +// { +// stopInertiaScroll(); +// startBounceBackIfNeeded(); +// } +// } +// else +// { +// if (!scrollChildren(_inertiaScrollDir.x * dt * _inertiaScrollOriginalSpeed, _inertiaScrollDir.y * dt * _inertiaScrollOriginalSpeed)) +// { +// stopInertiaScroll(); +// startBounceBackIfNeeded(); +// } +// } +// } } bool ScrollView::startBounceBackIfNeeded() @@ -346,18 +356,14 @@ bool ScrollView::startBounceBackIfNeeded() return false; } - _bounceBackTargetDelta = getHowMuchOutOfBoundary(Vec2::ZERO); - if(_bounceBackTargetDelta == Vec2::ZERO) + Vec2 outOfBoundary = getHowMuchOutOfBoundary(Vec2::ZERO); + if(outOfBoundary == Vec2::ZERO) { return false; } _bouncingBack = true; - _bounceBackAttenuate = true; - _bounceBackStartPosition = _innerContainer->getPosition(); - _bounceBackDuration = DEFAULT_BOUNCE_BACK_DURATION; - _bounceBackAccumulatedTime = 0; - + startAutoScroll(outOfBoundary, BOUNCE_BACK_DURATION, true); return true; } @@ -385,41 +391,48 @@ Vec2 ScrollView::getHowMuchOutOfBoundary(const Vec2& addition) const return result; } -void ScrollView::processBounceBack(float deltaTime) +void ScrollView::processAutoScrolling(float deltaTime) { - _bounceBackAccumulatedTime += deltaTime; - float percentage = _bounceBackAccumulatedTime / _bounceBackDuration; + CCLOG("%s : processAutoScrolling()", time()); + _autoScrollAccumulatedTime += deltaTime; + float percentage = _autoScrollAccumulatedTime / _autoScrollDuration; if(percentage >= 1) { - _innerContainer->setPosition(_bounceBackStartPosition + _bounceBackTargetDelta); + _innerContainer->setPosition(_autoScrollStartPosition + _autoScrollTargetDelta); + _autoScrolling = false; _bouncingBack = false; } else { - if(_bounceBackAttenuate) + if(_autoScrollAttenuate) { percentage = tweenfunc::expoEaseOut(percentage); } - Vec2 moveDelta = _bounceBackTargetDelta * percentage; + Vec2 moveDelta = _autoScrollTargetDelta * percentage; - // Dispatch related events - if(moveDelta.x > 0) + // Dispatch related events if bouncing + if(_bouncingBack) { - processScrollEvent(MoveDirection::RIGHT, true); + if(moveDelta.x > 0) + { + processScrollEvent(MoveDirection::RIGHT, true); + } + else if(moveDelta.x < 0) + { + processScrollEvent(MoveDirection::LEFT, true); + } + if(moveDelta.y > 0) + { + processScrollEvent(MoveDirection::TOP, true); + } + else if(moveDelta.y < 0) + { + processScrollEvent(MoveDirection::BOTTOM, true); + } } - else if(moveDelta.x < 0) - { - processScrollEvent(MoveDirection::LEFT, true); - } - if(moveDelta.y > 0) - { - processScrollEvent(MoveDirection::TOP, true); - } - else if(moveDelta.y < 0) - { - processScrollEvent(MoveDirection::BOTTOM, true); - } - _innerContainer->setPosition(_bounceBackStartPosition + moveDelta); + + CCLOG("%s : processAutoScrolling() _autoScrollStartPosition(%0.2f,%0.2f), moveDelta(%0.2f,%0.2f)", time(), _autoScrollStartPosition.x, _autoScrollStartPosition.y, moveDelta.x, moveDelta.y); + _innerContainer->setPosition(_autoScrollStartPosition + moveDelta); } } @@ -444,35 +457,21 @@ bool ScrollView::isOutOfBoundaryLeftOrRight() const return isOutOfBoundary(MoveDirection::LEFT) || isOutOfBoundary(MoveDirection::RIGHT); } -void ScrollView::startAutoScrollChildrenWithOriginalSpeed(const Vec2& dir, float v, bool attenuated, float acceleration) +void ScrollView::startAutoScroll(const Vec2& deltaMove, float duration, bool attenuated) { - stopAutoScrollChildren(); - _autoScrollDir = dir; - _isAutoScrollSpeedAttenuated = attenuated; - _autoScrollOriginalSpeed = v; - _autoScroll = true; - _autoScrollAcceleration = acceleration; + CCLOG("%s : startAutoScroll() deltaMove(%0.2f, %0.2f), duration=%0.2f, attenuated=%d", time(), deltaMove.x, deltaMove.y, duration, attenuated); + + _autoScrolling = true; + _autoScrollTargetDelta = deltaMove; + _autoScrollAttenuate = attenuated; + _autoScrollStartPosition = _innerContainer->getPosition(); + _autoScrollDuration = duration; + _autoScrollAccumulatedTime = 0; } void ScrollView::startAutoScrollChildrenWithDestination(const Vec2& des, float second, bool attenuated) { - _needCheckAutoScrollDestination = false; - _autoScrollDestination = des; - Vec2 dis = des - _innerContainer->getPosition(); - Vec2 dir = dis.getNormalized(); - float orSpeed = 0.0f; - float acceleration = -1000.0f; - if (attenuated) - { - acceleration = (-(2 * dis.getLength())) / (second * second); - orSpeed = 2 * dis.getLength() / second; - } - else - { - _needCheckAutoScrollDestination = true; - orSpeed = dis.getLength() / second; - } - startAutoScrollChildrenWithOriginalSpeed(dir, orSpeed, attenuated, acceleration); + startAutoScroll(des - _innerContainer->getPosition(), second, attenuated); } void ScrollView::jumpToDestination(const Vec2 &des) @@ -490,138 +489,192 @@ void ScrollView::jumpToDestination(const Vec2 &des) _innerContainer->setPosition(Vec2(finalOffsetX, finalOffsetY)); } -void ScrollView::stopAutoScrollChildren() +void ScrollView::startInertiaScroll() { - _autoScroll = false; - _autoScrollOriginalSpeed = 0.0f; - _autoScrollAddUpTime = 0.0f; + _inertiaScrolling = true; + + // Get the initial velocity + _inertiaVelocity; + CCLOG("%s : startInertiaScroll() startVelocity(%0.2f, %0.2f)", time(), _inertiaVelocity.x, _inertiaVelocity.y); + + + +// { +// if (_slidTime <= 0.016f) +// { +// return; +// } +// float totalDis = 0.0f; +// Vec2 dir; +// Vec2 touchEndPositionInNodeSpace = this->convertToNodeSpace(_touchEndPosition); +// Vec2 touchBeganPositionInNodeSpace = this->convertToNodeSpace(_touchBeganPosition); +// switch (_direction) +// { +// case Direction::VERTICAL: +// totalDis = touchEndPositionInNodeSpace.y - touchBeganPositionInNodeSpace.y; +// if (totalDis < 0.0f) +// { +// dir = SCROLLDIR_DOWN; +// } +// else +// { +// dir = SCROLLDIR_UP; +// } +// break; +// case Direction::HORIZONTAL: +// totalDis = touchEndPositionInNodeSpace.x - touchBeganPositionInNodeSpace.x; +// if (totalDis < 0.0f) +// { +// dir = SCROLLDIR_LEFT; +// } +// else +// { +// dir = SCROLLDIR_RIGHT; +// } +// break; +// case Direction::BOTH: +// { +// Vec2 subVector = touchEndPositionInNodeSpace - touchBeganPositionInNodeSpace; +// totalDis = subVector.getLength(); +// dir = subVector.getNormalized(); +// break; +// } +// default: +// break; +// } +// float orSpeed = MIN(fabs(totalDis)/(_slidTime), AUTOSCROLLMAXSPEED); +// // startAutoScroll(dir, orSpeed, true); +// _slidTime = 0.0f; +// } + + } -bool ScrollView::checkCustomScrollDestinationLeft(float* touchOffsetX, float* touchOffsetY) -{ - float icLeftPos = _innerContainer->getLeftBoundary(); - if (icLeftPos + *touchOffsetX >= _autoScrollDestination.x) - { - *touchOffsetX = _autoScrollDestination.x - icLeftPos; - return false; - } - return true; -} - -bool ScrollView::checkCustomScrollDestinationRight(float* touchOffsetX, float* touchOffsetY) -{ - float icRightPos = _innerContainer->getRightBoundary(); - if (icRightPos + *touchOffsetX <= _autoScrollDestination.x) - { - *touchOffsetX = _autoScrollDestination.x - icRightPos; - return false; - } - return true; -} - -bool ScrollView::checkCustomScrollDestination(float* touchOffsetX, float* touchOffsetY) -{ - bool scrollenabled = true; - switch (_direction) - { - case Direction::VERTICAL: - { - if (_autoScrollDir.y > 0) - { - float icBottomPos = _innerContainer->getBottomBoundary(); - if (icBottomPos + *touchOffsetY >= _autoScrollDestination.y) - { - *touchOffsetY = _autoScrollDestination.y - icBottomPos; - scrollenabled = false; - } - } - else - { - float icBottomPos = _innerContainer->getBottomBoundary(); - if (icBottomPos + *touchOffsetY <= _autoScrollDestination.y) - { - *touchOffsetY = _autoScrollDestination.y - icBottomPos; - scrollenabled = false; - } - } - break; - } - case Direction::HORIZONTAL: - { - if (_autoScrollDir.x > 0) - { - float icLeftPos = _innerContainer->getLeftBoundary(); - if (icLeftPos + *touchOffsetX >= _autoScrollDestination.x) - { - *touchOffsetX = _autoScrollDestination.x - icLeftPos; - scrollenabled = false; - } - } - else - { - float icLeftPos = _innerContainer->getLeftBoundary(); - if (icLeftPos + *touchOffsetX <= _autoScrollDestination.x) - { - *touchOffsetX = _autoScrollDestination.x - icLeftPos; - scrollenabled = false; - } - } - break; - } - case Direction::BOTH: - { - if (*touchOffsetY > 0.0f) // up - { - if (*touchOffsetX > 0.0f) // right - { - scrollenabled = checkCustomScrollDestinationLeft(touchOffsetX, touchOffsetY); - } - else if (*touchOffsetX < 0.0f) // left - { - scrollenabled = checkCustomScrollDestinationRight(touchOffsetX, touchOffsetY); - } - float icBottomPos = _innerContainer->getBottomBoundary(); - if (icBottomPos + *touchOffsetY >= _autoScrollDestination.y) - { - *touchOffsetY = _autoScrollDestination.y - icBottomPos; - scrollenabled = false; - } - } - else if (*touchOffsetY < 0.0f) // down - { - if (*touchOffsetX < 0.0f) // left - { - scrollenabled = checkCustomScrollDestinationRight(touchOffsetX, touchOffsetY); - } - else if (*touchOffsetX > 0.0f) // right - { - scrollenabled = checkCustomScrollDestinationLeft(touchOffsetX, touchOffsetY); - } - float icTopPos = _innerContainer->getTopBoundary(); - if (icTopPos + *touchOffsetY <= _autoScrollDestination.y) - { - *touchOffsetY = _autoScrollDestination.y - icTopPos; - scrollenabled = false; - } - } - else - { - if (*touchOffsetX < 0.0f) // left - { - scrollenabled = checkCustomScrollDestinationRight(touchOffsetX, touchOffsetY); - } - else if (*touchOffsetX > 0.0f) // right - { - scrollenabled = checkCustomScrollDestinationLeft(touchOffsetX, touchOffsetY); - } - } - break; - } - default: - break; - } - return scrollenabled; -} +//bool ScrollView::checkCustomScrollDestinationLeft(float* touchOffsetX, float* touchOffsetY) +//{ +// float icLeftPos = _innerContainer->getLeftBoundary(); +// if (icLeftPos + *touchOffsetX >= _inertiaScrollDestination.x) +// { +// *touchOffsetX = _inertiaScrollDestination.x - icLeftPos; +// return false; +// } +// return true; +//} +// +//bool ScrollView::checkCustomScrollDestinationRight(float* touchOffsetX, float* touchOffsetY) +//{ +// float icRightPos = _innerContainer->getRightBoundary(); +// if (icRightPos + *touchOffsetX <= _inertiaScrollDestination.x) +// { +// *touchOffsetX = _inertiaScrollDestination.x - icRightPos; +// return false; +// } +// return true; +//} +// +//bool ScrollView::checkCustomScrollDestination(float* touchOffsetX, float* touchOffsetY) +//{ +// bool scrollenabled = true; +// switch (_direction) +// { +// case Direction::VERTICAL: +// { +// if (_inertiaScrollDir.y > 0) +// { +// float icBottomPos = _innerContainer->getBottomBoundary(); +// if (icBottomPos + *touchOffsetY >= _inertiaScrollDestination.y) +// { +// *touchOffsetY = _inertiaScrollDestination.y - icBottomPos; +// scrollenabled = false; +// } +// } +// else +// { +// float icBottomPos = _innerContainer->getBottomBoundary(); +// if (icBottomPos + *touchOffsetY <= _inertiaScrollDestination.y) +// { +// *touchOffsetY = _inertiaScrollDestination.y - icBottomPos; +// scrollenabled = false; +// } +// } +// break; +// } +// case Direction::HORIZONTAL: +// { +// if (_inertiaScrollDir.x > 0) +// { +// float icLeftPos = _innerContainer->getLeftBoundary(); +// if (icLeftPos + *touchOffsetX >= _inertiaScrollDestination.x) +// { +// *touchOffsetX = _inertiaScrollDestination.x - icLeftPos; +// scrollenabled = false; +// } +// } +// else +// { +// float icLeftPos = _innerContainer->getLeftBoundary(); +// if (icLeftPos + *touchOffsetX <= _inertiaScrollDestination.x) +// { +// *touchOffsetX = _inertiaScrollDestination.x - icLeftPos; +// scrollenabled = false; +// } +// } +// break; +// } +// case Direction::BOTH: +// { +// if (*touchOffsetY > 0.0f) // up +// { +// if (*touchOffsetX > 0.0f) // right +// { +// scrollenabled = checkCustomScrollDestinationLeft(touchOffsetX, touchOffsetY); +// } +// else if (*touchOffsetX < 0.0f) // left +// { +// scrollenabled = checkCustomScrollDestinationRight(touchOffsetX, touchOffsetY); +// } +// float icBottomPos = _innerContainer->getBottomBoundary(); +// if (icBottomPos + *touchOffsetY >= _inertiaScrollDestination.y) +// { +// *touchOffsetY = _inertiaScrollDestination.y - icBottomPos; +// scrollenabled = false; +// } +// } +// else if (*touchOffsetY < 0.0f) // down +// { +// if (*touchOffsetX < 0.0f) // left +// { +// scrollenabled = checkCustomScrollDestinationRight(touchOffsetX, touchOffsetY); +// } +// else if (*touchOffsetX > 0.0f) // right +// { +// scrollenabled = checkCustomScrollDestinationLeft(touchOffsetX, touchOffsetY); +// } +// float icTopPos = _innerContainer->getTopBoundary(); +// if (icTopPos + *touchOffsetY <= _inertiaScrollDestination.y) +// { +// *touchOffsetY = _inertiaScrollDestination.y - icTopPos; +// scrollenabled = false; +// } +// } +// else +// { +// if (*touchOffsetX < 0.0f) // left +// { +// scrollenabled = checkCustomScrollDestinationRight(touchOffsetX, touchOffsetY); +// } +// else if (*touchOffsetX > 0.0f) // right +// { +// scrollenabled = checkCustomScrollDestinationLeft(touchOffsetX, touchOffsetY); +// } +// } +// break; +// } +// default: +// break; +// } +// return scrollenabled; +//} bool ScrollView::processScrollUp(float* offsetYResult, float touchOffsetY) { @@ -899,66 +952,23 @@ void ScrollView::jumpToPercentBothDirection(const Vec2& percent) void ScrollView::startRecordSlidAction() { - if (_autoScroll) + if (_inertiaScrolling) { - stopAutoScrollChildren(); + _inertiaScrolling = false; } - if (_bouncingBack) - { + if(_autoScrolling) + { + _autoScrolling = false; _bouncingBack = false; - } - _slidTime = 0.0f; + } } void ScrollView::endRecordSlidAction() { - if (!startBounceBackIfNeeded() && _inertiaScrollEnabled) - { - if (_slidTime <= 0.016f) - { - return; - } - float totalDis = 0.0f; - Vec2 dir; - Vec2 touchEndPositionInNodeSpace = this->convertToNodeSpace(_touchEndPosition); - Vec2 touchBeganPositionInNodeSpace = this->convertToNodeSpace(_touchBeganPosition); - switch (_direction) - { - case Direction::VERTICAL: - totalDis = touchEndPositionInNodeSpace.y - touchBeganPositionInNodeSpace.y; - if (totalDis < 0.0f) - { - dir = SCROLLDIR_DOWN; - } - else - { - dir = SCROLLDIR_UP; - } - break; - case Direction::HORIZONTAL: - totalDis = touchEndPositionInNodeSpace.x - touchBeganPositionInNodeSpace.x; - if (totalDis < 0.0f) - { - dir = SCROLLDIR_LEFT; - } - else - { - dir = SCROLLDIR_RIGHT; - } - break; - case Direction::BOTH: - { - Vec2 subVector = touchEndPositionInNodeSpace - touchBeganPositionInNodeSpace; - totalDis = subVector.getLength(); - dir = subVector.getNormalized(); - break; - } - default: - break; - } - float orSpeed = MIN(fabs(totalDis)/(_slidTime), AUTOSCROLLMAXSPEED); - startAutoScrollChildrenWithOriginalSpeed(dir, orSpeed, true, -1000); - _slidTime = 0.0f; + bool bounceBackStarted = startBounceBackIfNeeded(); + if(!bounceBackStarted && _inertiaScrollEnabled) + { + startInertiaScroll(); } } @@ -966,6 +976,7 @@ void ScrollView::handlePressLogic(Touch *touch) { startRecordSlidAction(); _bePressed = true; + _slidTime = 0; } void ScrollView::handleMoveLogic(Touch *touch) @@ -974,6 +985,12 @@ void ScrollView::handleMoveLogic(Touch *touch) Vec2 previousTouchPositionInNodeSpace = this->convertToNodeSpace(touch->getPreviousLocation()); Vec2 delta = touchPositionInNodeSpace - previousTouchPositionInNodeSpace; scrollChildren(delta.x, delta.y); + + struct timeval tv; + gettimeofday (&tv, NULL); + long long timestamp = tv.tv_sec * 1000 + tv.tv_usec / 1000; + + CCLOG("%s : handleMoveLogic() timestamp=%lld", time(), timestamp); } void ScrollView::handleReleaseLogic(Touch *touch) @@ -1026,13 +1043,14 @@ void ScrollView::onTouchCancelled(Touch *touch, Event *unusedEvent) void ScrollView::update(float dt) { - if (_autoScroll) + if (_inertiaScrolling) { - autoScrollChildren(dt); + inertiaScrollChildren(dt); } - if(_bouncingBack) + + if(_autoScrolling) { - processBounceBack(dt); + processAutoScrolling(dt); } recordSlidTime(dt); } @@ -1041,6 +1059,7 @@ void ScrollView::recordSlidTime(float dt) { if (_bePressed) { + CCLOG("%s : recordSlidTime() dt=%0.3f", time(), dt); _slidTime += dt; } } @@ -1085,7 +1104,7 @@ void ScrollView::interceptTouchEvent(Widget::TouchEventType event, Widget *sende void ScrollView::processScrollEvent(MoveDirection dir, bool bounce) { - CCLOG("processScrollEvent() %d", dir); + CCLOG("%s : processScrollEvent() dir=%d, bounce=%d", time(), dir, bounce); ScrollviewEventType scrollEventType; EventType eventType; switch(dir) { diff --git a/cocos/ui/UIScrollView.h b/cocos/ui/UIScrollView.h index e169d44a72..b4a9b65da0 100644 --- a/cocos/ui/UIScrollView.h +++ b/cocos/ui/UIScrollView.h @@ -27,6 +27,7 @@ THE SOFTWARE. #include "ui/UILayout.h" #include "ui/GUIExport.h" +#include NS_CC_BEGIN /** @@ -430,18 +431,22 @@ protected: bool isOutOfBoundaryLeftOrRight() const; void moveChildren(float offsetX, float offsetY); - void autoScrollChildren(float dt); - void startAutoScrollChildrenWithOriginalSpeed(const Vec2& dir, float v, bool attenuated, float acceleration); + + void startInertiaScroll(); + void inertiaScrollChildren(float dt); + + void startAutoScroll(const Vec2& deltaMove, float duration, bool attenuated); void startAutoScrollChildrenWithDestination(const Vec2& des, float second, bool attenuated); - void jumpToDestination(const Vec2& des); - void stopAutoScrollChildren(); + void jumpToDestination(const Vec2& des); + + void processAutoScrolling(float deltaTime); + bool startBounceBackIfNeeded(); - void processBounceBack(float deltaTime); - bool checkCustomScrollDestinationLeft(float* touchOffsetX, float* touchOffsetY); - bool checkCustomScrollDestinationRight(float* touchOffsetX, float* touchOffsetY); - bool checkCustomScrollDestination(float* touchOffsetX, float* touchOffsetY); +// bool checkCustomScrollDestinationLeft(float* touchOffsetX, float* touchOffsetY); +// bool checkCustomScrollDestinationRight(float* touchOffsetX, float* touchOffsetY); +// bool checkCustomScrollDestination(float* touchOffsetX, float* touchOffsetY); virtual bool scrollChildren(float touchOffsetX, float touchOffsetY); @@ -473,36 +478,40 @@ protected: Layout* _innerContainer; Direction _direction; - Vec2 _autoScrollDir; float _topBoundary; float _bottomBoundary; float _leftBoundary; float _rightBoundary; + + bool _inertiaScrollEnabled; + bool _inertiaScrolling; + Vec2 _inertiaVelocity; + std::list _slidMovements; + +// Vec2 _inertiaScrollDir; +// float _inertiaScrollAddUpTime; - bool _autoScroll; - float _autoScrollAddUpTime; - - float _autoScrollOriginalSpeed; - float _autoScrollAcceleration; - bool _isAutoScrollSpeedAttenuated; - bool _needCheckAutoScrollDestination; - Vec2 _autoScrollDestination; +// float _inertiaScrollOriginalSpeed; +// float _inertiaScrollAcceleration; +// bool _inertiaScrollSpeedAttenuated; +// bool _needCheckInertiaScrollDestination; +// Vec2 _inertiaScrollDestination; bool _bePressed; float _slidTime; float _childFocusCancelOffset; - - bool _bounceEnabled; - bool _bouncingBack; - bool _bounceBackAttenuate; - Vec2 _bounceBackStartPosition; - Vec2 _bounceBackTargetDelta; - float _bounceBackDuration; - float _bounceBackAccumulatedTime; - bool _inertiaScrollEnabled; - + bool _bounceEnabled; + bool _bouncingBack; + + bool _autoScrolling; + bool _autoScrollAttenuate; + Vec2 _autoScrollStartPosition; + Vec2 _autoScrollTargetDelta; + float _autoScrollDuration; + float _autoScrollAccumulatedTime; + Ref* _scrollViewEventListener; #if defined(__GNUC__) && ((__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1))) #pragma GCC diagnostic ignored "-Wdeprecated-declarations" From c4fa99444cd0084b59a5499127a4239e4b5cd416 Mon Sep 17 00:00:00 2001 From: Neo Kim Date: Mon, 22 Jun 2015 11:38:16 +0900 Subject: [PATCH 2/4] Simplify the inertia scroll implementation --- cocos/ui/UIScrollView.cpp | 350 ++++++++++---------------------------- cocos/ui/UIScrollView.h | 40 ++--- 2 files changed, 99 insertions(+), 291 deletions(-) diff --git a/cocos/ui/UIScrollView.cpp b/cocos/ui/UIScrollView.cpp index 3c731e54a5..6094cc5310 100644 --- a/cocos/ui/UIScrollView.cpp +++ b/cocos/ui/UIScrollView.cpp @@ -31,11 +31,9 @@ NS_CC_BEGIN namespace ui { -static const float AUTOSCROLLMAXSPEED = 1000.0f; - +static const float INERTIA_DEACCELERATION = 6000.0f; static const float BOUNCE_BACK_DURATION = 0.3f; - static char LOG_BUFFER[256]; char* time() { @@ -58,18 +56,13 @@ char* time() return LOG_BUFFER; } -inline long long getTimestamp() +static long long getTimestamp() { struct timeval tv; gettimeofday (&tv, NULL); return tv.tv_sec * 1000 + tv.tv_usec / 1000; } -const Vec2 SCROLLDIR_UP(0.0f, 1.0f); -const Vec2 SCROLLDIR_DOWN(0.0f, -1.0f); -const Vec2 SCROLLDIR_LEFT(-1.0f, 0.0f); -const Vec2 SCROLLDIR_RIGHT(1.0f, 0.0f); - IMPLEMENT_CLASS_GUI_INFO(ScrollView) ScrollView::ScrollView(): @@ -79,22 +72,17 @@ _topBoundary(0.0f), _bottomBoundary(0.0f), _leftBoundary(0.0f), _rightBoundary(0.0f), +_bePressed(false), +_childFocusCancelOffset(5.0f), _inertiaScrollEnabled(true), _inertiaScrolling(false), -//_inertiaScrollAddUpTime(0.0f), -//_inertiaScrollOriginalSpeed(0.0f), -//_inertiaScrollAcceleration(-1000.0f), -//_inertiaScrollSpeedAttenuated(false), -//_needCheckInertiaScrollDestination(false), -_bePressed(false), -_slidTime(0.0f), -_childFocusCancelOffset(5.0f), +_inertiaPrevTouchTimestamp(0), _autoScrolling(false), -_bounceEnabled(false), -_bouncingBack(false), _autoScrollAttenuate(true), _autoScrollDuration(0), _autoScrollAccumulatedTime(0), +_bounceEnabled(false), +_bouncingBack(false), _scrollViewEventListener(nullptr), _scrollViewEventSelector(nullptr), _eventCallback(nullptr) @@ -299,56 +287,6 @@ void ScrollView::moveChildren(float offsetX, float offsetY) _innerContainer->setPosition(position); } -void ScrollView::inertiaScrollChildren(float dt) -{ -// float lastTime = _inertiaScrollAddUpTime; -// _inertiaScrollAddUpTime += dt; -// if (_inertiaScrollSpeedAttenuated) -// { -// float nowSpeed = _inertiaScrollOriginalSpeed + _inertiaScrollAcceleration * _inertiaScrollAddUpTime; -// if (nowSpeed <= 0.0f) -// { -// stopInertiaScroll(); -// startBounceBackIfNeeded(); -// } -// else -// { -// float timeParam = lastTime * 2 + dt; -// float offset = (_inertiaScrollOriginalSpeed + _inertiaScrollAcceleration * timeParam * 0.5f) * dt; -// float offsetX = offset * _inertiaScrollDir.x; -// float offsetY = offset * _inertiaScrollDir.y; -// if (!scrollChildren(offsetX, offsetY)) -// { -// stopInertiaScroll(); -// startBounceBackIfNeeded(); -// } -// } -// } -// else -// { -// if (_needCheckInertiaScrollDestination) -// { -// float xOffset = _inertiaScrollDir.x * dt * _inertiaScrollOriginalSpeed; -// float yOffset = _inertiaScrollDir.y * dt * _inertiaScrollOriginalSpeed; -// bool notDone = checkCustomScrollDestination(&xOffset, &yOffset); -// bool scrollCheck = scrollChildren(xOffset, yOffset); -// if (!notDone || !scrollCheck) -// { -// stopInertiaScroll(); -// startBounceBackIfNeeded(); -// } -// } -// else -// { -// if (!scrollChildren(_inertiaScrollDir.x * dt * _inertiaScrollOriginalSpeed, _inertiaScrollDir.y * dt * _inertiaScrollOriginalSpeed)) -// { -// stopInertiaScroll(); -// startBounceBackIfNeeded(); -// } -// } -// } -} - bool ScrollView::startBounceBackIfNeeded() { if (!_bounceEnabled) @@ -491,190 +429,76 @@ void ScrollView::jumpToDestination(const Vec2 &des) void ScrollView::startInertiaScroll() { + if(_inertiaTouchTimeDeltas.empty()) + { + return; + } + + float totalDuration = 0; + for(auto i = _inertiaTouchTimeDeltas.begin(); i != _inertiaTouchTimeDeltas.end(); ++i) + { + totalDuration += (*i); + } + if(totalDuration >= 0.5f) + { + return; + } + _inertiaScrolling = true; - // Get the initial velocity - _inertiaVelocity; + // Calcualte the initial velocity + Vec2 totalMovement; + for(auto i = _inertiaTouchDisplacements.begin(); i != _inertiaTouchDisplacements.end(); ++i) + { + totalMovement += (*i); + } + totalMovement.x = (_direction == Direction::VERTICAL ? 0 : totalMovement.x); + totalMovement.y = (_direction == Direction::HORIZONTAL ? 0 : totalMovement.y); + + _inertiaVelocity = totalMovement / totalDuration; CCLOG("%s : startInertiaScroll() startVelocity(%0.2f, %0.2f)", time(), _inertiaVelocity.x, _inertiaVelocity.y); - - - -// { -// if (_slidTime <= 0.016f) -// { -// return; -// } -// float totalDis = 0.0f; -// Vec2 dir; -// Vec2 touchEndPositionInNodeSpace = this->convertToNodeSpace(_touchEndPosition); -// Vec2 touchBeganPositionInNodeSpace = this->convertToNodeSpace(_touchBeganPosition); -// switch (_direction) -// { -// case Direction::VERTICAL: -// totalDis = touchEndPositionInNodeSpace.y - touchBeganPositionInNodeSpace.y; -// if (totalDis < 0.0f) -// { -// dir = SCROLLDIR_DOWN; -// } -// else -// { -// dir = SCROLLDIR_UP; -// } -// break; -// case Direction::HORIZONTAL: -// totalDis = touchEndPositionInNodeSpace.x - touchBeganPositionInNodeSpace.x; -// if (totalDis < 0.0f) -// { -// dir = SCROLLDIR_LEFT; -// } -// else -// { -// dir = SCROLLDIR_RIGHT; -// } -// break; -// case Direction::BOTH: -// { -// Vec2 subVector = touchEndPositionInNodeSpace - touchBeganPositionInNodeSpace; -// totalDis = subVector.getLength(); -// dir = subVector.getNormalized(); -// break; -// } -// default: -// break; -// } -// float orSpeed = MIN(fabs(totalDis)/(_slidTime), AUTOSCROLLMAXSPEED); -// // startAutoScroll(dir, orSpeed, true); -// _slidTime = 0.0f; -// } - - } -//bool ScrollView::checkCustomScrollDestinationLeft(float* touchOffsetX, float* touchOffsetY) -//{ -// float icLeftPos = _innerContainer->getLeftBoundary(); -// if (icLeftPos + *touchOffsetX >= _inertiaScrollDestination.x) -// { -// *touchOffsetX = _inertiaScrollDestination.x - icLeftPos; -// return false; -// } -// return true; -//} -// -//bool ScrollView::checkCustomScrollDestinationRight(float* touchOffsetX, float* touchOffsetY) -//{ -// float icRightPos = _innerContainer->getRightBoundary(); -// if (icRightPos + *touchOffsetX <= _inertiaScrollDestination.x) -// { -// *touchOffsetX = _inertiaScrollDestination.x - icRightPos; -// return false; -// } -// return true; -//} -// -//bool ScrollView::checkCustomScrollDestination(float* touchOffsetX, float* touchOffsetY) -//{ -// bool scrollenabled = true; -// switch (_direction) -// { -// case Direction::VERTICAL: -// { -// if (_inertiaScrollDir.y > 0) -// { -// float icBottomPos = _innerContainer->getBottomBoundary(); -// if (icBottomPos + *touchOffsetY >= _inertiaScrollDestination.y) -// { -// *touchOffsetY = _inertiaScrollDestination.y - icBottomPos; -// scrollenabled = false; -// } -// } -// else -// { -// float icBottomPos = _innerContainer->getBottomBoundary(); -// if (icBottomPos + *touchOffsetY <= _inertiaScrollDestination.y) -// { -// *touchOffsetY = _inertiaScrollDestination.y - icBottomPos; -// scrollenabled = false; -// } -// } -// break; -// } -// case Direction::HORIZONTAL: -// { -// if (_inertiaScrollDir.x > 0) -// { -// float icLeftPos = _innerContainer->getLeftBoundary(); -// if (icLeftPos + *touchOffsetX >= _inertiaScrollDestination.x) -// { -// *touchOffsetX = _inertiaScrollDestination.x - icLeftPos; -// scrollenabled = false; -// } -// } -// else -// { -// float icLeftPos = _innerContainer->getLeftBoundary(); -// if (icLeftPos + *touchOffsetX <= _inertiaScrollDestination.x) -// { -// *touchOffsetX = _inertiaScrollDestination.x - icLeftPos; -// scrollenabled = false; -// } -// } -// break; -// } -// case Direction::BOTH: -// { -// if (*touchOffsetY > 0.0f) // up -// { -// if (*touchOffsetX > 0.0f) // right -// { -// scrollenabled = checkCustomScrollDestinationLeft(touchOffsetX, touchOffsetY); -// } -// else if (*touchOffsetX < 0.0f) // left -// { -// scrollenabled = checkCustomScrollDestinationRight(touchOffsetX, touchOffsetY); -// } -// float icBottomPos = _innerContainer->getBottomBoundary(); -// if (icBottomPos + *touchOffsetY >= _inertiaScrollDestination.y) -// { -// *touchOffsetY = _inertiaScrollDestination.y - icBottomPos; -// scrollenabled = false; -// } -// } -// else if (*touchOffsetY < 0.0f) // down -// { -// if (*touchOffsetX < 0.0f) // left -// { -// scrollenabled = checkCustomScrollDestinationRight(touchOffsetX, touchOffsetY); -// } -// else if (*touchOffsetX > 0.0f) // right -// { -// scrollenabled = checkCustomScrollDestinationLeft(touchOffsetX, touchOffsetY); -// } -// float icTopPos = _innerContainer->getTopBoundary(); -// if (icTopPos + *touchOffsetY <= _inertiaScrollDestination.y) -// { -// *touchOffsetY = _inertiaScrollDestination.y - icTopPos; -// scrollenabled = false; -// } -// } -// else -// { -// if (*touchOffsetX < 0.0f) // left -// { -// scrollenabled = checkCustomScrollDestinationRight(touchOffsetX, touchOffsetY); -// } -// else if (*touchOffsetX > 0.0f) // right -// { -// scrollenabled = checkCustomScrollDestinationLeft(touchOffsetX, touchOffsetY); -// } -// } -// break; -// } -// default: -// break; -// } -// return scrollenabled; -//} +void ScrollView::processInertiaScrolling(float dt) +{ + Vec2 displacement = _inertiaVelocity * dt; + if(!_bounceEnabled) + { + Vec2 outOfBoundary = getHowMuchOutOfBoundary(displacement); + if(outOfBoundary != Vec2::ZERO) + { + // Don't allow to go out of boundary + displacement += outOfBoundary; + _inertiaScrolling = false; + } + } + else + { + float deacceleration = INERTIA_DEACCELERATION * dt; + if(isOutOfBoundaryLeftOrRight() || isOutOfBoundaryTopOrBottom()) + { + // If the inner container is out of boundary, amplify deacceleration. + deacceleration *= 20; + } + + Vec2 deaccelVelocity = -_inertiaVelocity; + deaccelVelocity.normalize(); + deaccelVelocity *= deacceleration; + + if(_inertiaVelocity.length() > deacceleration) + { + _inertiaVelocity += deaccelVelocity; + } + else + { + _inertiaScrolling = false; + startBounceBackIfNeeded(); + } + } + + // Scroll + moveChildren(displacement.x, displacement.y); +} bool ScrollView::processScrollUp(float* offsetYResult, float touchOffsetY) { @@ -976,7 +800,10 @@ void ScrollView::handlePressLogic(Touch *touch) { startRecordSlidAction(); _bePressed = true; - _slidTime = 0; + + _inertiaPrevTouchTimestamp = getTimestamp(); + _inertiaTouchDisplacements.clear(); + _inertiaTouchTimeDeltas.clear(); } void ScrollView::handleMoveLogic(Touch *touch) @@ -986,10 +813,15 @@ void ScrollView::handleMoveLogic(Touch *touch) Vec2 delta = touchPositionInNodeSpace - previousTouchPositionInNodeSpace; scrollChildren(delta.x, delta.y); - struct timeval tv; - gettimeofday (&tv, NULL); - long long timestamp = tv.tv_sec * 1000 + tv.tv_usec / 1000; - + while(_inertiaTouchDisplacements.size() > 5) + { + _inertiaTouchDisplacements.pop_front(); + _inertiaTouchTimeDeltas.pop_front(); + } + _inertiaTouchDisplacements.push_back(delta); + long long timestamp = getTimestamp(); + _inertiaTouchTimeDeltas.push_back((timestamp - _inertiaPrevTouchTimestamp) / 1000.0f); + _inertiaPrevTouchTimestamp = timestamp; CCLOG("%s : handleMoveLogic() timestamp=%lld", time(), timestamp); } @@ -1045,23 +877,13 @@ void ScrollView::update(float dt) { if (_inertiaScrolling) { - inertiaScrollChildren(dt); + processInertiaScrolling(dt); } if(_autoScrolling) { processAutoScrolling(dt); } - recordSlidTime(dt); -} - -void ScrollView::recordSlidTime(float dt) -{ - if (_bePressed) - { - CCLOG("%s : recordSlidTime() dt=%0.3f", time(), dt); - _slidTime += dt; - } } void ScrollView::interceptTouchEvent(Widget::TouchEventType event, Widget *sender,Touch* touch) diff --git a/cocos/ui/UIScrollView.h b/cocos/ui/UIScrollView.h index b4a9b65da0..e6b0d67a0b 100644 --- a/cocos/ui/UIScrollView.h +++ b/cocos/ui/UIScrollView.h @@ -433,21 +433,17 @@ protected: void moveChildren(float offsetX, float offsetY); void startInertiaScroll(); - void inertiaScrollChildren(float dt); + void processInertiaScrolling(float dt); void startAutoScroll(const Vec2& deltaMove, float duration, bool attenuated); void startAutoScrollChildrenWithDestination(const Vec2& des, float second, bool attenuated); - - void jumpToDestination(const Vec2& des); - void processAutoScrolling(float deltaTime); - + bool startBounceBackIfNeeded(); -// bool checkCustomScrollDestinationLeft(float* touchOffsetX, float* touchOffsetY); -// bool checkCustomScrollDestinationRight(float* touchOffsetX, float* touchOffsetY); -// bool checkCustomScrollDestination(float* touchOffsetX, float* touchOffsetY); + void jumpToDestination(const Vec2& des); + virtual bool scrollChildren(float touchOffsetX, float touchOffsetY); // Without bounce @@ -466,8 +462,6 @@ protected: virtual void interceptTouchEvent(Widget::TouchEventType event,Widget* sender,Touch *touch) override; - void recordSlidTime(float dt); - void processScrollEvent(MoveDirection dir, bool bounce); void processScrollingEvent(); void dispatchEvent(ScrollviewEventType scrollEventType, EventType eventType); @@ -484,26 +478,15 @@ protected: float _leftBoundary; float _rightBoundary; + bool _bePressed; + float _childFocusCancelOffset; + bool _inertiaScrollEnabled; bool _inertiaScrolling; Vec2 _inertiaVelocity; - std::list _slidMovements; - -// Vec2 _inertiaScrollDir; -// float _inertiaScrollAddUpTime; - -// float _inertiaScrollOriginalSpeed; -// float _inertiaScrollAcceleration; -// bool _inertiaScrollSpeedAttenuated; -// bool _needCheckInertiaScrollDestination; -// Vec2 _inertiaScrollDestination; - - bool _bePressed; - float _slidTime; - float _childFocusCancelOffset; - - bool _bounceEnabled; - bool _bouncingBack; + std::list _inertiaTouchDisplacements; + std::list _inertiaTouchTimeDeltas; + long long _inertiaPrevTouchTimestamp; bool _autoScrolling; bool _autoScrollAttenuate; @@ -512,6 +495,9 @@ protected: float _autoScrollDuration; float _autoScrollAccumulatedTime; + bool _bounceEnabled; + bool _bouncingBack; + Ref* _scrollViewEventListener; #if defined(__GNUC__) && ((__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1))) #pragma GCC diagnostic ignored "-Wdeprecated-declarations" From 71c98da2aa290449ef8f048e238b7d96efe0b3ef Mon Sep 17 00:00:00 2001 From: Neo Kim Date: Mon, 22 Jun 2015 12:48:38 +0900 Subject: [PATCH 3/4] Apply ease out action on inertia scroll --- cocos/ui/UIScrollView.cpp | 61 +++++++++++++++++++-------------------- cocos/ui/UIScrollView.h | 4 ++- 2 files changed, 32 insertions(+), 33 deletions(-) diff --git a/cocos/ui/UIScrollView.cpp b/cocos/ui/UIScrollView.cpp index 6094cc5310..c30947d4ea 100644 --- a/cocos/ui/UIScrollView.cpp +++ b/cocos/ui/UIScrollView.cpp @@ -31,7 +31,7 @@ NS_CC_BEGIN namespace ui { -static const float INERTIA_DEACCELERATION = 6000.0f; +static const float INERTIA_DEACCELERATION = 3000.0f; static const float BOUNCE_BACK_DURATION = 0.3f; static char LOG_BUFFER[256]; @@ -77,6 +77,8 @@ _childFocusCancelOffset(5.0f), _inertiaScrollEnabled(true), _inertiaScrolling(false), _inertiaPrevTouchTimestamp(0), +_inertiaScrollExpectedTime(0), +_inertiaScrollElapsedTime(0), _autoScrolling(false), _autoScrollAttenuate(true), _autoScrollDuration(0), @@ -455,13 +457,34 @@ void ScrollView::startInertiaScroll() totalMovement.x = (_direction == Direction::VERTICAL ? 0 : totalMovement.x); totalMovement.y = (_direction == Direction::HORIZONTAL ? 0 : totalMovement.y); - _inertiaVelocity = totalMovement / totalDuration; - CCLOG("%s : startInertiaScroll() startVelocity(%0.2f, %0.2f)", time(), _inertiaVelocity.x, _inertiaVelocity.y); + _inertiaInitiVelocity = totalMovement / totalDuration; + + // Calculate values for ease out + _inertiaScrollExpectedTime = _inertiaInitiVelocity.length() / INERTIA_DEACCELERATION; + _inertiaScrollElapsedTime = 0; + + CCLOG("%s : startInertiaScroll() startVelocity(%0.2f, %0.2f)", time(), _inertiaInitiVelocity.x, _inertiaInitiVelocity.y); } void ScrollView::processInertiaScrolling(float dt) { - Vec2 displacement = _inertiaVelocity * dt; + _inertiaScrollElapsedTime += dt; + if(isOutOfBoundaryLeftOrRight() || isOutOfBoundaryTopOrBottom()) + { + // If the inner container is out of boundary, shorten the inertia time. + _inertiaScrollElapsedTime += dt * 15; + } + float percentage = _inertiaScrollElapsedTime / _inertiaScrollExpectedTime; + if(percentage >= 1) + { + _inertiaScrolling = false; + startBounceBackIfNeeded(); + return; + } + percentage = tweenfunc::expoEaseOut(percentage); + + Vec2 inertiaVelocity = _inertiaInitiVelocity * (1 - percentage); + Vec2 displacement = inertiaVelocity * dt; if(!_bounceEnabled) { Vec2 outOfBoundary = getHowMuchOutOfBoundary(displacement); @@ -472,31 +495,6 @@ void ScrollView::processInertiaScrolling(float dt) _inertiaScrolling = false; } } - else - { - float deacceleration = INERTIA_DEACCELERATION * dt; - if(isOutOfBoundaryLeftOrRight() || isOutOfBoundaryTopOrBottom()) - { - // If the inner container is out of boundary, amplify deacceleration. - deacceleration *= 20; - } - - Vec2 deaccelVelocity = -_inertiaVelocity; - deaccelVelocity.normalize(); - deaccelVelocity *= deacceleration; - - if(_inertiaVelocity.length() > deacceleration) - { - _inertiaVelocity += deaccelVelocity; - } - else - { - _inertiaScrolling = false; - startBounceBackIfNeeded(); - } - } - - // Scroll moveChildren(displacement.x, displacement.y); } @@ -819,10 +817,10 @@ void ScrollView::handleMoveLogic(Touch *touch) _inertiaTouchTimeDeltas.pop_front(); } _inertiaTouchDisplacements.push_back(delta); + long long timestamp = getTimestamp(); _inertiaTouchTimeDeltas.push_back((timestamp - _inertiaPrevTouchTimestamp) / 1000.0f); _inertiaPrevTouchTimestamp = timestamp; - CCLOG("%s : handleMoveLogic() timestamp=%lld", time(), timestamp); } void ScrollView::handleReleaseLogic(Touch *touch) @@ -879,8 +877,7 @@ void ScrollView::update(float dt) { processInertiaScrolling(dt); } - - if(_autoScrolling) + else if (_autoScrolling) { processAutoScrolling(dt); } diff --git a/cocos/ui/UIScrollView.h b/cocos/ui/UIScrollView.h index e6b0d67a0b..d12a45f190 100644 --- a/cocos/ui/UIScrollView.h +++ b/cocos/ui/UIScrollView.h @@ -483,10 +483,12 @@ protected: bool _inertiaScrollEnabled; bool _inertiaScrolling; - Vec2 _inertiaVelocity; + Vec2 _inertiaInitiVelocity; std::list _inertiaTouchDisplacements; std::list _inertiaTouchTimeDeltas; long long _inertiaPrevTouchTimestamp; + float _inertiaScrollExpectedTime; + float _inertiaScrollElapsedTime; bool _autoScrolling; bool _autoScrollAttenuate; From 9757be0f81e761b68a6c50f1fa7f2ee3c94ec05e Mon Sep 17 00:00:00 2001 From: Neo Kim Date: Mon, 22 Jun 2015 12:53:19 +0900 Subject: [PATCH 4/4] Remove debugging logs --- cocos/ui/UIScrollView.cpp | 32 -------------------------------- 1 file changed, 32 deletions(-) diff --git a/cocos/ui/UIScrollView.cpp b/cocos/ui/UIScrollView.cpp index c30947d4ea..82d05ae515 100644 --- a/cocos/ui/UIScrollView.cpp +++ b/cocos/ui/UIScrollView.cpp @@ -25,8 +25,6 @@ THE SOFTWARE. #include "ui/UIScrollView.h" #include "2d/CCTweenFunction.h" -#include "CCDirector.h" - NS_CC_BEGIN namespace ui { @@ -34,28 +32,6 @@ namespace ui { static const float INERTIA_DEACCELERATION = 3000.0f; static const float BOUNCE_BACK_DURATION = 0.3f; -static char LOG_BUFFER[256]; -char* time() -{ - int nBufferLength = 256; - // Get current local time - struct tm* ptm = NULL; - struct timeval tv; - { - gettimeofday (&tv, NULL); - ptm = localtime (&tv.tv_sec); - } - - // Format the date and time, down to a single second. - strftime (LOG_BUFFER, nBufferLength, "%Y-%m-%d %H:%M:%S", ptm); - size_t nCurrentLength = strlen(LOG_BUFFER); - - // Compute milliseconds from microseconds. - long lMilliseconds = tv.tv_usec / 1000; - snprintf(LOG_BUFFER + nCurrentLength, nBufferLength - nCurrentLength, ".%03ld", lMilliseconds); - return LOG_BUFFER; -} - static long long getTimestamp() { struct timeval tv; @@ -333,7 +309,6 @@ Vec2 ScrollView::getHowMuchOutOfBoundary(const Vec2& addition) const void ScrollView::processAutoScrolling(float deltaTime) { - CCLOG("%s : processAutoScrolling()", time()); _autoScrollAccumulatedTime += deltaTime; float percentage = _autoScrollAccumulatedTime / _autoScrollDuration; if(percentage >= 1) @@ -370,8 +345,6 @@ void ScrollView::processAutoScrolling(float deltaTime) processScrollEvent(MoveDirection::BOTTOM, true); } } - - CCLOG("%s : processAutoScrolling() _autoScrollStartPosition(%0.2f,%0.2f), moveDelta(%0.2f,%0.2f)", time(), _autoScrollStartPosition.x, _autoScrollStartPosition.y, moveDelta.x, moveDelta.y); _innerContainer->setPosition(_autoScrollStartPosition + moveDelta); } } @@ -399,8 +372,6 @@ bool ScrollView::isOutOfBoundaryLeftOrRight() const void ScrollView::startAutoScroll(const Vec2& deltaMove, float duration, bool attenuated) { - CCLOG("%s : startAutoScroll() deltaMove(%0.2f, %0.2f), duration=%0.2f, attenuated=%d", time(), deltaMove.x, deltaMove.y, duration, attenuated); - _autoScrolling = true; _autoScrollTargetDelta = deltaMove; _autoScrollAttenuate = attenuated; @@ -462,8 +433,6 @@ void ScrollView::startInertiaScroll() // Calculate values for ease out _inertiaScrollExpectedTime = _inertiaInitiVelocity.length() / INERTIA_DEACCELERATION; _inertiaScrollElapsedTime = 0; - - CCLOG("%s : startInertiaScroll() startVelocity(%0.2f, %0.2f)", time(), _inertiaInitiVelocity.x, _inertiaInitiVelocity.y); } void ScrollView::processInertiaScrolling(float dt) @@ -923,7 +892,6 @@ void ScrollView::interceptTouchEvent(Widget::TouchEventType event, Widget *sende void ScrollView::processScrollEvent(MoveDirection dir, bool bounce) { - CCLOG("%s : processScrollEvent() dir=%d, bounce=%d", time(), dir, bounce); ScrollviewEventType scrollEventType; EventType eventType; switch(dir) {