From f4b51457936bd64eb4ebc3b9a4e1cd40a4ecea58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D0=B5=D1=81=D1=88=D0=B0=D0=BF=D0=BE=D1=88=D0=BD?= =?UTF-8?q?=D0=B8=D0=BA=D0=BE=D0=B2=20=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0?= Date: Fri, 27 Nov 2015 10:49:12 +0300 Subject: [PATCH 01/19] Refactor ccui.ScrollView to correspond coso2d-x v3.9 api. --- .../uiwidgets/scroll-widget/UIScrollView.js | 1425 ++++++----------- 1 file changed, 518 insertions(+), 907 deletions(-) diff --git a/extensions/ccui/uiwidgets/scroll-widget/UIScrollView.js b/extensions/ccui/uiwidgets/scroll-widget/UIScrollView.js index db44fc6e28..7454460074 100644 --- a/extensions/ccui/uiwidgets/scroll-widget/UIScrollView.js +++ b/extensions/ccui/uiwidgets/scroll-widget/UIScrollView.js @@ -37,41 +37,35 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ _innerContainer: null, direction: null, - _autoScrollDir: null, _topBoundary: 0, _bottomBoundary: 0, _leftBoundary: 0, _rightBoundary: 0, - _bounceTopBoundary: 0, - _bounceBottomBoundary: 0, - _bounceLeftBoundary: 0, - _bounceRightBoundary: 0, + _touchMoveDisplacements: null, + _touchMoveTimeDeltas: null, + _touchMovePreviousTimestamp: 0, - _autoScroll: false, - _autoScrollAddUpTime: 0, - - _autoScrollOriginalSpeed: 0, - _autoScrollAcceleration: 0, - _isAutoScrollSpeedAttenuated: false, - _needCheckAutoScrollDestination: false, - _autoScrollDestination: null, + _autoScrolling: false, + _autoScrollTargetDelta: null, + _autoScrollAttenuate: true, + _autoScrollStartPosition : null, + _autoScrollTotalTime: 0, + _autoScrollAccumulatedTime: 0, + _autoScrollCurrentlyOutOfBoundary: false, + _autoScrollBraking: false, + _autoScrollBrakingStartPosition: null, _bePressed: false, - _slidTime: 0, - _moveChildPoint: null, - _childFocusCancelOffset: 0, - _leftBounceNeeded: false, - _topBounceNeeded: false, - _rightBounceNeeded: false, - _bottomBounceNeeded: false, + _childFocusCancelOffset: 0, bounceEnabled: false, - _bouncing: false, - _bounceDir: null, - _bounceOriginalSpeed: 0, + + _outOfBoundaryAmount: null, + _outOfBoundaryAmountDirty: true, + inertiaScrollEnabled: false, _scrollViewEventListener: null, @@ -88,16 +82,18 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ ctor: function () { ccui.Layout.prototype.ctor.call(this); this.direction = ccui.ScrollView.DIR_NONE; - this._autoScrollDir = cc.p(0, 0); - this._autoScrollAcceleration = -1000; - this._autoScrollDestination = cc.p(0, 0); - this._slidTime = 0; - this._moveChildPoint = cc.p(0, 0); this._childFocusCancelOffset = 5; - this._bounceDir = cc.p(0, 0); - this._bounceOriginalSpeed = 0; this.inertiaScrollEnabled = true; + + this._outOfBoundaryAmount = cc.p(0, 0); + this._autoScrollTargetDelta = cc.p(0, 0); + this._autoScrollStartPosition = cc.p(0, 0); + this._autoScrollBrakingStartPosition = cc.p(0, 0); + this._touchMoveDisplacements = []; + this._touchMoveTimeDeltas = []; + this._touchMovePreviousTimestamp = 0; + this.setTouchEnabled(true); }, @@ -163,12 +159,6 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ var locSize = this._contentSize; this._topBoundary = locSize.height; this._rightBoundary = locSize.width; - var bounceBoundaryParameterX = locSize.width / 3; - var bounceBoundaryParameterY = locSize.height / 3; - this._bounceTopBoundary = locSize.height - bounceBoundaryParameterY; - this._bounceBottomBoundary = bounceBoundaryParameterY; - this._bounceLeftBoundary = bounceBoundaryParameterX; - this._bounceRightBoundary = locSize.width - bounceBoundaryParameterX; var innerSize = this._innerContainer.getContentSize(); this._innerContainer.setContentSize(cc.size(Math.max(innerSize.width, locSize.width), Math.max(innerSize.height, locSize.height))); this._innerContainer.setPosition(0, locSize.height - this._innerContainer.getContentSize().height); @@ -197,46 +187,29 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ innerSizeHeight = size.height; innerContainer.setContentSize(cc.size(innerSizeWidth, innerSizeHeight)); - switch (this.direction) { - case ccui.ScrollView.DIR_VERTICAL: - newInnerSize = innerContainer.getContentSize(); - offset = originalInnerSize.height - newInnerSize.height; - // Made child nodes transform available for scroll - renderCmd.transform(renderCmd.getParentRenderCmd(), true); - this._scrollChildren(0, offset); - break; - case ccui.ScrollView.DIR_HORIZONTAL: - if (innerContainer.getRightBoundary() <= locSize.width) { - newInnerSize = innerContainer.getContentSize(); - offset = originalInnerSize.width - newInnerSize.width; - // Made child nodes transform available for scroll - renderCmd.transform(renderCmd.getParentRenderCmd(), true); - this._scrollChildren(offset, 0); - } - break; - case ccui.ScrollView.DIR_BOTH: - newInnerSize = innerContainer.getContentSize(); - var offsetY = originalInnerSize.height - newInnerSize.height; - var offsetX = (innerContainer.getRightBoundary() <= locSize.width) ? originalInnerSize.width - newInnerSize.width : 0; - // Made child nodes transform available for scroll - renderCmd.transform(renderCmd.getParentRenderCmd(), true); - this._scrollChildren(offsetX, offsetY); - break; - default: - break; + + var pos = this._innerContainer.getPosition(); + var contAP = this._innerContainer.getAnchorPoint(); + + if (this._innerContainer.getLeftBoundary() > 0.0) + { + pos.x = contAP.x * innerSizeWidth; + } + if (this._innerContainer.getRightBoundary() < this._contentSize.width) + { + pos.x = this._contentSize.width - ((1.0 - contAP.x) * innerSizeWidth); + } + if (pos.y > 0.0) + { + pos.y = contAP.y * innerSizeHeight; } + if (this._innerContainer.getTopBoundary() < this._contentSize.height) + { + pos.y = this._contentSize.height - (1.0 - contAP.y) * innerSizeWidth; + } + this.setInnerContainerPosition(pos); - var innerSize = innerContainer.getContentSize(); - var innerPos = innerContainer.getPosition(); - var innerAP = innerContainer.getAnchorPoint(); - if (innerContainer.getLeftBoundary() > 0.0) - innerContainer.setPosition(innerAP.x * innerSize.width, innerPos.y); - if (innerContainer.getRightBoundary() < locSize.width) - innerContainer.setPosition(locSize.width - ((1.0 - innerAP.x) * innerSize.width), innerPos.y); - if (innerPos.y > 0.0) - innerContainer.setPosition(innerPos.x, innerAP.y * innerSize.height); - if (innerContainer.getTopBoundary() < locSize.height) - innerContainer.setPosition(innerPos.x, locSize.height - (1.0 - innerAP.y) * innerSize.height); + //updateScrollBar(Vec2::ZERO); }, _setInnerWidth: function (width) { @@ -292,6 +265,44 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ if (container.getRightBoundary() < locH) container.y = locH - ((1.0 - innerAY) * innerHeight); }, + /** + * Set inner container position + * + * @param {cc.Point} position Inner container position. + */ + setInnerContainerPosition: function(position) + { + if(position.x === this._innerContainer.getPositionX() && position.y === this._innerContainer.getPositionY()) + { + return; + } + this._innerContainer.setPosition(position); + this._outOfBoundaryAmountDirty = true; + + // Process bouncing events + if(this.bounceEnabled) + { + for(var direction = ccui.ScrollView.MOVEDIR_TOP; direction < ccui.ScrollView.MOVEDIR_RIGHT; ++direction) + { + if(this._isOutOfBoundary(direction)) + { + this._processScrollEvent(direction, true); + } + } + } + + this._dispatchEvent(ccui.ScrollView.EVENT_CONTAINER_MOVED); + }, + + /** + * Get inner container position + * + * @return The inner container position. + */ + getInnerContainerPosition: function() + { + return this._innerContainer.getPosition(); + }, /** * Returns inner container size of ScrollView.
@@ -420,709 +431,346 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ return this._innerContainer.getChildByName(name); }, - _moveChildren: function (offsetX, offsetY) { - var locContainer = this._innerContainer; - //var pos = this._innerContainer.getPosition(); - this._moveChildPoint.x = locContainer.x + offsetX; - this._moveChildPoint.y = locContainer.y + offsetY; - this._innerContainer.setPosition(this._moveChildPoint); - if(this._innerContainer._children.length !== 0 ) - this.updateChildren(); - }, - - _autoScrollChildren: function (dt) { - var lastTime = this._autoScrollAddUpTime; - this._autoScrollAddUpTime += dt; - if (this._isAutoScrollSpeedAttenuated) { - var nowSpeed = this._autoScrollOriginalSpeed + this._autoScrollAcceleration * this._autoScrollAddUpTime; - if (nowSpeed <= 0) { - this._stopAutoScrollChildren(); - this._checkNeedBounce(); - } else { - var timeParam = lastTime * 2 + dt; - var offset = (this._autoScrollOriginalSpeed + this._autoScrollAcceleration * timeParam * 0.5) * dt; - var offsetX = offset * this._autoScrollDir.x; - var offsetY = offset * this._autoScrollDir.y; - if (!this._scrollChildren(offsetX, offsetY)) { - this._stopAutoScrollChildren(); - this._checkNeedBounce(); - } - } - } else { - if (this._needCheckAutoScrollDestination) { - var xOffset = this._autoScrollDir.x * dt * this._autoScrollOriginalSpeed; - var yOffset = this._autoScrollDir.y * dt * this._autoScrollOriginalSpeed; - var notDone = this._checkCustomScrollDestination(xOffset, yOffset); - var scrollCheck = this._scrollChildren(xOffset, yOffset); - if (!notDone || !scrollCheck) { - this._stopAutoScrollChildren(); - this._checkNeedBounce(); - } - } else { - if (!this._scrollChildren(this._autoScrollDir.x * dt * this._autoScrollOriginalSpeed, - this._autoScrollDir.y * dt * this._autoScrollOriginalSpeed)) { - this._stopAutoScrollChildren(); - this._checkNeedBounce(); - } - } - } + _flattenVectorByDirection: function(vector) + { + var result = cc.p(0 ,0); + result.x = (this.direction === ccui.ScrollView.DIR_VERTICAL ? 0 : vector.x); + result.y = (this.direction === ccui.ScrollView.DIR_HORIZONTAL ? 0 : vector.y); + return result; }, - _bounceChildren: function (dt) { - var locSpeed = this._bounceOriginalSpeed; - var locBounceDir = this._bounceDir; - if (locSpeed <= 0.0) - this._stopBounceChildren(); - if (!this._bounceScrollChildren(locBounceDir.x * dt * locSpeed, locBounceDir.y * dt * locSpeed)) - this._stopBounceChildren(); + _getHowMuchOutOfBoundary: function(addition) + { + if(addition === undefined) + addition = cc.p(0, 0); + + if(addition.x === 0 && addition.y === 0 && !this._outOfBoundaryAmountDirty) + { + return this._outOfBoundaryAmount; + } + + var outOfBoundaryAmount = cc.p(0, 0); + + if(this._innerContainer.getLeftBoundary() + addition.x > this._leftBoundary) + { + outOfBoundaryAmount.x = this._leftBoundary - (this._innerContainer.getLeftBoundary() + addition.x); + } + else if(this._innerContainer.getRightBoundary() + addition.x < this._rightBoundary) + { + outOfBoundaryAmount.x = this._rightBoundary - (this._innerContainer.getRightBoundary() + addition.x); + } + + if(this._innerContainer.getTopBoundary() + addition.y < this._topBoundary) + { + outOfBoundaryAmount.y = this._topBoundary - (this._innerContainer.getTopBoundary() + addition.y); + } + else if(this._innerContainer.getBottomBoundary() + addition.y > this._bottomBoundary) + { + outOfBoundaryAmount.y = this._bottomBoundary - (this._innerContainer.getBottomBoundary() + addition.y); + } + + if(addition.x === 0 && addition.y === 0 ) + { + this._outOfBoundaryAmount = outOfBoundaryAmount; + this._outOfBoundaryAmountDirty = false; + } + return outOfBoundaryAmount; }, - _checkNeedBounce: function () { - if (!this.bounceEnabled) - return false; - this._checkBounceBoundary(); - var locTopBounceNeeded = this._topBounceNeeded, locBottomBounceNeeded = this._bottomBounceNeeded, - locLeftBounceNeeded = this._leftBounceNeeded, locRightBounceNeeded = this._rightBounceNeeded; - - if (locTopBounceNeeded || locBottomBounceNeeded || locLeftBounceNeeded || locRightBounceNeeded) { - var scrollVector, orSpeed; - var locContentSize = this._contentSize, locInnerContainer = this._innerContainer; - if (locTopBounceNeeded && locLeftBounceNeeded) { - scrollVector = cc.pSub(cc.p(0.0, locContentSize.height), cc.p(locInnerContainer.getLeftBoundary(), locInnerContainer.getTopBoundary())); - orSpeed = cc.pLength(scrollVector) / 0.2; - this._bounceDir = cc.pNormalize(scrollVector); - this._startBounceChildren(orSpeed); - } else if (locTopBounceNeeded && locRightBounceNeeded) { - scrollVector = cc.pSub(cc.p(locContentSize.width, locContentSize.height), cc.p(locInnerContainer.getRightBoundary(), locInnerContainer.getTopBoundary())); - orSpeed = cc.pLength(scrollVector) / 0.2; - this._bounceDir = cc.pNormalize(scrollVector); - this._startBounceChildren(orSpeed); - } else if (locBottomBounceNeeded && locLeftBounceNeeded) { - scrollVector = cc.pSub(cc.p(0, 0), cc.p(locInnerContainer.getLeftBoundary(), locInnerContainer.getBottomBoundary())); - orSpeed = cc.pLength(scrollVector) / 0.2; - this._bounceDir = cc.pNormalize(scrollVector); - this._startBounceChildren(orSpeed); - } else if (locBottomBounceNeeded && locRightBounceNeeded) { - scrollVector = cc.pSub(cc.p(locContentSize.width, 0.0), cc.p(locInnerContainer.getRightBoundary(), locInnerContainer.getBottomBoundary())); - orSpeed = cc.pLength(scrollVector) / 0.2; - this._bounceDir = cc.pNormalize(scrollVector); - this._startBounceChildren(orSpeed); - } else if (locTopBounceNeeded) { - scrollVector = cc.pSub(cc.p(0, locContentSize.height), cc.p(0.0, locInnerContainer.getTopBoundary())); - orSpeed = cc.pLength(scrollVector) / 0.2; - this._bounceDir = cc.pNormalize(scrollVector); - this._startBounceChildren(orSpeed); - } else if (locBottomBounceNeeded) { - scrollVector = cc.pSub(cc.p(0, 0), cc.p(0.0, locInnerContainer.getBottomBoundary())); - orSpeed = cc.pLength(scrollVector) / 0.2; - this._bounceDir = cc.pNormalize(scrollVector); - this._startBounceChildren(orSpeed); - } else if (locLeftBounceNeeded) { - scrollVector = cc.pSub(cc.p(0, 0), cc.p(locInnerContainer.getLeftBoundary(), 0.0)); - orSpeed = cc.pLength(scrollVector) / 0.2; - this._bounceDir = cc.pNormalize(scrollVector); - this._startBounceChildren(orSpeed); - } else if (locRightBounceNeeded) { - scrollVector = cc.pSub(cc.p(locContentSize.width, 0), cc.p(locInnerContainer.getRightBoundary(), 0.0)); - orSpeed = cc.pLength(scrollVector) / 0.2; - this._bounceDir = cc.pNormalize(scrollVector); - this._startBounceChildren(orSpeed); + _isOutOfBoundary: function(dir) + { + var outOfBoundary = this._getHowMuchOutOfBoundary(); + if(dir !== undefined) + { + switch (dir) + { + case ccui.ScrollView.MOVEDIR_TOP: + return outOfBoundary.y > 0; + case ccui.ScrollView.MOVEDIR_BOTTOM: + return outOfBoundary.y < 0; + case ccui.ScrollView.MOVEDIR_LEFT: + return outOfBoundary.x < 0; + case ccui.ScrollView.MOVEDIR_RIGHT: + return outOfBoundary.x > 0; } - return true; + } + else + { + var howMuchOutOfBoundary = this._getHowMuchOutOfBoundary(); + return howMuchOutOfBoundary.x !==0 && howMuchOutOfBoundary.y !== 0; } return false; }, - _checkBounceBoundary: function () { - var locContainer = this._innerContainer; - var icBottomPos = locContainer.getBottomBoundary(); - if (icBottomPos > this._bottomBoundary) { - this._scrollToBottomEvent(); - this._bottomBounceNeeded = true; - } else - this._bottomBounceNeeded = false; - var icTopPos = locContainer.getTopBoundary(); - if (icTopPos < this._topBoundary) { - this._scrollToTopEvent(); - this._topBounceNeeded = true; - } else - this._topBounceNeeded = false; + _moveInnerContainer: function(deltaMove, canStartBounceBack) + { + var adjustedMove = this._flattenVectorByDirection(deltaMove); - var icRightPos = locContainer.getRightBoundary(); - if (icRightPos < this._rightBoundary) { - this._scrollToRightEvent(); - this._rightBounceNeeded = true; - } else - this._rightBounceNeeded = false; + this.setInnerContainerPosition(cc.pAdd(this.getInnerContainerPosition(), adjustedMove)); - var icLeftPos = locContainer.getLeftBoundary(); - if (icLeftPos > this._leftBoundary) { - this._scrollToLeftEvent(); - this._leftBounceNeeded = true; - } else - this._leftBounceNeeded = false; - }, - - _startBounceChildren: function (v) { - this._bounceOriginalSpeed = v; - this._bouncing = true; - }, - - _stopBounceChildren: function () { - this._bouncing = false; - this._bounceOriginalSpeed = 0.0; - this._leftBounceNeeded = false; - this._rightBounceNeeded = false; - this._topBounceNeeded = false; - this._bottomBounceNeeded = false; - }, - - _startAutoScrollChildrenWithOriginalSpeed: function (dir, v, attenuated, acceleration) { - this._stopAutoScrollChildren(); - this._autoScrollDir.x = dir.x; - this._autoScrollDir.y = dir.y; - this._isAutoScrollSpeedAttenuated = attenuated; - this._autoScrollOriginalSpeed = v; - this._autoScroll = true; - this._autoScrollAcceleration = acceleration; - }, - - _startAutoScrollChildrenWithDestination: function (des, time, attenuated) { - this._needCheckAutoScrollDestination = false; - this._autoScrollDestination = des; - var dis = cc.pSub(des, this._innerContainer.getPosition()); - var dir = cc.pNormalize(dis); - var orSpeed = 0.0; - var acceleration = -1000.0; - var disLength = cc.pLength(dis); - if (attenuated) { - acceleration = -(2 * disLength) / (time * time); - orSpeed = 2 * disLength / time; - } else { - this._needCheckAutoScrollDestination = true; - orSpeed = disLength / time; + var outOfBoundary =this._getHowMuchOutOfBoundary(); + //updateScrollBar(outOfBoundary); + + if(this.bounceEnabled && canStartBounceBack) + { + this._startBounceBackIfNeeded(); } - this._startAutoScrollChildrenWithOriginalSpeed(dir, orSpeed, attenuated, acceleration); }, - _jumpToDestination: function (dstX, dstY) { - if (dstX.x !== undefined) { - dstY = dstX.y; - dstX = dstX.x; + _calculateTouchMoveVelocity: function() + { + var totalTime = 0; + for(var i = 0; i < this._touchMoveTimeDeltas.length; ++i) + { + totalTime += this._touchMoveTimeDeltas[i]; } - var finalOffsetX = dstX; - var finalOffsetY = dstY; - switch (this.direction) { - case ccui.ScrollView.DIR_VERTICAL: - if (dstY <= 0) - finalOffsetY = Math.max(dstY, this._contentSize.height - this._innerContainer.getContentSize().height); - break; - case ccui.ScrollView.DIR_HORIZONTAL: - if (dstX <= 0) - finalOffsetX = Math.max(dstX, this._contentSize.width - this._innerContainer.getContentSize().width); - break; - case ccui.ScrollView.DIR_BOTH: - if (dstY <= 0) - finalOffsetY = Math.max(dstY, this._contentSize.height - this._innerContainer.getContentSize().height); - if (dstX <= 0) - finalOffsetX = Math.max(dstX, this._contentSize.width - this._innerContainer.getContentSize().width); - break; - default: - break; + if(totalTime == 0 || totalTime >= 0.5) + { + return cc.p(0, 0); } - this._innerContainer.setPosition(finalOffsetX, finalOffsetY); - }, - - _stopAutoScrollChildren: function () { - this._autoScroll = false; - this._autoScrollOriginalSpeed = 0; - this._autoScrollAddUpTime = 0; - }, - - _bounceScrollChildren: function (touchOffsetX, touchOffsetY) { - var scrollEnabled = true; - var realOffsetX, realOffsetY, icRightPos, icTopPos, icBottomPos; - var locContainer = this._innerContainer; - if (touchOffsetX > 0.0 && touchOffsetY > 0.0){ //first quadrant //bounce to top-right - realOffsetX = touchOffsetX; - realOffsetY = touchOffsetY; - icRightPos = locContainer.getRightBoundary(); - if (icRightPos + realOffsetX >= this._rightBoundary) { - realOffsetX = this._rightBoundary - icRightPos; - this._bounceRightEvent(); - scrollEnabled = false; - } - icTopPos = locContainer.getTopBoundary(); - if (icTopPos + touchOffsetY >= this._topBoundary) { - realOffsetY = this._topBoundary - icTopPos; - this._bounceTopEvent(); - scrollEnabled = false; - } - this._moveChildren(realOffsetX, realOffsetY); - } else if (touchOffsetX < 0.0 && touchOffsetY > 0.0){ //second quadrant //bounce to top-left - realOffsetX = touchOffsetX; - realOffsetY = touchOffsetY; - icLefrPos = locContainer.getLeftBoundary(); - if (icLefrPos + realOffsetX <= this._leftBoundary) { - realOffsetX = this._leftBoundary - icLefrPos; - this._bounceLeftEvent(); - scrollEnabled = false; - } - icTopPos = locContainer.getTopBoundary(); - if (icTopPos + touchOffsetY >= this._topBoundary) { - realOffsetY = this._topBoundary - icTopPos; - this._bounceTopEvent(); - scrollEnabled = false; - } - this._moveChildren(realOffsetX, realOffsetY); - }else if (touchOffsetX < 0.0 && touchOffsetY < 0.0){ //third quadrant //bounce to bottom-left - realOffsetX = touchOffsetX; - realOffsetY = touchOffsetY; - var icLefrPos = locContainer.getLeftBoundary(); - if (icLefrPos + realOffsetX <= this._leftBoundary) { - realOffsetX = this._leftBoundary - icLefrPos; - this._bounceLeftEvent(); - scrollEnabled = false; - } - icBottomPos = locContainer.getBottomBoundary(); - if (icBottomPos + touchOffsetY <= this._bottomBoundary) { - realOffsetY = this._bottomBoundary - icBottomPos; - this._bounceBottomEvent(); - scrollEnabled = false; - } - this._moveChildren(realOffsetX, realOffsetY); - } else if (touchOffsetX > 0.0 && touchOffsetY < 0.0){ //forth quadrant //bounce to bottom-right - realOffsetX = touchOffsetX; - realOffsetY = touchOffsetY; - icRightPos = locContainer.getRightBoundary(); - if (icRightPos + realOffsetX >= this._rightBoundary) { - realOffsetX = this._rightBoundary - icRightPos; - this._bounceRightEvent(); - scrollEnabled = false; - } - icBottomPos = locContainer.getBottomBoundary(); - if (icBottomPos + touchOffsetY <= this._bottomBoundary) { - realOffsetY = this._bottomBoundary - icBottomPos; - this._bounceBottomEvent(); - scrollEnabled = false; - } - this._moveChildren(realOffsetX, realOffsetY); - } else if (touchOffsetX === 0.0 && touchOffsetY > 0.0){ // bounce to top - realOffsetY = touchOffsetY; - icTopPos = locContainer.getTopBoundary(); - if (icTopPos + touchOffsetY >= this._topBoundary) { - realOffsetY = this._topBoundary - icTopPos; - this._bounceTopEvent(); - scrollEnabled = false; - } - this._moveChildren(0.0, realOffsetY); - } else if (touchOffsetX === 0.0 && touchOffsetY < 0.0) {//bounce to bottom - realOffsetY = touchOffsetY; - icBottomPos = locContainer.getBottomBoundary(); - if (icBottomPos + touchOffsetY <= this._bottomBoundary) { - realOffsetY = this._bottomBoundary - icBottomPos; - this._bounceBottomEvent(); - scrollEnabled = false; + + var totalMovement = cc.p(0 ,0); + + for(var i = 0; i < this._touchMoveDisplacements.length; ++i) + { + totalMovement.x += this._touchMoveDisplacements[i].x; + totalMovement.y += this._touchMoveDisplacements[i].y; + } + + return cc.pMult(totalMovement, 1 / totalTime); + }, + + _startInertiaScroll: function(touchMoveVelocity) + { + var MOVEMENT_FACTOR = 0.7; + var inertiaTotalMovement = cc.pMult(touchMoveVelocity, MOVEMENT_FACTOR); + this._startAttenuatingAutoScroll(inertiaTotalMovement, touchMoveVelocity); + }, + + _startBounceBackIfNeeded: function() + { + if (!this.bounceEnabled) + { + return false; + } + var bounceBackAmount = this._getHowMuchOutOfBoundary(); + if(bounceBackAmount.x === 0 && bounceBackAmount.y === 0) + { + return false; + } + + var BOUNCE_BACK_DURATION = 1.0; + this._startAutoScroll(bounceBackAmount, BOUNCE_BACK_DURATION, true); + return true; + }, + + _startAutoScrollToDestination: function(destination, timeInSec, attenuated) + { + this._startAutoScroll(cc.pSub(destination , this._innerContainer.getPosition()), timeInSec, attenuated); + }, + + _calculateAutoScrollTimeByInitialSpeed: function(initialSpeed) + { + // Calculate the time from the initial speed according to quintic polynomial. + return Math.sqrt(Math.sqrt(initialSpeed / 5)); + }, + + _startAttenuatingAutoScroll: function(deltaMove, initialVelocity) + { + var time = this._calculateAutoScrollTimeByInitialSpeed(cc.pLength(initialVelocity)); + this._startAutoScroll(deltaMove, time, true); + }, + + _startAutoScroll: function(deltaMove, timeInSec, attenuated) + { + var adjustedDeltaMove = this._flattenVectorByDirection(deltaMove); + + this._autoScrolling = true; + this._autoScrollTargetDelta = adjustedDeltaMove; + this._autoScrollAttenuate = attenuated; + this._autoScrollStartPosition = this._innerContainer.getPosition(); + this._autoScrollTotalTime = timeInSec; + this._autoScrollAccumulatedTime = 0; + this._autoScrollBraking = false; + this._autoScrollBrakingStartPosition = cc.p(0,0 ); + + // If the destination is also out of boundary of same side, start brake from beggining. + var currentOutOfBoundary = this._getHowMuchOutOfBoundary(); + if(currentOutOfBoundary.x !== 0 || currentOutOfBoundary.y !== 0) + { + this._autoScrollCurrentlyOutOfBoundary = true; + var afterOutOfBoundary = this._getHowMuchOutOfBoundary(adjustedDeltaMove); + if(currentOutOfBoundary.x * afterOutOfBoundary.x > 0 || currentOutOfBoundary.y * afterOutOfBoundary.y > 0) + { + this._autoScrollBraking = true; } - this._moveChildren(0.0, realOffsetY); - } else if (touchOffsetX > 0.0 && touchOffsetY === 0.0){ //bounce to right - realOffsetX = touchOffsetX; - icRightPos = locContainer.getRightBoundary(); - if (icRightPos + realOffsetX >= this._rightBoundary) { - realOffsetX = this._rightBoundary - icRightPos; - this._bounceRightEvent(); - scrollEnabled = false; + } + }, + + _isNecessaryAutoScrollBrake: function() + { + if(this._autoScrollBraking) + { + return true; + } + + if(this._isOutOfBoundary()) + { + // It just went out of boundary. + if(!this._autoScrollCurrentlyOutOfBoundary) + { + this._autoScrollCurrentlyOutOfBoundary = true; + this._autoScrollBraking = true; + this._autoScrollBrakingStartPosition = this.getInnerContainerPosition(); + return true; } - this._moveChildren(realOffsetX, 0.0); - }else if (touchOffsetX < 0.0 && touchOffsetY === 0.0){ //bounce to left - realOffsetX = touchOffsetX; - var icLeftPos = locContainer.getLeftBoundary(); - if (icLeftPos + realOffsetX <= this._leftBoundary) { - realOffsetX = this._leftBoundary - icLeftPos; - this._bounceLeftEvent(); - scrollEnabled = false; + } + else + { + this._autoScrollCurrentlyOutOfBoundary = false; + } + return false; + }, + + _processAutoScrolling: function(deltaTime) + { + var OUT_OF_BOUNDARY_BREAKING_FACTOR = 0.05; + // Make auto scroll shorter if it needs to deaccelerate. + var brakingFactor = (this._isNecessaryAutoScrollBrake() ? OUT_OF_BOUNDARY_BREAKING_FACTOR : 1); + + // Elapsed time + this._autoScrollAccumulatedTime += deltaTime * (1 / brakingFactor); + + // Calculate the progress percentage + var percentage = Math.min(1, this._autoScrollAccumulatedTime / this._autoScrollTotalTime); + if(this._autoScrollAttenuate) + { + percentage -= 1; + percentage = percentage * percentage * percentage * percentage * percentage + 1; + } + + // Calculate the new position + var newPosition = cc.pAdd(this._autoScrollStartPosition, cc.pMult(this._autoScrollTargetDelta,percentage)); + var reachedEnd = (percentage == 1); + + if(this.bounceEnabled) + { + // The new position is adjusted if out of boundary + newPosition = cc.pAdd(this._autoScrollBrakingStartPosition, cc.pMult(cc.pSub(newPosition, this._autoScrollBrakingStartPosition), brakingFactor)); + } + else + { + // Don't let go out of boundary + var moveDelta = cc.pSub(newPosition, this.getInnerContainerPosition()); + var outOfBoundary = this._getHowMuchOutOfBoundary(moveDelta); + if(outOfBoundary.x !== 0 || outOfBoundary.y !== 0) + { + newPosition.x += outOfBoundary.x; + newPosition.y += outOfBoundary.y; + + reachedEnd = true; } - this._moveChildren(realOffsetX, 0.0); } - return scrollEnabled; + + // Finish auto scroll if it ended + if(reachedEnd) + { + this._autoScrolling = false; + } + + this._moveInnerContainer(cc.pSub(newPosition, this.getInnerContainerPosition()), reachedEnd); }, - _checkCustomScrollDestination: function (touchOffsetX, touchOffsetY) { - var scrollEnabled = true; - var icBottomPos, icLeftPos, icRightPos, icTopPos; - var locContainer = this._innerContainer, locDestination = this._autoScrollDestination; - switch (this.direction) { - case ccui.ScrollView.DIR_VERTICAL: - if (this._autoScrollDir.y > 0) { - icBottomPos = locContainer.getBottomBoundary(); - if (icBottomPos + touchOffsetY >= locDestination.y) { - touchOffsetY = locDestination.y - icBottomPos; - scrollEnabled = false; - } - } else { - icBottomPos = locContainer.getBottomBoundary(); - if (icBottomPos + touchOffsetY <= locDestination.y) { - touchOffsetY = locDestination.y - icBottomPos; - scrollEnabled = false; - } - } - break; - case ccui.ScrollView.DIR_HORIZONTAL: - if (this._autoScrollDir.x > 0) { - icLeftPos = locContainer.getLeftBoundary(); - if (icLeftPos + touchOffsetX >= locDestination.x) { - touchOffsetX = locDestination.x - icLeftPos; - scrollEnabled = false; - } - } else { - icLeftPos = locContainer.getLeftBoundary(); - if (icLeftPos + touchOffsetX <= locDestination.x) { - touchOffsetX = locDestination.x - icLeftPos; - scrollEnabled = false; - } - } - break; - case ccui.ScrollView.DIR_BOTH: - if (touchOffsetX > 0.0 && touchOffsetY > 0.0){ // up right - icLeftPos = locContainer.getLeftBoundary(); - if (icLeftPos + touchOffsetX >= locDestination.x) { - touchOffsetX = locDestination.x - icLeftPos; - scrollEnabled = false; - } - icBottomPos = locContainer.getBottomBoundary(); - if (icBottomPos + touchOffsetY >= locDestination.y) { - touchOffsetY = locDestination.y - icBottomPos; - scrollEnabled = false; - } - } else if (touchOffsetX < 0.0 && touchOffsetY > 0.0){ // up left - icRightPos = locContainer.getRightBoundary(); - if (icRightPos + touchOffsetX <= locDestination.x) { - touchOffsetX = locDestination.x - icRightPos; - scrollEnabled = false; - } - icBottomPos = locContainer.getBottomBoundary(); - if (icBottomPos + touchOffsetY >= locDestination.y) { - touchOffsetY = locDestination.y - icBottomPos; - scrollEnabled = false; - } - } else if (touchOffsetX < 0.0 && touchOffsetY < 0.0){ // down left - icRightPos = locContainer.getRightBoundary(); - if (icRightPos + touchOffsetX <= locDestination.x) { - touchOffsetX = locDestination.x - icRightPos; - scrollEnabled = false; - } - icTopPos = locContainer.getTopBoundary(); - if (icTopPos + touchOffsetY <= locDestination.y) { - touchOffsetY = locDestination.y - icTopPos; - scrollEnabled = false; - } - } else if (touchOffsetX > 0.0 && touchOffsetY < 0.0){ // down right - icLeftPos = locContainer.getLeftBoundary(); - if (icLeftPos + touchOffsetX >= locDestination.x) { - touchOffsetX = locDestination.x - icLeftPos; - scrollEnabled = false; - } - icTopPos = locContainer.getTopBoundary(); - if (icTopPos + touchOffsetY <= locDestination.y) { - touchOffsetY = locDestination.y - icTopPos; - scrollEnabled = false; - } - } else if (touchOffsetX === 0.0 && touchOffsetY > 0.0){ // up - icBottomPos = locContainer.getBottomBoundary(); - if (icBottomPos + touchOffsetY >= locDestination.y) { - touchOffsetY = locDestination.y - icBottomPos; - scrollEnabled = false; - } - } else if (touchOffsetX < 0.0 && touchOffsetY === 0.0){ // left - icRightPos = locContainer.getRightBoundary(); - if (icRightPos + touchOffsetX <= locDestination.x) { - touchOffsetX = locDestination.x - icRightPos; - scrollEnabled = false; - } - } else if (touchOffsetX === 0.0 && touchOffsetY < 0.0){ // down - icTopPos = locContainer.getTopBoundary(); - if (icTopPos + touchOffsetY <= locDestination.y) { - touchOffsetY = locDestination.y - icTopPos; - scrollEnabled = false; - } - } else if (touchOffsetX > 0.0 && touchOffsetY === 0.0){ // right - icLeftPos = locContainer.getLeftBoundary(); - if (icLeftPos + touchOffsetX >= locDestination.x) { - touchOffsetX = locDestination.x - icLeftPos; - scrollEnabled = false; - } - } - break; - default: - break; + _jumpToDestination: function (desOrX, y) + { + if(desOrX.x === undefined) + { + desOrX = cc.p(desOrX, y); } - return scrollEnabled; + + this._autoScrolling = false; + this._moveInnerContainer(cc.pSub(desOrX, this.getInnerContainerPosition()), true); }, - _scrollChildren: function (touchOffsetX, touchOffsetY) { - var scrollEnabled = true; - this._scrollingEvent(); - switch (this.direction) { - case ccui.ScrollView.DIR_VERTICAL: // vertical - scrollEnabled = this._scrollChildrenVertical(touchOffsetX, touchOffsetY); - break; - case ccui.ScrollView.DIR_HORIZONTAL: // horizontal - scrollEnabled = this._scrollChildrenHorizontal(touchOffsetX, touchOffsetY); - break; - case ccui.ScrollView.DIR_BOTH: - scrollEnabled = this._scrollChildrenBoth(touchOffsetX, touchOffsetY); - break; - default: - break; + _scrollChildren: function(deltaMove) + { + var realMove = deltaMove; + if(this.bounceEnabled) + { + // If the position of the inner container is out of the boundary, the offsets should be divided by two. + var outOfBoundary = this._getHowMuchOutOfBoundary(); + realMove.x *= (outOfBoundary.x == 0 ? 1 : 0.5); + realMove.y *= (outOfBoundary.y == 0 ? 1 : 0.5); } - return scrollEnabled; - }, - - _scrollChildrenVertical: function(touchOffsetX, touchOffsetY){ - var realOffset = touchOffsetY; - var scrollEnabled = true; - var icBottomPos, icTopPos, locContainer = this._innerContainer; - if (this.bounceEnabled) { - icBottomPos = locContainer.getBottomBoundary(); - if (icBottomPos + touchOffsetY >= this._bounceBottomBoundary) { - realOffset = this._bounceBottomBoundary - icBottomPos; - this._scrollToBottomEvent(); - scrollEnabled = false; - } - icTopPos = locContainer.getTopBoundary(); - if (icTopPos + touchOffsetY <= this._bounceTopBoundary) { - realOffset = this._bounceTopBoundary - icTopPos; - this._scrollToTopEvent(); - scrollEnabled = false; - } - } else { - icBottomPos = locContainer.getBottomBoundary(); - if (icBottomPos + touchOffsetY >= this._bottomBoundary){ - realOffset = this._bottomBoundary - icBottomPos; - this._scrollToBottomEvent(); - scrollEnabled = false; - } - icTopPos = locContainer.getTopBoundary(); - if (icTopPos + touchOffsetY <= this._topBoundary) { - realOffset = this._topBoundary - icTopPos; - this._scrollToTopEvent(); - scrollEnabled = false; - } + if(!this.bounceEnabled) + { + var outOfBoundary = this._getHowMuchOutOfBoundary(realMove); + realMove.x += outOfBoundary.x; + realMove.y += outOfBoundary.y; } - this._moveChildren(0.0, realOffset); - return scrollEnabled; - }, - - _scrollChildrenHorizontal: function(touchOffsetX, touchOffestY){ - var scrollEnabled = true; - var realOffset = touchOffsetX; - var icRightPos, icLeftPos, locContainer = this._innerContainer; - if (this.bounceEnabled){ - icRightPos = locContainer.getRightBoundary(); - if (icRightPos + touchOffsetX <= this._bounceRightBoundary) { - realOffset = this._bounceRightBoundary - icRightPos; - this._scrollToRightEvent(); - scrollEnabled = false; - } - icLeftPos = locContainer.getLeftBoundary(); - if (icLeftPos + touchOffsetX >= this._bounceLeftBoundary) { - realOffset = this._bounceLeftBoundary - icLeftPos; - this._scrollToLeftEvent(); - scrollEnabled = false; - } - } else { - icRightPos = locContainer.getRightBoundary(); - if (icRightPos + touchOffsetX <= this._rightBoundary) { - realOffset = this._rightBoundary - icRightPos; - this._scrollToRightEvent(); - scrollEnabled = false; + + var scrolledToLeft = false; + var scrolledToRight = false; + var scrolledToTop = false; + var scrolledToBottom = false; + + if (realMove.y > 0.0) // up + { + var icBottomPos = this._innerContainer.getBottomBoundary(); + if (icBottomPos + realMove.y >= this._bottomBoundary) + { + scrolledToBottom = true; } - icLeftPos = locContainer.getLeftBoundary(); - if (icLeftPos + touchOffsetX >= this._leftBoundary) { - realOffset = this._leftBoundary - icLeftPos; - this._scrollToLeftEvent(); - scrollEnabled = false; + } + else if (realMove.y < 0.0) // down + { + var icTopPos = this._innerContainer.getTopBoundary(); + if (icTopPos + realMove.y <= this._topBoundary) + { + scrolledToTop = true; } } - this._moveChildren(realOffset, 0.0); - return scrollEnabled; - }, - - _scrollChildrenBoth: function (touchOffsetX, touchOffsetY) { - var scrollEnabled = true; - var realOffsetX = touchOffsetX; - var realOffsetY = touchOffsetY; - var icLeftPos, icBottomPos, icRightPos, icTopPos; - var locContainer = this._innerContainer; - if (this.bounceEnabled) { - if (touchOffsetX > 0.0 && touchOffsetY > 0.0) { // up right - icLeftPos = locContainer.getLeftBoundary(); - if (icLeftPos + touchOffsetX >= this._bounceLeftBoundary) { - realOffsetX = this._bounceLeftBoundary - icLeftPos; - this._scrollToLeftEvent(); - scrollEnabled = false; - } - icBottomPos = locContainer.getBottomBoundary(); - if (icBottomPos + touchOffsetY >= this._bounceBottomBoundary) { - realOffsetY = this._bounceBottomBoundary - icBottomPos; - this._scrollToBottomEvent(); - scrollEnabled = false; - } - } else if (touchOffsetX < 0.0 && touchOffsetY > 0.0) { // up left - icRightPos = locContainer.getRightBoundary(); - if (icRightPos + touchOffsetX <= this._bounceRightBoundary) { - realOffsetX = this._bounceRightBoundary - icRightPos; - this._scrollToRightEvent(); - scrollEnabled = false; - } - icBottomPos = locContainer.getBottomBoundary(); - if (icBottomPos + touchOffsetY >= this._bounceBottomBoundary) { - realOffsetY = this._bounceBottomBoundary - icBottomPos; - this._scrollToBottomEvent(); - scrollEnabled = false; - } - } else if (touchOffsetX < 0.0 && touchOffsetY < 0.0) { // down left - icRightPos = locContainer.getRightBoundary(); - if (icRightPos + touchOffsetX <= this._bounceRightBoundary) { - realOffsetX = this._bounceRightBoundary - icRightPos; - this._scrollToRightEvent(); - scrollEnabled = false; - } - icTopPos = locContainer.getTopBoundary(); - if (icTopPos + touchOffsetY <= this._bounceTopBoundary) { - realOffsetY = this._bounceTopBoundary - icTopPos; - this._scrollToTopEvent(); - scrollEnabled = false; - } - } else if (touchOffsetX > 0.0 && touchOffsetY < 0.0){ // down right - icLeftPos = locContainer.getLeftBoundary(); - if (icLeftPos + touchOffsetX >= this._bounceLeftBoundary) { - realOffsetX = this._bounceLeftBoundary - icLeftPos; - this._scrollToLeftEvent(); - scrollEnabled = false; - } - icTopPos = locContainer.getTopBoundary(); - if (icTopPos + touchOffsetY <= this._bounceTopBoundary) { - realOffsetY = this._bounceTopBoundary - icTopPos; - this._scrollToTopEvent(); - scrollEnabled = false; - } - } else if (touchOffsetX === 0.0 && touchOffsetY > 0.0){ // up - icBottomPos = locContainer.getBottomBoundary(); - if (icBottomPos + touchOffsetY >= this._bounceBottomBoundary) { - realOffsetY = this._bounceBottomBoundary - icBottomPos; - this._scrollToBottomEvent(); - scrollEnabled = false; - } - } else if (touchOffsetX < 0.0 && touchOffsetY === 0.0){ // left - icRightPos = locContainer.getRightBoundary(); - if (icRightPos + touchOffsetX <= this._bounceRightBoundary) { - realOffsetX = this._bounceRightBoundary - icRightPos; - this._scrollToRightEvent(); - scrollEnabled = false; - } - } else if (touchOffsetX === 0.0 && touchOffsetY < 0.0){ // down - icTopPos = locContainer.getTopBoundary(); - if (icTopPos + touchOffsetY <= this._bounceTopBoundary) { - realOffsetY = this._bounceTopBoundary - icTopPos; - this._scrollToTopEvent(); - scrollEnabled = false; - } - } else if (touchOffsetX > 0.0 && touchOffsetY === 0.0){ // right - icLeftPos = locContainer.getLeftBoundary(); - if (icLeftPos + touchOffsetX >= this._bounceLeftBoundary) { - realOffsetX = this._bounceLeftBoundary - icLeftPos; - this._scrollToLeftEvent(); - scrollEnabled = false; - } + + if (realMove.x < 0.0) // left + { + var icRightPos = this._innerContainer.getRightBoundary(); + if (icRightPos + realMove.x <= this._rightBoundary) + { + scrolledToRight = true; } - } else { - if (touchOffsetX > 0.0 && touchOffsetY > 0.0){ // up right - icLeftPos = locContainer.getLeftBoundary(); - if (icLeftPos + touchOffsetX >= this._leftBoundary) { - realOffsetX = this._leftBoundary - icLeftPos; - this._scrollToLeftEvent(); - scrollEnabled = false; - } - icBottomPos = locContainer.getBottomBoundary(); - if (icBottomPos + touchOffsetY >= this._bottomBoundary) { - realOffsetY = this._bottomBoundary - icBottomPos; - this._scrollToBottomEvent(); - scrollEnabled = false; - } - } else if (touchOffsetX < 0.0 && touchOffsetY > 0.0){ // up left - icRightPos = locContainer.getRightBoundary(); - if (icRightPos + touchOffsetX <= this._rightBoundary) { - realOffsetX = this._rightBoundary - icRightPos; - this._scrollToRightEvent(); - scrollEnabled = false; - } - icBottomPos = locContainer.getBottomBoundary(); - if (icBottomPos + touchOffsetY >= this._bottomBoundary) { - realOffsetY = this._bottomBoundary - icBottomPos; - this._scrollToBottomEvent(); - scrollEnabled = false; - } - } else if (touchOffsetX < 0.0 && touchOffsetY < 0.0){ // down left - icRightPos = locContainer.getRightBoundary(); - if (icRightPos + touchOffsetX <= this._rightBoundary) { - realOffsetX = this._rightBoundary - icRightPos; - this._scrollToRightEvent(); - scrollEnabled = false; - } - icTopPos = locContainer.getTopBoundary(); - if (icTopPos + touchOffsetY <= this._topBoundary) { - realOffsetY = this._topBoundary - icTopPos; - this._scrollToTopEvent(); - scrollEnabled = false; - } - } else if (touchOffsetX > 0.0 && touchOffsetY < 0.0){ // down right - icLeftPos = locContainer.getLeftBoundary(); - if (icLeftPos + touchOffsetX >= this._leftBoundary) { - realOffsetX = this._leftBoundary - icLeftPos; - this._scrollToLeftEvent(); - scrollEnabled = false; - } - icTopPos = this._innerContainer.getTopBoundary(); - if (icTopPos + touchOffsetY <= this._topBoundary) { - realOffsetY = this._topBoundary - icTopPos; - this._scrollToTopEvent(); - scrollEnabled = false; - } - } else if (touchOffsetX === 0.0 && touchOffsetY > 0.0) { // up - icBottomPos = this._innerContainer.getBottomBoundary(); - if (icBottomPos + touchOffsetY >= this._bottomBoundary) { - realOffsetY = this._bottomBoundary - icBottomPos; - this._scrollToBottomEvent(); - scrollEnabled = false; - } - } else if (touchOffsetX < 0.0 && touchOffsetY === 0.0){ // left - icRightPos = this._innerContainer.getRightBoundary(); - if (icRightPos + touchOffsetX <= this._rightBoundary) { - realOffsetX = this._rightBoundary - icRightPos; - this._scrollToRightEvent(); - scrollEnabled = false; - } - } else if (touchOffsetX === 0.0 && touchOffsetY < 0.0){ // down - icTopPos = this._innerContainer.getTopBoundary(); - if (icTopPos + touchOffsetY <= this._topBoundary) { - realOffsetY = this._topBoundary - icTopPos; - this._scrollToTopEvent(); - scrollEnabled = false; - } - } else if (touchOffsetX > 0.0 && touchOffsetY === 0.0){ // right - icLeftPos = this._innerContainer.getLeftBoundary(); - if (icLeftPos + touchOffsetX >= this._leftBoundary) { - realOffsetX = this._leftBoundary - icLeftPos; - this._scrollToLeftEvent(); - scrollEnabled = false; - } + } + else if (realMove.x > 0.0) // right + { + var icLeftPos = this._innerContainer.getLeftBoundary(); + if (icLeftPos + realMove.x >= this._leftBoundary) + { + scrolledToLeft = true; } } - this._moveChildren(realOffsetX, realOffsetY); - return scrollEnabled; + this._moveInnerContainer(realMove, false); + + if(realMove.x != 0 || realMove.y != 0) + { + this._processScrollingEvent(); + } + if(scrolledToBottom) + { + this._processScrollEvent(ccui.ScrollView.MOVEDIR_BOTTOM, false); + } + if(scrolledToTop) + { + this._processScrollEvent(ccui.ScrollView.MOVEDIR_TOP, false); + } + if(scrolledToLeft) + { + this._processScrollEvent(ccui.ScrollView.MOVEDIR_LEFT, false); + } + if(scrolledToRight) + { + this._processScrollEvent(ccui.ScrollView.MOVEDIR_RIGHT, false); + } }, /** @@ -1131,7 +779,7 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ * @param {Boolean} attenuated */ scrollToBottom: function (time, attenuated) { - this._startAutoScrollChildrenWithDestination(cc.p(this._innerContainer.getPositionX(), 0), time, attenuated); + this._startAutoScrollToDestination(cc.p(this._innerContainer.getPositionX(), 0), time, attenuated); }, /** @@ -1140,7 +788,7 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ * @param {Boolean} attenuated */ scrollToTop: function (time, attenuated) { - this._startAutoScrollChildrenWithDestination( + this._startAutoScrollToDestination( cc.p(this._innerContainer.getPositionX(), this._contentSize.height - this._innerContainer.getContentSize().height), time, attenuated); }, @@ -1150,7 +798,7 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ * @param {Boolean} attenuated */ scrollToLeft: function (time, attenuated) { - this._startAutoScrollChildrenWithDestination(cc.p(0, this._innerContainer.getPositionY()), time, attenuated); + this._startAutoScrollToDestination(cc.p(0, this._innerContainer.getPositionY()), time, attenuated); }, /** @@ -1159,7 +807,7 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ * @param {Boolean} attenuated */ scrollToRight: function (time, attenuated) { - this._startAutoScrollChildrenWithDestination( + this._startAutoScrollToDestination( cc.p(this._contentSize.width - this._innerContainer.getContentSize().width, this._innerContainer.getPositionY()), time, attenuated); }, @@ -1173,7 +821,7 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ cc.log("Scroll direction is not both!"); return; } - this._startAutoScrollChildrenWithDestination(cc.p(0, this._contentSize.height - this._innerContainer.getContentSize().height), time, attenuated); + this._startAutoScrollToDestination(cc.p(0, this._contentSize.height - this._innerContainer.getContentSize().height), time, attenuated); }, /** @@ -1187,7 +835,7 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ return; } var inSize = this._innerContainer.getContentSize(); - this._startAutoScrollChildrenWithDestination(cc.p(this._contentSize.width - inSize.width, + this._startAutoScrollToDestination(cc.p(this._contentSize.width - inSize.width, this._contentSize.height - inSize.height), time, attenuated); }, @@ -1201,7 +849,7 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ cc.log("Scroll direction is not both!"); return; } - this._startAutoScrollChildrenWithDestination(cc.p(0, 0), time, attenuated); + this._startAutoScrollToDestination(cc.p(0, 0), time, attenuated); }, /** @@ -1214,7 +862,7 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ cc.log("Scroll direction is not both!"); return; } - this._startAutoScrollChildrenWithDestination(cc.p(this._contentSize.width - this._innerContainer.getContentSize().width, 0), time, attenuated); + this._startAutoScrollToDestination(cc.p(this._contentSize.width - this._innerContainer.getContentSize().width, 0), time, attenuated); }, /** @@ -1226,7 +874,7 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ scrollToPercentVertical: function (percent, time, attenuated) { var minY = this._contentSize.height - this._innerContainer.getContentSize().height; var h = -minY; - this._startAutoScrollChildrenWithDestination(cc.p(this._innerContainer.getPositionX(), minY + percent * h / 100), time, attenuated); + this._startAutoScrollToDestination(cc.p(this._innerContainer.getPositionX(), minY + percent * h / 100), time, attenuated); }, /** @@ -1237,7 +885,7 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ */ scrollToPercentHorizontal: function (percent, time, attenuated) { var w = this._innerContainer.getContentSize().width - this._contentSize.width; - this._startAutoScrollChildrenWithDestination(cc.p(-(percent * w / 100), this._innerContainer.getPositionY()), time, attenuated); + this._startAutoScrollToDestination(cc.p(-(percent * w / 100), this._innerContainer.getPositionY()), time, attenuated); }, /** @@ -1252,7 +900,7 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ var minY = this._contentSize.height - this._innerContainer.getContentSize().height; var h = -minY; var w = this._innerContainer.getContentSize().width - this._contentSize.width; - this._startAutoScrollChildrenWithDestination(cc.p(-(percent.x * w / 100), minY + percent.y * h / 100), time, attenuated); + this._startAutoScrollToDestination(cc.p(-(percent.x * w / 100), minY + percent.y * h / 100), time, attenuated); }, /** @@ -1361,72 +1009,80 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ this._jumpToDestination(-(percent.x * w / 100), minY + percent.y * h / 100); }, - _startRecordSlidAction: function () { - if (this._autoScroll) - this._stopAutoScrollChildren(); - if (this._bouncing) - this._stopBounceChildren(); - this._slidTime = 0.0; - }, - - _endRecordSlidAction: function () { - if (!this._checkNeedBounce() && this.inertiaScrollEnabled) { - if (this._slidTime <= 0.016) - return; - var totalDis = 0, dir; - var touchEndPositionInNodeSpace = this.convertToNodeSpace(this._touchEndPosition); - var touchBeganPositionInNodeSpace = this.convertToNodeSpace(this._touchBeganPosition); - switch (this.direction) { - case ccui.ScrollView.DIR_VERTICAL : - totalDis = touchEndPositionInNodeSpace.y - touchBeganPositionInNodeSpace.y; - dir = (totalDis < 0) ? ccui.ScrollView.SCROLLDIR_DOWN : ccui.ScrollView.SCROLLDIR_UP; - break; - case ccui.ScrollView.DIR_HORIZONTAL: - totalDis = touchEndPositionInNodeSpace.x - touchBeganPositionInNodeSpace.x; - dir = totalDis < 0 ? ccui.ScrollView.SCROLLDIR_LEFT : ccui.ScrollView.SCROLLDIR_RIGHT; - break; - case ccui.ScrollView.DIR_BOTH : - var subVector = cc.pSub(touchEndPositionInNodeSpace, touchBeganPositionInNodeSpace); - totalDis = cc.pLength(subVector); - dir = cc.pNormalize(subVector); - break; - default: - dir = cc.p(0,0); - break; - } - var orSpeed = Math.min(Math.abs(totalDis) / (this._slidTime), ccui.ScrollView.AUTO_SCROLL_MAX_SPEED); - this._startAutoScrollChildrenWithOriginalSpeed(dir, orSpeed, true, -1000); - this._slidTime = 0; + _gatherTouchMove: function(delta) + { + var NUMBER_OF_GATHERED_TOUCHES_FOR_MOVE_SPEED = 5; + while(this._touchMoveDisplacements.length >= NUMBER_OF_GATHERED_TOUCHES_FOR_MOVE_SPEED) + { + this._touchMoveDisplacements.splice(0,1); + this._touchMoveTimeDeltas.splice(0,1) } + this._touchMoveDisplacements.push(delta); + + var timestamp = (new Date()).getTime(); + this._touchMoveTimeDeltas.push((timestamp - this._touchMovePreviousTimestamp) / 1000); + this._touchMovePreviousTimestamp = timestamp; }, _handlePressLogic: function (touch) { - this._startRecordSlidAction(); this._bePressed = true; + this._autoScrolling = false; + + // Clear gathered touch move information + + this._touchMovePreviousTimestamp = (new Date()).getTime(); + this._touchMoveDisplacements.length = 0; + this._touchMoveTimeDeltas.length = 0; + + // + //if(_verticalScrollBar != nullptr) + //{ + // _verticalScrollBar->onTouchBegan(); + //} + //if(_horizontalScrollBar != nullptr) + //{ + // _horizontalScrollBar->onTouchBegan(); + //} + }, _handleMoveLogic: function (touch) { var touchPositionInNodeSpace = this.convertToNodeSpace(touch.getLocation()), previousTouchPositionInNodeSpace = this.convertToNodeSpace(touch.getPreviousLocation()); var delta = cc.pSub(touchPositionInNodeSpace, previousTouchPositionInNodeSpace); - switch (this.direction) { - case ccui.ScrollView.DIR_VERTICAL: // vertical - this._scrollChildren(0.0, delta.y); - break; - case ccui.ScrollView.DIR_HORIZONTAL: // horizontal - this._scrollChildren(delta.x, 0); - break; - case ccui.ScrollView.DIR_BOTH: // both - this._scrollChildren(delta.x, delta.y); - break; - default: - break; - } + + this._scrollChildren(delta); + this._gatherTouchMove(delta); }, _handleReleaseLogic: function (touch) { - this._endRecordSlidAction(); + + var touchPositionInNodeSpace = this.convertToNodeSpace(touch.getLocation()), + previousTouchPositionInNodeSpace = this.convertToNodeSpace(touch.getPreviousLocation()); + var delta = cc.pSub(touchPositionInNodeSpace, previousTouchPositionInNodeSpace); + + this._gatherTouchMove(delta); + this._bePressed = false; + + var bounceBackStarted = this._startBounceBackIfNeeded(); + if(!bounceBackStarted && this.inertiaScrollEnabled) + { + var touchMoveVelocity = this._calculateTouchMoveVelocity(); + if(touchMoveVelocity.x !== 0 || touchMoveVelocity.y !== 0) + { + this._startInertiaScroll(touchMoveVelocity); + } + } + + //if(_verticalScrollBar != nullptr) + //{ + // _verticalScrollBar->onTouchEnded(); + //} + //if(_horizontalScrollBar != nullptr) + //{ + // _horizontalScrollBar->onTouchEnded(); + //} }, /** @@ -1475,7 +1131,7 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ onTouchCancelled: function (touch, event) { ccui.Layout.prototype.onTouchCancelled.call(this, touch, event); if (!this._isInterceptTouch) - this.handleReleaseLogic(touch); + this._handleReleaseLogic(touch); this._isInterceptTouch = false; }, @@ -1484,16 +1140,8 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ * @param {Number} dt */ update: function (dt) { - if (this._autoScroll) - this._autoScrollChildren(dt); - if (this._bouncing) - this._bounceChildren(dt); - this._recordSlidTime(dt); - }, - - _recordSlidTime: function (dt) { - if (this._bePressed) - this._slidTime += dt; + if (this._autoScrolling) + this._processAutoScrolling(dt); }, /** @@ -1537,103 +1185,44 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ } }, - _scrollToTopEvent: function () { - if(this._scrollViewEventSelector){ - if (this._scrollViewEventListener) - this._scrollViewEventSelector.call(this._scrollViewEventListener, this, ccui.ScrollView.EVENT_SCROLL_TO_TOP); - else - this._scrollViewEventSelector(this, ccui.ScrollView.EVENT_SCROLL_TO_TOP); - } - if(this._ccEventCallback) - this._ccEventCallback(this, ccui.ScrollView.EVENT_SCROLL_TO_TOP); - }, - - _scrollToBottomEvent: function () { - if(this._scrollViewEventSelector){ - if (this._scrollViewEventListener) - this._scrollViewEventSelector.call(this._scrollViewEventListener, this, ccui.ScrollView.EVENT_SCROLL_TO_BOTTOM); - else - this._scrollViewEventSelector(this, ccui.ScrollView.EVENT_SCROLL_TO_BOTTOM); - } - if(this._ccEventCallback) - this._ccEventCallback(this, ccui.ScrollView.EVENT_SCROLL_TO_BOTTOM); - }, - - _scrollToLeftEvent: function () { - if(this._scrollViewEventSelector){ - if (this._scrollViewEventListener) - this._scrollViewEventSelector.call(this._scrollViewEventListener, this, ccui.ScrollView.EVENT_SCROLL_TO_LEFT); - else - this._scrollViewEventSelector(this, ccui.ScrollView.EVENT_SCROLL_TO_LEFT); - } - if(this._ccEventCallback) - this._ccEventCallback(this, ccui.ScrollView.EVENT_SCROLL_TO_LEFT); - }, - - _scrollToRightEvent: function () { - if(this._scrollViewEventSelector){ - if (this._scrollViewEventListener) - this._scrollViewEventSelector.call(this._scrollViewEventListener, this, ccui.ScrollView.EVENT_SCROLL_TO_RIGHT); - else - this._scrollViewEventSelector(this, ccui.ScrollView.EVENT_SCROLL_TO_RIGHT); - } - if(this._ccEventCallback) - this._ccEventCallback(this, ccui.ScrollView.EVENT_SCROLL_TO_RIGHT); - }, - - _scrollingEvent: function () { - if(this._scrollViewEventSelector){ - if (this._scrollViewEventListener) - this._scrollViewEventSelector.call(this._scrollViewEventListener, this, ccui.ScrollView.EVENT_SCROLLING); - else - this._scrollViewEventSelector(this, ccui.ScrollView.EVENT_SCROLLING); - } - if(this._ccEventCallback) - this._ccEventCallback(this, ccui.ScrollView.EVENT_SCROLLING); - }, + _processScrollEvent: function(directionEvent, bounce) + { + var event = 0; - _bounceTopEvent: function () { - if(this._scrollViewEventSelector){ - if (this._scrollViewEventListener) - this._scrollViewEventSelector.call(this._scrollViewEventListener, this, ccui.ScrollView.EVENT_BOUNCE_TOP); - else - this._scrollViewEventSelector(this, ccui.ScrollView.EVENT_BOUNCE_TOP); + switch(directionEvent) + { + case ccui.ScrollView.MOVEDIR_TOP: + event = (bounce ? ccui.ScrollView.EVENT_BOUNCE_TOP : ccui.ScrollView.EVENT_SCROLL_TO_TOP); + break; + case ccui.ScrollView.MOVEDIR_BOTTOM: + event = (bounce ? ccui.ScrollView.EVENT_BOUNCE_BOTTOM : ccui.ScrollView.EVENT_SCROLL_TO_BOTTOM); + break; + case ccui.ScrollView.MOVEDIR_LEFT: + event = (bounce ? ccui.ScrollView.EVENT_BOUNCE_LEFT : ccui.ScrollView.EVENT_SCROLL_TO_LEFT); + break; + case ccui.ScrollView.MOVEDIR_RIGHT: + event = (bounce ? ccui.ScrollView.EVENT_BOUNCE_RIGHT : ccui.ScrollView.EVENT_SCROLL_TO_RIGHT); + break; } - if(this._ccEventCallback) - this._ccEventCallback(this, ccui.ScrollView.EVENT_BOUNCE_TOP); - }, - _bounceBottomEvent: function () { - if(this._scrollViewEventSelector){ - if (this._scrollViewEventListener) - this._scrollViewEventSelector.call(this._scrollViewEventListener, this, ccui.ScrollView.EVENT_BOUNCE_BOTTOM); - else - this._scrollViewEventSelector(this, ccui.ScrollView.EVENT_BOUNCE_BOTTOM); - } - if(this._ccEventCallback) - this._ccEventCallback(this, ccui.ScrollView.EVENT_BOUNCE_BOTTOM); + this._dispatchEvent(event); }, - _bounceLeftEvent: function () { - if(this._scrollViewEventSelector){ - if (this._scrollViewEventListener) - this._scrollViewEventSelector.call(this._scrollViewEventListener, this, ccui.ScrollView.EVENT_BOUNCE_LEFT); - else - this._scrollViewEventSelector(this, ccui.ScrollView.EVENT_BOUNCE_LEFT); - } - if(this._ccEventCallback) - this._ccEventCallback(this, ccui.ScrollView.EVENT_BOUNCE_LEFT); + _processScrollingEvent: function() + { + this._dispatchEvent( ccui.ScrollView.EVENT_SCROLLING); }, - _bounceRightEvent: function () { + _dispatchEvent: function(event) + { if(this._scrollViewEventSelector){ if (this._scrollViewEventListener) - this._scrollViewEventSelector.call(this._scrollViewEventListener, this, ccui.ScrollView.EVENT_BOUNCE_RIGHT); + this._scrollViewEventSelector.call(this._scrollViewEventListener, this, event); else - this._scrollViewEventSelector(this, ccui.ScrollView.EVENT_BOUNCE_RIGHT); + this._scrollViewEventSelector(this, event); } if(this._ccEventCallback) - this._ccEventCallback(this, ccui.ScrollView.EVENT_BOUNCE_RIGHT); + this._ccEventCallback(this, event); }, /** @@ -1755,9 +1344,31 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ if(scrollView instanceof ccui.ScrollView) { ccui.Layout.prototype._copySpecialProperties.call(this, scrollView); this.setInnerContainerSize(scrollView.getInnerContainerSize()); + this.setInnerContainerPosition(scrollView.getInnerContainerPosition()); this.setDirection(scrollView.direction); + + this._topBoundary = scrollView._topBoundary; + this._bottomBoundary = scrollView._bottomBoundary; + this._leftBoundary = scrollView._leftBoundary; + this._rightBoundary = scrollView._rightBoundary; + this._bePressed = scrollView._bePressed; + this._childFocusCancelOffset = scrollView._childFocusCancelOffset; + this._touchMoveDisplacements = scrollView._touchMoveDisplacements; + this._touchMoveTimeDeltas = scrollView._touchMoveTimeDeltas; + this._touchMovePreviousTimestamp = scrollView._touchMovePreviousTimestamp; + this._autoScrolling = scrollView._autoScrolling; + this._autoScrollAttenuate = scrollView._autoScrollAttenuate; + this._autoScrollStartPosition = scrollView._autoScrollStartPosition; + this._autoScrollTargetDelta = scrollView._autoScrollTargetDelta; + this._autoScrollTotalTime = scrollView._autoScrollTotalTime; + this._autoScrollAccumulatedTime = scrollView._autoScrollAccumulatedTime; + this._autoScrollCurrentlyOutOfBoundary = scrollView._autoScrollCurrentlyOutOfBoundary; + this._autoScrollBraking = scrollView._autoScrollBraking; + this._autoScrollBrakingStartPosition = scrollView._autoScrollBrakingStartPosition; + this.setBounceEnabled(scrollView.bounceEnabled); this.setInertiaScrollEnabled(scrollView.inertiaScrollEnabled); + this._scrollViewEventListener = scrollView._scrollViewEventListener; this._scrollViewEventSelector = scrollView._scrollViewEventSelector; this._ccEventCallback = scrollView._ccEventCallback; @@ -1924,18 +1535,18 @@ ccui.ScrollView.EVENT_BOUNCE_LEFT = 7; * @type {number} */ ccui.ScrollView.EVENT_BOUNCE_RIGHT = 8; - /** - * The auto scroll max speed of ccui.ScrollView. + * The flag container moved of ccui.ScrollView's event. * @constant * @type {number} */ -ccui.ScrollView.AUTO_SCROLL_MAX_SPEED = 1000; +ccui.ScrollView.EVENT_CONTAINER_MOVED = 9; /** * @ignore */ -ccui.ScrollView.SCROLLDIR_UP = cc.p(0, 1); -ccui.ScrollView.SCROLLDIR_DOWN = cc.p(0, -1); -ccui.ScrollView.SCROLLDIR_LEFT = cc.p(-1, 0); -ccui.ScrollView.SCROLLDIR_RIGHT = cc.p(1, 0); + +ccui.ScrollView.MOVEDIR_TOP = 0; +ccui.ScrollView.MOVEDIR_BOTTOM = 1; +ccui.ScrollView.MOVEDIR_LEFT = 2; +ccui.ScrollView.MOVEDIR_RIGHT = 3; From 716d77d48eedd9f0e6e5c81a8db9418e271e631c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D0=B5=D1=81=D1=88=D0=B0=D0=BF=D0=BE=D1=88=D0=BD?= =?UTF-8?q?=D0=B8=D0=BA=D0=BE=D0=B2=20=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0?= Date: Fri, 27 Nov 2015 10:49:24 +0300 Subject: [PATCH 02/19] Refactor ccui.ListView to correspond coso2d-x v3.9 api. --- .../uiwidgets/scroll-widget/UIListView.js | 578 +++++++++++++++++- 1 file changed, 560 insertions(+), 18 deletions(-) diff --git a/extensions/ccui/uiwidgets/scroll-widget/UIListView.js b/extensions/ccui/uiwidgets/scroll-widget/UIListView.js index 16be0493c9..edb9ab6344 100644 --- a/extensions/ccui/uiwidgets/scroll-widget/UIListView.js +++ b/extensions/ccui/uiwidgets/scroll-widget/UIListView.js @@ -49,6 +49,9 @@ ccui.ListView = ccui.ScrollView.extend(/** @lends ccui.ListView# */{ _listViewEventListener: null, _listViewEventSelector: null, + + _magneticAllowedOutOfBoundary: true, + _magneticType: 0, /** * allocates and initializes a UIListView. * Constructor of ccui.ListView, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function. @@ -57,8 +60,8 @@ ccui.ListView = ccui.ScrollView.extend(/** @lends ccui.ListView# */{ * var aListView = new ccui.ListView(); */ ctor: function () { - ccui.ScrollView.prototype.ctor.call(this); this._items = []; + ccui.ScrollView.prototype.ctor.call(this); this._gravity = ccui.ListView.GRAVITY_CENTER_VERTICAL; this.setTouchEnabled(true); @@ -72,7 +75,7 @@ ccui.ListView = ccui.ScrollView.extend(/** @lends ccui.ListView# */{ */ init: function () { if (ccui.ScrollView.prototype.init.call(this)) { - this.setLayoutType(ccui.Layout.LINEAR_VERTICAL); + this.setDirection(ccui.ScrollView.DIR_VERTICAL); return true; } return false; @@ -91,6 +94,16 @@ ccui.ListView = ccui.ScrollView.extend(/** @lends ccui.ListView# */{ this._model = model; }, + _handleReleaseLogic: function(touch) + { + ccui.ScrollView.prototype._handleReleaseLogic.call(this, touch); + + if(!this._autoScrolling) + { + this._startMagneticScroll(); + } + }, + _updateInnerContainerSize: function () { var locItems = this._items, length, i; switch (this.direction) { @@ -235,7 +248,10 @@ ccui.ListView = ccui.ScrollView.extend(/** @lends ccui.ListView# */{ tag = tag || widget.getName(); ccui.ScrollView.prototype.addChild.call(this, widget, zOrder, tag); if(widget instanceof ccui.Widget) + { this._items.push(widget); + this._outOfBoundaryAmountDirty = true; + } } }, @@ -250,6 +266,9 @@ ccui.ListView = ccui.ScrollView.extend(/** @lends ccui.ListView# */{ var index = this._items.indexOf(widget); if(index > -1) this._items.splice(index, 1); + + this._outOfBoundaryAmountDirty = true; + ccui.ScrollView.prototype.removeChild.call(this, widget, cleanup); } }, @@ -268,6 +287,8 @@ ccui.ListView = ccui.ScrollView.extend(/** @lends ccui.ListView# */{ removeAllChildrenWithCleanup: function(cleanup){ ccui.ScrollView.prototype.removeAllChildrenWithCleanup.call(this, cleanup); this._items = []; + + this._outOfBoundaryAmountDirty = true; }, /** @@ -277,6 +298,8 @@ ccui.ListView = ccui.ScrollView.extend(/** @lends ccui.ListView# */{ */ insertCustomItem: function (item, index) { this._items.splice(index, 0, item); + + this._outOfBoundaryAmountDirty = true; ccui.ScrollView.prototype.addChild.call(this, item); this._remedyLayoutParameter(item); this._refreshViewDirty = true; @@ -349,6 +372,44 @@ ccui.ListView = ccui.ScrollView.extend(/** @lends ccui.ListView# */{ this._refreshViewDirty = true; }, + /** + * Set magnetic type of ListView. + * @param {ccui.ListView.MAGNETIC_NONE|ccui.ListView.MAGNETIC_CENTER,ccui.ListView.MAGNETIC_BOTH_END|ccui.ListView.MAGNETIC_LEFT|ccui.ListView.MAGNETIC_RIGHT|ccui.ListView.MAGNETIC_TOP|ccui.ListView.MAGNETIC_BOTTOM} magneticType + */ + setMagneticType: function(magneticType) + { + this._magneticType = magneticType; + this._outOfBoundaryAmountDirty = true; + this._startMagneticScroll(); + }, + + /** + * Get magnetic type of ListView. + * @returns {number} + */ + getMagneticType: function() + { + return this._magneticType; + }, + + /** + * Set magnetic allowed out of boundary. + * @param {boolean} magneticAllowedOutOfBoundary + */ + setMagneticAllowedOutOfBoundary: function(magneticAllowedOutOfBoundary) + { + this._magneticAllowedOutOfBoundary = magneticAllowedOutOfBoundary; + }, + + /** + * Query whether the magnetic out of boundary is allowed. + * @returns {boolean} + */ + getMagneticAllowedOutOfBoundary: function() + { + return this._magneticAllowedOutOfBoundary; + }, + /** * Changes the margin between each item. * @param {Number} margin @@ -389,8 +450,373 @@ ccui.ListView = ccui.ScrollView.extend(/** @lends ccui.ListView# */{ ccui.ScrollView.prototype.setDirection.call(this, dir); }, + _getHowMuchOutOfBoundary: function(addition) + { + if(!this._magneticAllowedOutOfBoundary || this._items.length === 0) + { + return ccui.ScrollView.prototype._getHowMuchOutOfBoundary.call(this, addition); + } + else if(this._magneticType === ccui.ListView.MAGNETIC_NONE || this._magneticType === ccui.ListView.MAGNETIC_BOTH_END) + { + return ccui.ScrollView.prototype._getHowMuchOutOfBoundary.call(this, addition); + } + else if(addition.x === 0 && addition.y === 0 && !this._outOfBoundaryAmountDirty) + { + return this._outOfBoundaryAmount; + } + + // If it is allowed to be out of boundary by magnetic, adjust the boundaries according to the magnetic type. + var leftBoundary = this._leftBoundary; + var rightBoundary = this._rightBoundary; + var topBoundary = this._topBoundary; + var bottomBoundary = this._bottomBoundary; + + var lastItemIndex = this._items.length - 1; + var contentSize = this.getContentSize(); + var firstItemAdjustment = cc.p(0, 0); + var lastItemAdjustment = cc.p(0, 0); + + switch (this._magneticType) + { + case ccui.ListView.MAGNETIC_CENTER: + firstItemAdjustment.x = (contentSize.width - this._items[0].width) / 2; + firstItemAdjustment.y = (contentSize.height - this._items[0].height) / 2; + + lastItemAdjustment.x = (contentSize.width - this._items[lastItemIndex].width) / 2; + lastItemAdjustment.y = (contentSize.height - this._items[lastItemIndex].height) / 2; + + break; + case ccui.ListView.MAGNETIC_LEFT: + case ccui.ListView.MAGNETIC_TOP: + lastItemAdjustment.x = contentSize.width - this._items[lastItemIndex].width; + lastItemAdjustment.y = contentSize.height - this._items[lastItemIndex].height; + break; + case ccui.ListView.MAGNETIC_RIGHT: + case ccui.ListView.MAGNETIC_BOTTOM: + firstItemAdjustment.x = contentSize.width - this._items[0].width; + firstItemAdjustment.y = contentSize.height - this._items[0].height; + break; + } + + leftBoundary += firstItemAdjustment.x; + rightBoundary -= lastItemAdjustment.x; + topBoundary -= firstItemAdjustment.y; + bottomBoundary += lastItemAdjustment.y; + + + // Calculate the actual amount + var outOfBoundaryAmount = cc.p(0, 0); + + if(this._innerContainer.getLeftBoundary() + addition.x > leftBoundary) + { + outOfBoundaryAmount.x = leftBoundary - (this._innerContainer.getLeftBoundary() + addition.x); + } + else if(this._innerContainer.getRightBoundary() + addition.x < rightBoundary) + { + outOfBoundaryAmount.x = rightBoundary - (this._innerContainer.getRightBoundary() + addition.x); + } + + if(this._innerContainer.getTopBoundary() + addition.y < topBoundary) + { + outOfBoundaryAmount.y = topBoundary - (this._innerContainer.getTopBoundary() + addition.y); + } + else if(this._innerContainer.getBottomBoundary() + addition.y > bottomBoundary) + { + outOfBoundaryAmount.y = bottomBoundary - (this._innerContainer.getBottomBoundary() + addition.y); + } + + if(addition.x === 0 && addition.y === 0) + { + this._outOfBoundaryAmount = outOfBoundaryAmount; + this._outOfBoundaryAmountDirty = false; + } + return outOfBoundaryAmount; + }, + + _calculateItemPositionWithAnchor: function(item, itemAnchorPoint) + { + var origin = cc.p(item.getLeftBoundary(), item.getBottomBoundary()); + var size = item.getContentSize(); + + return cc.p(origin. x + size.width * itemAnchorPoint.x, origin.y + size.height * itemAnchorPoint.y); + }, + + _findClosestItem: function(targetPosition, items, itemAnchorPoint, firstIndex, distanceFromFirst, lastIndex, distanceFromLast) + { + cc.assert(firstIndex >= 0 && lastIndex < items.length && firstIndex <= lastIndex, ""); + if (firstIndex === lastIndex) + { + return items[firstIndex]; + } + if (lastIndex - firstIndex === 1) + { + if (distanceFromFirst <= distanceFromLast) + { + return items[firstIndex]; + } + else + { + return items[lastIndex]; + } + } + + // Binary search + var midIndex = Math.floor((firstIndex + lastIndex) / 2); + var itemPosition = this._calculateItemPositionWithAnchor(items[midIndex], itemAnchorPoint); + var distanceFromMid = cc.pLength(cc.pSub(targetPosition, itemPosition)); + + if (distanceFromFirst <= distanceFromLast) + { + // Left half + return this._findClosestItem(targetPosition, items, itemAnchorPoint, firstIndex, distanceFromFirst, midIndex, distanceFromMid); + } + else + { + // Right half + return this._findClosestItem(targetPosition, items, itemAnchorPoint, midIndex, distanceFromMid, lastIndex, distanceFromLast); + } + }, + + /** + * Query the closest item to a specific position in inner container. + * + * @param {cc.Point} targetPosition Specifies the target position in inner container's coordinates. + * @param {cc.Point} itemAnchorPoint Specifies an anchor point of each item for position to calculate distance. + * @returns {?ccui.Widget} A item instance if list view is not empty. Otherwise, returns null. + */ + getClosestItemToPosition: function(targetPosition, itemAnchorPoint) + { + if (this._items.length === 0) + { + return null; + } + + // Find the closest item through binary search + var firstIndex = 0; + var firstPosition = this._calculateItemPositionWithAnchor(this._items[firstIndex], itemAnchorPoint); + var distanceFromFirst = cc.pLength(cc.pSub(targetPosition, firstPosition)); + + var lastIndex = this._items.length - 1; + var lastPosition = this._calculateItemPositionWithAnchor(this._items[lastIndex], itemAnchorPoint); + var distanceFromLast = cc.pLength(cc.pSub(targetPosition, lastPosition)); + + return this._findClosestItem(targetPosition, this._items, itemAnchorPoint, firstIndex, distanceFromFirst, lastIndex, distanceFromLast); + }, + + /** + * Query the closest item to a specific position in current view.
+ * For instance, to find the item in the center of view, call 'getClosestItemToPositionInCurrentView(cc.p(0.5, 0.5), cc.p(0.5, 0.5))'. + * + * @param {cc.Point} positionRatioInView Specifies the target position with ratio in list view's content size. + * @param {cc.Point} itemAnchorPoint Specifies an anchor point of each item for position to calculate distance. + * @returns {?ccui.Widget} A item instance if list view is not empty. Otherwise, returns null. + */ + + getClosestItemToPositionInCurrentView: function(positionRatioInView, itemAnchorPoint) + { + // Calculate the target position + var contentSize = this.getContentSize(); + var targetPosition = cc.pMult(this._innerContainer.getPosition(), -1); + targetPosition.x += contentSize.width * positionRatioInView.x; + targetPosition.y += contentSize.height * positionRatioInView.y; + + return this.getClosestItemToPosition(targetPosition, itemAnchorPoint); + }, + + /** + * Query the center item + * @returns {?ccui.Widget} A item instance. + */ + getCenterItemInCurrentView: function() + { + return this.getClosestItemToPositionInCurrentView(cc.p(0.5, 0.5), cc.p(0.5, 0.5)); + }, + + /** + * Query the leftmost item in horizontal list + * @returns {?ccui.Widget} A item instance. + */ + getLeftmostItemInCurrentView: function() + { + if(this._direction === ccui.ScrollView.DIR_HORIZONTAL) + { + return this.getClosestItemToPositionInCurrentView(cc.p(0, 0.5), cc.p(0.5, 0.5)); + } + + return null; + }, + + /** + * Query the rightmost item in horizontal list + * @returns {?ccui.Widget} A item instance. + */ + getRightmostItemInCurrentView: function() + { + if(this._direction === ccui.ScrollView.DIR_HORIZONTAL) + { + return this.getClosestItemToPositionInCurrentView(cc.p(1, 0.5), cc.p(0.5, 0.5)); + } + + return null; + }, + + /** + * Query the topmost item in horizontal list + * @returns {?ccui.Widget} A item instance. + */ + getTopmostItemInCurrentView: function() + { + if(this._direction === ccui.ScrollView.DIR_VERTICAL) + { + return this.getClosestItemToPositionInCurrentView(cc.p(0.5, 1), cc.p(0.5, 0.5)); + } + + return null; + }, + + /** + * Query the topmost item in horizontal list + * @returns {?ccui.Widget} A item instance. + */ + getBottommostItemInCurrentView: function() + { + if(this._direction === ccui.ScrollView.DIR_VERTICAL) + { + return this.getClosestItemToPositionInCurrentView(cc.p(0.5, 0), cc.p(0.5, 0.5)); + } + + return null; + }, + + _calculateItemDestination: function(positionRatioInView, item, itemAnchorPoint) + { + var contentSize = this.getContentSize(); + var positionInView = cc.p(0, 0); + positionInView.x += contentSize.width * positionRatioInView.x; + positionInView.y += contentSize.height * positionRatioInView.y; + + var itemPosition = this._calculateItemPositionWithAnchor(item, itemAnchorPoint); + return cc.pMult(cc.pSub(itemPosition, positionInView), -1); + }, + + jumpToBottom: function() + { + this.doLayout(); + ccui.ScrollView.prototype.jumpToBottom.call(this); + }, + + jumpToTop: function() + { + this.doLayout(); + ccui.ScrollView.prototype.jumpToTop.call(this); + }, + + jumpToLeft: function() + { + this.doLayout(); + ccui.ScrollView.prototype.jumpToLeft.call(this); + }, + + jumpToRight: function() + { + this.doLayout(); + ccui.ScrollView.prototype.jumpToRight.call(this); + }, + + jumpToTopLeft: function() + { + this.doLayout(); + ccui.ScrollView.prototype.jumpToTopLeft.call(this); + }, + + jumpToTopRight: function() + { + this.doLayout(); + ccui.ScrollView.prototype.jumpToTopRight.call(this); + }, + + jumpToBottomLeft: function() + { + this.doLayout(); + ccui.ScrollView.prototype.jumpToBottomLeft.call(this); + }, + + jumpToBottomRight: function() + { + this.doLayout(); + ccui.ScrollView.prototype.jumpToBottomRight.call(this); + }, + + jumpToPercentVertical: function(percent) + { + this.doLayout(); + ccui.ScrollView.prototype.jumpToPercentVertical.call(this, percent); + }, + + jumpToPercentHorizontal: function(percent) + { + this.doLayout(); + ccui.ScrollView.prototype.jumpToPercentHorizontal.call(this, percent); + }, + + jumpToPercentBothDirection: function(percent) + { + this.doLayout(); + ccui.ScrollView.prototype.jumpToPercentBothDirection.call(this, percent); + }, + + /** + * Jump to specific item + * @param {number} itemIndex Specifies the item's index + * @param {cc.Point} positionRatioInView Specifies the position with ratio in list view's content size. + * @param {cc.Point} itemAnchorPoint Specifies an anchor point of each item for position to calculate distance. + */ + jumpToItem: function(itemIndex, positionRatioInView, itemAnchorPoint) + { + var item = this.getItem(itemIndex); + + if(!item) + return; + + this.doLayout(); + + var destination = this._calculateItemDestination(positionRatioInView, item, itemAnchorPoint); + + if(!this.bounceEnabled) + { + var delta = cc.pSub(destination, this._innerContainer.getPosition()); + var outOfBoundary = this._getHowMuchOutOfBoundary(delta); + destination.x += outOfBoundary.x; + destination.y += outOfBoundary.y; + } + + this._jumpToDestination(destination); + }, + + /** + * Scroll to specific item + * @param {number} itemIndex Specifies the item's index + * @param {cc.Point} positionRatioInView Specifies the position with ratio in list view's content size. + * @param {cc.Point} itemAnchorPoint Specifies an anchor point of each item for position to calculate distance. + * @param {number} [timeInSec = 1.0] Scroll time + */ + scrollToItem: function(itemIndex, positionRatioInView, itemAnchorPoint, timeInSec) + { + if(timeInSec === undefined) + timeInSec = 1; + + var item = this.getItem(itemIndex); + + if(!item) + return; + + var destination = this._calculateItemDestination(positionRatioInView, item, itemAnchorPoint); + this._startAutoScrollToDestination(destination, timeInSec, true); + }, + /** * Requests refresh list view. + * @deprecated Use method requestDoLayout() instead */ requestRefreshView: function () { this._refreshViewDirty = true; @@ -398,15 +824,10 @@ ccui.ListView = ccui.ScrollView.extend(/** @lends ccui.ListView# */{ /** * Refreshes list view. + * @deprecated Use method forceDoLayout() instead */ refreshView: function () { - var locItems = this._items; - for (var i = 0; i < locItems.length; i++) { - var item = locItems[i]; - item.setLocalZOrder(i); - this._remedyLayoutParameter(item); - } - this._updateInnerContainerSize(); + this.forceDoLayout() }, /** @@ -416,10 +837,22 @@ ccui.ListView = ccui.ScrollView.extend(/** @lends ccui.ListView# */{ this._doLayout(); }, + requestDoLayout: function() + { + this._refreshViewDirty = true; + }, + _doLayout: function(){ - ccui.Layout.prototype._doLayout.call(this); + //ccui.Layout.prototype._doLayout.call(this); if (this._refreshViewDirty) { - this.refreshView(); + var locItems = this._items; + for (var i = 0; i < locItems.length; i++) { + var item = locItems[i]; + item.setLocalZOrder(i); + this._remedyLayoutParameter(item); + } + this._updateInnerContainerSize(); + this._innerContainer.forceDoLayout(); this._refreshViewDirty = false; } }, @@ -527,13 +960,76 @@ ccui.ListView = ccui.ScrollView.extend(/** @lends ccui.ListView# */{ } }, - //v3.3 - forceDoLayout: function(){ - if (this._refreshViewDirty) { - this.refreshView(); - this._refreshViewDirty = false; + _startAttenuatingAutoScroll: function(deltaMove, initialVelocity) + { + var adjustedDeltaMove = deltaMove; + + if(this._items.length !== 0 && this._magneticType !== ccui.ListView.MAGNETIC_NONE) + { + adjustedDeltaMove = this._flattenVectorByDirection(adjustedDeltaMove); + + var howMuchOutOfBoundary = this._getHowMuchOutOfBoundary(adjustedDeltaMove); + // If the destination is out of boundary, do nothing here. Because it will be handled by bouncing back. + if(howMuchOutOfBoundary.x === 0 && howMuchOutOfBoundary.y === 0 ) + { + var magType = this._magneticType; + if(magType === ccui.ListView.MAGNETIC_BOTH_END) + { + if(this._direction === ccui.ScrollView.DIR_HORIZONTAL) + { + magType = (adjustedDeltaMove.x > 0 ? ccui.ListView.MAGNETIC_LEFT : ccui.ListView.MAGNETIC_RIGHT); + } + else if(this._direction === ccui.ScrollView.DIR_VERTICAL) + { + magType = (adjustedDeltaMove.y > 0 ? ccui.ListView.MAGNETIC_BOTTOM : ccui.ListView.MAGNETIC_TOP); + } + } + + // Adjust the delta move amount according to the magnetic type + var magneticAnchorPoint = this._getAnchorPointByMagneticType(magType); + var magneticPosition = cc.pMult(this._innerContainer.getPosition(), -1); + magneticPosition.x += this.width * magneticAnchorPoint.x; + magneticPosition.y += this.height * magneticAnchorPoint.y; + + var pTargetItem = this.getClosestItemToPosition(cc.pSub(magneticPosition, adjustedDeltaMove), magneticAnchorPoint); + var itemPosition = this._calculateItemPositionWithAnchor(pTargetItem, magneticAnchorPoint); + adjustedDeltaMove = magneticPosition - itemPosition; + } + } + ccui.ScrollView.prototype._startAttenuatingAutoScroll.call(this,adjustedDeltaMove, initialVelocity); + }, + + _getAnchorPointByMagneticType: function(magneticType) + { + switch(magneticType) + { + case ccui.ListView.MAGNETIC_NONE: return cc.p(0, 0); + case ccui.ListView.MAGNETIC_BOTH_END: return cc.p(0, 1); + case ccui.ListView.MAGNETIC_CENTER: return cc.p(0.5, 0.5); + case ccui.ListView.MAGNETIC_LEFT: return cc.p(0, 0.5); + case ccui.ListView.MAGNETIC_RIGHT: return cc.p(1, 0.5); + case ccui.ListView.MAGNETIC_TOP: return cc.p(0.5, 1); + case ccui.ListView.MAGNETIC_BOTTOM: return cc.p(0.5, 0); + } + + return cc.p(0, 0); + }, + + _startMagneticScroll: function() + { + if(this._items.length === 0 || this._magneticType === ccui.ListView.MAGNETIC_NONE) + { + return; } - this._innerContainer.forceDoLayout(); + + // Find the closest item + var magneticAnchorPoint =this._getAnchorPointByMagneticType(this._magneticType); + var magneticPosition = cc.pMult(this._innerContainer.getPosition(), -1); + magneticPosition.x += this.width * magneticAnchorPoint.x; + magneticPosition.y += this.height * magneticAnchorPoint.y; + + var pTargetItem = this.getClosestItemToPosition(magneticPosition, magneticAnchorPoint); + this.scrollToItem(this.getIndex(pTargetItem), magneticAnchorPoint, magneticAnchorPoint); } }); @@ -603,4 +1099,50 @@ ccui.ListView.GRAVITY_BOTTOM = 4; * @constant * @type {number} */ -ccui.ListView.GRAVITY_CENTER_VERTICAL = 5; \ No newline at end of file +ccui.ListView.GRAVITY_CENTER_VERTICAL = 5; + +/** + * The flag of ccui.ListView's magnetic none type. + * @constant + * @type {number} + */ +ccui.ListView.MAGNETIC_NONE = 0; +/** + * The flag of ccui.ListView's magnetic center type.
+ * ListView tries to align its items in center of current view. + * @constant + * @type {number} + */ +ccui.ListView.MAGNETIC_CENTER = 0; +/** + * The flag of ccui.ListView's magnetic both end type.
+ * ListView tries to align its items in left or right end if it is horizontal, top or bottom in vertical.
+ * The aligning side (left or right, top or bottom) is determined by user's scroll direction. + * @constant + * @type {number} + */ +ccui.ListView.MAGNETIC_BOTH_END = 0; +/** + * The flag of ccui.ListView's magnetic left type. + * @constant + * @type {number} + */ +ccui.ListView.MAGNETIC_LEFT = 0; +/** + * The flag of ccui.ListView's magnetic right type. + * @constant + * @type {number} + */ +ccui.ListView.MAGNETIC_RIGHT = 0; +/** + * The flag of ccui.ListView's magnetic top type. + * @constant + * @type {number} + */ +ccui.ListView.MAGNETIC_TOP = 0; +/** + * The flag of ccui.ListView's magnetic bottom type. + * @constant + * @type {number} + */ +ccui.ListView.MAGNETIC_BOTTOM = 0; \ No newline at end of file From 8d6a364ab8008e19e1d371312bf1453067575746 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D0=B5=D1=81=D1=88=D0=B0=D0=BF=D0=BE=D1=88=D0=BD?= =?UTF-8?q?=D0=B8=D0=BA=D0=BE=D0=B2=20=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0?= Date: Fri, 27 Nov 2015 10:49:36 +0300 Subject: [PATCH 03/19] Refactor ccui.PageView to correspond coso2d-x v3.9 api. --- .../uiwidgets/scroll-widget/UIPageView.js | 502 ++++-------------- 1 file changed, 118 insertions(+), 384 deletions(-) diff --git a/extensions/ccui/uiwidgets/scroll-widget/UIPageView.js b/extensions/ccui/uiwidgets/scroll-widget/UIPageView.js index 92adc17686..eaf9ac4a6f 100644 --- a/extensions/ccui/uiwidgets/scroll-widget/UIPageView.js +++ b/extensions/ccui/uiwidgets/scroll-widget/UIPageView.js @@ -26,37 +26,19 @@ /** * The PageView control of Cocos UI. * @class - * @extends ccui.Layout - * @exmaple + * @extends ccui.ListView + * @example * var pageView = new ccui.PageView(); * pageView.setTouchEnabled(true); * pageView.addPage(new ccui.Layout()); * this.addChild(pageView); */ -ccui.PageView = ccui.Layout.extend(/** @lends ccui.PageView# */{ +ccui.PageView = ccui.ListView.extend(/** @lends ccui.PageView# */{ _curPageIdx: 0, - _pages: null, - _touchMoveDirection: null, - _touchStartLocation: 0, - _touchMoveStartLocation: 0, - _movePagePoint: null, - _leftBoundaryChild: null, - _rightBoundaryChild: null, - _leftBoundary: 0, - _rightBoundary: 0, - - _isAutoScrolling: false, - _autoScrollDistance: 0, - _autoScrollSpeed: 0, - _autoScrollDirection: 0, - _childFocusCancelOffset: 0, _pageViewEventListener: null, _pageViewEventSelector: null, _className:"PageView", - //v3.2 - _customScrollThreshold: 0, - _usingCustomScrollThreshold: false, /** * Allocates and initializes a UIPageView. @@ -66,18 +48,11 @@ ccui.PageView = ccui.Layout.extend(/** @lends ccui.PageView# */{ * var uiPageView = new ccui.PageView(); */ ctor: function () { - ccui.Layout.prototype.ctor.call(this); - this._pages = []; - this._touchMoveDirection = ccui.PageView.TOUCH_DIR_LEFT; - - this._movePagePoint = null; - this._leftBoundaryChild = null; - this._rightBoundaryChild = null; + ccui.ListView.prototype.ctor.call(this); this._childFocusCancelOffset = 5; this._pageViewEventListener = null; this._pageViewEventSelector = null; - this.setTouchEnabled(true); }, /** @@ -85,447 +60,178 @@ ccui.PageView = ccui.Layout.extend(/** @lends ccui.PageView# */{ * @returns {boolean} */ init: function () { - if (ccui.Layout.prototype.init.call(this)) { - this.setClippingEnabled(true); + if (ccui.ListView.prototype.init.call(this)) { + this.setDirection(ccui.ScrollView.DIR_HORIZONTAL); + this.setMagneticType(ccui.ListView.MAGNETIC_CENTER); return true; } return false; }, - /** - * Calls the parent class' onEnter and schedules update function. - * @override - */ - onEnter:function(){ - ccui.Layout.prototype.onEnter.call(this); - this.scheduleUpdate(true); - }, - /** * Add a widget to a page of PageView. + * @deprecated since v3.9, please use 'insertPage(Widget* page, int idx)' instead. * @param {ccui.Widget} widget widget to be added to PageView. * @param {number} pageIdx index of page. * @param {Boolean} forceCreate if force create and there is no page exist, PageView would create a default page for adding widget. */ addWidgetToPage: function (widget, pageIdx, forceCreate) { - if (!widget || pageIdx < 0) - return; - - var pageCount = this._getPageCount(); - if (pageIdx < 0 || pageIdx >= pageCount) { - if (forceCreate) { - if (pageIdx > pageCount) - cc.log("pageIdx is %d, it will be added as page id [%d]", pageIdx, pageCount); - var newPage = this._createPage(); - newPage.addChild(widget); - this.addPage(newPage); - } - } else { - var page = this._pages[pageIdx]; - if (page) - page.addChild(widget); - } - }, - - _createPage: function () { - var newPage = new ccui.Layout(); - newPage.setContentSize(this.getContentSize()); - return newPage; + this.insertCustomItem(widget, pageIdx); }, /** - * Adds a page to ccui.PageView. - * @param {ccui.Layout} page + * Insert a page into the end of PageView. + * @param {ccui.Widget} page Page to be inserted. */ - addPage: function (page) { - if (!page || this._pages.indexOf(page) !== -1) - return; - - this.addChild(page); - this._pages.push(page); - this._doLayoutDirty = true; + addPage: function(page) + { + this.pushBackCustomItem(page); }, /** - * Inserts a page in the specified location. - * @param {ccui.Layout} page page to be added to PageView. - * @param {Number} idx index + * Insert a page into PageView at a given index. + * @param {ccui.Widget} page Page to be inserted. + * @param {number} idx A given index. */ - insertPage: function (page, idx) { - if (idx < 0 || !page || this._pages.indexOf(page) !== -1) - return; - - var pageCount = this._getPageCount(); - if (idx >= pageCount) - this.addPage(page); - else { - this._pages[idx] = page; - this.addChild(page); - } - this._doLayoutDirty = true; + insertPage: function(page, idx) + { + this.insertCustomItem(page, idx); }, /** * Removes a page from PageView. - * @param {ccui.Layout} page + * @param {ccui.Widget} page Page to be removed. */ removePage: function (page) { - if (!page) - return; - this.removeChild(page); - var index = this._pages.indexOf(page); - if(index > -1) - this._pages.splice(index, 1); - this._doLayoutDirty = true; + this.removeItem(this.getIndex(page)); }, /** * Removes a page at index of PageView. - * @param {number} index + * @param {number} index A given index. */ removePageAtIndex: function (index) { - if (index < 0 || index >= this._pages.length) - return; - var page = this._pages[index]; - if (page) - this.removePage(page); + this.removeItem(index); }, /** * Removes all pages from PageView */ removeAllPages: function(){ - var locPages = this._pages; - for(var i = 0, len = locPages.length; i < len; i++) - this.removeChild(locPages[i]); - this._pages.length = 0; - }, - - _updateBoundaryPages: function () { - var locPages = this._pages; - if (locPages.length <= 0) { - this._leftBoundaryChild = null; - this._rightBoundaryChild = null; - return; - } - this._leftBoundaryChild = locPages[0]; - this._rightBoundaryChild = locPages[locPages.length - 1]; - }, - - _getPageCount: function(){ - return this._pages.length; + this.removeAllItems(); }, /** - * Get x position by index - * @param {number} idx - * @returns {number} + * scroll PageView to index. + * @param {number} idx A given index in the PageView. Index start from 0 to pageCount -1. */ - _getPositionXByIndex: function (idx) { - return (this.getContentSize().width * (idx - this._curPageIdx)); - }, - - _onSizeChanged: function () { - ccui.Layout.prototype._onSizeChanged.call(this); - this._rightBoundary = this.getContentSize().width; - this._doLayoutDirty = true; - }, - - _updateAllPagesSize: function(){ - var selfSize = this.getContentSize(); - var locPages = this._pages; - for (var i = 0, len = locPages.length; i < len; i++) - locPages[i].setContentSize(selfSize); - }, - - _updateAllPagesPosition: function(){ - var pageCount = this._getPageCount(); - if (pageCount <= 0) { - this._curPageIdx = 0; - return; - } - - if (this._curPageIdx >= pageCount) - this._curPageIdx = pageCount-1; - - var pageWidth = this.getContentSize().width; - var locPages = this._pages; - for (var i=0; i< pageCount; i++) - locPages[i].setPosition(cc.p((i - this._curPageIdx) * pageWidth, 0)); + scrollToItem: function (idx) { + ccui.ListView.prototype.scrollToItem.call(this, idx, cc.p(0.5, 0.5), cc.p(0.5, 0.5)); }, /** * scroll PageView to index. - * @param {number} idx index of page. + * @param {number} idx A given index in the PageView. Index start from 0 to pageCount -1. */ scrollToPage: function (idx) { - if (idx < 0 || idx >= this._pages.length) - return; - this._curPageIdx = idx; - var curPage = this._pages[idx]; - this._autoScrollDistance = -(curPage.getPosition().x); - this._autoScrollSpeed = Math.abs(this._autoScrollDistance) / 0.2; - this._autoScrollDirection = this._autoScrollDistance > 0 ? ccui.PageView.DIRECTION_RIGHT : ccui.PageView.DIRECTION_LEFT; - this._isAutoScrolling = true; - }, - - /** - * Called once per frame. Time is the number of seconds of a frame interval. - * @override - * @param {Number} dt - */ - update: function (dt) { - if (this._isAutoScrolling) - this._autoScroll(dt); - }, - - /** - * Does nothing. ccui.PageView's layout type is ccui.Layout.ABSOLUTE. - * @override - * @param {Number} type - */ - setLayoutType:function(type){ - }, - - /** - * Returns the layout type of ccui.PageView. it's always ccui.Layout.ABSOLUTE. - * @returns {number} - */ - getLayoutType: function(){ - return ccui.Layout.ABSOLUTE; - }, - - _autoScroll: function(dt){ - var step; - switch (this._autoScrollDirection) { - case ccui.PageView.DIRECTION_LEFT: - step = this._autoScrollSpeed * dt; - if (this._autoScrollDistance + step >= 0.0) { - step = -this._autoScrollDistance; - this._autoScrollDistance = 0.0; - this._isAutoScrolling = false; - } else - this._autoScrollDistance += step; - this._scrollPages(-step); - if(!this._isAutoScrolling) - this._pageTurningEvent(); - break; - break; - case ccui.PageView.DIRECTION_RIGHT: - step = this._autoScrollSpeed * dt; - if (this._autoScrollDistance - step <= 0.0) { - step = this._autoScrollDistance; - this._autoScrollDistance = 0.0; - this._isAutoScrolling = false; - } else - this._autoScrollDistance -= step; - this._scrollPages(step); - if(!this._isAutoScrolling) - this._pageTurningEvent(); - break; - default: - break; - } - }, - - /** - * The touch moved event callback handler of ccui.PageView. - * @override - * @param {cc.Touch} touch - * @param {cc.Event} event - */ - onTouchMoved: function (touch, event) { - ccui.Layout.prototype.onTouchMoved.call(this, touch, event); - if (!this._isInterceptTouch) - this._handleMoveLogic(touch); + this.scrollToItem(idx); }, - /** - * The touch ended event callback handler of ccui.PageView. - * @override - * @param {cc.Touch} touch - * @param {cc.Event} event - */ - onTouchEnded: function (touch, event) { - ccui.Layout.prototype.onTouchEnded.call(this, touch, event); - if (!this._isInterceptTouch) - this._handleReleaseLogic(touch); - this._isInterceptTouch = false; - }, - - /** - * The touch canceled event callback handler of ccui.PageView. - * @param {cc.Touch} touch - * @param {cc.Event} event - */ - onTouchCancelled: function (touch, event) { - ccui.Layout.prototype.onTouchCancelled.call(this, touch, event); - if (!this._isInterceptTouch) - this._handleReleaseLogic(touch); - this._isInterceptTouch = false; - }, _doLayout: function(){ - if (!this._doLayoutDirty) + if (!this._refreshViewDirty) return; - this._updateAllPagesPosition(); - this._updateAllPagesSize(); - this._updateBoundaryPages(); - this._doLayoutDirty = false; - }, - - _movePages: function (offset) { - var arrayPages = this._pages; - var length = arrayPages.length; - for (var i = 0; i < length; i++) { - var child = arrayPages[i]; - //var pos = child.getPosition(); - //child.setPosition(pos.x + offset, pos.y); - child.setPositionX(child.getPositionX() + offset); - } - }, - - _scrollPages: function (touchOffset) { - if (this._pages.length <= 0) - return false; - if (!this._leftBoundaryChild || !this._rightBoundaryChild) - return false; - - var realOffset = touchOffset; - switch (this._touchMoveDirection) { - case ccui.PageView.TOUCH_DIR_LEFT: // left - var rightBoundary = this._rightBoundaryChild.getRightBoundary(); - if (rightBoundary + touchOffset <= this._rightBoundary) { - realOffset = this._rightBoundary - rightBoundary; - this._movePages(realOffset); - return false; - } - break; - case ccui.PageView.TOUCH_DIR_RIGHT: // right - var leftBoundary = this._leftBoundaryChild.getLeftBoundary(); - if (leftBoundary + touchOffset >= this._leftBoundary) { - realOffset = this._leftBoundary - leftBoundary; - this._movePages(realOffset); - return false; - } - break; - default: - break; - } + ccui.ListView.prototype._doLayout.call(this); - this._movePages(realOffset); - return true; - }, - - _handleMoveLogic: function (touch) { - var offset = touch.getLocation().x - touch.getPreviousLocation().x; - if (offset < 0) - this._touchMoveDirection = ccui.PageView.TOUCH_DIR_LEFT; - else if (offset > 0) - this._touchMoveDirection = ccui.PageView.TOUCH_DIR_RIGHT; - this._scrollPages(offset); + this._refreshViewDirty = false; }, /** * Set custom scroll threshold to page view. If you don't specify the value, the pageView will scroll when half page view width reached. * @since v3.2 * @param threshold + * @deprecated Since v3.9, this method has no effect. */ setCustomScrollThreshold: function(threshold){ - cc.assert(threshold>0, "Invalid threshold!"); - this._customScrollThreshold = threshold; - this.setUsingCustomScrollThreshold(true); + }, /** * Returns user defined scroll page threshold. * @since v3.2 + * @deprecated Since v3.9, this method always returns 0. */ getCustomScrollThreshold: function(){ - return this._customScrollThreshold; + return 0; }, /** * Set using user defined scroll page threshold or not. If you set it to false, then the default scroll threshold is pageView.width / 2. * @since v3.2 + * @deprecated Since v3.9, this method has no effect. */ setUsingCustomScrollThreshold: function(flag){ - this._usingCustomScrollThreshold = flag; }, /** * Queries whether we are using user defined scroll page threshold or not + * @deprecated Since v3.9, this method always returns false. */ isUsingCustomScrollThreshold: function(){ - return this._usingCustomScrollThreshold; + return false; + }, + + _moveInnerContainer: function(deltaMove, canStartBounceBack) + { + ccui.ListView.prototype._moveInnerContainer.call(this, deltaMove, canStartBounceBack); + this._curPageIdx = this.getIndex(this.getCenterItemInCurrentView()); }, _handleReleaseLogic: function (touchPoint) { - if (this._pages.length <= 0) + + ccui.ScrollView._handleReleaseLogic.call(this, touchPoint); + + if (this._items.length <= 0) return; - var curPage = this._pages[this._curPageIdx]; - if (curPage) { - var curPagePos = curPage.getPosition(); - var pageCount = this._pages.length; - var curPageLocation = curPagePos.x; - var pageWidth = this.getSize().width; - if (!this._usingCustomScrollThreshold) - this._customScrollThreshold = pageWidth / 2.0; - var boundary = this._customScrollThreshold; - if (curPageLocation <= -boundary) { - if (this._curPageIdx >= pageCount - 1) - this._scrollPages(-curPageLocation); - else - this.scrollToPage(this._curPageIdx + 1); - } else if (curPageLocation >= boundary) { - if (this._curPageIdx <= 0) - this._scrollPages(-curPageLocation); - else - this.scrollToPage(this._curPageIdx - 1); - } else - this.scrollToPage(this._curPageIdx); - } - }, - /** - * Intercept touch event, handle its child's touch event. - * @param {Number} eventType event type - * @param {ccui.Widget} sender - * @param {cc.Touch} touch - */ - interceptTouchEvent: function (eventType, sender, touch) { - if(!this._touchEnabled) + var touchMoveVelocity = this._flattenVectorByDirection(this._calculateTouchMoveVelocity()); + + var INERTIA_THRESHOLD = 500; + if(cc.pLength(touchMoveVelocity) < INERTIA_THRESHOLD) { - ccui.Layout.prototype.interceptTouchEvent.call(this, eventType, sender, touch); - return; + this._startMagneticScroll(); } - var touchPoint = touch.getLocation(); - switch (eventType) { - case ccui.Widget.TOUCH_BEGAN: - this._touchBeganPosition.x = touchPoint.x; - this._touchBeganPosition.y = touchPoint.y; - this._isInterceptTouch = true; - break; - case ccui.Widget.TOUCH_MOVED: - this._touchMovePosition.x = touchPoint.x; - this._touchMovePosition.y = touchPoint.y; - var offset = 0; - offset = Math.abs(sender.getTouchBeganPosition().x - touchPoint.x); - if (offset > this._childFocusCancelOffset) { - sender.setHighlighted(false); - this._handleMoveLogic(touch); + else + { + // Handle paging by inertia force. + var currentPage = this.getItem(this._curPageIdx); + var destination = this._calculateItemDestination(cc.p(0.5, 0.5), currentPage, cc.p(0.5, 0.5)); + var deltaToCurrentPage = cc.pSub(destination, this.getInnerContainerPosition()); + deltaToCurrentPage = this._flattenVectorByDirection(deltaToCurrentPage); + + // If the direction of displacement to current page and the direction of touch are same, just start magnetic scroll to the current page. + // Otherwise, move to the next page of touch direction. + if(touchMoveVelocity.x * deltaToCurrentPage.x > 0 || touchMoveVelocity.y * deltaToCurrentPage.y > 0) + { + this._startMagneticScroll(); + } + else + { + if(touchMoveVelocity.x < 0 || touchMoveVelocity.y > 0) + { + ++this._curPageIdx; + } + else + { + --this._curPageIdx; } - break; - case ccui.Widget.TOUCH_ENDED: - case ccui.Widget.TOUCH_CANCELED: - this._touchEndPosition.x = touchPoint.x; - this._touchEndPosition.y = touchPoint.y; - this._handleReleaseLogic(touch); - if (sender.isSwallowTouches()) - this._isInterceptTouch = false; - break; + this._curPageIdx = Math.min(this._curPageIdx, this._items.length); + this._curPageIdx = Math.max(this._curPageIdx, 0); + this.scrollToItem(this._curPageIdx); + } } + }, _pageTurningEvent: function () { @@ -559,20 +265,51 @@ ccui.PageView = ccui.Layout.extend(/** @lends ccui.PageView# */{ this._pageViewEventListener = target; }, + /** + * Jump to a page with a given index without scrolling. + * This is the different between scrollToPage. + * @param {number} index A given index in PageView. Index start from 0 to pageCount -1. + */ + setCurrentPageIndex: function(index) + { + this.jumpToItem(index, cc.p(0.5, 0.5), cc.p(0.5, 0.5)); + }, + + /** + * Jump to a page with a given index without scrolling. + * This is the different between scrollToPage. + * @param {number} index A given index in PageView. Index start from 0 to pageCount -1. + * @deprecated since v3.9, this is deprecated. Use `setCurrentPageIndex()` instead. + */ + setCurPageIndex: function(index) + { + this.setCurrentPageIndex(index); + }, + /** * Returns current page index * @returns {number} */ - getCurPageIndex: function () { + getCurrentPageIndex: function () { return this._curPageIdx; }, + /** + * Returns current page index + * @deprecated since v3.9, this is deprecated. Use `getCurrentPageIndex()` instead. + * @returns {number} + */ + getCurPageIndex: function () { + var widget = this.getCenterItemInCurrentView(); + return this.getIndex(widget); + }, + /** * Returns all pages of PageView * @returns {Array} */ getPages:function(){ - return this._pages; + return this.getItems(); }, /** @@ -581,9 +318,7 @@ ccui.PageView = ccui.Layout.extend(/** @lends ccui.PageView# */{ * @returns {ccui.Layout} */ getPage: function(index){ - if (index < 0 || index >= this._pages.length) - return null; - return this._pages[index]; + return this.getItem(index); }, /** @@ -611,7 +346,6 @@ ccui.PageView = ccui.Layout.extend(/** @lends ccui.PageView# */{ this._ccEventCallback = pageView._ccEventCallback; this._pageViewEventListener = pageView._pageViewEventListener; this._pageViewEventSelector = pageView._pageViewEventSelector; - this._usingCustomScrollThreshold = pageView._usingCustomScrollThreshold; this._customScrollThreshold = pageView._customScrollThreshold; } }); From e9eb595eeb7812fb1f16bbfce731beccddbb621d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D0=B5=D1=81=D1=88=D0=B0=D0=BF=D0=BE=D1=88=D0=BD?= =?UTF-8?q?=D0=B8=D0=BA=D0=BE=D0=B2=20=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0?= Date: Fri, 27 Nov 2015 13:01:10 +0300 Subject: [PATCH 04/19] Add ccui.ScrollViewBar class. --- .../scroll-widget/UIScrollViewBar.js | 387 ++++++++++++++++++ moduleConfig.json | 1 + tools/build.xml | 1 + tools/jsdoc_toolkit/build.xml | 1 + tools/template/build.xml | 1 + 5 files changed, 391 insertions(+) create mode 100644 extensions/ccui/uiwidgets/scroll-widget/UIScrollViewBar.js diff --git a/extensions/ccui/uiwidgets/scroll-widget/UIScrollViewBar.js b/extensions/ccui/uiwidgets/scroll-widget/UIScrollViewBar.js new file mode 100644 index 0000000000..b5e7b57368 --- /dev/null +++ b/extensions/ccui/uiwidgets/scroll-widget/UIScrollViewBar.js @@ -0,0 +1,387 @@ +/**************************************************************************** + Copyright (c) 2015 Neo Kim (neo.kim@neofect.com) + Copyright (c) 2015 Nikita Besshaposhnikov (nikita.besshapshnikov@gmail.com) + + http://www.cocos2d-x.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + ****************************************************************************/ + +/** + * The ScrollViewBar control of Cocos UI
+ * Scroll bar being attached to ScrollView layout container. + * @class + * @extends ccui.ProtectedNode + * + * @property {Number} opacity - Opacity of the scroll view bar + * @property {Boolean} autoHideEnabled - Auto hide is enabled in the scroll view bar + * @property {Number} autoHideTime - Auto hide time of the scroll view bar + */ +ccui.ScrollViewBar = ccui.ProtectedNode.extend(/** @lends ccui.ScrollViewBar# */{ + _parentScroll: null, + _direction: 0, + + _upperHalfCircle: null, + _lowerHalfCircle: null, + _body: null, + + _opacity : 255, + + _marginFromBoundary : 0, + _marginForLength: 0, + + _touching: false, + + _autoHideEnabled: true, + autoHideTime : 0, + _autoHideRemainingTime : 0, + _className: "ScrollViewBar", + + /** + * Allocates and initializes a UIScrollViewBar. + * Constructor of ccui.ScrollViewBar. override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function. + * @param {ccui.ScrollView} parent A parent of scroll bar. + * @param {ccui.ScrollView.DIR_NONE | ccui.ScrollView.DIR_HORIZONTAL | ccui.ScrollView.DIR_VERTICAL | ccui.ScrollView.DIR_BOTH} direction + */ + ctor: function (parent, direction) { + cc.ProtectedNode.prototype.ctor.call(this); + this._direction = direction; + this._parentScroll = parent; + + this._marginFromBoundary = ccui.ScrollViewBar.DEFAULT_MARGIN; + this._marginForLength = ccui.ScrollViewBar.DEFAULT_MARGIN; + this.opacity = 255 * ccui.ScrollViewBar.DEFAULT_SCROLLBAR_OPACITY; + this.autoHideTime = ccui.ScrollViewBar.DEFAULT_AUTO_HIDE_TIME; + this._autoHideEnabled = true; + + this.init(); + + this.setCascadeColorEnabled(true); + this.setCascadeOpacityEnabled(true); + }, + + /** + * Initializes a ccui.ScrollViewBar. Please do not call this function by yourself, you should pass the parameters to constructor to initialize it. + * @returns {boolean} + */ + init: function () { + if (cc.ProtectedNode.prototype.init.call(this)) { + + var halfPixelImage = new Image(); + halfPixelImage.src = ccui.ScrollViewBar.HALF_CIRCLE_IMAGE; + + this._upperHalfCircle = new cc.Sprite(halfPixelImage); + this._upperHalfCircle.setAnchorPoint(cc.p(0.5, 0)); + + this._lowerHalfCircle = new cc.Sprite(halfPixelImage); + this._lowerHalfCircle.setAnchorPoint(cc.p(0.5, 0)); + this._lowerHalfCircle.setScaleY(-1); + + this.addProtectedChild(this._upperHalfCircle); + this.addProtectedChild(this._lowerHalfCircle); + + var bodyImage = new Image(); + bodyImage.src = ccui.ScrollViewBar.BODY_IMAGE_1_PIXEL_HEIGHT; + + this._body = new cc.Sprite(bodyImage); + this._body.setAnchorPoint(cc.p(0.5, 0)); + this.addProtectedChild(this._body); + + this.setColor(ccui.ScrollViewBar.DEFAULT_COLOR); + + if(this._direction === ccui.ScrollView.DIR_HORIZONTAL) + { + this.setRotation(90); + } + + if(this._autoHideEnabled) + { + cc.ProtectedNode.prototype.setOpacity.call(this, 0) + } + + return true; + } + return false; + }, + + /** + * Set the scroll bar position from the left-bottom corner (horizontal) or right-top corner (vertical). + * @param {cc.Point} positionFromCorner The position from the left-bottom corner (horizontal) or right-top corner (vertical). + */ + setPositionFromCorner: function(positionFromCorner) + { + if(this._direction === ccui.ScrollView.DIR_VERTICAL) + { + this._marginForLength = positionFromCorner.y; + this._marginFromBoundary = positionFromCorner.x; + } + else + { + this._marginForLength = positionFromCorner.x; + this._marginFromBoundary = positionFromCorner.y; + } + }, + + onEnter: function() + { + cc.ProtectedNode.prototype.onEnter.call(this); + this.scheduleUpdate(); + }, + + /** + * Get the scroll bar position from the left-bottom corner (horizontal) or right-top corner (vertical). + * @returns {cc.Point} + */ + getPositionFromCorner: function() + { + if(this._direction === ccui.ScrollView.DIR_VERTICAL) + { + return cc.p(this._marginFromBoundary, this._marginForLength); + } + else + { + return cc.p(this._marginForLength, this._marginFromBoundary); + } + }, + /** + * Set the scroll bar's width + * @param {number} width The scroll bar's width + */ + setWidth: function(width) + { + var scale = width / this._body.width; + this._body.setScaleX(scale); + this._upperHalfCircle.setScale(scale); + this._lowerHalfCircle.setScale(-scale); + }, + + /** + * Get the scroll bar's width + * @returns {number} the scroll bar's width + */ + getWidth: function() + { + return this._body.getBoundingBox().width; + }, + + /** + * Set scroll bar auto hide state + * @param {boolean} autoHideEnabled scroll bar auto hide state + */ + setAutoHideEnabled: function(autoHideEnabled) + { + this._autoHideEnabled = autoHideEnabled; + cc.ProtectedNode.prototype.setOpacity.call(this, this.opacity); + }, + /** + * Query scroll bar auto hide state + * @returns {boolean} True if scroll bar auto hide is enabled, false otherwise. + */ + isAutoHideEnabled: function() + { + return this._autoHideEnabled; + }, + + /** + * Set scroll bar opacity + * @param {number} opacity scroll bar opacity + */ + setOpacity: function(opacity) + { + this._opacity = opacity; + }, + + /** + * Get scroll bar opacity + * @returns {number} + */ + getOpacity: function() + { + return this._opacity; + }, + + _updateLength: function(length) + { + var ratio = length / this._body.getTextureRect().height; + this._body.setScaleY(ratio); + this._upperHalfCircle.setPositionY(this._body.getPositionY() + length); + }, + + _processAutoHide: function(dt) + { + if(!this._autoHideEnabled || this._autoHideRemainingTime <= 0) + { + return; + } + else if(this._touching) + { + // If it is touching, don't auto hide. + return; + } + + this._autoHideRemainingTime -= dt; + if(this._autoHideRemainingTime <= this.autoHideTime) + { + this. _autoHideRemainingTime = Math.max(0, this._autoHideRemainingTime); + cc.ProtectedNode.prototype.setOpacity.call(this, this._opacity * (this._autoHideRemainingTime / this.autoHideTime)); + } + }, + + + update: function(dt) + { + this._processAutoHide(dt); + }, + + /** + * This is called by parent ScrollView when a touch is began. Don't call this directly. + */ + onTouchBegan: function() + { + if(!this._autoHideEnabled) + { + return; + } + this._touching = true; + }, + + /** + * This is called by parent ScrollView when a touch is ended. Don't call this directly. + */ + onTouchEnded: function() + { + if(!this._autoHideEnabled) + { + return; + } + this._touching = false; + + if(this._autoHideRemainingTime <= 0) + { + // If the remaining time is 0, it means that it didn't moved after touch started so scroll bar is not showing. + return; + } + this._autoHideRemainingTime = this.autoHideTime; + }, + + /** + * @brief This is called by parent ScrollView when the parent is scrolled. Don't call this directly. + * + * @param {cc.Point} outOfBoundary amount how much the inner container of ScrollView is out of boundary + */ + onScrolled: function(outOfBoundary) + { + if(this._autoHideEnabled) + { + this._autoHideRemainingTime = this.autoHideTime; + cc.ProtectedNode.prototype.setOpacity.call(this, this.opacity); + } + + var innerContainer = this._parentScroll.getInnerContainer(); + + var innerContainerMeasure = 0; + var scrollViewMeasure = 0; + var outOfBoundaryValue = 0; + var innerContainerPosition = 0; + + if(this._direction === ccui.ScrollView.DIR_VERTICAL) + { + innerContainerMeasure = innerContainer.height; + scrollViewMeasure = this._parentScroll.height; + outOfBoundaryValue = outOfBoundary.y; + innerContainerPosition = -innerContainer.getPositionY(); + } + else if(this._direction === ccui.ScrollView.DIR_HORIZONTAL) + { + innerContainerMeasure = innerContainer.width; + scrollViewMeasure = this._parentScroll.width; + outOfBoundaryValue = outOfBoundary.x; + innerContainerPosition = -innerContainer.getPositionX(); + } + + var length = this._calculateLength(innerContainerMeasure, scrollViewMeasure, outOfBoundaryValue); + var position = this._calculatePosition(innerContainerMeasure, scrollViewMeasure, innerContainerPosition, outOfBoundaryValue, length); + this._updateLength(length); + this.setPosition(position); + }, + + _calculateLength: function(innerContainerMeasure, scrollViewMeasure, outOfBoundaryValue) + { + var denominatorValue = innerContainerMeasure; + if(outOfBoundaryValue !== 0) + { + // If it is out of boundary, the length of scroll bar gets shorter quickly. + var GETTING_SHORTER_FACTOR = 20; + denominatorValue += (outOfBoundaryValue > 0 ? outOfBoundaryValue : -outOfBoundaryValue) * GETTING_SHORTER_FACTOR; + } + + var lengthRatio = scrollViewMeasure / denominatorValue; + return Math.abs(scrollViewMeasure - 2 * this._marginForLength) * lengthRatio; + }, + + _calculatePosition: function(innerContainerMeasure, scrollViewMeasure, innerContainerPosition, outOfBoundaryValue, length) + { + var denominatorValue = innerContainerMeasure - scrollViewMeasure; + if(outOfBoundaryValue !== 0) + { + denominatorValue += Math.abs(outOfBoundaryValue); + } + + var positionRatio = 0; + + if(denominatorValue !== 0) + { + positionRatio = innerContainerPosition / denominatorValue; + positionRatio = Math.max(positionRatio, 0); + positionRatio = Math.min(positionRatio, 1); + } + + var position = (scrollViewMeasure - length - 2 * this._marginForLength) * positionRatio + this._marginForLength; + + if(this._direction === ccui.ScrollView.DIR_VERTICAL) + { + return cc.p(this._parentScroll.width - this._marginFromBoundary, position); + } + else + { + return cc.p(position, this._marginFromBoundary); + } + } + +}); + +var _p = ccui.ScrollViewBar.prototype; + +// Extended properties +/** @expose */ +_p.opacity; +cc.defineGetterSetter(_p, "opacity", _p.getOpacity, _p.setOpacity); + +_p.autoHideEnabled; +cc.defineGetterSetter(_p, "autoHideEnabled", _p.isAutoHideEnabled, _p.setAutoHideEnabled); + +/** + * @ignore + */ +ccui.ScrollViewBar.DEFAULT_COLOR = cc.color(52, 65, 87); +ccui.ScrollViewBar.DEFAULT_MARGIN = 20; +ccui.ScrollViewBar.DEFAULT_AUTO_HIDE_TIME = 0.2; +ccui.ScrollViewBar.DEFAULT_SCROLLBAR_OPACITY = 0.4; +ccui.ScrollViewBar.HALF_CIRCLE_IMAGE = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAAGCAMAAADAMI+zAAAAJ1BMVEX///////////////////////////////////////////////////9Ruv0SAAAADHRSTlMABgcbbW7Hz9Dz+PmlcJP5AAAAMElEQVR4AUXHwQ2AQAhFwYcLH1H6r1djzDK3ASxUpTBeK/uTCyz7dx54b44m4p5cD1MwAooEJyk3AAAAAElFTkSuQmCC"; +ccui.ScrollViewBar.BODY_IMAGE_1_PIXEL_HEIGHT = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAwAAAABCAMAAADdNb8LAAAAA1BMVEX///+nxBvIAAAACklEQVR4AWNABgAADQABYc2cpAAAAABJRU5ErkJggg=="; \ No newline at end of file diff --git a/moduleConfig.json b/moduleConfig.json index 74d5f6bf3c..787b42cafb 100644 --- a/moduleConfig.json +++ b/moduleConfig.json @@ -336,6 +336,7 @@ "extensions/ccui/uiwidgets/UIVideoPlayer.js", "extensions/ccui/uiwidgets/UIRichText.js", "extensions/ccui/uiwidgets/UIWebView.js", + "extensions/ccui/uiwidgets/scroll-widget/UIScrollViewBar.js", "extensions/ccui/uiwidgets/scroll-widget/UIScrollView.js", "extensions/ccui/uiwidgets/scroll-widget/UIListView.js", "extensions/ccui/uiwidgets/scroll-widget/UIPageView.js", diff --git a/tools/build.xml b/tools/build.xml index 152895902c..6cdd087478 100644 --- a/tools/build.xml +++ b/tools/build.xml @@ -227,6 +227,7 @@ + diff --git a/tools/jsdoc_toolkit/build.xml b/tools/jsdoc_toolkit/build.xml index e037685c34..0b9ec01f79 100644 --- a/tools/jsdoc_toolkit/build.xml +++ b/tools/jsdoc_toolkit/build.xml @@ -159,6 +159,7 @@ + diff --git a/tools/template/build.xml b/tools/template/build.xml index f2490a94ac..9fc7a7e231 100644 --- a/tools/template/build.xml +++ b/tools/template/build.xml @@ -158,6 +158,7 @@ + From 1c6443e8e46268cc7d2f8a91818d891ed01e2840 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D0=B5=D1=81=D1=88=D0=B0=D0=BF=D0=BE=D1=88=D0=BD?= =?UTF-8?q?=D0=B8=D0=BA=D0=BE=D0=B2=20=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0?= Date: Fri, 27 Nov 2015 13:01:33 +0300 Subject: [PATCH 05/19] Add using of scroll bar in ccui.ScrollView. --- .../uiwidgets/scroll-widget/UIScrollView.js | 377 +++++++++++++++++- 1 file changed, 357 insertions(+), 20 deletions(-) diff --git a/extensions/ccui/uiwidgets/scroll-widget/UIScrollView.js b/extensions/ccui/uiwidgets/scroll-widget/UIScrollView.js index 7454460074..ca9c93629d 100644 --- a/extensions/ccui/uiwidgets/scroll-widget/UIScrollView.js +++ b/extensions/ccui/uiwidgets/scroll-widget/UIScrollView.js @@ -68,6 +68,10 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ inertiaScrollEnabled: false, + _scrollBarEnabled: true, + _verticalScrollBar: null, + _horizontalScrollBar: null, + _scrollViewEventListener: null, _scrollViewEventSelector: null, _className: "ScrollView", @@ -94,6 +98,8 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ this._touchMoveTimeDeltas = []; this._touchMovePreviousTimestamp = 0; + this._scrollBarEnabled = true; + this.setTouchEnabled(true); }, @@ -105,6 +111,10 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ if (ccui.Layout.prototype.init.call(this)) { this.setClippingEnabled(true); this._innerContainer.setTouchEnabled(false); + if(this._scrollBarEnabled) + { + this._initScrollBar(); + } return true; } return false; @@ -116,7 +126,7 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ */ onEnter: function () { ccui.Layout.prototype.onEnter.call(this); - this.scheduleUpdate(true); + this.scheduleUpdate(); }, /** @@ -209,7 +219,7 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ } this.setInnerContainerPosition(pos); - //updateScrollBar(Vec2::ZERO); + this._updateScrollBar(cc.p(0 ,0)); }, _setInnerWidth: function (width) { @@ -510,7 +520,7 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ this.setInnerContainerPosition(cc.pAdd(this.getInnerContainerPosition(), adjustedMove)); var outOfBoundary =this._getHowMuchOutOfBoundary(); - //updateScrollBar(outOfBoundary); + this._updateScrollBar(outOfBoundary); if(this.bounceEnabled && canStartBounceBack) { @@ -518,6 +528,18 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ } }, + _updateScrollBar: function(outOfBoundary) + { + if(this._verticalScrollBar) + { + this._verticalScrollBar.onScrolled(outOfBoundary); + } + if(this._horizontalScrollBar) + { + this._horizontalScrollBar.onScrolled(outOfBoundary); + } + }, + _calculateTouchMoveVelocity: function() { var totalTime = 0; @@ -1034,16 +1056,15 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ this._touchMoveDisplacements.length = 0; this._touchMoveTimeDeltas.length = 0; - // - //if(_verticalScrollBar != nullptr) - //{ - // _verticalScrollBar->onTouchBegan(); - //} - //if(_horizontalScrollBar != nullptr) - //{ - // _horizontalScrollBar->onTouchBegan(); - //} + if(this._verticalScrollBar) + { + this._verticalScrollBar.onTouchBegan(); + } + if(this._horizontalScrollBar) + { + this._horizontalScrollBar.onTouchBegan(); + } }, _handleMoveLogic: function (touch) { @@ -1075,14 +1096,14 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ } } - //if(_verticalScrollBar != nullptr) - //{ - // _verticalScrollBar->onTouchEnded(); - //} - //if(_horizontalScrollBar != nullptr) - //{ - // _horizontalScrollBar->onTouchEnded(); - //} + if(this._verticalScrollBar) + { + this._verticalScrollBar.onTouchEnded(); + } + if(this._horizontalScrollBar) + { + this._horizontalScrollBar.onTouchEnded(); + } }, /** @@ -1252,6 +1273,12 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ */ setDirection: function (dir) { this.direction = dir; + + if(this._scrollBarEnabled) + { + this._removeScrollBar(); + this._initScrollBar(); + } }, /** @@ -1294,6 +1321,271 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ return this.inertiaScrollEnabled; }, + /** + * Toggle scroll bar enabled. + * @param {boolean} enabled True if enable scroll bar, false otherwise. + */ + setScrollBarEnabled: function(enabled) + { + if(this._scrollBarEnabled === enabled) + { + return; + } + + if(this._scrollBarEnabled) + { + this._removeScrollBar(); + } + this._scrollBarEnabled = enabled; + if(this._scrollBarEnabled) + { + this._initScrollBar(); + } + }, + /** + * Query scroll bar state. + * @returns {boolean} True if scroll bar is enabled, false otherwise. + */ + isScrollBarEnabled: function() + { + return this._scrollBarEnabled; + }, + + /** + * Set the scroll bar positions from the left-bottom corner (horizontal) and right-top corner (vertical). + * @param {cc.Point} positionFromCorner The position from the left-bottom corner (horizontal) and right-top corner (vertical). + */ + setScrollBarPositionFromCorner: function(positionFromCorner) + { + if(this.direction !== ccui.ScrollView.DIR_HORIZONTAL) + { + this.setScrollBarPositionFromCornerForVertical(positionFromCorner); + } + if(this.direction !=ccui.ScrollView.DIR_VERTICAL) + { + this.setScrollBarPositionFromCornerForHorizontal(positionFromCorner); + } + }, + + /** + * Set the vertical scroll bar position from right-top corner. + * @param {cc.Point} positionFromCorner The position from right-top corner + */ + setScrollBarPositionFromCornerForVertical: function(positionFromCorner) + { + cc.assert(this._scrollBarEnabled, "Scroll bar should be enabled!"); + cc.assert(this.direction !== ccui.ScrollView.DIR_HORIZONTAL, "Scroll view doesn't have a vertical scroll bar!"); + this._verticalScrollBar.setPositionFromCorner(positionFromCorner); + }, + + /** + * Get the vertical scroll bar's position from right-top corner. + * @returns {cc.Point} + */ + getScrollBarPositionFromCornerForVertical: function() + { + cc.assert(this._scrollBarEnabled, "Scroll bar should be enabled!"); + cc.assert(this.direction !== ccui.ScrollView.DIR_HORIZONTAL, "Scroll view doesn't have a vertical scroll bar!"); + return this._verticalScrollBar.getPositionFromCorner(); + }, + + /** + * Set the horizontal scroll bar position from left-bottom corner. + * @param {cc.Point} positionFromCorner The position from left-bottom corner + */ + setScrollBarPositionFromCornerForHorizontal: function(positionFromCorner) + { + cc.assert(this._scrollBarEnabled, "Scroll bar should be enabled!"); + cc.assert(this.direction !== ccui.ScrollView.DIR_VERTICAL, "Scroll view doesn't have a horizontal scroll bar!"); + this._horizontalScrollBar.setPositionFromCorner(positionFromCorner); + }, + + /** + * Get the horizontal scroll bar's position from right-top corner. + * @returns {cc.Point} + */ + getScrollBarPositionFromCornerForHorizontal: function() + { + cc.assert(this._scrollBarEnabled, "Scroll bar should be enabled!"); + cc.assert(this.direction !== ccui.ScrollView.DIR_VERTICAL, "Scroll view doesn't have a horizontal scroll bar!"); + return this._horizontalScrollBar.getPositionFromCorner(); + }, + + /** + * Set the scroll bar's width + * @param {number} width The scroll bar's width + */ + setScrollBarWidth: function(width) + { + cc.assert(this._scrollBarEnabled, "Scroll bar should be enabled!"); + if(this._verticalScrollBar) + { + this._verticalScrollBar.setWidth(width); + } + if(this._horizontalScrollBar) + { + this._horizontalScrollBar.setWidth(width); + } + }, + + /** + * Get the scroll bar's width + * @returns {number} the scroll bar's width + */ + getScrollBarWidth: function() + { + cc.assert(this._scrollBarEnabled, "Scroll bar should be enabled!"); + if(this._verticalScrollBar) + { + return this._verticalScrollBar.getWidth(); + } + if(this._horizontalScrollBar) + { + return this._horizontalScrollBar.getWidth(); + } + return 0; + }, + + /** + * Set the scroll bar's color + * @param {cc.Color} color the scroll bar's color + */ + setScrollBarColor: function(color) + { + cc.assert(this._scrollBarEnabled, "Scroll bar should be enabled!"); + if(this._verticalScrollBar) + { + this._verticalScrollBar.setColor(color); + } + if(this._horizontalScrollBar) + { + this._horizontalScrollBar.setColor(color); + } + }, + + /** + * Get the scroll bar's color + * @returns {cc.Color} the scroll bar's color + */ + getScrollBarColor: function() + { + cc.assert(this._scrollBarEnabled, "Scroll bar should be enabled!"); + if(this._verticalScrollBar) + { + this._verticalScrollBar.getColor(); + } + if(this._horizontalScrollBar) + { + this._horizontalScrollBar.getColor(); + } + return cc.color.WHITE; + }, + + /** + * Set the scroll bar's opacity + * @param {number} opacity the scroll bar's opacity + */ + setScrollBarOpacity: function(opacity) + { + cc.assert(this._scrollBarEnabled, "Scroll bar should be enabled!"); + if(this._verticalScrollBar) + { + this._verticalScrollBar.opacity = opacity; + } + if(this._horizontalScrollBar) + { + this._horizontalScrollBar.opacity = opacity; + } + }, + + /** + * Get the scroll bar's opacity + * @returns {number} + */ + getScrollBarOpacity: function() + { + cc.assert(this._scrollBarEnabled, "Scroll bar should be enabled!"); + if(this._verticalScrollBar) + { + return this._verticalScrollBar.opacity; + } + if(this._horizontalScrollBar) + { + return this._horizontalScrollBar.opacity; + } + return -1; + }, + + /** + * Set scroll bar auto hide state + * @param {boolean} autoHideEnabled scroll bar auto hide state + */ + setScrollBarAutoHideEnabled: function(autoHideEnabled) + { + cc.assert(this._scrollBarEnabled, "Scroll bar should be enabled!"); + if(this._verticalScrollBar) + { + this._verticalScrollBar.autoHideEnabled = autoHideEnabled; + } + if(this._horizontalScrollBar) + { + this._horizontalScrollBar.autoHideEnabled = autoHideEnabled; + } + }, + + /** + * Query scroll bar auto hide state + * @returns {boolean} + */ + isScrollBarAutoHideEnabled: function() + { + cc.assert(this._scrollBarEnabled, "Scroll bar should be enabled!"); + if(this._verticalScrollBar) + { + return this._verticalScrollBar.autoHideEnabled; + } + if(this._horizontalScrollBar) + { + return this._horizontalScrollBar.autoHideEnabled; + } + return false; + }, + + /** + * Set scroll bar auto hide time + * @param {number} autoHideTime scroll bar auto hide state + */ + setScrollBarAutoHideTime: function(autoHideTime) + { + cc.assert(this._scrollBarEnabled, "Scroll bar should be enabled!"); + if(this._verticalScrollBar) + { + this._verticalScrollBar.autoHideTime = autoHideTime; + } + if(this._horizontalScrollBar) + { + this._horizontalScrollBar.autoHideTime = autoHideTime; + } + }, + + /** + * Get the scroll bar's auto hide time + * @returns {number} + */ + getScrollBarAutoHideTime: function() + { + cc.assert(this._scrollBarEnabled, "Scroll bar should be enabled!"); + if(this._verticalScrollBar) + { + return this._verticalScrollBar.autoHideTime; + } + if(this._horizontalScrollBar) + { + return this._horizontalScrollBar.autoHideTime; + } + return 0; + }, + /** * Gets inner container of ScrollView. Inner container is the container of ScrollView's children. * @returns {ccui.Layout} @@ -1372,6 +1664,51 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ this._scrollViewEventListener = scrollView._scrollViewEventListener; this._scrollViewEventSelector = scrollView._scrollViewEventSelector; this._ccEventCallback = scrollView._ccEventCallback; + + this.setScrollBarEnabled(scrollView.isScrollBarEnabled()); + if(this.isScrollBarEnabled()) + { + if(this.direction !== ccui.ScrollView.DIR_HORIZONTAL) + { + this.setScrollBarPositionFromCornerForVertical(scrollView.getScrollBarPositionFromCornerForVertical()); + } + if(this.direction !== ccui.ScrollView.DIR_VERTICAL) + { + this.setScrollBarPositionFromCornerForHorizontal(scrollView.getScrollBarPositionFromCornerForHorizontal()); + } + this.setScrollBarWidth(scrollView.getScrollBarWidth()); + this.setScrollBarColor(scrollView.getScrollBarColor()); + this.setScrollBarAutoHideEnabled(scrollView.isScrollBarAutoHideEnabled()); + this.setScrollBarAutoHideTime(scrollView.getScrollBarAutoHideTime()); + } + } + }, + + _initScrollBar: function() + { + if(this.direction !== ccui.ScrollView.DIR_HORIZONTAL && !this._verticalScrollBar) + { + this._verticalScrollBar = new ccui.ScrollViewBar(this, ccui.ScrollView.DIR_VERTICAL); + this.addProtectedChild(this._verticalScrollBar, 2); + } + if(this.direction !== ccui.ScrollView.DIR_VERTICAL && !this._horizontalScrollBar) + { + this._horizontalScrollBar = new ccui.ScrollViewBar(this, ccui.ScrollView.DIR_HORIZONTAL); + this.addProtectedChild(this._horizontalScrollBar, 2); + } + }, + + _removeScrollBar: function() + { + if(this._verticalScrollBar) + { + this.removeProtectedChild(this._verticalScrollBar); + this._verticalScrollBar = null; + } + if(this._horizontalScrollBar) + { + this.removeProtectedChild(this._horizontalScrollBar); + this._horizontalScrollBar = null; } }, From dde5c67ae14454e67d8e874269e858433ba3c7ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D0=B5=D1=81=D1=88=D0=B0=D0=BF=D0=BE=D1=88=D0=BD?= =?UTF-8?q?=D0=B8=D0=BA=D0=BE=D0=B2=20=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0?= Date: Fri, 27 Nov 2015 13:01:50 +0300 Subject: [PATCH 06/19] Corrected working of ccui.PageView. --- extensions/ccui/uiwidgets/scroll-widget/UIPageView.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/extensions/ccui/uiwidgets/scroll-widget/UIPageView.js b/extensions/ccui/uiwidgets/scroll-widget/UIPageView.js index eaf9ac4a6f..ecd0964b82 100644 --- a/extensions/ccui/uiwidgets/scroll-widget/UIPageView.js +++ b/extensions/ccui/uiwidgets/scroll-widget/UIPageView.js @@ -63,6 +63,8 @@ ccui.PageView = ccui.ListView.extend(/** @lends ccui.PageView# */{ if (ccui.ListView.prototype.init.call(this)) { this.setDirection(ccui.ScrollView.DIR_HORIZONTAL); this.setMagneticType(ccui.ListView.MAGNETIC_CENTER); + this.setScrollBarEnabled(false); + return true; } return false; @@ -190,7 +192,7 @@ ccui.PageView = ccui.ListView.extend(/** @lends ccui.PageView# */{ _handleReleaseLogic: function (touchPoint) { - ccui.ScrollView._handleReleaseLogic.call(this, touchPoint); + ccui.ScrollView.prototype._handleReleaseLogic.call(this, touchPoint); if (this._items.length <= 0) return; @@ -342,7 +344,7 @@ ccui.PageView = ccui.ListView.extend(/** @lends ccui.PageView# */{ }, _copySpecialProperties: function (pageView) { - ccui.Layout.prototype._copySpecialProperties.call(this, pageView); + ccui.ListView.prototype._copySpecialProperties.call(this, pageView); this._ccEventCallback = pageView._ccEventCallback; this._pageViewEventListener = pageView._pageViewEventListener; this._pageViewEventSelector = pageView._pageViewEventSelector; From 5bde597ef004ea77d589a03c40b363f17e0854e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D0=B5=D1=81=D1=88=D0=B0=D0=BF=D0=BE=D1=88=D0=BD?= =?UTF-8?q?=D0=B8=D0=BA=D0=BE=D0=B2=20=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0?= Date: Fri, 27 Nov 2015 13:38:32 +0300 Subject: [PATCH 07/19] Some corrections in ScrollViewBar --- extensions/ccui/uiwidgets/scroll-widget/UIScrollViewBar.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/extensions/ccui/uiwidgets/scroll-widget/UIScrollViewBar.js b/extensions/ccui/uiwidgets/scroll-widget/UIScrollViewBar.js index b5e7b57368..a5cc2f432e 100644 --- a/extensions/ccui/uiwidgets/scroll-widget/UIScrollViewBar.js +++ b/extensions/ccui/uiwidgets/scroll-widget/UIScrollViewBar.js @@ -1,6 +1,6 @@ /**************************************************************************** Copyright (c) 2015 Neo Kim (neo.kim@neofect.com) - Copyright (c) 2015 Nikita Besshaposhnikov (nikita.besshapshnikov@gmail.com) + Copyright (c) 2015 Nikita Besshaposhnikov (nikita.besshaposhnikov@gmail.com) http://www.cocos2d-x.org @@ -35,7 +35,7 @@ */ ccui.ScrollViewBar = ccui.ProtectedNode.extend(/** @lends ccui.ScrollViewBar# */{ _parentScroll: null, - _direction: 0, + _direction: null, _upperHalfCircle: null, _lowerHalfCircle: null, @@ -372,7 +372,7 @@ var _p = ccui.ScrollViewBar.prototype; /** @expose */ _p.opacity; cc.defineGetterSetter(_p, "opacity", _p.getOpacity, _p.setOpacity); - +/** @expose */ _p.autoHideEnabled; cc.defineGetterSetter(_p, "autoHideEnabled", _p.isAutoHideEnabled, _p.setAutoHideEnabled); From 1e67c08128289f6a121e6d81a57b0d24fb6743d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D0=B5=D1=81=D1=88=D0=B0=D0=BF=D0=BE=D1=88=D0=BD?= =?UTF-8?q?=D0=B8=D0=BA=D0=BE=D0=B2=20=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0?= Date: Fri, 27 Nov 2015 13:41:41 +0300 Subject: [PATCH 08/19] Incapsulate direction property of ccui.ScrollView --- .../uiwidgets/scroll-widget/UIScrollView.js | 96 +++++++++---------- 1 file changed, 48 insertions(+), 48 deletions(-) diff --git a/extensions/ccui/uiwidgets/scroll-widget/UIScrollView.js b/extensions/ccui/uiwidgets/scroll-widget/UIScrollView.js index ca9c93629d..d431289770 100644 --- a/extensions/ccui/uiwidgets/scroll-widget/UIScrollView.js +++ b/extensions/ccui/uiwidgets/scroll-widget/UIScrollView.js @@ -36,7 +36,7 @@ */ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ _innerContainer: null, - direction: null, + _direction: null, _topBoundary: 0, _bottomBoundary: 0, @@ -85,7 +85,7 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ */ ctor: function () { ccui.Layout.prototype.ctor.call(this); - this.direction = ccui.ScrollView.DIR_NONE; + this._direction = ccui.ScrollView.DIR_NONE; this._childFocusCancelOffset = 5; this.inertiaScrollEnabled = true; @@ -130,10 +130,10 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ }, /** - * When a widget is in a layout, you could call this method to get the next focused widget within a specified direction.
+ * When a widget is in a layout, you could call this method to get the next focused widget within a specified _direction.
* If the widget is not in a layout, it will return itself * - * @param {Number} direction the direction to look for the next focused widget in a layout + * @param {Number} _direction the _direction to look for the next focused widget in a layout * @param {ccui.Widget} current the current focused widget * @returns {ccui.Widget} */ @@ -182,10 +182,8 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ setInnerContainerSize: function (size) { var innerContainer = this._innerContainer, locSize = this._contentSize, - innerSizeWidth = locSize.width, innerSizeHeight = locSize.height, - originalInnerSize = innerContainer.getContentSize(), - renderCmd = this._renderCmd, - newInnerSize, offset; + innerSizeWidth = locSize.width, innerSizeHeight = locSize.height; + if (size.width < locSize.width) cc.log("Inner width <= ScrollView width, it will be force sized!"); else @@ -233,7 +231,7 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ innerWidth = width; container.width = innerWidth; - switch (this.direction) { + switch (this._direction) { case ccui.ScrollView.DIR_HORIZONTAL: case ccui.ScrollView.DIR_BOTH: if (container.getRightBoundary() <= locW) { @@ -261,7 +259,7 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ innerHeight = height; container.height = innerHeight; - switch (this.direction) { + switch (this._direction) { case ccui.ScrollView.DIR_VERTICAL: case ccui.ScrollView.DIR_BOTH: var newInnerHeight = innerHeight; @@ -292,11 +290,11 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ // Process bouncing events if(this.bounceEnabled) { - for(var direction = ccui.ScrollView.MOVEDIR_TOP; direction < ccui.ScrollView.MOVEDIR_RIGHT; ++direction) + for(var _direction = ccui.ScrollView.MOVEDIR_TOP; _direction < ccui.ScrollView.MOVEDIR_RIGHT; ++_direction) { - if(this._isOutOfBoundary(direction)) + if(this._isOutOfBoundary(_direction)) { - this._processScrollEvent(direction, true); + this._processScrollEvent(_direction, true); } } } @@ -444,8 +442,8 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ _flattenVectorByDirection: function(vector) { var result = cc.p(0 ,0); - result.x = (this.direction === ccui.ScrollView.DIR_VERTICAL ? 0 : vector.x); - result.y = (this.direction === ccui.ScrollView.DIR_HORIZONTAL ? 0 : vector.y); + result.x = (this._direction === ccui.ScrollView.DIR_VERTICAL ? 0 : vector.x); + result.y = (this._direction === ccui.ScrollView.DIR_HORIZONTAL ? 0 : vector.y); return result; }, @@ -839,7 +837,7 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ * @param {Boolean} attenuated */ scrollToTopLeft: function (time, attenuated) { - if (this.direction !== ccui.ScrollView.DIR_BOTH) { + if (this._direction !== ccui.ScrollView.DIR_BOTH) { cc.log("Scroll direction is not both!"); return; } @@ -852,7 +850,7 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ * @param {Boolean} attenuated */ scrollToTopRight: function (time, attenuated) { - if (this.direction !== ccui.ScrollView.DIR_BOTH) { + if (this._direction !== ccui.ScrollView.DIR_BOTH) { cc.log("Scroll direction is not both!"); return; } @@ -867,7 +865,7 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ * @param {Boolean} attenuated */ scrollToBottomLeft: function (time, attenuated) { - if (this.direction !== ccui.ScrollView.DIR_BOTH) { + if (this._direction !== ccui.ScrollView.DIR_BOTH) { cc.log("Scroll direction is not both!"); return; } @@ -880,7 +878,7 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ * @param {Boolean} attenuated */ scrollToBottomRight: function (time, attenuated) { - if (this.direction !== ccui.ScrollView.DIR_BOTH) { + if (this._direction !== ccui.ScrollView.DIR_BOTH) { cc.log("Scroll direction is not both!"); return; } @@ -911,13 +909,13 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ }, /** - * Scroll inner container to both direction percent position of ScrollView. + * Scroll inner container to both _direction percent position of ScrollView. * @param {cc.Point} percent * @param {Number} time * @param {Boolean} attenuated */ scrollToPercentBothDirection: function (percent, time, attenuated) { - if (this.direction !== ccui.ScrollView.DIR_BOTH) + if (this._direction !== ccui.ScrollView.DIR_BOTH) return; var minY = this._contentSize.height - this._innerContainer.getContentSize().height; var h = -minY; @@ -957,8 +955,8 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ * Move inner container to top and left boundary of ScrollView. */ jumpToTopLeft: function () { - if (this.direction !== ccui.ScrollView.DIR_BOTH) { - cc.log("Scroll direction is not both!"); + if (this._direction !== ccui.ScrollView.DIR_BOTH) { + cc.log("Scroll _direction is not both!"); return; } this._jumpToDestination(0, this._contentSize.height - this._innerContainer.getContentSize().height); @@ -968,8 +966,8 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ * Move inner container to top and right boundary of ScrollView. */ jumpToTopRight: function () { - if (this.direction !== ccui.ScrollView.DIR_BOTH) { - cc.log("Scroll direction is not both!"); + if (this._direction !== ccui.ScrollView.DIR_BOTH) { + cc.log("Scroll _direction is not both!"); return; } var inSize = this._innerContainer.getContentSize(); @@ -980,8 +978,8 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ * Move inner container to bottom and left boundary of ScrollView. */ jumpToBottomLeft: function () { - if (this.direction !== ccui.ScrollView.DIR_BOTH) { - cc.log("Scroll direction is not both!"); + if (this._direction !== ccui.ScrollView.DIR_BOTH) { + cc.log("Scroll _direction is not both!"); return; } this._jumpToDestination(0, 0); @@ -991,8 +989,8 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ * Move inner container to bottom and right boundary of ScrollView. */ jumpToBottomRight: function () { - if (this.direction !== ccui.ScrollView.DIR_BOTH) { - cc.log("Scroll direction is not both!"); + if (this._direction !== ccui.ScrollView.DIR_BOTH) { + cc.log("Scroll _direction is not both!"); return; } this._jumpToDestination(this._contentSize.width - this._innerContainer.getContentSize().width, 0); @@ -1018,11 +1016,11 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ }, /** - * Move inner container to both direction percent position of ScrollView. + * Move inner container to both _direction percent position of ScrollView. * @param {cc.Point} percent The destination vertical percent, accept value between 0 - 100 */ jumpToPercentBothDirection: function (percent) { - if (this.direction !== ccui.ScrollView.DIR_BOTH) + if (this._direction !== ccui.ScrollView.DIR_BOTH) return; var inSize = this._innerContainer.getContentSize(); var minY = this._contentSize.height - inSize.height; @@ -1206,11 +1204,11 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ } }, - _processScrollEvent: function(directionEvent, bounce) + _processScrollEvent: function(_directionEvent, bounce) { var event = 0; - switch(directionEvent) + switch(_directionEvent) { case ccui.ScrollView.MOVEDIR_TOP: event = (bounce ? ccui.ScrollView.EVENT_BOUNCE_TOP : ccui.ScrollView.EVENT_SCROLL_TO_TOP); @@ -1267,12 +1265,12 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ }, /** - * Changes scroll direction of ScrollView. + * Changes scroll _direction of ScrollView. * @param {ccui.ScrollView.DIR_NONE | ccui.ScrollView.DIR_VERTICAL | ccui.ScrollView.DIR_HORIZONTAL | ccui.ScrollView.DIR_BOTH} dir * Direction::VERTICAL means vertical scroll, Direction::HORIZONTAL means horizontal scroll */ setDirection: function (dir) { - this.direction = dir; + this._direction = dir; if(this._scrollBarEnabled) { @@ -1286,7 +1284,7 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ * @returns {ccui.ScrollView.DIR_NONE | ccui.ScrollView.DIR_VERTICAL | ccui.ScrollView.DIR_HORIZONTAL | ccui.ScrollView.DIR_BOTH} */ getDirection: function () { - return this.direction; + return this._direction; }, /** @@ -1357,11 +1355,11 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ */ setScrollBarPositionFromCorner: function(positionFromCorner) { - if(this.direction !== ccui.ScrollView.DIR_HORIZONTAL) + if(this._direction !== ccui.ScrollView.DIR_HORIZONTAL) { this.setScrollBarPositionFromCornerForVertical(positionFromCorner); } - if(this.direction !=ccui.ScrollView.DIR_VERTICAL) + if(this._direction !== ccui.ScrollView.DIR_VERTICAL) { this.setScrollBarPositionFromCornerForHorizontal(positionFromCorner); } @@ -1374,7 +1372,7 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ setScrollBarPositionFromCornerForVertical: function(positionFromCorner) { cc.assert(this._scrollBarEnabled, "Scroll bar should be enabled!"); - cc.assert(this.direction !== ccui.ScrollView.DIR_HORIZONTAL, "Scroll view doesn't have a vertical scroll bar!"); + cc.assert(this._direction !== ccui.ScrollView.DIR_HORIZONTAL, "Scroll view doesn't have a vertical scroll bar!"); this._verticalScrollBar.setPositionFromCorner(positionFromCorner); }, @@ -1385,7 +1383,7 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ getScrollBarPositionFromCornerForVertical: function() { cc.assert(this._scrollBarEnabled, "Scroll bar should be enabled!"); - cc.assert(this.direction !== ccui.ScrollView.DIR_HORIZONTAL, "Scroll view doesn't have a vertical scroll bar!"); + cc.assert(this._direction !== ccui.ScrollView.DIR_HORIZONTAL, "Scroll view doesn't have a vertical scroll bar!"); return this._verticalScrollBar.getPositionFromCorner(); }, @@ -1396,7 +1394,7 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ setScrollBarPositionFromCornerForHorizontal: function(positionFromCorner) { cc.assert(this._scrollBarEnabled, "Scroll bar should be enabled!"); - cc.assert(this.direction !== ccui.ScrollView.DIR_VERTICAL, "Scroll view doesn't have a horizontal scroll bar!"); + cc.assert(this._direction !== ccui.ScrollView.DIR_VERTICAL, "Scroll view doesn't have a horizontal scroll bar!"); this._horizontalScrollBar.setPositionFromCorner(positionFromCorner); }, @@ -1407,7 +1405,7 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ getScrollBarPositionFromCornerForHorizontal: function() { cc.assert(this._scrollBarEnabled, "Scroll bar should be enabled!"); - cc.assert(this.direction !== ccui.ScrollView.DIR_VERTICAL, "Scroll view doesn't have a horizontal scroll bar!"); + cc.assert(this._direction !== ccui.ScrollView.DIR_VERTICAL, "Scroll view doesn't have a horizontal scroll bar!"); return this._horizontalScrollBar.getPositionFromCorner(); }, @@ -1637,7 +1635,7 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ ccui.Layout.prototype._copySpecialProperties.call(this, scrollView); this.setInnerContainerSize(scrollView.getInnerContainerSize()); this.setInnerContainerPosition(scrollView.getInnerContainerPosition()); - this.setDirection(scrollView.direction); + this.setDirection(scrollView._direction); this._topBoundary = scrollView._topBoundary; this._bottomBoundary = scrollView._bottomBoundary; @@ -1668,11 +1666,11 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ this.setScrollBarEnabled(scrollView.isScrollBarEnabled()); if(this.isScrollBarEnabled()) { - if(this.direction !== ccui.ScrollView.DIR_HORIZONTAL) + if(this._direction !== ccui.ScrollView.DIR_HORIZONTAL) { this.setScrollBarPositionFromCornerForVertical(scrollView.getScrollBarPositionFromCornerForVertical()); } - if(this.direction !== ccui.ScrollView.DIR_VERTICAL) + if(this._direction !== ccui.ScrollView.DIR_VERTICAL) { this.setScrollBarPositionFromCornerForHorizontal(scrollView.getScrollBarPositionFromCornerForHorizontal()); } @@ -1686,12 +1684,12 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ _initScrollBar: function() { - if(this.direction !== ccui.ScrollView.DIR_HORIZONTAL && !this._verticalScrollBar) + if(this._direction !== ccui.ScrollView.DIR_HORIZONTAL && !this._verticalScrollBar) { this._verticalScrollBar = new ccui.ScrollViewBar(this, ccui.ScrollView.DIR_VERTICAL); this.addProtectedChild(this._verticalScrollBar, 2); } - if(this.direction !== ccui.ScrollView.DIR_VERTICAL && !this._horizontalScrollBar) + if(this._direction !== ccui.ScrollView.DIR_VERTICAL && !this._horizontalScrollBar) { this._horizontalScrollBar = new ccui.ScrollViewBar(this, ccui.ScrollView.DIR_HORIZONTAL); this.addProtectedChild(this._horizontalScrollBar, 2); @@ -1778,7 +1776,9 @@ cc.defineGetterSetter(_p, "innerWidth", _p._getInnerWidth, _p._setInnerWidth); /** @expose */ _p.innerHeight; cc.defineGetterSetter(_p, "innerHeight", _p._getInnerHeight, _p._setInnerHeight); - +/** @expose */ +_p.direction; +cc.defineGetterSetter(_p, "direction", _p.getDirection, _p.setDirection); _p = null; /** From 6dd32110d38f56ec1a17276cd241ea0f891ea17d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D0=B5=D1=81=D1=88=D0=B0=D0=BF=D0=BE=D1=88=D0=BD?= =?UTF-8?q?=D0=B8=D0=BA=D0=BE=D0=B2=20=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0?= Date: Fri, 27 Nov 2015 14:53:01 +0300 Subject: [PATCH 09/19] Move setting _outOfBoundaryAmountDirty param in list view to function. --- .../ccui/uiwidgets/scroll-widget/UIListView.js | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/extensions/ccui/uiwidgets/scroll-widget/UIListView.js b/extensions/ccui/uiwidgets/scroll-widget/UIListView.js index edb9ab6344..c4396c7f93 100644 --- a/extensions/ccui/uiwidgets/scroll-widget/UIListView.js +++ b/extensions/ccui/uiwidgets/scroll-widget/UIListView.js @@ -52,6 +52,8 @@ ccui.ListView = ccui.ScrollView.extend(/** @lends ccui.ListView# */{ _magneticAllowedOutOfBoundary: true, _magneticType: 0, + _className:"ListView", + /** * allocates and initializes a UIListView. * Constructor of ccui.ListView, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function. @@ -104,6 +106,11 @@ ccui.ListView = ccui.ScrollView.extend(/** @lends ccui.ListView# */{ } }, + _onItemListChanged: function() + { + this._outOfBoundaryAmountDirty = true; + }, + _updateInnerContainerSize: function () { var locItems = this._items, length, i; switch (this.direction) { @@ -250,7 +257,7 @@ ccui.ListView = ccui.ScrollView.extend(/** @lends ccui.ListView# */{ if(widget instanceof ccui.Widget) { this._items.push(widget); - this._outOfBoundaryAmountDirty = true; + this._onItemListChanged(); } } }, @@ -267,7 +274,7 @@ ccui.ListView = ccui.ScrollView.extend(/** @lends ccui.ListView# */{ if(index > -1) this._items.splice(index, 1); - this._outOfBoundaryAmountDirty = true; + this._onItemListChanged(); ccui.ScrollView.prototype.removeChild.call(this, widget, cleanup); } @@ -288,7 +295,7 @@ ccui.ListView = ccui.ScrollView.extend(/** @lends ccui.ListView# */{ ccui.ScrollView.prototype.removeAllChildrenWithCleanup.call(this, cleanup); this._items = []; - this._outOfBoundaryAmountDirty = true; + this._onItemListChanged(); }, /** @@ -299,7 +306,7 @@ ccui.ListView = ccui.ScrollView.extend(/** @lends ccui.ListView# */{ insertCustomItem: function (item, index) { this._items.splice(index, 0, item); - this._outOfBoundaryAmountDirty = true; + this._onItemListChanged(); ccui.ScrollView.prototype.addChild.call(this, item); this._remedyLayoutParameter(item); this._refreshViewDirty = true; @@ -379,7 +386,7 @@ ccui.ListView = ccui.ScrollView.extend(/** @lends ccui.ListView# */{ setMagneticType: function(magneticType) { this._magneticType = magneticType; - this._outOfBoundaryAmountDirty = true; + this._onItemListChanged(); this._startMagneticScroll(); }, From e6f17fab90c05289c807fb78b042b61a3200927f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D0=B5=D1=81=D1=88=D0=B0=D0=BF=D0=BE=D1=88=D0=BD?= =?UTF-8?q?=D0=B8=D0=BA=D0=BE=D0=B2=20=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0?= Date: Fri, 27 Nov 2015 14:56:27 +0300 Subject: [PATCH 10/19] Add ccui.PageViewIndicator --- .../scroll-widget/UIPageViewIndicator.js | 236 ++++++++++++++++++ moduleConfig.json | 2 + tools/build.xml | 1 + tools/jsdoc_toolkit/build.xml | 1 + tools/template/build.xml | 1 + 5 files changed, 241 insertions(+) create mode 100644 extensions/ccui/uiwidgets/scroll-widget/UIPageViewIndicator.js diff --git a/extensions/ccui/uiwidgets/scroll-widget/UIPageViewIndicator.js b/extensions/ccui/uiwidgets/scroll-widget/UIPageViewIndicator.js new file mode 100644 index 0000000000..e4416e67f1 --- /dev/null +++ b/extensions/ccui/uiwidgets/scroll-widget/UIPageViewIndicator.js @@ -0,0 +1,236 @@ +/**************************************************************************** + Copyright (c) 2015 Neo Kim (neo.kim@neofect.com) + Copyright (c) 2015 Nikita Besshaposhnikov (nikita.besshaposhnikov@gmail.com) + + http://www.cocos2d-x.org + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + ****************************************************************************/ + +/** + * The PageViewIndicator control of Cocos UI
+ * Indicator being attached to page view. + * @class + * @extends ccui.ProtectedNode + * @property {Number} spaceBetweenIndexNodes - Space between index nodes in PageViewIndicator + */ +ccui.PageViewIndicator = ccui.ProtectedNode.extend(/** @lends ccui.PageViewIndicator# */{ + _direction: null, + _indexNodes: null, + _currentIndexNode: null, + _spaceBetweenIndexNodes: 0, + _className: "PageViewIndicator", + + /** + * Allocates and initializes a PageViewIndicator. + * Constructor of ccui.PageViewIndicator. override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function. + */ + ctor: function () { + cc.ProtectedNode.prototype.ctor.call(this); + + this._direction = ccui.ScrollView.DIR_HORIZONTAL; + this._indexNodes = []; + this._spaceBetweenIndexNodes = ccui.PageViewIndicator.SPACE_BETWEEN_INDEX_NODES_DEFAULT; + + this.init(); + + this.setCascadeColorEnabled(true); + this.setCascadeOpacityEnabled(true); + }, + + /** + * Initializes a ccui.PageViewIndicator. Please do not call this function by yourself, you should pass the parameters to constructor to initialize it. + * @returns {boolean} + */ + init: function () { + if (cc.ProtectedNode.prototype.init.call(this)) { + + var image = new Image(); + image.src = ccui.PageViewIndicator.CIRCLE_IMAGE; + + this._currentIndexNode = new cc.Sprite(image); + this._currentIndexNode.setVisible(false); + this.addProtectedChild(this._currentIndexNode, 1); + + return true; + } + return false; + }, + + /** + * Sets direction of indicator + * @param {ccui.ScrollView.DIR_NONE | ccui.ScrollView.DIR_VERTICAL | ccui.ScrollView.DIR_HORIZONTAL | ccui.ScrollView.DIR_BOTH} direction + */ + setDirection: function(direction) + { + this._direction = direction; + this._rearrange(); + }, + + /** + * resets indicator with new page count. + * @param {number} numberOfTotalPages + */ + reset: function(numberOfTotalPages) + { + while(this._indexNodes.length < numberOfTotalPages) + { + this._increaseNumberOfPages(); + } + while(this._indexNodes.length > numberOfTotalPages) + { + this._decreaseNumberOfPages(); + } + this._rearrange(); + this._currentIndexNode.setVisible(this._indexNodes.length > 0); + }, + + /** + * Indicates node by index + * @param {number} index + */ + indicate: function(index) + { + if (index < 0 || index >= this._indexNodes.length) + { + return; + } + this._currentIndexNode.setPosition(this._indexNodes[index].getPosition()); + }, + + _rearrange: function() + { + if(this._indexNodes.length === 0) + { + return; + } + + var horizontal = (this._direction === ccui.ScrollView.DIR_HORIZONTAL); + + // Calculate total size + var indexNodeSize = this._indexNodes[0].getContentSize(); + var sizeValue = (horizontal ? indexNodeSize.width : indexNodeSize.height); + + var numberOfItems = this._indexNodes.length; + var totalSizeValue = sizeValue * numberOfItems + this._spaceBetweenIndexNodes * (numberOfItems - 1); + + var posValue = -(totalSizeValue / 2) + (sizeValue / 2); + for(var i = 0; i < this._indexNodes.length; ++i) + { + var position; + if(horizontal) + { + position = cc.p(posValue, indexNodeSize.height / 2.0); + } + else + { + position = cc.p(indexNodeSize.width / 2.0, -posValue); + } + this._indexNodes[i].setPosition(position); + posValue += sizeValue + this._spaceBetweenIndexNodes; + } + }, + + /** + * Sets space between index nodes. + * @param {number} spaceBetweenIndexNodes + */ + setSpaceBetweenIndexNodes: function(spaceBetweenIndexNodes) + { + if(this._spaceBetweenIndexNodes === spaceBetweenIndexNodes) + { + return; + } + this._spaceBetweenIndexNodes = spaceBetweenIndexNodes; + this._rearrange(); + }, + + /** + * Gets space between index nodes. + * @returns {number} + */ + getSpaceBetweenIndexNodes: function() + { + return this._spaceBetweenIndexNodes; + }, + + /** + * Sets color of selected index node + * @param {cc.Color} color + */ + setSelectedIndexColor: function(color) + { + this._currentIndexNode.setColor(color); + }, + + /** + * Gets color of selected index node + * @returns {cc.Color} + */ + getSelectedIndexColor: function() + { + return this._currentIndexNode.getColor(); + }, + + _increaseNumberOfPages: function() + { + var image = new Image(); + image.src = ccui.PageViewIndicator.CIRCLE_IMAGE; + + var indexNode = new cc.Sprite(image); + this.addProtectedChild(indexNode, 1); + this._indexNodes.push(indexNode); + }, + + _decreaseNumberOfPages: function() + { + if(this._indexNodes.length === 0) + { + return; + } + this.removeProtectedChild(this._indexNodes[0]); + this._indexNodes.splice(0, 1); + }, + + /** + * Removes all index nodes. + */ + clear: function() + { + for(var i = 0; i < this._indexNodes.length; ++i) + { + this.removeProtectedChild(this._indexNodes[i]); + } + this._indexNodes.length = 0; + this._currentIndexNode.setVisible(false); + } + +}); + +var _p = ccui.PageViewIndicator.prototype; + +// Extended properties +/** @expose */ +_p.spaceBetweenIndexNodes; +cc.defineGetterSetter(_p, "spaceBetweenIndexNodes", _p.getSpaceBetweenIndexNodes, _p.setSpaceBetweenIndexNodes); +/** + * @ignore + */ +ccui.PageViewIndicator.SPACE_BETWEEN_INDEX_NODES_DEFAULT = 23; +ccui.PageViewIndicator.CIRCLE_IMAGE = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAQAAADZc7J/AAAA8ElEQVRIx62VyRGCQBBF+6gWRCEmYDIQkhiBCgHhSclC8YqWzOV5oVzKAYZp3r1/9fpbxAIBMTsKrjx5cqVgR0wgLhCRUWOjJiPqD56xoaGPhpRZV/iSEy6crHmw5oIrF9b/lVeMofrJgjlnxlIy/wik+JB+mme8BExbBhm+5CJC2LE2LtSEQoyGWDioBA5CoRIohJtK4CYDxzNEM4GAugR1E9VjVC+SZpXvhCJCrjomESLvc17pDGX7bWmlh6UtpjPVCWy9zaJ0TD7qfm3pwERMz2trRVZk3K3BD/L34AY+dEDCniMVBkPFkT2J/b2/AIV+dRpFLOYoAAAAAElFTkSuQmCC"; \ No newline at end of file diff --git a/moduleConfig.json b/moduleConfig.json index 787b42cafb..4e3a85882c 100644 --- a/moduleConfig.json +++ b/moduleConfig.json @@ -340,6 +340,8 @@ "extensions/ccui/uiwidgets/scroll-widget/UIScrollView.js", "extensions/ccui/uiwidgets/scroll-widget/UIListView.js", "extensions/ccui/uiwidgets/scroll-widget/UIPageView.js", + "extensions/ccui/uiwidgets/scroll-widget/UIPageViewIndicator.js", + "extensions/ccui/uiwidgets/scroll-widget/UIPageView.js", "extensions/ccui/uiwidgets/scroll-widget/UIScrollViewCanvasRenderCmd.js", "extensions/ccui/uiwidgets/scroll-widget/UIScrollViewWebGLRenderCmd.js" ], diff --git a/tools/build.xml b/tools/build.xml index 6cdd087478..f09786f922 100644 --- a/tools/build.xml +++ b/tools/build.xml @@ -230,6 +230,7 @@ + diff --git a/tools/jsdoc_toolkit/build.xml b/tools/jsdoc_toolkit/build.xml index 0b9ec01f79..fcbd830237 100644 --- a/tools/jsdoc_toolkit/build.xml +++ b/tools/jsdoc_toolkit/build.xml @@ -162,6 +162,7 @@ + diff --git a/tools/template/build.xml b/tools/template/build.xml index 9fc7a7e231..c2abc27616 100644 --- a/tools/template/build.xml +++ b/tools/template/build.xml @@ -161,6 +161,7 @@ + From f8983ede215de2662a8853791011cb7bc87ee120 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D0=B5=D1=81=D1=88=D0=B0=D0=BF=D0=BE=D1=88=D0=BD?= =?UTF-8?q?=D0=B8=D0=BA=D0=BE=D0=B2=20=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0?= Date: Fri, 27 Nov 2015 14:56:58 +0300 Subject: [PATCH 11/19] Add PageViewIndicator to PageView --- .../uiwidgets/scroll-widget/UIPageView.js | 186 ++++++++++++++++++ 1 file changed, 186 insertions(+) diff --git a/extensions/ccui/uiwidgets/scroll-widget/UIPageView.js b/extensions/ccui/uiwidgets/scroll-widget/UIPageView.js index ecd0964b82..045fffddce 100644 --- a/extensions/ccui/uiwidgets/scroll-widget/UIPageView.js +++ b/extensions/ccui/uiwidgets/scroll-widget/UIPageView.js @@ -40,6 +40,8 @@ ccui.PageView = ccui.ListView.extend(/** @lends ccui.PageView# */{ _pageViewEventSelector: null, _className:"PageView", + _indicator: null, + _indicatorPositionAsAnchorPoint: null, /** * Allocates and initializes a UIPageView. * Constructor of ccui.PageView. please do not call this function by yourself, you should pass the parameters to constructor to initialize it
. @@ -51,6 +53,7 @@ ccui.PageView = ccui.ListView.extend(/** @lends ccui.PageView# */{ ccui.ListView.prototype.ctor.call(this); this._childFocusCancelOffset = 5; + this._indicatorPositionAsAnchorPoint = cc.p(0.5, 1); this._pageViewEventListener = null; this._pageViewEventSelector = null; }, @@ -146,9 +149,38 @@ ccui.PageView = ccui.ListView.extend(/** @lends ccui.PageView# */{ ccui.ListView.prototype._doLayout.call(this); + if(this._indicator) + { + var index = this.getIndex(this.getCenterItemInCurrentView()); + this._indicator.indicate(index); + } + this._refreshViewDirty = false; }, + /** + * Changes scroll direction of ccui.PageView. + * @param {ccui.ScrollView.DIR_NONE | ccui.ScrollView.DIR_VERTICAL | ccui.ScrollView.DIR_HORIZONTAL | ccui.ScrollView.DIR_BOTH} direction + */ + setDirection: function(direction) + { + ccui.ListView.prototype.setDirection.call(this, direction); + if(direction === ccui.ScrollView.DIR_HORIZONTAL) + { + this._indicatorPositionAsAnchorPoint = cc.p(0.5, 0.1); + } + else if(direction === ccui.ScrollView.DIR_VERTICAL) + { + this._indicatorPositionAsAnchorPoint = cc.p(0.1, 0.5); + } + + if(this._indicator) + { + this._indicator.setDirection(direction); + this._refreshIndicatorPosition(); + } + }, + /** * Set custom scroll threshold to page view. If you don't specify the value, the pageView will scroll when half page view width reached. * @since v3.2 @@ -188,6 +220,36 @@ ccui.PageView = ccui.ListView.extend(/** @lends ccui.PageView# */{ { ccui.ListView.prototype._moveInnerContainer.call(this, deltaMove, canStartBounceBack); this._curPageIdx = this.getIndex(this.getCenterItemInCurrentView()); + if(this._indicator) + { + this._indicator.indicate(this._curPageIdx); + } + }, + + _onItemListChanged: function() + { + ccui.ListView.prototype._onItemListChanged.call(this); + if(this._indicator) + { + this._indicator.reset(this._items.length); + } + }, + + _onSizeChanged: function() + { + ccui.ListView.prototype._onSizeChanged.call(this); + this._refreshIndicatorPosition(); + }, + + _refreshIndicatorPosition: function() + { + if(this._indicator) + { + var contentSize = this.getContentSize(); + var posX = contentSize.width * this._indicatorPositionAsAnchorPoint.x; + var posY = contentSize.height * this._indicatorPositionAsAnchorPoint.y; + this._indicator.setPosition(cc.p(posX, posY)); + } }, _handleReleaseLogic: function (touchPoint) { @@ -349,6 +411,130 @@ ccui.PageView = ccui.ListView.extend(/** @lends ccui.PageView# */{ this._pageViewEventListener = pageView._pageViewEventListener; this._pageViewEventSelector = pageView._pageViewEventSelector; this._customScrollThreshold = pageView._customScrollThreshold; + }, + + + /** + * Toggle page indicator enabled. + * @param {boolean} enabled True if enable page indicator, false otherwise. + */ + setIndicatorEnabled: function(enabled) + { + if(enabled == (this._indicator !== null)) + { + return; + } + + if(!enabled) + { + this.removeProtectedChild(this._indicator); + this._indicator = null; + } + else + { + this._indicator = new ccui.PageViewIndicator(); + this._indicator.setDirection(this.getDirection()); + this.addProtectedChild(this._indicator, 10000); + this.setIndicatorSelectedIndexColor(cc.color(100, 100, 255)); + this._refreshIndicatorPosition(); + } + }, + + /** + * Query page indicator state. + * @returns {boolean} True if page indicator is enabled, false otherwise. + */ + getIndicatorEnabled: function() + { + return this._indicator !== null; + }, + + /** + * Set the page indicator's position using anchor point. + * @param {cc.Point} positionAsAnchorPoint The position as anchor point. + */ + setIndicatorPositionAsAnchorPoint: function(positionAsAnchorPoint) + { + this._indicatorPositionAsAnchorPoint = positionAsAnchorPoint; + this._refreshIndicatorPosition(); + }, + + /** + * Get the page indicator's position as anchor point. + * @returns {cc.Point} + */ + getIndicatorPositionAsAnchorPoint: function() + { + return this._indicatorPositionAsAnchorPoint; + }, + + /** + * Set the page indicator's position in page view. + * @param {cc.Point} position The position in page view + */ + setIndicatorPosition: function(position) + { + if(this._indicator) + { + var contentSize = this.getContentSize(); + this._indicatorPositionAsAnchorPoint.x = position.x / contentSize.width; + this._indicatorPositionAsAnchorPoint.y = position.y / contentSize.height; + this._indicator.setPosition(position); + } + }, + + /** + * Get the page indicator's position. + * @returns {cc.Point} + */ + getIndicatorPosition: function() + { + cc.assert(this._indicator !== null, ""); + return this._indicator.getPosition(); + }, + + /** + * Set space between page indicator's index nodes. + * @param {number} spaceBetweenIndexNodes Space between nodes in pixel. + */ + setIndicatorSpaceBetweenIndexNodes: function(spaceBetweenIndexNodes) + { + if(this._indicator) + { + this._indicator.setSpaceBetweenIndexNodes(spaceBetweenIndexNodes); + } + }, + + /** + * Get the space between page indicator's index nodes. + * @returns {number} + */ + getIndicatorSpaceBetweenIndexNodes: function() + { + cc.assert(this._indicator !== null, ""); + return this._indicator.getSpaceBetweenIndexNodes(); + }, + + /** + * Set color of page indicator's selected index. + * @param {cc.Color} color Color for indicator + */ + setIndicatorSelectedIndexColor: function(color) + { + if(this._indicator) + { + this._indicator.setSelectedIndexColor(color); + } + }, + + /** + * Get the color of page indicator's selected index. + * @returns {cc.Color} + */ + getIndicatorSelectedIndexColor: function() + { + cc.assert(this._indicator !== null, ""); + return this._indicator.getSelectedIndexColor(); } }); /** From 0e65775b26a2019f585fdd8e78d81943da945a91 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D0=B5=D1=81=D1=88=D0=B0=D0=BF=D0=BE=D1=88=D0=BD?= =?UTF-8?q?=D0=B8=D0=BA=D0=BE=D0=B2=20=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0?= Date: Wed, 30 Mar 2016 10:45:16 +0300 Subject: [PATCH 12/19] Make last changes to correspond v 3.11 --- .../uiwidgets/scroll-widget/UIPageView.js | 11 +++ .../uiwidgets/scroll-widget/UIScrollView.js | 90 +++++++++++++++---- .../scroll-widget/UIScrollViewBar.js | 14 +-- 3 files changed, 90 insertions(+), 25 deletions(-) diff --git a/extensions/ccui/uiwidgets/scroll-widget/UIPageView.js b/extensions/ccui/uiwidgets/scroll-widget/UIPageView.js index 045fffddce..978b02bf2a 100644 --- a/extensions/ccui/uiwidgets/scroll-widget/UIPageView.js +++ b/extensions/ccui/uiwidgets/scroll-widget/UIPageView.js @@ -241,6 +241,12 @@ ccui.PageView = ccui.ListView.extend(/** @lends ccui.PageView# */{ this._refreshIndicatorPosition(); }, + _remedyLayoutParameter: function (item) + { + item.setContentSize(this.getContentSize()); + ccui.ListView.prototype._remedyLayoutParameter.call(this, item); + }, + _refreshIndicatorPosition: function() { if(this._indicator) @@ -298,6 +304,11 @@ ccui.PageView = ccui.ListView.extend(/** @lends ccui.PageView# */{ }, + _getAutoScrollStopEpsilon: function() + { + return 0.001; + }, + _pageTurningEvent: function () { if(this._pageViewEventSelector){ if (this._pageViewEventListener) diff --git a/extensions/ccui/uiwidgets/scroll-widget/UIScrollView.js b/extensions/ccui/uiwidgets/scroll-widget/UIScrollView.js index d431289770..671e604c89 100644 --- a/extensions/ccui/uiwidgets/scroll-widget/UIScrollView.js +++ b/extensions/ccui/uiwidgets/scroll-widget/UIScrollView.js @@ -46,6 +46,7 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ _touchMoveDisplacements: null, _touchMoveTimeDeltas: null, _touchMovePreviousTimestamp: 0, + _touchTotalTimeThreshold : 0.5, _autoScrolling: false, _autoScrollTargetDelta: null, @@ -172,6 +173,12 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ var innerSize = this._innerContainer.getContentSize(); this._innerContainer.setContentSize(cc.size(Math.max(innerSize.width, locSize.width), Math.max(innerSize.height, locSize.height))); this._innerContainer.setPosition(0, locSize.height - this._innerContainer.getContentSize().height); + + if(this._verticalScrollBar) + this._verticalScrollBar.onScrolled(this._getHowMuchOutOfBoundary()); + + if(this._horizontalScrollBar) + this._horizontalScrollBar.onScrolled(this._getHowMuchOutOfBoundary()); }, /** @@ -199,21 +206,13 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ var pos = this._innerContainer.getPosition(); var contAP = this._innerContainer.getAnchorPoint(); - if (this._innerContainer.getLeftBoundary() > 0.0) + if (this._innerContainer.getLeftBoundary() != 0.0) { pos.x = contAP.x * innerSizeWidth; } - if (this._innerContainer.getRightBoundary() < this._contentSize.width) - { - pos.x = this._contentSize.width - ((1.0 - contAP.x) * innerSizeWidth); - } - if (pos.y > 0.0) + if (this._innerContainer.getTopBoundary() != this._contentSize.height) { - pos.y = contAP.y * innerSizeHeight; - } - if (this._innerContainer.getTopBoundary() < this._contentSize.height) - { - pos.y = this._contentSize.height - (1.0 - contAP.y) * innerSizeWidth; + pos.y = this._contentSize.height - (1.0 - contAP.y) * innerSizeHeight; } this.setInnerContainerPosition(pos); @@ -504,9 +503,9 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ } else { - var howMuchOutOfBoundary = this._getHowMuchOutOfBoundary(); - return howMuchOutOfBoundary.x !==0 && howMuchOutOfBoundary.y !== 0; + return !this._fltEqualZero(outOfBoundary); } + return false; }, @@ -545,7 +544,7 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ { totalTime += this._touchMoveTimeDeltas[i]; } - if(totalTime == 0 || totalTime >= 0.5) + if(totalTime == 0 || totalTime >= this._touchTotalTimeThreshold) { return cc.p(0, 0); } @@ -561,6 +560,25 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ return cc.pMult(totalMovement, 1 / totalTime); }, + /** + * Set the touch total time threshold + * @param {Number} touchTotalTimeThreshold + */ + setTouchTotalTimeThreshold: function(touchTotalTimeThreshold) + { + this._touchTotalTimeThreshold = touchTotalTimeThreshold; + }, + + + /** + * Get the touch total time threshold + * @returns {Number} + */ + getTouchTotalTimeThreshold: function() + { + return this._touchTotalTimeThreshold; + }, + _startInertiaScroll: function(touchMoveVelocity) { var MOVEMENT_FACTOR = 0.7; @@ -575,7 +593,7 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ return false; } var bounceBackAmount = this._getHowMuchOutOfBoundary(); - if(bounceBackAmount.x === 0 && bounceBackAmount.y === 0) + if(this._fltEqualZero(bounceBackAmount)) { return false; } @@ -617,7 +635,7 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ // If the destination is also out of boundary of same side, start brake from beggining. var currentOutOfBoundary = this._getHowMuchOutOfBoundary(); - if(currentOutOfBoundary.x !== 0 || currentOutOfBoundary.y !== 0) + if(!this._fltEqualZero(currentOutOfBoundary)) { this._autoScrollCurrentlyOutOfBoundary = true; var afterOutOfBoundary = this._getHowMuchOutOfBoundary(adjustedDeltaMove); @@ -628,6 +646,17 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ } }, + /** + * Immediately stops inner container scroll initiated by any of the "scrollTo*" member functions + */ + stopAutoScroll: function() + { + this._autoScrolling = false; + this._autoScrollAttenuate = true; + this._autoScrollTotalTime = 0; + this._autoScrollAccumulatedTime = 0; + }, + _isNecessaryAutoScrollBrake: function() { if(this._autoScrollBraking) @@ -653,6 +682,16 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ return false; }, + _getAutoScrollStopEpsilon: function() + { + return 0.0001; + }, + + _fltEqualZero: function(point) + { + return (Math.abs(point.x) <= 0.0001 && Math.abs(point.y) <= 0.0001); + }, + _processAutoScrolling: function(deltaTime) { var OUT_OF_BOUNDARY_BREAKING_FACTOR = 0.05; @@ -672,7 +711,7 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ // Calculate the new position var newPosition = cc.pAdd(this._autoScrollStartPosition, cc.pMult(this._autoScrollTargetDelta,percentage)); - var reachedEnd = (percentage == 1); + var reachedEnd = Math.abs(percentage - 1) <= this._getAutoScrollStopEpsilon(); if(this.bounceEnabled) { @@ -684,7 +723,7 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ // Don't let go out of boundary var moveDelta = cc.pSub(newPosition, this.getInnerContainerPosition()); var outOfBoundary = this._getHowMuchOutOfBoundary(moveDelta); - if(outOfBoundary.x !== 0 || outOfBoundary.y !== 0) + if(!this._fltEqualZero(outOfBoundary)) { newPosition.x += outOfBoundary.x; newPosition.y += outOfBoundary.y; @@ -697,6 +736,7 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ if(reachedEnd) { this._autoScrolling = false; + this._dispatchEvent(ccui.ScrollView.EVENT_AUTOSCROLL_ENDED); } this._moveInnerContainer(cc.pSub(newPosition, this.getInnerContainerPosition()), reachedEnd); @@ -1176,6 +1216,10 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ ccui.Layout.prototype.interceptTouchEvent.call(this, event, sender, touch); return; } + + if(this._direction === ccui.ScrollView.DIR_NONE) + return; + var touchPoint = touch.getLocation(); switch (event) { case ccui.Widget.TOUCH_BEGAN: @@ -1779,8 +1823,10 @@ cc.defineGetterSetter(_p, "innerHeight", _p._getInnerHeight, _p._setInnerHeight) /** @expose */ _p.direction; cc.defineGetterSetter(_p, "direction", _p.getDirection, _p.setDirection); +/** @expose */ +_p.touchTotalTimeThreshold; +cc.defineGetterSetter(_p, "touchTotalTimeThreshold", _p.getTouchTotalTimeThreshold, _p.setTouchTotalTimeThreshold); _p = null; - /** * allocates and initializes a UIScrollView. * @deprecated since v3.0, please use new ccui.ScrollView() instead. @@ -1878,6 +1924,12 @@ ccui.ScrollView.EVENT_BOUNCE_RIGHT = 8; * @type {number} */ ccui.ScrollView.EVENT_CONTAINER_MOVED = 9; +/** + * The flag autoscroll ended of ccui.ScrollView's event. + * @constant + * @type {number} + */ +ccui.ScrollView.EVENT_AUTOSCROLL_ENDED = 10; /** * @ignore diff --git a/extensions/ccui/uiwidgets/scroll-widget/UIScrollViewBar.js b/extensions/ccui/uiwidgets/scroll-widget/UIScrollViewBar.js index a5cc2f432e..35d782744f 100644 --- a/extensions/ccui/uiwidgets/scroll-widget/UIScrollViewBar.js +++ b/extensions/ccui/uiwidgets/scroll-widget/UIScrollViewBar.js @@ -104,17 +104,15 @@ ccui.ScrollViewBar = ccui.ProtectedNode.extend(/** @lends ccui.ScrollViewBar# */ this.addProtectedChild(this._body); this.setColor(ccui.ScrollViewBar.DEFAULT_COLOR); + this.onScrolled(cc.p(0, 0)); + cc.ProtectedNode.prototype.setOpacity.call(this, 0); + this._autoHideRemainingTime = 0; if(this._direction === ccui.ScrollView.DIR_HORIZONTAL) { this.setRotation(90); } - if(this._autoHideEnabled) - { - cc.ProtectedNode.prototype.setOpacity.call(this, 0) - } - return true; } return false; @@ -187,7 +185,11 @@ ccui.ScrollViewBar = ccui.ProtectedNode.extend(/** @lends ccui.ScrollViewBar# */ setAutoHideEnabled: function(autoHideEnabled) { this._autoHideEnabled = autoHideEnabled; - cc.ProtectedNode.prototype.setOpacity.call(this, this.opacity); + + if(!this._autoHideEnabled && !this._touching && this._autoHideRemainingTime <= 0) + cc.ProtectedNode.prototype.setOpacity.call(this, this.opacity); + else + cc.ProtectedNode.prototype.setOpacity.call(this, 0); }, /** * Query scroll bar auto hide state From 147696d4288e772f3e494c496d2b809869b50c1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D0=B5=D1=81=D1=88=D0=B0=D0=BF=D0=BE=D1=88=D0=BD?= =?UTF-8?q?=D0=B8=D0=BA=D0=BE=D0=B2=20=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0?= Date: Fri, 8 Apr 2016 10:11:31 +0300 Subject: [PATCH 13/19] Remove duplicated lines in moduleConfig.json --- moduleConfig.json | 1 - 1 file changed, 1 deletion(-) diff --git a/moduleConfig.json b/moduleConfig.json index 4e3a85882c..4fc43ccfef 100644 --- a/moduleConfig.json +++ b/moduleConfig.json @@ -341,7 +341,6 @@ "extensions/ccui/uiwidgets/scroll-widget/UIListView.js", "extensions/ccui/uiwidgets/scroll-widget/UIPageView.js", "extensions/ccui/uiwidgets/scroll-widget/UIPageViewIndicator.js", - "extensions/ccui/uiwidgets/scroll-widget/UIPageView.js", "extensions/ccui/uiwidgets/scroll-widget/UIScrollViewCanvasRenderCmd.js", "extensions/ccui/uiwidgets/scroll-widget/UIScrollViewWebGLRenderCmd.js" ], From 7cb9cb17958a20063e5abffd8676705bf1e425a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D0=B5=D1=81=D1=88=D0=B0=D0=BF=D0=BE=D1=88=D0=BD?= =?UTF-8?q?=D0=B8=D0=BA=D0=BE=D0=B2=20=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0?= Date: Fri, 8 Apr 2016 10:29:36 +0300 Subject: [PATCH 14/19] Documented 'touchTotalTimeThreshold' property of ccui.ScrollView --- extensions/ccui/uiwidgets/scroll-widget/UIScrollView.js | 1 + 1 file changed, 1 insertion(+) diff --git a/extensions/ccui/uiwidgets/scroll-widget/UIScrollView.js b/extensions/ccui/uiwidgets/scroll-widget/UIScrollView.js index 671e604c89..8d4ef097a6 100644 --- a/extensions/ccui/uiwidgets/scroll-widget/UIScrollView.js +++ b/extensions/ccui/uiwidgets/scroll-widget/UIScrollView.js @@ -33,6 +33,7 @@ * @property {ccui.ScrollView.DIR_NONE | ccui.ScrollView.DIR_VERTICAL | ccui.ScrollView.DIR_HORIZONTAL | ccui.ScrollView.DIR_BOTH} direction - Scroll direction of the scroll view * @property {Boolean} bounceEnabled - Indicate whether bounce is enabled * @property {Boolean} inertiaScrollEnabled - Indicate whether inertiaScroll is enabled + * @property {Number} touchTotalTimeThreshold - Touch total time threshold */ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ _innerContainer: null, From 71f346728d47afb17be0b86367ef06b9cb7ea0ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D0=B5=D1=81=D1=88=D0=B0=D0=BF=D0=BE=D1=88=D0=BD?= =?UTF-8?q?=D0=B8=D0=BA=D0=BE=D0=B2=20=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0?= Date: Fri, 8 Apr 2016 13:39:46 +0300 Subject: [PATCH 15/19] Corrected listener logic of scroll widgets --- .../ccui/uiwidgets/scroll-widget/UIListView.js | 9 --------- .../ccui/uiwidgets/scroll-widget/UIPageView.js | 16 +++++++--------- .../ccui/uiwidgets/scroll-widget/UIScrollView.js | 9 ++++----- 3 files changed, 11 insertions(+), 23 deletions(-) diff --git a/extensions/ccui/uiwidgets/scroll-widget/UIListView.js b/extensions/ccui/uiwidgets/scroll-widget/UIListView.js index c4396c7f93..65664e29fd 100644 --- a/extensions/ccui/uiwidgets/scroll-widget/UIListView.js +++ b/extensions/ccui/uiwidgets/scroll-widget/UIListView.js @@ -871,15 +871,6 @@ ccui.ListView = ccui.ScrollView.extend(/** @lends ccui.ListView# */{ * @deprecated since v3.0, please use addEventListener instead. */ addEventListenerListView: function (selector, target) { - this.addEventListener(selector, target); - }, - - /** - * Adds event listener to ccui.ListView. - * @param {Function} selector - * @param {Object} [target=] - */ - addEventListener: function(selector, target){ this._listViewEventListener = target; this._listViewEventSelector = selector; }, diff --git a/extensions/ccui/uiwidgets/scroll-widget/UIPageView.js b/extensions/ccui/uiwidgets/scroll-widget/UIPageView.js index 978b02bf2a..c09a649ddb 100644 --- a/extensions/ccui/uiwidgets/scroll-widget/UIPageView.js +++ b/extensions/ccui/uiwidgets/scroll-widget/UIPageView.js @@ -327,19 +327,17 @@ ccui.PageView = ccui.ListView.extend(/** @lends ccui.PageView# */{ * @deprecated since v3.0, please use addEventListener instead. */ addEventListenerPageView: function (selector, target) { - this.addEventListener(selector, target); - }, - - /** - * Adds event listener to ccui.PageView. - * @param {Function} selector - * @param {Object} [target=] - */ - addEventListener: function(selector, target){ this._pageViewEventSelector = selector; this._pageViewEventListener = target; }, + addEventListener: function(selector){ + this._ccEventCallback = function(ref, eventType) { + if(eventType == ccui.ScrollView.EVENT_AUTOSCROLL_ENDED) + selector(this, eventType) + }; + }, + /** * Jump to a page with a given index without scrolling. * This is the different between scrollToPage. diff --git a/extensions/ccui/uiwidgets/scroll-widget/UIScrollView.js b/extensions/ccui/uiwidgets/scroll-widget/UIScrollView.js index 8d4ef097a6..a0ab5278c7 100644 --- a/extensions/ccui/uiwidgets/scroll-widget/UIScrollView.js +++ b/extensions/ccui/uiwidgets/scroll-widget/UIScrollView.js @@ -1296,17 +1296,16 @@ ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{ * @deprecated since v3.0, please use addEventListener instead. */ addEventListenerScrollView: function (selector, target) { - this.addEventListener(selector, target); + this._scrollViewEventSelector = selector; + this._scrollViewEventListener = target; }, /** * Adds callback function called ScrollView event triggered * @param {Function} selector - * @param {Object} [target=] */ - addEventListener: function(selector, target){ - this._scrollViewEventSelector = selector; - this._scrollViewEventListener = target; + addEventListener: function(selector){ + this._ccEventCallback = selector; }, /** From dadc4952c18f38920f1f1c2606b2c0c420c480f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D0=B5=D1=81=D1=88=D0=B0=D0=BF=D0=BE=D1=88=D0=BD?= =?UTF-8?q?=D0=B8=D0=BA=D0=BE=D0=B2=20=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0?= Date: Fri, 8 Apr 2016 14:33:59 +0300 Subject: [PATCH 16/19] Fixed ccui.ListView constants values. --- .../ccui/uiwidgets/scroll-widget/UIListView.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/extensions/ccui/uiwidgets/scroll-widget/UIListView.js b/extensions/ccui/uiwidgets/scroll-widget/UIListView.js index 65664e29fd..ad681ef751 100644 --- a/extensions/ccui/uiwidgets/scroll-widget/UIListView.js +++ b/extensions/ccui/uiwidgets/scroll-widget/UIListView.js @@ -1111,7 +1111,7 @@ ccui.ListView.MAGNETIC_NONE = 0; * @constant * @type {number} */ -ccui.ListView.MAGNETIC_CENTER = 0; +ccui.ListView.MAGNETIC_CENTER = 1; /** * The flag of ccui.ListView's magnetic both end type.
* ListView tries to align its items in left or right end if it is horizontal, top or bottom in vertical.
@@ -1119,28 +1119,28 @@ ccui.ListView.MAGNETIC_CENTER = 0; * @constant * @type {number} */ -ccui.ListView.MAGNETIC_BOTH_END = 0; +ccui.ListView.MAGNETIC_BOTH_END = 2; /** * The flag of ccui.ListView's magnetic left type. * @constant * @type {number} */ -ccui.ListView.MAGNETIC_LEFT = 0; +ccui.ListView.MAGNETIC_LEFT = 3; /** * The flag of ccui.ListView's magnetic right type. * @constant * @type {number} */ -ccui.ListView.MAGNETIC_RIGHT = 0; +ccui.ListView.MAGNETIC_RIGHT = 4; /** * The flag of ccui.ListView's magnetic top type. * @constant * @type {number} */ -ccui.ListView.MAGNETIC_TOP = 0; +ccui.ListView.MAGNETIC_TOP = 5; /** * The flag of ccui.ListView's magnetic bottom type. * @constant * @type {number} */ -ccui.ListView.MAGNETIC_BOTTOM = 0; \ No newline at end of file +ccui.ListView.MAGNETIC_BOTTOM = 6; \ No newline at end of file From 577a205071e0abf2f6412dfbb0b1684c47248d1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D0=B5=D1=81=D1=88=D0=B0=D0=BF=D0=BE=D1=88=D0=BD?= =?UTF-8?q?=D0=B8=D0=BA=D0=BE=D0=B2=20=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0?= Date: Fri, 8 Apr 2016 14:34:28 +0300 Subject: [PATCH 17/19] Fixed ccui.ListView '_getHowMuchOutOfBoundary' function --- extensions/ccui/uiwidgets/scroll-widget/UIListView.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/extensions/ccui/uiwidgets/scroll-widget/UIListView.js b/extensions/ccui/uiwidgets/scroll-widget/UIListView.js index ad681ef751..e23e44697f 100644 --- a/extensions/ccui/uiwidgets/scroll-widget/UIListView.js +++ b/extensions/ccui/uiwidgets/scroll-widget/UIListView.js @@ -459,6 +459,9 @@ ccui.ListView = ccui.ScrollView.extend(/** @lends ccui.ListView# */{ _getHowMuchOutOfBoundary: function(addition) { + if(addition === undefined) + addition = cc.p(0, 0); + if(!this._magneticAllowedOutOfBoundary || this._items.length === 0) { return ccui.ScrollView.prototype._getHowMuchOutOfBoundary.call(this, addition); From 5d643e1b80a31690391ea14996dfc16aaaf67e42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D0=B5=D1=81=D1=88=D0=B0=D0=BF=D0=BE=D1=88=D0=BD?= =?UTF-8?q?=D0=B8=D0=BA=D0=BE=D0=B2=20=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0?= Date: Fri, 8 Apr 2016 15:10:27 +0300 Subject: [PATCH 18/19] Fixed ccui.ListView '_startAttenuatingAutoScroll' function. --- extensions/ccui/uiwidgets/scroll-widget/UIListView.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/extensions/ccui/uiwidgets/scroll-widget/UIListView.js b/extensions/ccui/uiwidgets/scroll-widget/UIListView.js index e23e44697f..c69608370f 100644 --- a/extensions/ccui/uiwidgets/scroll-widget/UIListView.js +++ b/extensions/ccui/uiwidgets/scroll-widget/UIListView.js @@ -994,7 +994,7 @@ ccui.ListView = ccui.ScrollView.extend(/** @lends ccui.ListView# */{ var pTargetItem = this.getClosestItemToPosition(cc.pSub(magneticPosition, adjustedDeltaMove), magneticAnchorPoint); var itemPosition = this._calculateItemPositionWithAnchor(pTargetItem, magneticAnchorPoint); - adjustedDeltaMove = magneticPosition - itemPosition; + adjustedDeltaMove = cc.pSub(magneticPosition, itemPosition); } } ccui.ScrollView.prototype._startAttenuatingAutoScroll.call(this,adjustedDeltaMove, initialVelocity); From 2f2b4930665b92d0fe25df49c8870bfa23fecc9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=91=D0=B5=D1=81=D1=88=D0=B0=D0=BF=D0=BE=D1=88=D0=BD?= =?UTF-8?q?=D0=B8=D0=BA=D0=BE=D0=B2=20=D0=9D=D0=B8=D0=BA=D0=B8=D1=82=D0=B0?= Date: Fri, 8 Apr 2016 15:30:05 +0300 Subject: [PATCH 19/19] Corrected displaying of PageViewIndicator: -fixed anchor point in PageView -fixed z oder of indexed items in PageViewIndicator --- extensions/ccui/uiwidgets/scroll-widget/UIPageView.js | 2 +- .../ccui/uiwidgets/scroll-widget/UIPageViewIndicator.js | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/extensions/ccui/uiwidgets/scroll-widget/UIPageView.js b/extensions/ccui/uiwidgets/scroll-widget/UIPageView.js index c09a649ddb..ee73541bca 100644 --- a/extensions/ccui/uiwidgets/scroll-widget/UIPageView.js +++ b/extensions/ccui/uiwidgets/scroll-widget/UIPageView.js @@ -53,7 +53,7 @@ ccui.PageView = ccui.ListView.extend(/** @lends ccui.PageView# */{ ccui.ListView.prototype.ctor.call(this); this._childFocusCancelOffset = 5; - this._indicatorPositionAsAnchorPoint = cc.p(0.5, 1); + this._indicatorPositionAsAnchorPoint = cc.p(0.5, 0.1); this._pageViewEventListener = null; this._pageViewEventSelector = null; }, diff --git a/extensions/ccui/uiwidgets/scroll-widget/UIPageViewIndicator.js b/extensions/ccui/uiwidgets/scroll-widget/UIPageViewIndicator.js index e4416e67f1..ae1c17364e 100644 --- a/extensions/ccui/uiwidgets/scroll-widget/UIPageViewIndicator.js +++ b/extensions/ccui/uiwidgets/scroll-widget/UIPageViewIndicator.js @@ -50,8 +50,8 @@ ccui.PageViewIndicator = ccui.ProtectedNode.extend(/** @lends ccui.PageViewIndic this.init(); - this.setCascadeColorEnabled(true); - this.setCascadeOpacityEnabled(true); + // this.setCascadeColorEnabled(true); + // this.setCascadeOpacityEnabled(true); }, /** @@ -194,7 +194,7 @@ ccui.PageViewIndicator = ccui.ProtectedNode.extend(/** @lends ccui.PageViewIndic image.src = ccui.PageViewIndicator.CIRCLE_IMAGE; var indexNode = new cc.Sprite(image); - this.addProtectedChild(indexNode, 1); + this.addProtectedChild(indexNode); this._indexNodes.push(indexNode); },