Merge pull request #13646 from neokim/refactor_scrollview_inertia_scroll

Refactor scroll view's inertia scroll
This commit is contained in:
子龙山人 2015-09-07 22:38:20 +08:00
commit 75882e64a0
2 changed files with 228 additions and 208 deletions

View File

@ -31,11 +31,10 @@ THE SOFTWARE.
#include "2d/CCCamera.h" #include "2d/CCCamera.h"
NS_CC_BEGIN NS_CC_BEGIN
namespace ui { static const float OUT_OF_BOUND_TIME_RESCALE = 0.05f;
static const float OUT_OF_BOUND_DISTANCE_RESCALE = 0.05f;
static const float INERTIA_DEACCELERATION = 700.0f;
static const float INERTIA_VELOCITY_MAX = 2500;
static const float BOUNCE_BACK_DURATION = 1.0f; static const float BOUNCE_BACK_DURATION = 1.0f;
#define MOVE_INCH 7.0f/160.0f #define MOVE_INCH 7.0f/160.0f
static float convertDistanceFromPointToInch(const Vec2& dis) static float convertDistanceFromPointToInch(const Vec2& dis)
@ -46,6 +45,8 @@ static float convertDistanceFromPointToInch(const Vec2& dis)
return distance; return distance;
} }
namespace ui {
IMPLEMENT_CLASS_GUI_INFO(ScrollView) IMPLEMENT_CLASS_GUI_INFO(ScrollView)
ScrollView::ScrollView(): ScrollView::ScrollView():
@ -57,17 +58,17 @@ _leftBoundary(0.0f),
_rightBoundary(0.0f), _rightBoundary(0.0f),
_bePressed(false), _bePressed(false),
_childFocusCancelOffsetInInch(MOVE_INCH), _childFocusCancelOffsetInInch(MOVE_INCH),
_inertiaScrollEnabled(true), _touchMovePreviousTimestamp(0),
_inertiaScrolling(false),
_inertiaPrevTouchTimestamp(0),
_inertiaScrollExpectedTime(0),
_inertiaScrollElapsedTime(0),
_autoScrolling(false), _autoScrolling(false),
_autoScrollAttenuate(true), _autoScrollAttenuate(true),
_autoScrollDuration(0), _autoScrollDuration(0),
_autoScrollAccumulatedTime(0), _autoScrollAccumulatedTime(0),
_autoScrollCompleteCallback(nullptr),
_autoScrollMoveCallback(nullptr),
_outOfBoundaryDuringInertiaScroll(false),
_inertiaScrollEnabled(true),
_inertiaScrolling(false),
_bounceEnabled(false), _bounceEnabled(false),
_bouncingBack(false),
_scrollBarEnabled(true), _scrollBarEnabled(true),
_verticalScrollBar(nullptr), _verticalScrollBar(nullptr),
_horizontalScrollBar(nullptr), _horizontalScrollBar(nullptr),
@ -223,6 +224,10 @@ const Size& ScrollView::getInnerContainerSize() const
void ScrollView::setInnerContainerPosition(const Vec2 &position) void ScrollView::setInnerContainerPosition(const Vec2 &position)
{ {
if(position == _innerContainer->getPosition())
{
return;
}
_innerContainer->setPosition(position); _innerContainer->setPosition(position);
this->retain(); this->retain();
@ -340,8 +345,27 @@ bool ScrollView::startBounceBackIfNeeded()
return false; return false;
} }
_bouncingBack = true; startAutoScroll(outOfBoundary, BOUNCE_BACK_DURATION, true,
startAutoScroll(outOfBoundary, BOUNCE_BACK_DURATION, true); nullptr,
[this](const Vec2& moveDelta) {
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);
}
}
);
return true; return true;
} }
@ -369,57 +393,16 @@ Vec2 ScrollView::getHowMuchOutOfBoundary(const Vec2& addition) const
return result; return result;
} }
void ScrollView::processAutoScrolling(float deltaTime)
{
_autoScrollAccumulatedTime += deltaTime;
float percentage = _autoScrollAccumulatedTime / _autoScrollDuration;
if(percentage >= 1)
{
moveChildrenToPosition(_autoScrollStartPosition + _autoScrollTargetDelta);
_autoScrolling = false;
_bouncingBack = false;
}
else
{
if(_autoScrollAttenuate)
{
percentage = tweenfunc::quintEaseOut(percentage);
}
Vec2 moveDelta = _autoScrollTargetDelta * percentage;
moveChildrenToPosition(_autoScrollStartPosition + moveDelta);
// Dispatch related events if bouncing
if(_bouncingBack)
{
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);
}
}
}
}
bool ScrollView::isOutOfBoundary(MoveDirection dir) const bool ScrollView::isOutOfBoundary(MoveDirection dir) const
{ {
switch(dir) switch(dir)
{ {
case MoveDirection::TOP: return _innerContainer->getTopBoundary() < _topBoundary; case MoveDirection::TOP: return _innerContainer->getTopBoundary() < _topBoundary;
case MoveDirection::BOTTOM: return _innerContainer->getBottomBoundary() > _bottomBoundary; case MoveDirection::BOTTOM: return _innerContainer->getBottomBoundary() > _bottomBoundary;
case MoveDirection::LEFT: return _innerContainer->getLeftBoundary() > _leftBoundary; case MoveDirection::LEFT: return _innerContainer->getLeftBoundary() > _leftBoundary;
case MoveDirection::RIGHT: return _innerContainer->getRightBoundary() < _rightBoundary; case MoveDirection::RIGHT: return _innerContainer->getRightBoundary() < _rightBoundary;
} }
return false;
} }
bool ScrollView::isOutOfBoundaryTopOrBottom() const bool ScrollView::isOutOfBoundaryTopOrBottom() const
@ -432,7 +415,17 @@ bool ScrollView::isOutOfBoundaryLeftOrRight() const
return isOutOfBoundary(MoveDirection::LEFT) || isOutOfBoundary(MoveDirection::RIGHT); return isOutOfBoundary(MoveDirection::LEFT) || isOutOfBoundary(MoveDirection::RIGHT);
} }
void ScrollView::startAutoScroll(const Vec2& deltaMove, float duration, bool attenuated) bool ScrollView::isOutOfBoundary() const
{
return isOutOfBoundaryTopOrBottom() || isOutOfBoundaryLeftOrRight();
}
void ScrollView::startAutoScrollChildrenWithDestination(const Vec2& des, float second, bool attenuated)
{
startAutoScroll(des - _innerContainer->getPosition(), second, attenuated);
}
void ScrollView::startAutoScroll(const Vec2& deltaMove, float duration, bool attenuated, std::function<void()> completeCallback, std::function<void(const Vec2&)> moveCallback)
{ {
_autoScrolling = true; _autoScrolling = true;
_autoScrollTargetDelta = deltaMove; _autoScrollTargetDelta = deltaMove;
@ -440,11 +433,79 @@ void ScrollView::startAutoScroll(const Vec2& deltaMove, float duration, bool att
_autoScrollStartPosition = _innerContainer->getPosition(); _autoScrollStartPosition = _innerContainer->getPosition();
_autoScrollDuration = duration; _autoScrollDuration = duration;
_autoScrollAccumulatedTime = 0; _autoScrollAccumulatedTime = 0;
_autoScrollCompleteCallback = completeCallback;
_autoScrollMoveCallback = moveCallback;
_outOfBoundaryDuringInertiaScroll = false;
_outOfBoundaryPositionDuringInertiaScroll = Vec2::ZERO;
} }
void ScrollView::startAutoScrollChildrenWithDestination(const Vec2& des, float second, bool attenuated) void ScrollView::processAutoScrolling(float deltaTime)
{ {
startAutoScroll(des - _innerContainer->getPosition(), second, attenuated); // Shorten the auto scroll distance and time if it is out of boundary during inertia scroll.
float timeRescale = 1;
float distanceRescale = 1;
{
bool currentlyOutOfBoundDuringInertiaScroll = (_inertiaScrolling && isOutOfBoundary());
if(!_outOfBoundaryDuringInertiaScroll && currentlyOutOfBoundDuringInertiaScroll)
{
_outOfBoundaryDuringInertiaScroll = true;
_outOfBoundaryPositionDuringInertiaScroll = getInnerContainerPosition();
}
timeRescale = (_outOfBoundaryDuringInertiaScroll ? OUT_OF_BOUND_TIME_RESCALE : 1);
distanceRescale = (_outOfBoundaryDuringInertiaScroll ? OUT_OF_BOUND_DISTANCE_RESCALE : 1);
}
// Calculate the percentage
float percentage = 0;
{
_autoScrollAccumulatedTime += deltaTime * (1 / timeRescale);
percentage = MIN(1, _autoScrollAccumulatedTime / _autoScrollDuration);
if(_autoScrollAttenuate)
{
// Use quintic(5th degree) polynomial
percentage = tweenfunc::quintEaseOut(percentage);
}
}
// Calculate the new position
Vec2 deltaFromInitialPosition = _autoScrollTargetDelta * percentage;
Vec2 newPosition = _autoScrollStartPosition + deltaFromInitialPosition;
bool reachedEnd = false;
// Adjust the new position according to the bounce opiton
{
if(_bounceEnabled)
{
newPosition = _outOfBoundaryPositionDuringInertiaScroll + (newPosition - _outOfBoundaryPositionDuringInertiaScroll) * distanceRescale;
}
else
{
Vec2 moveDelta = newPosition - getInnerContainerPosition();
Vec2 outOfBoundary = getHowMuchOutOfBoundary(moveDelta);
if(outOfBoundary != Vec2::ZERO)
{
newPosition += outOfBoundary;
reachedEnd = true;
}
}
}
moveChildrenToPosition(newPosition);
if(_autoScrollMoveCallback)
{
_autoScrollMoveCallback(getInnerContainerPosition() - newPosition);
}
// Finish auto scroll if it ended
if(percentage == 1 || reachedEnd)
{
_autoScrolling = false;
if(_autoScrollCompleteCallback)
{
_autoScrollCompleteCallback();
}
}
} }
void ScrollView::jumpToDestination(const Vec2 &des) void ScrollView::jumpToDestination(const Vec2 &des)
@ -462,75 +523,43 @@ void ScrollView::jumpToDestination(const Vec2 &des)
moveChildrenToPosition(Vec2(finalOffsetX, finalOffsetY)); moveChildrenToPosition(Vec2(finalOffsetX, finalOffsetY));
} }
void ScrollView::startInertiaScroll() Vec2 ScrollView::calculateTouchMoveVelocity() const
{ {
float totalDuration = 0; float totalDuration = 0;
for(auto &timeDelta : _inertiaTouchTimeDeltas) for(auto &timeDelta : _touchMoveTimeDeltas)
{ {
totalDuration += timeDelta; totalDuration += timeDelta;
} }
if(totalDuration == 0 || totalDuration >= 0.5f) if(totalDuration == 0 || totalDuration >= 0.5f)
{ {
return; return Vec2::ZERO;
} }
_inertiaScrolling = true;
// Calcualte the initial velocity
Vec2 totalMovement; Vec2 totalMovement;
for(auto &displacement : _inertiaTouchDisplacements) for(auto &displacement : _touchMoveDisplacements)
{
totalMovement += displacement;
}
for(auto i = _inertiaTouchDisplacements.begin(); i != _inertiaTouchDisplacements.end(); ++i)
{ {
totalMovement += (*i); totalMovement += displacement;
} }
totalMovement.x = (_direction == Direction::VERTICAL ? 0 : totalMovement.x); return totalMovement / totalDuration;
totalMovement.y = (_direction == Direction::HORIZONTAL ? 0 : totalMovement.y);
_inertiaInitiVelocity = totalMovement / totalDuration;
_inertiaInitiVelocity.x = MIN(_inertiaInitiVelocity.x, INERTIA_VELOCITY_MAX);
_inertiaInitiVelocity.y = MIN(_inertiaInitiVelocity.y, INERTIA_VELOCITY_MAX);
_inertiaInitiVelocity.x = MAX(_inertiaInitiVelocity.x, -INERTIA_VELOCITY_MAX);
_inertiaInitiVelocity.y = MAX(_inertiaInitiVelocity.y, -INERTIA_VELOCITY_MAX);
// Calculate values for ease out
_inertiaScrollExpectedTime = _inertiaInitiVelocity.length() / INERTIA_DEACCELERATION;
_inertiaScrollElapsedTime = 0;
} }
void ScrollView::processInertiaScrolling(float dt) void ScrollView::startInertiaScroll(const Vec2& touchMoveVelocity)
{ {
_inertiaScrollElapsedTime += dt; Vec2 initialVelocity = touchMoveVelocity;
if(isOutOfBoundaryLeftOrRight() || isOutOfBoundaryTopOrBottom()) initialVelocity.x = (_direction == Direction::VERTICAL ? 0 : initialVelocity.x);
{ initialVelocity.y = (_direction == Direction::HORIZONTAL ? 0 : initialVelocity.y);
// If the inner container is out of boundary, shorten the inertia time.
_inertiaScrollElapsedTime += dt * (45000 / INERTIA_DEACCELERATION); const float MOVEMENT_FACTOR = 0.7f;
} Vec2 inertiaTotalDisplacement = initialVelocity * MOVEMENT_FACTOR;
float percentage = _inertiaScrollElapsedTime / _inertiaScrollExpectedTime;
if(percentage >= 1) // Calculate the duration from the initial velocity according to quintic polynomial.
{ float duration = sqrtf(sqrtf(initialVelocity.length() / 5));
_inertiaScrolling = true;
startAutoScroll(inertiaTotalDisplacement, duration, true, [this]() {
_inertiaScrolling = false; _inertiaScrolling = false;
startBounceBackIfNeeded(); startBounceBackIfNeeded();
return; });
}
percentage = tweenfunc::quartEaseOut(percentage);
Vec2 inertiaVelocity = _inertiaInitiVelocity * (1 - percentage);
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;
}
}
moveChildren(displacement.x, displacement.y);
} }
bool ScrollView::scrollChildren(float touchOffsetX, float touchOffsetY) bool ScrollView::scrollChildren(float touchOffsetX, float touchOffsetY)
@ -803,36 +832,18 @@ void ScrollView::jumpToPercentBothDirection(const Vec2& percent)
jumpToDestination(Vec2(-(percent.x * w / 100.0f), minY + percent.y * h / 100.0f)); jumpToDestination(Vec2(-(percent.x * w / 100.0f), minY + percent.y * h / 100.0f));
} }
void ScrollView::startRecordSlidAction()
{
if (_inertiaScrolling)
{
_inertiaScrolling = false;
}
if(_autoScrolling)
{
_autoScrolling = false;
_bouncingBack = false;
}
}
void ScrollView::endRecordSlidAction()
{
bool bounceBackStarted = startBounceBackIfNeeded();
if(!bounceBackStarted && _inertiaScrollEnabled)
{
startInertiaScroll();
}
}
void ScrollView::handlePressLogic(Touch *touch) void ScrollView::handlePressLogic(Touch *touch)
{ {
startRecordSlidAction();
_bePressed = true; _bePressed = true;
_autoScrolling = false;
_inertiaScrolling = false;
_inertiaPrevTouchTimestamp = utils::getTimeInMilliseconds(); // Initialize touch move information
_inertiaTouchDisplacements.clear(); {
_inertiaTouchTimeDeltas.clear(); _touchMovePreviousTimestamp = utils::getTimeInMilliseconds();
_touchMoveDisplacements.clear();
_touchMoveTimeDeltas.clear();
}
if(_verticalScrollBar != nullptr) if(_verticalScrollBar != nullptr)
{ {
@ -857,23 +868,35 @@ void ScrollView::handleMoveLogic(Touch *touch)
Vec2 delta(delta3.x, delta3.y); Vec2 delta(delta3.x, delta3.y);
scrollChildren(delta.x, delta.y); scrollChildren(delta.x, delta.y);
while(_inertiaTouchDisplacements.size() > 5) // Gather touch move information for speed calculation
{ {
_inertiaTouchDisplacements.pop_front(); while(_touchMoveDisplacements.size() > 5)
_inertiaTouchTimeDeltas.pop_front(); {
} _touchMoveDisplacements.pop_front();
_inertiaTouchDisplacements.push_back(delta); _touchMoveTimeDeltas.pop_front();
}
_touchMoveDisplacements.push_back(delta);
long long timestamp = utils::getTimeInMilliseconds(); long long timestamp = utils::getTimeInMilliseconds();
_inertiaTouchTimeDeltas.push_back((timestamp - _inertiaPrevTouchTimestamp) / 1000.0f); _touchMoveTimeDeltas.push_back((timestamp - _touchMovePreviousTimestamp) / 1000.0f);
_inertiaPrevTouchTimestamp = timestamp; _touchMovePreviousTimestamp = timestamp;
}
} }
void ScrollView::handleReleaseLogic(Touch *touch) void ScrollView::handleReleaseLogic(Touch *touch)
{ {
endRecordSlidAction();
_bePressed = false; _bePressed = false;
bool bounceBackStarted = startBounceBackIfNeeded();
if(!bounceBackStarted && _inertiaScrollEnabled)
{
Vec2 touchMoveVelocity = calculateTouchMoveVelocity();
if(touchMoveVelocity != Vec2::ZERO)
{
startInertiaScroll(touchMoveVelocity);
}
}
if(_verticalScrollBar != nullptr) if(_verticalScrollBar != nullptr)
{ {
_verticalScrollBar->onTouchEnded(); _verticalScrollBar->onTouchEnded();
@ -928,11 +951,7 @@ void ScrollView::onTouchCancelled(Touch *touch, Event *unusedEvent)
void ScrollView::update(float dt) void ScrollView::update(float dt)
{ {
if (_inertiaScrolling) if (_autoScrolling)
{
processInertiaScrolling(dt);
}
else if (_autoScrolling)
{ {
processAutoScrolling(dt); processAutoScrolling(dt);
} }
@ -1002,29 +1021,29 @@ void ScrollView::processScrollEvent(MoveDirection dir, bool bounce)
ScrollviewEventType scrollEventType; ScrollviewEventType scrollEventType;
EventType eventType; EventType eventType;
switch(dir) { switch(dir) {
case MoveDirection::TOP: case MoveDirection::TOP:
{ {
scrollEventType = (bounce ? SCROLLVIEW_EVENT_BOUNCE_TOP : SCROLLVIEW_EVENT_SCROLL_TO_TOP); scrollEventType = (bounce ? SCROLLVIEW_EVENT_BOUNCE_TOP : SCROLLVIEW_EVENT_SCROLL_TO_TOP);
eventType = (bounce ? EventType::BOUNCE_TOP : EventType::SCROLL_TO_TOP); eventType = (bounce ? EventType::BOUNCE_TOP : EventType::SCROLL_TO_TOP);
break; break;
} }
case MoveDirection::BOTTOM: case MoveDirection::BOTTOM:
{ {
scrollEventType = (bounce ? SCROLLVIEW_EVENT_BOUNCE_BOTTOM : SCROLLVIEW_EVENT_SCROLL_TO_BOTTOM); scrollEventType = (bounce ? SCROLLVIEW_EVENT_BOUNCE_BOTTOM : SCROLLVIEW_EVENT_SCROLL_TO_BOTTOM);
eventType = (bounce ? EventType::BOUNCE_BOTTOM : EventType::SCROLL_TO_BOTTOM); eventType = (bounce ? EventType::BOUNCE_BOTTOM : EventType::SCROLL_TO_BOTTOM);
break; break;
} }
case MoveDirection::LEFT: case MoveDirection::LEFT:
{ {
scrollEventType = (bounce ? SCROLLVIEW_EVENT_BOUNCE_LEFT : SCROLLVIEW_EVENT_SCROLL_TO_LEFT); scrollEventType = (bounce ? SCROLLVIEW_EVENT_BOUNCE_LEFT : SCROLLVIEW_EVENT_SCROLL_TO_LEFT);
eventType = (bounce ? EventType::BOUNCE_LEFT : EventType::SCROLL_TO_LEFT); eventType = (bounce ? EventType::BOUNCE_LEFT : EventType::SCROLL_TO_LEFT);
break; break;
} }
case MoveDirection::RIGHT: case MoveDirection::RIGHT:
{ {
scrollEventType = (bounce ? SCROLLVIEW_EVENT_BOUNCE_RIGHT : SCROLLVIEW_EVENT_SCROLL_TO_RIGHT); scrollEventType = (bounce ? SCROLLVIEW_EVENT_BOUNCE_RIGHT : SCROLLVIEW_EVENT_SCROLL_TO_RIGHT);
eventType = (bounce ? EventType::BOUNCE_RIGHT : EventType::SCROLL_TO_RIGHT); eventType = (bounce ? EventType::BOUNCE_RIGHT : EventType::SCROLL_TO_RIGHT);
break; break;
} }
} }
dispatchEvent(scrollEventType, eventType); dispatchEvent(scrollEventType, eventType);
@ -1351,22 +1370,22 @@ void ScrollView::copySpecialProperties(Widget *widget)
_rightBoundary = scrollView->_rightBoundary; _rightBoundary = scrollView->_rightBoundary;
_bePressed = scrollView->_bePressed; _bePressed = scrollView->_bePressed;
_childFocusCancelOffsetInInch = scrollView->_childFocusCancelOffsetInInch; _childFocusCancelOffsetInInch = scrollView->_childFocusCancelOffsetInInch;
setInertiaScrollEnabled(scrollView->_inertiaScrollEnabled); _touchMoveDisplacements = scrollView->_touchMoveDisplacements;
_inertiaScrolling = scrollView->_inertiaScrolling; _touchMoveTimeDeltas = scrollView->_touchMoveTimeDeltas;
_inertiaInitiVelocity = scrollView->_inertiaInitiVelocity; _touchMovePreviousTimestamp = scrollView->_touchMovePreviousTimestamp;
_inertiaTouchDisplacements = scrollView->_inertiaTouchDisplacements;
_inertiaTouchTimeDeltas = scrollView->_inertiaTouchTimeDeltas;
_inertiaPrevTouchTimestamp = scrollView->_inertiaPrevTouchTimestamp;
_inertiaScrollExpectedTime = scrollView->_inertiaScrollExpectedTime;
_inertiaScrollElapsedTime = scrollView->_inertiaScrollElapsedTime;
_autoScrolling = scrollView->_autoScrolling; _autoScrolling = scrollView->_autoScrolling;
_autoScrollAttenuate = scrollView->_autoScrollAttenuate; _autoScrollAttenuate = scrollView->_autoScrollAttenuate;
_autoScrollStartPosition = scrollView->_autoScrollStartPosition; _autoScrollStartPosition = scrollView->_autoScrollStartPosition;
_autoScrollTargetDelta = scrollView->_autoScrollTargetDelta; _autoScrollTargetDelta = scrollView->_autoScrollTargetDelta;
_autoScrollDuration = scrollView->_autoScrollDuration; _autoScrollDuration = scrollView->_autoScrollDuration;
_autoScrollAccumulatedTime = scrollView->_autoScrollAccumulatedTime; _autoScrollAccumulatedTime = scrollView->_autoScrollAccumulatedTime;
_outOfBoundaryDuringInertiaScroll = scrollView->_outOfBoundaryDuringInertiaScroll;
_outOfBoundaryPositionDuringInertiaScroll = scrollView->_outOfBoundaryPositionDuringInertiaScroll;
_autoScrollCompleteCallback = scrollView->_autoScrollCompleteCallback;
_autoScrollMoveCallback = scrollView->_autoScrollMoveCallback;
setInertiaScrollEnabled(scrollView->_inertiaScrollEnabled);
_inertiaScrolling = scrollView->_inertiaScrolling;
setBounceEnabled(scrollView->_bounceEnabled); setBounceEnabled(scrollView->_bounceEnabled);
_bouncingBack = scrollView->_bouncingBack;
_scrollViewEventListener = scrollView->_scrollViewEventListener; _scrollViewEventListener = scrollView->_scrollViewEventListener;
_scrollViewEventSelector = scrollView->_scrollViewEventSelector; _scrollViewEventSelector = scrollView->_scrollViewEventSelector;
_eventCallback = scrollView->_eventCallback; _eventCallback = scrollView->_eventCallback;

View File

@ -568,14 +568,16 @@ protected:
bool isOutOfBoundary(MoveDirection dir) const; bool isOutOfBoundary(MoveDirection dir) const;
bool isOutOfBoundaryTopOrBottom() const; bool isOutOfBoundaryTopOrBottom() const;
bool isOutOfBoundaryLeftOrRight() const; bool isOutOfBoundaryLeftOrRight() const;
bool isOutOfBoundary() const;
void moveChildren(float offsetX, float offsetY); void moveChildren(float offsetX, float offsetY);
void moveChildrenToPosition(const Vec2& position); void moveChildrenToPosition(const Vec2& position);
void startInertiaScroll(); Vec2 calculateTouchMoveVelocity() const;
void processInertiaScrolling(float dt);
void startAutoScroll(const Vec2& deltaMove, float duration, bool attenuated); void startInertiaScroll(const Vec2& touchMoveVelocity);
void startAutoScroll(const Vec2& deltaMove, float duration, bool attenuated, std::function<void()> completeCallback = nullptr, std::function<void(const Vec2&)> moveCallback = nullptr);
void startAutoScrollChildrenWithDestination(const Vec2& des, float second, bool attenuated); void startAutoScrollChildrenWithDestination(const Vec2& des, float second, bool attenuated);
void processAutoScrolling(float deltaTime); void processAutoScrolling(float deltaTime);
@ -585,10 +587,6 @@ protected:
virtual bool scrollChildren(float touchOffsetX, float touchOffsetY); virtual bool scrollChildren(float touchOffsetX, float touchOffsetY);
void startRecordSlidAction();
virtual void endRecordSlidAction();
//ScrollViewProtocol
virtual void handlePressLogic(Touch *touch); virtual void handlePressLogic(Touch *touch);
virtual void handleMoveLogic(Touch *touch); virtual void handleMoveLogic(Touch *touch);
virtual void handleReleaseLogic(Touch *touch); virtual void handleReleaseLogic(Touch *touch);
@ -617,14 +615,10 @@ protected:
float _childFocusCancelOffsetInInch; float _childFocusCancelOffsetInInch;
bool _inertiaScrollEnabled; // Touch move speed
bool _inertiaScrolling; std::list<Vec2> _touchMoveDisplacements;
Vec2 _inertiaInitiVelocity; std::list<float> _touchMoveTimeDeltas;
std::list<Vec2> _inertiaTouchDisplacements; long long _touchMovePreviousTimestamp;
std::list<float> _inertiaTouchTimeDeltas;
long long _inertiaPrevTouchTimestamp;
float _inertiaScrollExpectedTime;
float _inertiaScrollElapsedTime;
bool _autoScrolling; bool _autoScrolling;
bool _autoScrollAttenuate; bool _autoScrollAttenuate;
@ -632,9 +626,16 @@ protected:
Vec2 _autoScrollTargetDelta; Vec2 _autoScrollTargetDelta;
float _autoScrollDuration; float _autoScrollDuration;
float _autoScrollAccumulatedTime; float _autoScrollAccumulatedTime;
bool _outOfBoundaryDuringInertiaScroll;
Vec2 _outOfBoundaryPositionDuringInertiaScroll;
std::function<void()> _autoScrollCompleteCallback;
std::function<void(const Vec2& moveDelta)> _autoScrollMoveCallback;
// Inertia scroll
bool _inertiaScrollEnabled;
bool _inertiaScrolling;
bool _bounceEnabled; bool _bounceEnabled;
bool _bouncingBack;
bool _scrollBarEnabled; bool _scrollBarEnabled;
ScrollViewBar* _verticalScrollBar; ScrollViewBar* _verticalScrollBar;