1 /****************************************************************************
  2  Copyright (c) 2011-2012 cocos2d-x.org
  3  Copyright (c) 2013-2014 Chukong Technologies Inc.
  4 
  5  http://www.cocos2d-x.org
  6 
  7  Permission is hereby granted, free of charge, to any person obtaining a copy
  8  of this software and associated documentation files (the "Software"), to deal
  9  in the Software without restriction, including without limitation the rights
 10  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 11  copies of the Software, and to permit persons to whom the Software is
 12  furnished to do so, subject to the following conditions:
 13 
 14  The above copyright notice and this permission notice shall be included in
 15  all copies or substantial portions of the Software.
 16 
 17  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 18  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 19  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 20  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 21  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 22  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 23  THE SOFTWARE.
 24  ****************************************************************************/
 25 
 26 /**
 27  * The ScrollView control of Cocos UI
 28  * @class
 29  * @extends ccui.Layout
 30  *
 31  * @property {Number}               innerWidth              - Inner container width of the scroll view
 32  * @property {Number}               innerHeight             - Inner container height of the scroll view
 33  * @property {ccui.ScrollView.DIR_NONE | ccui.ScrollView.DIR_VERTICAL | ccui.ScrollView.DIR_HORIZONTAL | ccui.ScrollView.DIR_BOTH}    direction               - Scroll direction of the scroll view
 34  * @property {Boolean}              bounceEnabled           - Indicate whether bounce is enabled
 35  * @property {Boolean}              inertiaScrollEnabled    - Indicate whether inertiaScroll is enabled
 36  */
 37 ccui.ScrollView = ccui.Layout.extend(/** @lends ccui.ScrollView# */{
 38     _innerContainer: null,
 39     direction: null,
 40     _autoScrollDir: null,
 41 
 42     _topBoundary: 0,
 43     _bottomBoundary: 0,
 44     _leftBoundary: 0,
 45     _rightBoundary: 0,
 46 
 47     _bounceTopBoundary: 0,
 48     _bounceBottomBoundary: 0,
 49     _bounceLeftBoundary: 0,
 50     _bounceRightBoundary: 0,
 51 
 52     _autoScroll: false,
 53     _autoScrollAddUpTime: 0,
 54 
 55     _autoScrollOriginalSpeed: 0,
 56     _autoScrollAcceleration: 0,
 57     _isAutoScrollSpeedAttenuated: false,
 58     _needCheckAutoScrollDestination: false,
 59     _autoScrollDestination: null,
 60 
 61     _bePressed: false,
 62     _slidTime: 0,
 63     _moveChildPoint: null,
 64     _childFocusCancelOffset: 0,
 65 
 66     _leftBounceNeeded: false,
 67     _topBounceNeeded: false,
 68     _rightBounceNeeded: false,
 69     _bottomBounceNeeded: false,
 70 
 71     bounceEnabled: false,
 72     _bouncing: false,
 73     _bounceDir: null,
 74     _bounceOriginalSpeed: 0,
 75     inertiaScrollEnabled: false,
 76 
 77     _scrollViewEventListener: null,
 78     _scrollViewEventSelector: null,
 79     _className: "ScrollView",
 80     _eventCallback: null,
 81 
 82     /**
 83      * Allocates and initializes a UIScrollView.
 84      * Constructor of ccui.ScrollView. override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
 85      * @example
 86      * // example
 87      * var uiScrollView = new ccui.ScrollView();
 88      */
 89     ctor: function () {
 90         ccui.Layout.prototype.ctor.call(this);
 91         this.direction = ccui.ScrollView.DIR_NONE;
 92         this._autoScrollDir = cc.p(0, 0);
 93 
 94         this._autoScrollAcceleration = -1000;
 95         this._autoScrollDestination = cc.p(0, 0);
 96         this._slidTime = 0;
 97         this._moveChildPoint = cc.p(0, 0);
 98         this._childFocusCancelOffset = 5;
 99         this._bounceDir = cc.p(0, 0);
100         this._bounceOriginalSpeed = 0;
101         this.inertiaScrollEnabled = true;
102         this.setTouchEnabled(true);
103     },
104 
105     /**
106      * Initializes a ccui.ScrollView. Please do not call this function by yourself, you should pass the parameters to constructor to initialize it.
107      * @returns {boolean}
108      */
109     init: function () {
110         if (ccui.Layout.prototype.init.call(this)) {
111             this.setClippingEnabled(true);
112             this._innerContainer.setTouchEnabled(false);
113             return true;
114         }
115         return false;
116     },
117 
118     /**
119      * Calls the parent class' onEnter and schedules update function.
120      * @override
121      */
122     onEnter: function () {
123         ccui.Layout.prototype.onEnter.call(this);
124         this.scheduleUpdate(true);
125     },
126 
127     /**
128      * When a widget is in a layout, you could call this method to get the next focused widget within a specified direction.             <br/>
129      * If the widget is not in a layout, it will return itself
130      *
131      * @param {Number} direction the direction to look for the next focused widget in a layout
132      * @param {ccui.Widget} current the current focused widget
133      * @returns {ccui.Widget}
134      */
135     findNextFocusedWidget: function(direction, current){
136         if (this.getLayoutType() == ccui.Layout.LINEAR_VERTICAL
137             || this.getLayoutType() == ccui.Layout.LINEAR_HORIZONTAL) {
138             return this._innerContainer.findNextFocusedWidget(direction, current);
139         } else
140             return ccui.Widget.prototype.findNextFocusedWidget.call(this, direction, current);
141     },
142 
143     _initRenderer: function () {
144         ccui.Layout.prototype._initRenderer.call(this);
145         this._innerContainer = ccui.Layout.create();
146         this.addProtectedChild(this._innerContainer, 1, 1);
147     },
148 
149     _onSizeChanged: function () {
150         ccui.Layout.prototype._onSizeChanged.call(this);
151         var locSize = this._contentSize;
152         this._topBoundary = locSize.height;
153         this._rightBoundary = locSize.width;
154         var bounceBoundaryParameterX = locSize.width / 3;
155         var bounceBoundaryParameterY = locSize.height / 3;
156         this._bounceTopBoundary = locSize.height - bounceBoundaryParameterY;
157         this._bounceBottomBoundary = bounceBoundaryParameterY;
158         this._bounceLeftBoundary = bounceBoundaryParameterX;
159         this._bounceRightBoundary = locSize.width - bounceBoundaryParameterX;
160         var innerSize = this._innerContainer.getContentSize();
161         this._innerContainer.setContentSize(cc.size(Math.max(innerSize.width, locSize.width), Math.max(innerSize.height, locSize.height)));
162         this._innerContainer.setPosition(0, locSize.height - this._innerContainer.getContentSize().height);
163     },
164 
165     /**
166      * Changes inner container size of ScrollView.     <br/>
167      * Inner container size must be larger than or equal the size of ScrollView.
168      * @param {cc.Size} size inner container size.
169      */
170     setInnerContainerSize: function (size) {
171         var innerContainer = this._innerContainer;
172         var locSize = this._contentSize;
173         var innerSizeWidth = locSize.width, innerSizeHeight = locSize.height;
174         var originalInnerSize = innerContainer.getContentSize();
175         if (size.width < locSize.width)
176             cc.log("Inner width <= ScrollView width, it will be force sized!");
177         else
178             innerSizeWidth = size.width;
179 
180         if (size.height < locSize.height)
181             cc.log("Inner height <= ScrollView height, it will be force sized!");
182         else
183             innerSizeHeight = size.height;
184 
185         innerContainer.setContentSize(cc.size(innerSizeWidth, innerSizeHeight));
186         var newInnerSize, offset;
187         switch (this.direction) {
188             case ccui.ScrollView.DIR_VERTICAL:
189                 newInnerSize = innerContainer.getContentSize();
190                 offset = originalInnerSize.height - newInnerSize.height;
191                 this._scrollChildren(0, offset);
192                 break;
193             case ccui.ScrollView.DIR_HORIZONTAL:
194                 if (innerContainer.getRightBoundary() <= locSize.width) {
195                     newInnerSize = innerContainer.getContentSize();
196                     offset = originalInnerSize.width - newInnerSize.width;
197                     this._scrollChildren(offset, 0);
198                 }
199                 break;
200             case ccui.ScrollView.DIR_BOTH:
201                 newInnerSize = innerContainer.getContentSize();
202                 var offsetY = originalInnerSize.height - newInnerSize.height;
203                 var offsetX = (innerContainer.getRightBoundary() <= locSize.width) ? originalInnerSize.width - newInnerSize.width : 0;
204                 this._scrollChildren(offsetX, offsetY);
205                 break;
206             default:
207                 break;
208         }
209 
210         var innerSize = innerContainer.getContentSize();
211         var innerPos = innerContainer.getPosition();
212         var innerAP = innerContainer.getAnchorPoint();
213         if (innerContainer.getLeftBoundary() > 0.0)
214             innerContainer.setPosition(innerAP.x * innerSize.width, innerPos.y);
215         if (innerContainer.getRightBoundary() < locSize.width)
216             innerContainer.setPosition(locSize.width - ((1.0 - innerAP.x) * innerSize.width), innerPos.y);
217         if (innerPos.y > 0.0)
218             innerContainer.setPosition(innerPos.x, innerAP.y * innerSize.height);
219         if (innerContainer.getTopBoundary() < locSize.height)
220             innerContainer.setPosition(innerPos.x, locSize.height - (1.0 - innerAP.y) * innerSize.height);
221     },
222 
223     _setInnerWidth: function (width) {
224         var locW = this._contentSize.width,
225             innerWidth = locW,
226             container = this._innerContainer,
227             oldInnerWidth = container.width;
228         if (width < locW)
229             cc.log("Inner width <= scrollview width, it will be force sized!");
230         else
231             innerWidth = width;
232         container.width = innerWidth;
233 
234         switch (this.direction) {
235             case ccui.ScrollView.DIR_HORIZONTAL:
236             case ccui.ScrollView.DIR_BOTH:
237                 if (container.getRightBoundary() <= locW) {
238                     var newInnerWidth = container.width;
239                     var offset = oldInnerWidth - newInnerWidth;
240                     this._scrollChildren(offset, 0);
241                 }
242                 break;
243         }
244         var innerAX = container.anchorX;
245         if (container.getLeftBoundary() > 0.0)
246             container.x = innerAX * innerWidth;
247         if (container.getRightBoundary() < locW)
248             container.x = locW - ((1.0 - innerAX) * innerWidth);
249     },
250 
251     _setInnerHeight: function (height) {
252         var locH = this._contentSize.height,
253             innerHeight = locH,
254             container = this._innerContainer,
255             oldInnerHeight = container.height;
256         if (height < locH)
257             cc.log("Inner height <= scrollview height, it will be force sized!");
258         else
259             innerHeight = height;
260         container.height = innerHeight;
261 
262         switch (this.direction) {
263             case ccui.ScrollView.DIR_VERTICAL:
264             case ccui.ScrollView.DIR_BOTH:
265                 var newInnerHeight = innerHeight;
266                 var offset = oldInnerHeight - newInnerHeight;
267                 this._scrollChildren(0, offset);
268                 break;
269         }
270         var innerAY = container.anchorY;
271         if (container.getLeftBoundary() > 0.0)
272             container.y = innerAY * innerHeight;
273         if (container.getRightBoundary() < locH)
274             container.y = locH - ((1.0 - innerAY) * innerHeight);
275     },
276 
277     /**
278      * Returns inner container size of ScrollView.     <br/>
279      * Inner container size must be larger than or equal ScrollView's size.
280      *
281      * @return {cc.Size} inner container size.
282      */
283     getInnerContainerSize: function () {
284         return this._innerContainer.getContentSize();
285     },
286     _getInnerWidth: function () {
287         return this._innerContainer.width;
288     },
289     _getInnerHeight: function () {
290         return this._innerContainer.height;
291     },
292 
293     /**
294      * Add child to ccui.ScrollView.
295      * @param {cc.Node} widget
296      * @param {Number} [zOrder]
297      * @param {Number|string} [tag] tag or name
298      * @returns {boolean}
299      */
300     addChild: function (widget, zOrder, tag) {
301         if(!widget)
302             return false;
303         zOrder = zOrder || widget.getLocalZOrder();
304         tag = tag || widget.getTag();
305         return this._innerContainer.addChild(widget, zOrder, tag);
306     },
307 
308     /**
309      * Removes all children.
310      */
311     removeAllChildren: function () {
312         this.removeAllChildrenWithCleanup(true);
313     },
314 
315     /**
316      * Removes all children.
317      * @param {Boolean} cleanup
318      */
319     removeAllChildrenWithCleanup: function(cleanup){
320         this._innerContainer.removeAllChildrenWithCleanup(cleanup);
321     },
322 
323     /**
324      * Removes widget child
325      * @override
326      * @param {ccui.Widget} child
327      * @param {Boolean} cleanup
328      * @returns {boolean}
329      */
330     removeChild: function (child, cleanup) {
331         return this._innerContainer.removeChild(child, cleanup);
332     },
333 
334     /**
335      * Returns inner container's children
336      * @returns {Array}
337      */
338     getChildren: function () {
339         return this._innerContainer.getChildren();
340     },
341 
342     /**
343      * Gets the count of inner container's children
344      * @returns {Number}
345      */
346     getChildrenCount: function () {
347         return this._innerContainer.getChildrenCount();
348     },
349 
350     /**
351      * Gets a child from the container given its tag
352      * @param {Number} tag
353      * @returns {ccui.Widget}
354      */
355     getChildByTag: function (tag) {
356         return this._innerContainer.getChildByTag(tag);
357     },
358 
359     /**
360      * Gets a child from the container given its name
361      * @param {String} name
362      * @returns {ccui.Widget}
363      */
364     getChildByName: function (name) {
365         return this._innerContainer.getChildByName(name);
366     },
367 
368     _moveChildren: function (offsetX, offsetY) {
369         var locContainer = this._innerContainer;
370         //var pos = this._innerContainer.getPosition();
371         this._moveChildPoint.x = locContainer.x + offsetX;
372         this._moveChildPoint.y = locContainer.y + offsetY;
373         this._innerContainer.setPosition(this._moveChildPoint);
374     },
375 
376     _autoScrollChildren: function (dt) {
377         var lastTime = this._autoScrollAddUpTime;
378         this._autoScrollAddUpTime += dt;
379         if (this._isAutoScrollSpeedAttenuated) {
380             var nowSpeed = this._autoScrollOriginalSpeed + this._autoScrollAcceleration * this._autoScrollAddUpTime;
381             if (nowSpeed <= 0) {
382                 this._stopAutoScrollChildren();
383                 this._checkNeedBounce();
384             } else {
385                 var timeParam = lastTime * 2 + dt;
386                 var offset = (this._autoScrollOriginalSpeed + this._autoScrollAcceleration * timeParam * 0.5) * dt;
387                 var offsetX = offset * this._autoScrollDir.x;
388                 var offsetY = offset * this._autoScrollDir.y;
389                 if (!this._scrollChildren(offsetX, offsetY)) {
390                     this._stopAutoScrollChildren();
391                     this._checkNeedBounce();
392                 }
393             }
394         } else {
395             if (this._needCheckAutoScrollDestination) {
396                 var xOffset = this._autoScrollDir.x * dt * this._autoScrollOriginalSpeed;
397                 var yOffset = this._autoScrollDir.y * dt * this._autoScrollOriginalSpeed;
398                 var notDone = this._checkCustomScrollDestination(xOffset, yOffset);
399                 var scrollCheck = this._scrollChildren(xOffset, yOffset);
400                 if (!notDone || !scrollCheck) {
401                     this._stopAutoScrollChildren();
402                     this._checkNeedBounce();
403                 }
404             } else {
405                 if (!this._scrollChildren(this._autoScrollDir.x * dt * this._autoScrollOriginalSpeed,
406                         this._autoScrollDir.y * dt * this._autoScrollOriginalSpeed)) {
407                     this._stopAutoScrollChildren();
408                     this._checkNeedBounce();
409                 }
410             }
411         }
412     },
413 
414     _bounceChildren: function (dt) {
415         var locSpeed = this._bounceOriginalSpeed;
416         var locBounceDir = this._bounceDir;
417         if (locSpeed <= 0.0)
418             this._stopBounceChildren();
419         if (!this._bounceScrollChildren(locBounceDir.x * dt * locSpeed, locBounceDir.y * dt * locSpeed))
420             this._stopBounceChildren();
421     },
422 
423     _checkNeedBounce: function () {
424         if (!this.bounceEnabled)
425             return false;
426         this._checkBounceBoundary();
427         var locTopBounceNeeded = this._topBounceNeeded, locBottomBounceNeeded = this._bottomBounceNeeded,
428             locLeftBounceNeeded = this._leftBounceNeeded, locRightBounceNeeded = this._rightBounceNeeded;
429 
430         if (locTopBounceNeeded || locBottomBounceNeeded || locLeftBounceNeeded || locRightBounceNeeded) {
431             var scrollVector, orSpeed;
432             var locContentSize = this._contentSize, locInnerContainer = this._innerContainer;
433             if (locTopBounceNeeded && locLeftBounceNeeded) {
434                 scrollVector = cc.pSub(cc.p(0.0, locContentSize.height), cc.p(locInnerContainer.getLeftBoundary(), locInnerContainer.getTopBoundary()));
435                 orSpeed = cc.pLength(scrollVector) / 0.2;
436                 this._bounceDir = cc.pNormalize(scrollVector);
437                 this._startBounceChildren(orSpeed);
438             } else if (locTopBounceNeeded && locRightBounceNeeded) {
439                 scrollVector = cc.pSub(cc.p(locContentSize.width, locContentSize.height), cc.p(locInnerContainer.getRightBoundary(), locInnerContainer.getTopBoundary()));
440                 orSpeed = cc.pLength(scrollVector) / 0.2;
441                 this._bounceDir = cc.pNormalize(scrollVector);
442                 this._startBounceChildren(orSpeed);
443             } else if (locBottomBounceNeeded && locLeftBounceNeeded) {
444                 scrollVector = cc.pSub(cc.p(0, 0), cc.p(locInnerContainer.getLeftBoundary(), locInnerContainer.getBottomBoundary()));
445                 orSpeed = cc.pLength(scrollVector) / 0.2;
446                 this._bounceDir = cc.pNormalize(scrollVector);
447                 this._startBounceChildren(orSpeed);
448             } else if (locBottomBounceNeeded && locRightBounceNeeded) {
449                 scrollVector = cc.pSub(cc.p(locContentSize.width, 0.0), cc.p(locInnerContainer.getRightBoundary(), locInnerContainer.getBottomBoundary()));
450                 orSpeed = cc.pLength(scrollVector) / 0.2;
451                 this._bounceDir = cc.pNormalize(scrollVector);
452                 this._startBounceChildren(orSpeed);
453             } else if (locTopBounceNeeded) {
454                 scrollVector = cc.pSub(cc.p(0, locContentSize.height), cc.p(0.0, locInnerContainer.getTopBoundary()));
455                 orSpeed = cc.pLength(scrollVector) / 0.2;
456                 this._bounceDir = cc.pNormalize(scrollVector);
457                 this._startBounceChildren(orSpeed);
458             } else if (locBottomBounceNeeded) {
459                 scrollVector = cc.pSub(cc.p(0, 0), cc.p(0.0, locInnerContainer.getBottomBoundary()));
460                 orSpeed = cc.pLength(scrollVector) / 0.2;
461                 this._bounceDir = cc.pNormalize(scrollVector);
462                 this._startBounceChildren(orSpeed);
463             } else if (locLeftBounceNeeded) {
464                 scrollVector = cc.pSub(cc.p(0, 0), cc.p(locInnerContainer.getLeftBoundary(), 0.0));
465                 orSpeed = cc.pLength(scrollVector) / 0.2;
466                 this._bounceDir = cc.pNormalize(scrollVector);
467                 this._startBounceChildren(orSpeed);
468             } else if (locRightBounceNeeded) {
469                 scrollVector = cc.pSub(cc.p(locContentSize.width, 0), cc.p(locInnerContainer.getRightBoundary(), 0.0));
470                 orSpeed = cc.pLength(scrollVector) / 0.2;
471                 this._bounceDir = cc.pNormalize(scrollVector);
472                 this._startBounceChildren(orSpeed);
473             }
474             return true;
475         }
476         return false;
477     },
478 
479     _checkBounceBoundary: function () {
480         var locContainer = this._innerContainer;
481         var icBottomPos = locContainer.getBottomBoundary();
482         if (icBottomPos > this._bottomBoundary) {
483             this._scrollToBottomEvent();
484             this._bottomBounceNeeded = true;
485         } else
486             this._bottomBounceNeeded = false;
487 
488         var icTopPos = locContainer.getTopBoundary();
489         if (icTopPos < this._topBoundary) {
490             this._scrollToTopEvent();
491             this._topBounceNeeded = true;
492         } else
493             this._topBounceNeeded = false;
494 
495         var icRightPos = locContainer.getRightBoundary();
496         if (icRightPos < this._rightBoundary) {
497             this._scrollToRightEvent();
498             this._rightBounceNeeded = true;
499         } else
500             this._rightBounceNeeded = false;
501 
502         var icLeftPos = locContainer.getLeftBoundary();
503         if (icLeftPos > this._leftBoundary) {
504             this._scrollToLeftEvent();
505             this._leftBounceNeeded = true;
506         } else
507             this._leftBounceNeeded = false;
508     },
509 
510     _startBounceChildren: function (v) {
511         this._bounceOriginalSpeed = v;
512         this._bouncing = true;
513     },
514 
515     _stopBounceChildren: function () {
516         this._bouncing = false;
517         this._bounceOriginalSpeed = 0.0;
518         this._leftBounceNeeded = false;
519         this._rightBounceNeeded = false;
520         this._topBounceNeeded = false;
521         this._bottomBounceNeeded = false;
522     },
523 
524     _startAutoScrollChildrenWithOriginalSpeed: function (dir, v, attenuated, acceleration) {
525         this._stopAutoScrollChildren();
526         this._autoScrollDir.x = dir.x;
527         this._autoScrollDir.y = dir.y;
528         this._isAutoScrollSpeedAttenuated = attenuated;
529         this._autoScrollOriginalSpeed = v;
530         this._autoScroll = true;
531         this._autoScrollAcceleration = acceleration;
532     },
533 
534     _startAutoScrollChildrenWithDestination: function (des, time, attenuated) {
535         this._needCheckAutoScrollDestination = false;
536         this._autoScrollDestination = des;
537         var dis = cc.pSub(des, this._innerContainer.getPosition());
538         var dir = cc.pNormalize(dis);
539         var orSpeed = 0.0;
540         var acceleration = -1000.0;
541         var disLength = cc.pLength(dis);
542         if (attenuated) {
543             acceleration = -(2 * disLength) / (time * time);
544             orSpeed = 2 * disLength / time;
545         } else {
546             this._needCheckAutoScrollDestination = true;
547             orSpeed = disLength / time;
548         }
549         this._startAutoScrollChildrenWithOriginalSpeed(dir, orSpeed, attenuated, acceleration);
550     },
551 
552     _jumpToDestination: function (dstX, dstY) {
553         if (dstX.x !== undefined) {
554             dstY = dstX.y;
555             dstX = dstX.x;
556         }
557         var finalOffsetX = dstX;
558         var finalOffsetY = dstY;
559         switch (this.direction) {
560             case ccui.ScrollView.DIR_VERTICAL:
561                 if (dstY <= 0)
562                     finalOffsetY = Math.max(dstY, this._contentSize.height - this._innerContainer.getContentSize().height);
563                 break;
564             case ccui.ScrollView.DIR_HORIZONTAL:
565                 if (dstX <= 0)
566                     finalOffsetX = Math.max(dstX, this._contentSize.width - this._innerContainer.getContentSize().width);
567                 break;
568             case ccui.ScrollView.DIR_BOTH:
569                 if (dstY <= 0)
570                     finalOffsetY = Math.max(dstY, this._contentSize.height - this._innerContainer.getContentSize().height);
571                 if (dstX <= 0)
572                     finalOffsetX = Math.max(dstX, this._contentSize.width - this._innerContainer.getContentSize().width);
573                 break;
574             default:
575                 break;
576         }
577         this._innerContainer.setPosition(finalOffsetX, finalOffsetY);
578     },
579 
580     _stopAutoScrollChildren: function () {
581         this._autoScroll = false;
582         this._autoScrollOriginalSpeed = 0;
583         this._autoScrollAddUpTime = 0;
584     },
585 
586     _bounceScrollChildren: function (touchOffsetX, touchOffsetY) {
587         var scrollEnabled = true;
588         var realOffsetX, realOffsetY, icRightPos, icTopPos, icBottomPos;
589         var locContainer = this._innerContainer;
590         if (touchOffsetX > 0.0 && touchOffsetY > 0.0){              //first quadrant //bounce to top-right
591             realOffsetX = touchOffsetX;
592             realOffsetY = touchOffsetY;
593             icRightPos = locContainer.getRightBoundary();
594             if (icRightPos + realOffsetX >= this._rightBoundary) {
595                 realOffsetX = this._rightBoundary - icRightPos;
596                 this._bounceRightEvent();
597                 scrollEnabled = false;
598             }
599             icTopPos = locContainer.getTopBoundary();
600             if (icTopPos + touchOffsetY >= this._topBoundary) {
601                 realOffsetY = this._topBoundary - icTopPos;
602                 this._bounceTopEvent();
603                 scrollEnabled = false;
604             }
605             this._moveChildren(realOffsetX, realOffsetY);
606         } else if (touchOffsetX < 0.0 && touchOffsetY > 0.0){       //second quadrant //bounce to top-left
607             realOffsetX = touchOffsetX;
608             realOffsetY = touchOffsetY;
609             icLefrPos = locContainer.getLeftBoundary();
610             if (icLefrPos + realOffsetX <= this._leftBoundary) {
611                 realOffsetX = this._leftBoundary - icLefrPos;
612                 this._bounceLeftEvent();
613                 scrollEnabled = false;
614             }
615             icTopPos = locContainer.getTopBoundary();
616             if (icTopPos + touchOffsetY >= this._topBoundary) {
617                 realOffsetY = this._topBoundary - icTopPos;
618                 this._bounceTopEvent();
619                 scrollEnabled = false;
620             }
621             this._moveChildren(realOffsetX, realOffsetY);
622         }else if (touchOffsetX < 0.0 && touchOffsetY < 0.0){ //third quadrant //bounce to bottom-left
623             realOffsetX = touchOffsetX;
624             realOffsetY = touchOffsetY;
625             var icLefrPos = locContainer.getLeftBoundary();
626             if (icLefrPos + realOffsetX <= this._leftBoundary) {
627                 realOffsetX = this._leftBoundary - icLefrPos;
628                 this._bounceLeftEvent();
629                 scrollEnabled = false;
630             }
631             icBottomPos = locContainer.getBottomBoundary();
632             if (icBottomPos + touchOffsetY <= this._bottomBoundary) {
633                 realOffsetY = this._bottomBoundary - icBottomPos;
634                 this._bounceBottomEvent();
635                 scrollEnabled = false;
636             }
637             this._moveChildren(realOffsetX, realOffsetY);
638         } else if (touchOffsetX > 0.0 && touchOffsetY < 0.0){ //forth quadrant //bounce to bottom-right
639             realOffsetX = touchOffsetX;
640             realOffsetY = touchOffsetY;
641             icRightPos = locContainer.getRightBoundary();
642             if (icRightPos + realOffsetX >= this._rightBoundary) {
643                 realOffsetX = this._rightBoundary - icRightPos;
644                 this._bounceRightEvent();
645                 scrollEnabled = false;
646             }
647             icBottomPos = locContainer.getBottomBoundary();
648             if (icBottomPos + touchOffsetY <= this._bottomBoundary) {
649                 realOffsetY = this._bottomBoundary - icBottomPos;
650                 this._bounceBottomEvent();
651                 scrollEnabled = false;
652             }
653             this._moveChildren(realOffsetX, realOffsetY);
654         } else if (touchOffsetX == 0.0 && touchOffsetY > 0.0){ // bounce to top
655             realOffsetY = touchOffsetY;
656             icTopPos = locContainer.getTopBoundary();
657             if (icTopPos + touchOffsetY >= this._topBoundary) {
658                 realOffsetY = this._topBoundary - icTopPos;
659                 this._bounceTopEvent();
660                 scrollEnabled = false;
661             }
662             this._moveChildren(0.0, realOffsetY);
663         } else if (touchOffsetX == 0.0 && touchOffsetY < 0.0) {//bounce to bottom
664             realOffsetY = touchOffsetY;
665             icBottomPos = locContainer.getBottomBoundary();
666             if (icBottomPos + touchOffsetY <= this._bottomBoundary) {
667                 realOffsetY = this._bottomBoundary - icBottomPos;
668                 this._bounceBottomEvent();
669                 scrollEnabled = false;
670             }
671             this._moveChildren(0.0, realOffsetY);
672         } else if (touchOffsetX > 0.0 && touchOffsetY == 0.0){ //bounce to right
673             realOffsetX = touchOffsetX;
674             icRightPos = locContainer.getRightBoundary();
675             if (icRightPos + realOffsetX >= this._rightBoundary) {
676                 realOffsetX = this._rightBoundary - icRightPos;
677                 this._bounceRightEvent();
678                 scrollEnabled = false;
679             }
680             this._moveChildren(realOffsetX, 0.0);
681         }else if (touchOffsetX < 0.0 && touchOffsetY == 0.0){ //bounce to left
682             realOffsetX = touchOffsetX;
683             var icLeftPos = locContainer.getLeftBoundary();
684             if (icLeftPos + realOffsetX <= this._leftBoundary) {
685                 realOffsetX = this._leftBoundary - icLeftPos;
686                 this._bounceLeftEvent();
687                 scrollEnabled = false;
688             }
689             this._moveChildren(realOffsetX, 0.0);
690         }
691         return scrollEnabled;
692     },
693 
694     _checkCustomScrollDestination: function (touchOffsetX, touchOffsetY) {
695         var scrollEnabled = true;
696         var icBottomPos, icLeftPos, icRightPos, icTopPos;
697         var locContainer = this._innerContainer, locDestination = this._autoScrollDestination;
698         switch (this.direction) {
699             case ccui.ScrollView.DIR_VERTICAL: // vertical
700                 if (this._autoScrollDir.y > 0) {
701                     icBottomPos = locContainer.getBottomBoundary();
702                     if (icBottomPos + touchOffsetY >= locDestination.y) {
703                         touchOffsetY = locDestination.y - icBottomPos;
704                         scrollEnabled = false;
705                     }
706                 } else {
707                     icBottomPos = locContainer.getBottomBoundary();
708                     if (icBottomPos + touchOffsetY <= locDestination.y) {
709                         touchOffsetY = locDestination.y - icBottomPos;
710                         scrollEnabled = false;
711                     }
712                 }
713                 break;
714             case ccui.ScrollView.DIR_HORIZONTAL: // horizontal
715                 if (this._autoScrollDir.x > 0) {
716                     icLeftPos = locContainer.getLeftBoundary();
717                     if (icLeftPos + touchOffsetX >= locDestination.x) {
718                         touchOffsetX = locDestination.x - icLeftPos;
719                         scrollEnabled = false;
720                     }
721                 } else {
722                     icLeftPos = locContainer.getLeftBoundary();
723                     if (icLeftPos + touchOffsetX <= locDestination.x) {
724                         touchOffsetX = locDestination.x - icLeftPos;
725                         scrollEnabled = false;
726                     }
727                 }
728                 break;
729             case ccui.ScrollView.DIR_BOTH:
730                 if (touchOffsetX > 0.0 && touchOffsetY > 0.0){ // up right
731                     icLeftPos = locContainer.getLeftBoundary();
732                     if (icLeftPos + touchOffsetX >= locDestination.x) {
733                         touchOffsetX = locDestination.x - icLeftPos;
734                         scrollEnabled = false;
735                     }
736                     icBottomPos = locContainer.getBottomBoundary();
737                     if (icBottomPos + touchOffsetY >= locDestination.y) {
738                         touchOffsetY = locDestination.y - icBottomPos;
739                         scrollEnabled = false;
740                     }
741                 } else if (touchOffsetX < 0.0 && touchOffsetY > 0.0){ // up left
742                     icRightPos = locContainer.getRightBoundary();
743                     if (icRightPos + touchOffsetX <= locDestination.x) {
744                         touchOffsetX = locDestination.x - icRightPos;
745                         scrollEnabled = false;
746                     }
747                     icBottomPos = locContainer.getBottomBoundary();
748                     if (icBottomPos + touchOffsetY >= locDestination.y) {
749                         touchOffsetY = locDestination.y - icBottomPos;
750                         scrollEnabled = false;
751                     }
752                 } else if (touchOffsetX < 0.0 && touchOffsetY < 0.0){ // down left
753                     icRightPos = locContainer.getRightBoundary();
754                     if (icRightPos + touchOffsetX <= locDestination.x) {
755                         touchOffsetX = locDestination.x - icRightPos;
756                         scrollEnabled = false;
757                     }
758                     icTopPos = locContainer.getTopBoundary();
759                     if (icTopPos + touchOffsetY <= locDestination.y) {
760                         touchOffsetY = locDestination.y - icTopPos;
761                         scrollEnabled = false;
762                     }
763                 } else if (touchOffsetX > 0.0 && touchOffsetY < 0.0){ // down right
764                     icLeftPos = locContainer.getLeftBoundary();
765                     if (icLeftPos + touchOffsetX >= locDestination.x) {
766                         touchOffsetX = locDestination.x - icLeftPos;
767                         scrollEnabled = false;
768                     }
769                     icTopPos = locContainer.getTopBoundary();
770                     if (icTopPos + touchOffsetY <= locDestination.y) {
771                         touchOffsetY = locDestination.y - icTopPos;
772                         scrollEnabled = false;
773                     }
774                 } else if (touchOffsetX == 0.0 && touchOffsetY > 0.0){ // up
775                     icBottomPos = locContainer.getBottomBoundary();
776                     if (icBottomPos + touchOffsetY >= locDestination.y) {
777                         touchOffsetY = locDestination.y - icBottomPos;
778                         scrollEnabled = false;
779                     }
780                 } else if (touchOffsetX < 0.0 && touchOffsetY == 0.0){ // left
781                     icRightPos = locContainer.getRightBoundary();
782                     if (icRightPos + touchOffsetX <= locDestination.x) {
783                         touchOffsetX = locDestination.x - icRightPos;
784                         scrollEnabled = false;
785                     }
786                 } else if (touchOffsetX == 0.0 && touchOffsetY < 0.0){ // down
787                     icTopPos = locContainer.getTopBoundary();
788                     if (icTopPos + touchOffsetY <= locDestination.y) {
789                         touchOffsetY = locDestination.y - icTopPos;
790                         scrollEnabled = false;
791                     }
792                 } else if (touchOffsetX > 0.0 && touchOffsetY == 0.0){ // right
793                     icLeftPos = locContainer.getLeftBoundary();
794                     if (icLeftPos + touchOffsetX >= locDestination.x) {
795                         touchOffsetX = locDestination.x - icLeftPos;
796                         scrollEnabled = false;
797                     }
798                 }
799                 break;
800             default:
801                 break;
802         }
803         return scrollEnabled;
804     },
805 
806     _scrollChildren: function (touchOffsetX, touchOffsetY) {
807         var scrollEnabled = true;
808         this._scrollingEvent();
809         switch (this.direction) {
810             case ccui.ScrollView.DIR_VERTICAL: // vertical
811                 scrollEnabled = this._scrollChildrenVertical(touchOffsetX, touchOffsetY);
812                 break;
813             case ccui.ScrollView.DIR_HORIZONTAL: // horizontal
814                 scrollEnabled = this._scrollChildrenHorizontal(touchOffsetX, touchOffsetY);
815                 break;
816             case ccui.ScrollView.DIR_BOTH:
817                 scrollEnabled = this._scrollChildrenBoth(touchOffsetX, touchOffsetY);
818                 break;
819             default:
820                 break;
821         }
822         return scrollEnabled;
823     },
824 
825     _scrollChildrenVertical: function(touchOffsetX, touchOffsetY){
826         var realOffset = touchOffsetY;
827         var scrollEnabled = true;
828         var icBottomPos, icTopPos, locContainer = this._innerContainer;
829         if (this.bounceEnabled) {
830             icBottomPos = locContainer.getBottomBoundary();
831             if (icBottomPos + touchOffsetY >= this._bounceBottomBoundary) {
832                 realOffset = this._bounceBottomBoundary - icBottomPos;
833                 this._scrollToBottomEvent();
834                 scrollEnabled = false;
835             }
836             icTopPos = locContainer.getTopBoundary();
837             if (icTopPos + touchOffsetY <= this._bounceTopBoundary) {
838                 realOffset = this._bounceTopBoundary - icTopPos;
839                 this._scrollToTopEvent();
840                 scrollEnabled = false;
841 
842             }
843         } else {
844             icBottomPos = locContainer.getBottomBoundary();
845             if (icBottomPos + touchOffsetY >= this._bottomBoundary){
846                 realOffset = this._bottomBoundary - icBottomPos;
847                 this._scrollToBottomEvent();
848                 scrollEnabled = false;
849             }
850             icTopPos = locContainer.getTopBoundary();
851             if (icTopPos + touchOffsetY <= this._topBoundary) {
852                 realOffset = this._topBoundary - icTopPos;
853                 this._scrollToTopEvent();
854                 scrollEnabled = false;
855             }
856         }
857         this._moveChildren(0.0, realOffset);
858         return scrollEnabled;
859     },
860 
861     _scrollChildrenHorizontal: function(touchOffsetX, touchOffestY){
862         var scrollEnabled = true;
863         var realOffset = touchOffsetX;
864         var icRightPos, icLeftPos, locContainer = this._innerContainer;
865         if (this.bounceEnabled){
866             icRightPos = locContainer.getRightBoundary();
867             if (icRightPos + touchOffsetX <= this._bounceRightBoundary) {
868                 realOffset = this._bounceRightBoundary - icRightPos;
869                 this._scrollToRightEvent();
870                 scrollEnabled = false;
871             }
872             icLeftPos = locContainer.getLeftBoundary();
873             if (icLeftPos + touchOffsetX >= this._bounceLeftBoundary) {
874                 realOffset = this._bounceLeftBoundary - icLeftPos;
875                 this._scrollToLeftEvent();
876                 scrollEnabled = false;
877             }
878         } else {
879             icRightPos = locContainer.getRightBoundary();
880             if (icRightPos + touchOffsetX <= this._rightBoundary) {
881                 realOffset = this._rightBoundary - icRightPos;
882                 this._scrollToRightEvent();
883                 scrollEnabled = false;
884             }
885             icLeftPos = locContainer.getLeftBoundary();
886             if (icLeftPos + touchOffsetX >= this._leftBoundary) {
887                 realOffset = this._leftBoundary - icLeftPos;
888                 this._scrollToLeftEvent();
889                 scrollEnabled = false;
890             }
891         }
892         this._moveChildren(realOffset, 0.0);
893         return scrollEnabled;
894     },
895 
896     _scrollChildrenBoth: function (touchOffsetX, touchOffsetY) {
897         var scrollEnabled = true;
898         var realOffsetX = touchOffsetX;
899         var realOffsetY = touchOffsetY;
900         var icLeftPos, icBottomPos, icRightPos, icTopPos;
901         var locContainer = this._innerContainer;
902         if (this.bounceEnabled) {
903             if (touchOffsetX > 0.0 && touchOffsetY > 0.0) { // up right
904                 icLeftPos = locContainer.getLeftBoundary();
905                 if (icLeftPos + touchOffsetX >= this._bounceLeftBoundary) {
906                     realOffsetX = this._bounceLeftBoundary - icLeftPos;
907                     this._scrollToLeftEvent();
908                     scrollEnabled = false;
909                 }
910                 icBottomPos = locContainer.getBottomBoundary();
911                 if (icBottomPos + touchOffsetY >= this._bounceBottomBoundary) {
912                     realOffsetY = this._bounceBottomBoundary - icBottomPos;
913                     this._scrollToBottomEvent();
914                     scrollEnabled = false;
915                 }
916             } else if (touchOffsetX < 0.0 && touchOffsetY > 0.0) { // up left
917                 icRightPos = locContainer.getRightBoundary();
918                 if (icRightPos + touchOffsetX <= this._bounceRightBoundary) {
919                     realOffsetX = this._bounceRightBoundary - icRightPos;
920                     this._scrollToRightEvent();
921                     scrollEnabled = false;
922                 }
923                 icBottomPos = locContainer.getBottomBoundary();
924                 if (icBottomPos + touchOffsetY >= this._bounceBottomBoundary) {
925                     realOffsetY = this._bounceBottomBoundary - icBottomPos;
926                     this._scrollToBottomEvent();
927                     scrollEnabled = false;
928                 }
929             } else if (touchOffsetX < 0.0 && touchOffsetY < 0.0) { // down left
930                 icRightPos = locContainer.getRightBoundary();
931                 if (icRightPos + touchOffsetX <= this._bounceRightBoundary) {
932                     realOffsetX = this._bounceRightBoundary - icRightPos;
933                     this._scrollToRightEvent();
934                     scrollEnabled = false;
935                 }
936                 icTopPos = locContainer.getTopBoundary();
937                 if (icTopPos + touchOffsetY <= this._bounceTopBoundary) {
938                     realOffsetY = this._bounceTopBoundary - icTopPos;
939                     this._scrollToTopEvent();
940                     scrollEnabled = false;
941                 }
942             } else if (touchOffsetX > 0.0 && touchOffsetY < 0.0){ // down right
943                 icLeftPos = locContainer.getLeftBoundary();
944                 if (icLeftPos + touchOffsetX >= this._bounceLeftBoundary) {
945                     realOffsetX = this._bounceLeftBoundary - icLeftPos;
946                     this._scrollToLeftEvent();
947                     scrollEnabled = false;
948                 }
949                 icTopPos = locContainer.getTopBoundary();
950                 if (icTopPos + touchOffsetY <= this._bounceTopBoundary) {
951                     realOffsetY = this._bounceTopBoundary - icTopPos;
952                     this._scrollToTopEvent();
953                     scrollEnabled = false;
954                 }
955             } else if (touchOffsetX == 0.0 && touchOffsetY > 0.0){ // up
956                 icBottomPos = locContainer.getBottomBoundary();
957                 if (icBottomPos + touchOffsetY >= this._bounceBottomBoundary) {
958                     realOffsetY = this._bounceBottomBoundary - icBottomPos;
959                     this._scrollToBottomEvent();
960                     scrollEnabled = false;
961                 }
962             } else if (touchOffsetX < 0.0 && touchOffsetY == 0.0){ // left
963                 icRightPos = locContainer.getRightBoundary();
964                 if (icRightPos + touchOffsetX <= this._bounceRightBoundary) {
965                     realOffsetX = this._bounceRightBoundary - icRightPos;
966                     this._scrollToRightEvent();
967                     scrollEnabled = false;
968                 }
969             } else if (touchOffsetX == 0.0 && touchOffsetY < 0.0){ // down
970                 icTopPos = locContainer.getTopBoundary();
971                 if (icTopPos + touchOffsetY <= this._bounceTopBoundary) {
972                     realOffsetY = this._bounceTopBoundary - icTopPos;
973                     this._scrollToTopEvent();
974                     scrollEnabled = false;
975                 }
976             } else if (touchOffsetX > 0.0 && touchOffsetY == 0.0){ // right
977                 icLeftPos = locContainer.getLeftBoundary();
978                 if (icLeftPos + touchOffsetX >= this._bounceLeftBoundary) {
979                     realOffsetX = this._bounceLeftBoundary - icLeftPos;
980                     this._scrollToLeftEvent();
981                     scrollEnabled = false;
982                 }
983             }
984         } else {
985             if (touchOffsetX > 0.0 && touchOffsetY > 0.0){ // up right
986                 icLeftPos = locContainer.getLeftBoundary();
987                 if (icLeftPos + touchOffsetX >= this._leftBoundary) {
988                     realOffsetX = this._leftBoundary - icLeftPos;
989                     this._scrollToLeftEvent();
990                     scrollEnabled = false;
991                 }
992                 icBottomPos = locContainer.getBottomBoundary();
993                 if (icBottomPos + touchOffsetY >= this._bottomBoundary) {
994                     realOffsetY = this._bottomBoundary - icBottomPos;
995                     this._scrollToBottomEvent();
996                     scrollEnabled = false;
997                 }
998             } else if (touchOffsetX < 0.0 && touchOffsetY > 0.0){ // up left
999                 icRightPos = locContainer.getRightBoundary();
1000                 if (icRightPos + touchOffsetX <= this._rightBoundary) {
1001                     realOffsetX = this._rightBoundary - icRightPos;
1002                     this._scrollToRightEvent();
1003                     scrollEnabled = false;
1004                 }
1005                 icBottomPos = locContainer.getBottomBoundary();
1006                 if (icBottomPos + touchOffsetY >= this._bottomBoundary) {
1007                     realOffsetY = this._bottomBoundary - icBottomPos;
1008                     this._scrollToBottomEvent();
1009                     scrollEnabled = false;
1010                 }
1011             } else if (touchOffsetX < 0.0 && touchOffsetY < 0.0){ // down left
1012                 icRightPos = locContainer.getRightBoundary();
1013                 if (icRightPos + touchOffsetX <= this._rightBoundary) {
1014                     realOffsetX = this._rightBoundary - icRightPos;
1015                     this._scrollToRightEvent();
1016                     scrollEnabled = false;
1017                 }
1018                 icTopPos = locContainer.getTopBoundary();
1019                 if (icTopPos + touchOffsetY <= this._topBoundary) {
1020                     realOffsetY = this._topBoundary - icTopPos;
1021                     this._scrollToTopEvent();
1022                     scrollEnabled = false;
1023                 }
1024             } else if (touchOffsetX > 0.0 && touchOffsetY < 0.0){ // down right
1025                 icLeftPos = locContainer.getLeftBoundary();
1026                 if (icLeftPos + touchOffsetX >= this._leftBoundary) {
1027                     realOffsetX = this._leftBoundary - icLeftPos;
1028                     this._scrollToLeftEvent();
1029                     scrollEnabled = false;
1030                 }
1031                 icTopPos = this._innerContainer.getTopBoundary();
1032                 if (icTopPos + touchOffsetY <= this._topBoundary) {
1033                     realOffsetY = this._topBoundary - icTopPos;
1034                     this._scrollToTopEvent();
1035                     scrollEnabled = false;
1036                 }
1037             } else if (touchOffsetX == 0.0 && touchOffsetY > 0.0) { // up
1038                 icBottomPos = this._innerContainer.getBottomBoundary();
1039                 if (icBottomPos + touchOffsetY >= this._bottomBoundary) {
1040                     realOffsetY = this._bottomBoundary - icBottomPos;
1041                     this._scrollToBottomEvent();
1042                     scrollEnabled = false;
1043                 }
1044             } else if (touchOffsetX < 0.0 && touchOffsetY == 0.0){ // left
1045                 icRightPos = this._innerContainer.getRightBoundary();
1046                 if (icRightPos + touchOffsetX <= this._rightBoundary) {
1047                     realOffsetX = this._rightBoundary - icRightPos;
1048                     this._scrollToRightEvent();
1049                     scrollEnabled = false;
1050                 }
1051             } else if (touchOffsetX == 0.0 && touchOffsetY < 0.0){  // down
1052                 icTopPos = this._innerContainer.getTopBoundary();
1053                 if (icTopPos + touchOffsetY <= this._topBoundary) {
1054                     realOffsetY = this._topBoundary - icTopPos;
1055                     this._scrollToTopEvent();
1056                     scrollEnabled = false;
1057                 }
1058             }  else if (touchOffsetX > 0.0 && touchOffsetY == 0.0){ // right
1059                 icLeftPos = this._innerContainer.getLeftBoundary();
1060                 if (icLeftPos + touchOffsetX >= this._leftBoundary) {
1061                     realOffsetX = this._leftBoundary - icLeftPos;
1062                     this._scrollToLeftEvent();
1063                     scrollEnabled = false;
1064                 }
1065             }
1066         }
1067         this._moveChildren(realOffsetX, realOffsetY);
1068         return scrollEnabled;
1069     },
1070 
1071     /**
1072      * Scroll inner container to bottom boundary of ScrollView.
1073      * @param {Number} time
1074      * @param {Boolean} attenuated
1075      */
1076     scrollToBottom: function (time, attenuated) {
1077         this._startAutoScrollChildrenWithDestination(cc.p(this._innerContainer.getPositionX(), 0), time, attenuated);
1078     },
1079 
1080     /**
1081      * Scroll inner container to top boundary of ScrollView.
1082      * @param {Number} time
1083      * @param {Boolean} attenuated
1084      */
1085     scrollToTop: function (time, attenuated) {
1086         this._startAutoScrollChildrenWithDestination(
1087             cc.p(this._innerContainer.getPositionX(), this._contentSize.height - this._innerContainer.getContentSize().height), time, attenuated);
1088     },
1089 
1090     /**
1091      * Scroll inner container to left boundary of ScrollView.
1092      * @param {Number} time
1093      * @param {Boolean} attenuated
1094      */
1095     scrollToLeft: function (time, attenuated) {
1096         this._startAutoScrollChildrenWithDestination(cc.p(0, this._innerContainer.getPositionY()), time, attenuated);
1097     },
1098 
1099     /**
1100      * Scroll inner container to right boundary of ScrollView.
1101      * @param {Number} time
1102      * @param {Boolean} attenuated
1103      */
1104     scrollToRight: function (time, attenuated) {
1105         this._startAutoScrollChildrenWithDestination(
1106             cc.p(this._contentSize.width - this._innerContainer.getContentSize().width, this._innerContainer.getPositionY()), time, attenuated);
1107     },
1108 
1109     /**
1110      * Scroll inner container to top and left boundary of ScrollView.
1111      * @param {Number} time
1112      * @param {Boolean} attenuated
1113      */
1114     scrollToTopLeft: function (time, attenuated) {
1115         if (this.direction != ccui.ScrollView.DIR_BOTH) {
1116             cc.log("Scroll direction is not both!");
1117             return;
1118         }
1119         this._startAutoScrollChildrenWithDestination(cc.p(0, this._contentSize.height - this._innerContainer.getContentSize().height), time, attenuated);
1120     },
1121 
1122     /**
1123      * Scroll inner container to top and right boundary of ScrollView.
1124      * @param {Number} time
1125      * @param {Boolean} attenuated
1126      */
1127     scrollToTopRight: function (time, attenuated) {
1128         if (this.direction != ccui.ScrollView.DIR_BOTH) {
1129             cc.log("Scroll direction is not both!");
1130             return;
1131         }
1132         var inSize = this._innerContainer.getContentSize();
1133         this._startAutoScrollChildrenWithDestination(cc.p(this._contentSize.width - inSize.width,
1134                 this._contentSize.height - inSize.height), time, attenuated);
1135     },
1136 
1137     /**
1138      * Scroll inner container to bottom and left boundary of ScrollView.
1139      * @param {Number} time
1140      * @param {Boolean} attenuated
1141      */
1142     scrollToBottomLeft: function (time, attenuated) {
1143         if (this.direction != ccui.ScrollView.DIR_BOTH) {
1144             cc.log("Scroll direction is not both!");
1145             return;
1146         }
1147         this._startAutoScrollChildrenWithDestination(cc.p(0, 0), time, attenuated);
1148     },
1149 
1150     /**
1151      * Scroll inner container to bottom and right boundary of ScrollView.
1152      * @param {Number} time
1153      * @param {Boolean} attenuated
1154      */
1155     scrollToBottomRight: function (time, attenuated) {
1156         if (this.direction != ccui.ScrollView.DIR_BOTH) {
1157             cc.log("Scroll direction is not both!");
1158             return;
1159         }
1160         this._startAutoScrollChildrenWithDestination(cc.p(this._contentSize.width - this._innerContainer.getContentSize().width, 0), time, attenuated);
1161     },
1162 
1163     /**
1164      * Scroll inner container to vertical percent position of ScrollView.
1165      * @param {Number} percent
1166      * @param {Number} time
1167      * @param {Boolean} attenuated
1168      */
1169     scrollToPercentVertical: function (percent, time, attenuated) {
1170         var minY = this._contentSize.height - this._innerContainer.getContentSize().height;
1171         var h = -minY;
1172         this._startAutoScrollChildrenWithDestination(cc.p(this._innerContainer.getPositionX(), minY + percent * h / 100), time, attenuated);
1173     },
1174 
1175     /**
1176      * Scroll inner container to horizontal percent position of ScrollView.
1177      * @param {Number} percent
1178      * @param {Number} time
1179      * @param {Boolean} attenuated
1180      */
1181     scrollToPercentHorizontal: function (percent, time, attenuated) {
1182         var w = this._innerContainer.getContentSize().width - this._contentSize.width;
1183         this._startAutoScrollChildrenWithDestination(cc.p(-(percent * w / 100), this._innerContainer.getPositionY()), time, attenuated);
1184     },
1185 
1186     /**
1187      * Scroll inner container to both direction percent position of ScrollView.
1188      * @param {cc.Point} percent
1189      * @param {Number} time
1190      * @param {Boolean} attenuated
1191      */
1192     scrollToPercentBothDirection: function (percent, time, attenuated) {
1193         if (this.direction != ccui.ScrollView.DIR_BOTH)
1194             return;
1195         var minY = this._contentSize.height - this._innerContainer.getContentSize().height;
1196         var h = -minY;
1197         var w = this._innerContainer.getContentSize().width - this._contentSize.width;
1198         this._startAutoScrollChildrenWithDestination(cc.p(-(percent.x * w / 100), minY + percent.y * h / 100), time, attenuated);
1199     },
1200 
1201     /**
1202      * Move inner container to bottom boundary of ScrollView.
1203      */
1204     jumpToBottom: function () {
1205         this._jumpToDestination(this._innerContainer.getPositionX(), 0);
1206     },
1207 
1208     /**
1209      * Move inner container to top boundary of ScrollView.
1210      */
1211     jumpToTop: function () {
1212         this._jumpToDestination(this._innerContainer.getPositionX(), this._contentSize.height - this._innerContainer.getContentSize().height);
1213     },
1214 
1215     /**
1216      * Move inner container to left boundary of ScrollView.
1217      */
1218     jumpToLeft: function () {
1219         this._jumpToDestination(0, this._innerContainer.getPositionY());
1220     },
1221 
1222     /**
1223      * Move inner container to right boundary of ScrollView.
1224      */
1225     jumpToRight: function () {
1226         this._jumpToDestination(this._contentSize.width - this._innerContainer.getContentSize().width, this._innerContainer.getPositionY());
1227     },
1228 
1229     /**
1230      * Move inner container to top and left boundary of ScrollView.
1231      */
1232     jumpToTopLeft: function () {
1233         if (this.direction != ccui.ScrollView.DIR_BOTH) {
1234             cc.log("Scroll direction is not both!");
1235             return;
1236         }
1237         this._jumpToDestination(0, this._contentSize.height - this._innerContainer.getContentSize().height);
1238     },
1239 
1240     /**
1241      * Move inner container to top and right boundary of ScrollView.
1242      */
1243     jumpToTopRight: function () {
1244         if (this.direction != ccui.ScrollView.DIR_BOTH) {
1245             cc.log("Scroll direction is not both!");
1246             return;
1247         }
1248         var inSize = this._innerContainer.getContentSize();
1249         this._jumpToDestination(this._contentSize.width - inSize.width, this._contentSize.height - inSize.height);
1250     },
1251 
1252     /**
1253      * Move inner container to bottom and left boundary of ScrollView.
1254      */
1255     jumpToBottomLeft: function () {
1256         if (this.direction != ccui.ScrollView.DIR_BOTH) {
1257             cc.log("Scroll direction is not both!");
1258             return;
1259         }
1260         this._jumpToDestination(0, 0);
1261     },
1262 
1263     /**
1264      * Move inner container to bottom and right boundary of ScrollView.
1265      */
1266     jumpToBottomRight: function () {
1267         if (this.direction != ccui.ScrollView.DIR_BOTH) {
1268             cc.log("Scroll direction is not both!");
1269             return;
1270         }
1271         this._jumpToDestination(this._contentSize.width - this._innerContainer.getContentSize().width, 0);
1272     },
1273 
1274     /**
1275      * Move inner container to vertical percent position of ScrollView.
1276      * @param {Number} percent The destination vertical percent, accept value between 0 - 100
1277      */
1278     jumpToPercentVertical: function (percent) {
1279         var minY = this._contentSize.height - this._innerContainer.getContentSize().height;
1280         var h = -minY;
1281         this._jumpToDestination(this._innerContainer.getPositionX(), minY + percent * h / 100);
1282     },
1283 
1284     /**
1285      * Move inner container to horizontal percent position of ScrollView.
1286      * @param {Number} percent The destination vertical percent, accept value between 0 - 100
1287      */
1288     jumpToPercentHorizontal: function (percent) {
1289         var w = this._innerContainer.getContentSize().width - this._contentSize.width;
1290         this._jumpToDestination(-(percent * w / 100), this._innerContainer.getPositionY());
1291     },
1292 
1293     /**
1294      * Move inner container to both direction percent position of ScrollView.
1295      * @param {cc.Point} percent The destination vertical percent, accept value between 0 - 100
1296      */
1297     jumpToPercentBothDirection: function (percent) {
1298         if (this.direction != ccui.ScrollView.DIR_BOTH)
1299             return;
1300         var inSize = this._innerContainer.getContentSize();
1301         var minY = this._contentSize.height - inSize.height;
1302         var h = -minY;
1303         var w = inSize.width - this._contentSize.width;
1304         this._jumpToDestination(-(percent.x * w / 100), minY + percent.y * h / 100);
1305     },
1306 
1307     _startRecordSlidAction: function () {
1308         if (this._autoScroll)
1309             this._stopAutoScrollChildren();
1310         if (this._bouncing)
1311             this._stopBounceChildren();
1312         this._slidTime = 0.0;
1313     },
1314 
1315     _endRecordSlidAction: function () {
1316         if (!this._checkNeedBounce() && this.inertiaScrollEnabled) {
1317             if (this._slidTime <= 0.016)
1318                 return;
1319             var totalDis = 0;
1320             var dir;
1321             switch (this.direction) {
1322                 case ccui.ScrollView.DIR_VERTICAL :
1323                     totalDis = this._touchEndPosition.y - this._touchBeganPosition.y;
1324                     dir = (totalDis < 0) ? ccui.ScrollView.SCROLLDIR_DOWN : ccui.ScrollView.SCROLLDIR_UP;
1325                     break;
1326                 case ccui.ScrollView.DIR_HORIZONTAL:
1327                     totalDis = this._touchEndPosition.x - this._touchBeganPosition.x;
1328                     dir = totalDis < 0 ? ccui.ScrollView.SCROLLDIR_LEFT : ccui.ScrollView.SCROLLDIR_RIGHT;
1329                     break;
1330                 case ccui.ScrollView.DIR_BOTH :
1331                     var subVector = cc.pSub(this._touchEndPosition, this._touchBeganPosition);
1332                     totalDis = cc.pLength(subVector);
1333                     dir = cc.pNormalize(subVector);
1334                     break;
1335                 default:
1336                     break;
1337             }
1338             var orSpeed = Math.min(Math.abs(totalDis) / (this._slidTime), ccui.ScrollView.AUTO_SCROLL_MAX_SPEED);
1339             this._startAutoScrollChildrenWithOriginalSpeed(dir, orSpeed, true, -1000);
1340             this._slidTime = 0;
1341         }
1342     },
1343 
1344     _handlePressLogic: function (touch) {
1345         this._startRecordSlidAction();
1346         this._bePressed = true;
1347     },
1348 
1349     _handleMoveLogic: function (touch) {
1350         var delta = cc.pSub(touch.getLocation(), touch.getPreviousLocation());
1351         switch (this.direction) {
1352             case ccui.ScrollView.DIR_VERTICAL: // vertical
1353                 this._scrollChildren(0.0, delta.y);
1354                 break;
1355             case ccui.ScrollView.DIR_HORIZONTAL: // horizontal
1356                 this._scrollChildren(delta.x, 0);
1357                 break;
1358             case ccui.ScrollView.DIR_BOTH: // both
1359                 this._scrollChildren(delta.x, delta.y);
1360                 break;
1361             default:
1362                 break;
1363         }
1364     },
1365 
1366     _handleReleaseLogic: function (touch) {
1367         this._endRecordSlidAction();
1368         this._bePressed = false;
1369     },
1370 
1371     /**
1372      * The touch began event callback handler of ccui.ScrollView.
1373      * @param {cc.Touch} touch
1374      * @param {cc.Event} event
1375      * @returns {boolean}
1376      */
1377     onTouchBegan: function (touch, event) {
1378         var pass = ccui.Layout.prototype.onTouchBegan.call(this, touch, event);
1379         if (this._hit)
1380             this._handlePressLogic(touch);
1381         return pass;
1382     },
1383 
1384     /**
1385      * The touch moved event callback handler of ccui.ScrollView.
1386      * @param {cc.Touch} touch
1387      * @param {cc.Event} event
1388      */
1389     onTouchMoved: function (touch, event) {
1390         ccui.Layout.prototype.onTouchMoved.call(this, touch, event);
1391         this._handleMoveLogic(touch);
1392     },
1393 
1394     /**
1395      * The touch ended event callback handler of ccui.ScrollView.
1396      * @param {cc.Touch} touch
1397      * @param {cc.Event} event
1398      */
1399     onTouchEnded: function (touch, event) {
1400         ccui.Layout.prototype.onTouchEnded.call(this, touch, event);
1401         this._handleReleaseLogic(touch);
1402     },
1403 
1404     /**
1405      * The touch canceled event callback of ccui.ScrollView.
1406      * @param {cc.Touch} touch
1407      * @param {cc.Event} event
1408      */
1409     onTouchCancelled: function (touch, event) {
1410         ccui.Layout.prototype.onTouchCancelled.call(this, touch, event);
1411     },
1412 
1413     /**
1414      * The update callback handler.
1415      * @param {Number} dt
1416      */
1417     update: function (dt) {
1418         if (this._autoScroll)
1419             this._autoScrollChildren(dt);
1420         if (this._bouncing)
1421             this._bounceChildren(dt);
1422         this._recordSlidTime(dt);
1423     },
1424 
1425     _recordSlidTime: function (dt) {
1426         if (this._bePressed)
1427             this._slidTime += dt;
1428     },
1429 
1430     /**
1431      * Intercept touch event, handle its child's touch event.
1432      * @override
1433      * @param {number} event event type
1434      * @param {ccui.Widget} sender
1435      * @param {cc.Touch} touch
1436      */
1437     interceptTouchEvent: function (event, sender, touch) {
1438         var touchPoint = touch.getLocation();
1439         switch (event) {
1440             case ccui.Widget.TOUCH_BEGAN:
1441                 this._touchBeganPosition.x = touchPoint.x;
1442                 this._touchBeganPosition.y = touchPoint.y;
1443                 this._handlePressLogic(touch);
1444                 break;
1445             case ccui.Widget.TOUCH_MOVED:
1446                 var offset = cc.pLength(cc.pSub(sender.getTouchBeganPosition(), touchPoint));
1447                 if (offset > this._childFocusCancelOffset) {
1448                     sender.setHighlighted(false);
1449                     this._touchMovePosition.x = touchPoint.x;
1450                     this._touchMovePosition.y = touchPoint.y;
1451                     this._handleMoveLogic(touch);
1452                 }
1453                 break;
1454             case ccui.Widget.TOUCH_CANCELED:
1455             case ccui.Widget.TOUCH_ENDED:
1456                 this._touchEndPosition.x = touchPoint.x;
1457                 this._touchEndPosition.y = touchPoint.y;
1458                 this._handleReleaseLogic(touch);
1459                 break;
1460         }
1461     },
1462 
1463     _scrollToTopEvent: function () {
1464         if (this._scrollViewEventListener && this._scrollViewEventSelector)
1465             this._scrollViewEventSelector.call(this._scrollViewEventListener, this, ccui.ScrollView.EVENT_SCROLL_TO_TOP);
1466         if (this._eventCallback)
1467             this._eventCallback(this,ccui.ScrollView.EVENT_SCROLL_TO_TOP);
1468     },
1469 
1470     _scrollToBottomEvent: function () {
1471         if (this._scrollViewEventListener && this._scrollViewEventSelector)
1472             this._scrollViewEventSelector.call(this._scrollViewEventListener, this, ccui.ScrollView.EVENT_SCROLL_TO_BOTTOM);
1473         if (this._eventCallback)
1474             this._eventCallback(this,ccui.ScrollView.EVENT_SCROLL_TO_BOTTOM);
1475     },
1476 
1477     _scrollToLeftEvent: function () {
1478         if (this._scrollViewEventListener && this._scrollViewEventSelector)
1479             this._scrollViewEventSelector.call(this._scrollViewEventListener, this, ccui.ScrollView.EVENT_SCROLL_TO_LEFT);
1480         if (this._eventCallback)
1481             this._eventCallback(this,ccui.ScrollView.EVENT_SCROLL_TO_LEFT);
1482     },
1483 
1484     _scrollToRightEvent: function () {
1485         if (this._scrollViewEventListener && this._scrollViewEventSelector)
1486             this._scrollViewEventSelector.call(this._scrollViewEventListener, this, ccui.ScrollView.EVENT_SCROLL_TO_RIGHT);
1487         if (this._eventCallback)
1488             this._eventCallback(this, ccui.ScrollView.EVENT_SCROLL_TO_RIGHT);
1489     },
1490 
1491     _scrollingEvent: function () {
1492         if (this._scrollViewEventListener && this._scrollViewEventSelector)
1493             this._scrollViewEventSelector.call(this._scrollViewEventListener, this, ccui.ScrollView.EVENT_SCROLLING);
1494         if (this._eventCallback)
1495             this._eventCallback(this,ccui.ScrollView.EVENT_SCROLLING);
1496     },
1497 
1498     _bounceTopEvent: function () {
1499         if (this._scrollViewEventListener && this._scrollViewEventSelector) 
1500             this._scrollViewEventSelector.call(this._scrollViewEventListener, this, ccui.ScrollView.EVENT_BOUNCE_TOP);
1501         if (this._eventCallback) 
1502             this._eventCallback(this,ccui.ScrollView.EVENT_BOUNCE_TOP);
1503     },
1504 
1505     _bounceBottomEvent: function () {
1506         if (this._scrollViewEventListener && this._scrollViewEventSelector) 
1507             this._scrollViewEventSelector.call(this._scrollViewEventListener, this, ccui.ScrollView.EVENT_BOUNCE_BOTTOM);
1508         if (this._eventCallback)
1509             this._eventCallback(this,ccui.ScrollView.EVENT_BOUNCE_BOTTOM);
1510     },
1511 
1512     _bounceLeftEvent: function () {
1513         if (this._scrollViewEventListener && this._scrollViewEventSelector)
1514             this._scrollViewEventSelector.call(this._scrollViewEventListener, this, ccui.ScrollView.EVENT_BOUNCE_LEFT);
1515         if (this._eventCallback)
1516             this._eventCallback(this, ccui.ScrollView.EVENT_BOUNCE_LEFT);
1517     },
1518 
1519     _bounceRightEvent: function () {
1520         if (this._scrollViewEventListener && this._scrollViewEventSelector)
1521             this._scrollViewEventSelector.call(this._scrollViewEventListener, this, ccui.ScrollView.EVENT_BOUNCE_RIGHT);
1522         if (this._eventCallback)
1523             this._eventCallback(this, ccui.ScrollView.EVENT_BOUNCE_RIGHT);
1524     },
1525 
1526     /**
1527      * Adds callback function called ScrollView event triggered
1528      * @param {Function} selector
1529      * @param {Object} target
1530      * @deprecated since v3.0, please use addEventListener instead.
1531      */
1532     addEventListenerScrollView: function (selector, target) {
1533         this._scrollViewEventSelector = selector;
1534         this._scrollViewEventListener = target;
1535     },
1536 
1537     /**
1538      * Adds callback function called ScrollView event triggered
1539      * @param {function} callback
1540      */
1541     addEventListener: function(callback){
1542         this._eventCallback = callback;
1543     },
1544 
1545     /**
1546      * Changes scroll direction of ScrollView.
1547      * @param {ccui.ScrollView.DIR_NONE | ccui.ScrollView.DIR_VERTICAL | ccui.ScrollView.DIR_HORIZONTAL | ccui.ScrollView.DIR_BOTH} dir
1548      *   Direction::VERTICAL means vertical scroll, Direction::HORIZONTAL means horizontal scroll
1549      */
1550     setDirection: function (dir) {
1551         this.direction = dir;
1552     },
1553 
1554     /**
1555      * Returns scroll direction of ScrollView.
1556      * @returns {ccui.ScrollView.DIR_NONE | ccui.ScrollView.DIR_VERTICAL | ccui.ScrollView.DIR_HORIZONTAL | ccui.ScrollView.DIR_BOTH}
1557      */
1558     getDirection: function () {
1559         return this.direction;
1560     },
1561 
1562     /**
1563      * Sets bounce enabled
1564      * @param {Boolean} enabled
1565      */
1566     setBounceEnabled: function (enabled) {
1567         this.bounceEnabled = enabled;
1568     },
1569 
1570     /**
1571      * Returns whether bounce is enabled
1572      * @returns {boolean}
1573      */
1574     isBounceEnabled: function () {
1575         return this.bounceEnabled;
1576     },
1577 
1578     /**
1579      * Sets inertiaScroll enabled
1580      * @param {boolean} enabled
1581      */
1582     setInertiaScrollEnabled: function (enabled) {
1583         this.inertiaScrollEnabled = enabled;
1584     },
1585 
1586     /**
1587      * Returns whether inertiaScroll is enabled
1588      * @returns {boolean}
1589      */
1590     isInertiaScrollEnabled: function () {
1591         return this.inertiaScrollEnabled;
1592     },
1593 
1594     /**
1595      * Gets inner container of ScrollView. Inner container is the container of ScrollView's children.
1596      * @returns {ccui.Layout}
1597      */
1598     getInnerContainer: function () {
1599         return this._innerContainer;
1600     },
1601 
1602     /**
1603      * Sets LayoutType of ccui.ScrollView.
1604      * @param {ccui.Layout.ABSOLUTE|ccui.Layout.LINEAR_VERTICAL|ccui.Layout.LINEAR_HORIZONTAL|ccui.Layout.RELATIVE} type
1605      */
1606     setLayoutType: function (type) {
1607         this._innerContainer.setLayoutType(type);
1608     },
1609 
1610     /**
1611      * Returns the layout type of ccui.ScrollView.
1612      * @returns {ccui.Layout.ABSOLUTE|ccui.Layout.LINEAR_VERTICAL|ccui.Layout.LINEAR_HORIZONTAL|ccui.Layout.RELATIVE}
1613      */
1614     getLayoutType: function () {
1615         return this._innerContainer.getLayoutType();
1616     },
1617 
1618     _doLayout: function () {
1619         if (!this._doLayoutDirty)
1620             return;
1621         this._doLayoutDirty = false;
1622     },
1623 
1624     /**
1625      * Returns the "class name" of ccui.ScrollView.
1626      * @returns {string}
1627      */
1628     getDescription: function () {
1629         return "ScrollView";
1630     },
1631 
1632     _createCloneInstance: function(){
1633         return ccui.ScrollView.create();
1634     },
1635 
1636     _copyClonedWidgetChildren: function (model) {
1637         ccui.Layout.prototype._copyClonedWidgetChildren.call(this, model);
1638     },
1639 
1640     _copySpecialProperties: function (scrollView) {
1641         if(scrollView instanceof ccui.ScrollView) {
1642             ccui.Layout.prototype._copySpecialProperties.call(this, scrollView);
1643             this.setInnerContainerSize(scrollView.getInnerContainerSize());
1644             this.setDirection(scrollView.direction);
1645             this.setBounceEnabled(scrollView.bounceEnabled);
1646             this.setInertiaScrollEnabled(scrollView.inertiaScrollEnabled);
1647             this._scrollViewEventListener = scrollView._scrollViewEventListener;
1648             this._scrollViewEventSelector = scrollView._scrollViewEventSelector;
1649             this._eventCallback = scrollView._eventCallback;
1650         }
1651     },
1652 
1653     /**
1654      * Returns a node by tag
1655      * @param {Number} tag
1656      * @returns {cc.Node}
1657      * @deprecated  since v3.0, please use getChildByTag instead.
1658      */
1659     getNodeByTag: function (tag) {
1660         return this._innerContainer.getNodeByTag(tag);
1661     },
1662 
1663     /**
1664      * Returns all nodes of inner container
1665      * @returns {Array}
1666      * @deprecated since v3.0, please use getChildren instead.
1667      */
1668     getNodes: function () {
1669         return this._innerContainer.getNodes();
1670     },
1671 
1672     /**
1673      * Removes a node from ccui.ScrollView.
1674      * @param {cc.Node} node
1675      * @deprecated since v3.0, please use removeChild instead.
1676      */
1677     removeNode: function (node) {
1678         this._innerContainer.removeNode(node);
1679     },
1680 
1681     /**
1682      * Removes a node by tag
1683      * @param {Number} tag
1684      * @deprecated since v3.0, please use removeChildByTag instead.
1685      */
1686     removeNodeByTag: function (tag) {
1687         this._innerContainer.removeNodeByTag(tag);
1688     },
1689 
1690     /**
1691      * Remove all node from ccui.ScrollView.
1692      * @deprecated since v3.0, please use removeAllChildren instead.
1693      */
1694     removeAllNodes: function () {
1695         this._innerContainer.removeAllNodes();
1696     },
1697 
1698     /**
1699      * Add node for scrollView
1700      * @param {cc.Node} node
1701      * @param {Number} zOrder
1702      * @param {Number} tag
1703      * @deprecated since v3.0, please use addChild instead.
1704      */
1705     addNode: function (node, zOrder, tag) {
1706         this._innerContainer.addNode(node, zOrder, tag);
1707     }
1708 });
1709 
1710 var _p = ccui.ScrollView.prototype;
1711 
1712 // Extended properties
1713 /** @expose */
1714 _p.innerWidth;
1715 cc.defineGetterSetter(_p, "innerWidth", _p._getInnerWidth, _p._setInnerWidth);
1716 /** @expose */
1717 _p.innerHeight;
1718 cc.defineGetterSetter(_p, "innerHeight", _p._getInnerHeight, _p._setInnerHeight);
1719 
1720 _p = null;
1721 
1722 /**
1723  * allocates and initializes a UIScrollView.
1724  * @deprecated since v3.0, please use new ccui.ScrollView() instead.
1725  * @return {ccui.ScrollView}
1726  * @example
1727  * // example
1728  * var uiScrollView = ccui.ScrollView.create();
1729  */
1730 ccui.ScrollView.create = function () {
1731     return new ccui.ScrollView();
1732 };
1733 
1734 // Constants
1735 //ScrollView direction
1736 /**
1737  * The none flag of ccui.ScrollView's direction.
1738  * @constant
1739  * @type {number}
1740  */
1741 ccui.ScrollView.DIR_NONE = 0;
1742 /**
1743  * The vertical flag of ccui.ScrollView's direction.
1744  * @constant
1745  * @type {number}
1746  */
1747 ccui.ScrollView.DIR_VERTICAL = 1;
1748 /**
1749  * The horizontal flag of ccui.ScrollView's direction.
1750  * @constant
1751  * @type {number}
1752  */
1753 ccui.ScrollView.DIR_HORIZONTAL = 2;
1754 /**
1755  * The both flag of ccui.ScrollView's direction.
1756  * @constant
1757  * @type {number}
1758  */
1759 ccui.ScrollView.DIR_BOTH = 3;
1760 
1761 //ScrollView event
1762 /**
1763  * The flag scroll to top of ccui.ScrollView's event.
1764  * @constant
1765  * @type {number}
1766  */
1767 ccui.ScrollView.EVENT_SCROLL_TO_TOP = 0;
1768 /**
1769  * The flag scroll to bottom of ccui.ScrollView's event.
1770  * @constant
1771  * @type {number}
1772  */
1773 ccui.ScrollView.EVENT_SCROLL_TO_BOTTOM = 1;
1774 /**
1775  * The flag scroll to left of ccui.ScrollView's event.
1776  * @constant
1777  * @type {number}
1778  */
1779 ccui.ScrollView.EVENT_SCROLL_TO_LEFT = 2;
1780 /**
1781  * The flag scroll to right of ccui.ScrollView's event.
1782  * @constant
1783  * @type {number}
1784  */
1785 ccui.ScrollView.EVENT_SCROLL_TO_RIGHT = 3;
1786 /**
1787  * The scrolling flag of ccui.ScrollView's event.
1788  * @constant
1789  * @type {number}
1790  */
1791 ccui.ScrollView.EVENT_SCROLLING = 4;
1792 /**
1793  * The flag bounce top of ccui.ScrollView's event.
1794  * @constant
1795  * @type {number}
1796  */
1797 ccui.ScrollView.EVENT_BOUNCE_TOP = 5;
1798 /**
1799  * The flag bounce bottom of ccui.ScrollView's event.
1800  * @constant
1801  * @type {number}
1802  */
1803 ccui.ScrollView.EVENT_BOUNCE_BOTTOM = 6;
1804 /**
1805  * The flag bounce left of ccui.ScrollView's event.
1806  * @constant
1807  * @type {number}
1808  */
1809 ccui.ScrollView.EVENT_BOUNCE_LEFT = 7;
1810 /**
1811  * The flag bounce right of ccui.ScrollView's event.
1812  * @constant
1813  * @type {number}
1814  */
1815 ccui.ScrollView.EVENT_BOUNCE_RIGHT = 8;
1816 
1817 /**
1818  * The auto scroll max speed of ccui.ScrollView.
1819  * @constant
1820  * @type {number}
1821  */
1822 ccui.ScrollView.AUTO_SCROLL_MAX_SPEED = 1000;
1823 
1824 /**
1825  * @ignore
1826  */
1827 ccui.ScrollView.SCROLLDIR_UP = cc.p(0, 1);
1828 ccui.ScrollView.SCROLLDIR_DOWN = cc.p(0, -1);
1829 ccui.ScrollView.SCROLLDIR_LEFT = cc.p(-1, 0);
1830 ccui.ScrollView.SCROLLDIR_RIGHT = cc.p(1, 0);