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