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 base class for ccui controls and layout
 28  * @sample
 29  * var uiWidget = ccui.Widget.create();
 30  * this.addChild(uiWidget);
 31  * @class
 32  * @extends ccui.ProtectedNode
 33  *
 34  * @property {Number}           xPercent        - Position x in percentage of width
 35  * @property {Number}           yPercent        - Position y in percentage of height
 36  * @property {Number}           widthPercent    - Width in percentage of parent width
 37  * @property {Number}           heightPercent   - Height in percentage of parent height
 38  * @property {ccui.Widget}      widgetParent    - <@readonly> The direct parent when it's a widget also, otherwise equals null
 39  * @property {Boolean}          enabled         - Indicate whether the widget is enabled
 40  * @property {Boolean}          focused         - Indicate whether the widget is focused
 41  * @property {ccui.Widget.SIZE_ABSOLUTE|ccui.Widget.SIZE_PERCENT}     sizeType        - The size type of the widget
 42  * @property {ccui.Widget.TYPE_WIDGET|ccui.Widget.TYPE_CONTAINER}   widgetType      - <@readonly> The type of the widget
 43  * @property {Boolean}          touchEnabled    - Indicate whether touch events are enabled
 44  * @property {Boolean}          updateEnabled   - Indicate whether the update function is scheduled
 45  * @property {Boolean}          bright          - Indicate whether the widget is bright
 46  * @property {String}           name            - The name of the widget
 47  * @property {Number}           actionTag       - The action tag of the widget
 48  */
 49 ccui.Widget = ccui.ProtectedNode.extend(/** @lends ccui.Widget# */{
 50     _enabled: true,            ///< Highest control of widget
 51     _bright: true,             ///< is this widget bright
 52     _touchEnabled: false,       ///< is this widget touch endabled
 53 
 54     _brightStyle: null, ///< bright style
 55 
 56     _touchBeganPosition: null,    ///< touch began point
 57     _touchMovePosition: null,     ///< touch moved point
 58     _touchEndPosition: null,      ///< touch ended point
 59 
 60     _touchEventListener: null,
 61     _touchEventSelector: null,
 62 
 63     _name: "default",
 64     _widgetType: null,
 65     _actionTag: 0,
 66     _customSize: null,
 67     _layoutParameterDictionary: null,
 68     _layoutParameterType:0,
 69 
 70     _focused: false,
 71     _focusEnabled: true,
 72 
 73     _ignoreSize: false,
 74     _affectByClipping: false,
 75 
 76     _sizeType: null,
 77     _sizePercent: null,
 78     _positionType: null,
 79     _positionPercent: null,
 80     _reorderWidgetChildDirty: false,
 81     _hit: false,
 82     _nodes: null,
 83     _touchListener: null,
 84     _className: "Widget",
 85     _flippedX: false,
 86     _flippedY: false,
 87     _opacity: 255,
 88     _highlight: false,
 89 
 90     _touchEventCallback: null,
 91 
 92     /**
 93      * Constructor function, override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
 94      * @function
 95      */
 96     ctor: function () {
 97         cc.ProtectedNode.prototype.ctor.call(this);
 98         this._brightStyle = ccui.Widget.BRIGHT_STYLE_NONE;
 99         this._touchBeganPosition = cc.p(0, 0);
100         this._touchMovePosition = cc.p(0, 0);
101         this._touchEndPosition = cc.p(0, 0);
102         this._widgetType = ccui.Widget.TYPE_WIDGET;
103         this._customSize = cc.size(0, 0);
104         this._layoutParameterDictionary = {};
105         this._sizeType = ccui.Widget.SIZE_ABSOLUTE;
106         this._sizePercent = cc.p(0, 0);
107         this._positionType = ccui.Widget.POSITION_ABSOLUTE;
108         this._positionPercent = cc.p(0, 0);
109         this._nodes = [];
110         this._layoutParameterType = ccui.LayoutParameter.NONE;
111         this.init();                        //TODO
112     },
113 
114     /**
115      * initializes state of widget. please do not call this function by yourself, you should pass the parameters to constructor to initialize it
.
116      * @returns {boolean}
117      */
118     init: function () {
119         if (cc.ProtectedNode.prototype.init.call(this)) {
120             this._layoutParameterDictionary = {};
121             this._initRenderer();
122             this.setBright(true);
123 
124             this.onFocusChanged = this.onFocusChange.bind(this);
125             this.onNextFocusedWidget = null;
126             this.setAnchorPoint(cc.p(0.5, 0.5));
127 
128             this.ignoreContentAdaptWithSize(true);
129             return true;
130         }
131         return false;
132     },
133 
134     /**
135      * Calls updateSizeAndPosition and its parent's onEnter
136      * @override
137      */
138     onEnter: function () {
139         this.updateSizeAndPosition();
140         cc.ProtectedNode.prototype.onEnter.call(this);
141     },
142 
143     /**
144      * Calls unscheduleUpdate and its parent's onExit
145      * @override
146      */
147     onExit: function(){
148         this.unscheduleUpdate();
149         cc.ProtectedNode.prototype.onExit.call(this);
150     },
151 
152     /**
153      * Calls _adaptRenderers(its subClass will override it) before calls its parent's visit.
154      * @param {CanvasRenderingContext2D|WebGLRenderingContext} ctx
155      * @override
156      */
157     visit: function (ctx) {
158         if (this._visible) {
159             this._adaptRenderers();
160             cc.ProtectedNode.prototype.visit.call(this, ctx);
161         }
162     },
163 
164     /**
165      * The direct parent when it's a widget also, otherwise equals null
166      * @returns {ccui.Widget|null}
167      */
168     getWidgetParent: function () {
169         var widget = this.getParent();
170         if (widget instanceof ccui.Widget)
171             return widget;
172         return null;
173     },
174 
175     _updateContentSizeWithTextureSize: function(size){
176         this.setContentSize(this._ignoreSize ? size : this._customSize);
177     },
178 
179     _isAncestorsEnabled: function(){
180         var parentWidget = this._getAncensterWidget(this);
181         if (parentWidget == null)
182             return true;
183         if (parentWidget && !parentWidget.isEnabled())
184             return false;
185 
186         return parentWidget._isAncestorsEnabled();
187     },
188 
189     _getAncensterWidget: function(node){
190         if (null == node)
191             return null;
192 
193         var parent = node.getParent();
194         if (null == parent)
195             return null;
196 
197         if (parent instanceof ccui.Widget)
198             return parent;
199         else
200             return this._getAncensterWidget(parent.getParent());
201     },
202 
203     _isAncestorsVisible: function(node){
204         if (null == node)
205             return true;
206 
207         var parent = node.getParent();
208 
209         if (parent && !parent.isVisible())
210             return false;
211         return this._isAncestorsVisible(parent);
212     },
213 
214     _cleanupWidget: function(){
215         //clean up _touchListener
216         this._eventDispatcher.removeEventListener(this._touchListener);
217 
218         //cleanup focused widget and focus navigation controller
219         if (ccui.Widget._focusedWidget == this)
220             ccui.Widget._focusedWidget = null;
221     },
222 
223     /**
224      * <p>
225      *     Sets whether the widget is enabled                                                                                    <br/>
226      *     true if the widget is enabled, widget may be touched , false if the widget is disabled, widget cannot be touched.     <br/>
227      *     The default value is true, a widget is default to enabled
228      * </p>
229      * @param {Boolean} enabled
230      */
231     setEnabled: function (enabled) {
232         this._enabled = enabled;
233     },
234 
235     /**
236      * initializes renderer of widget.
237      */
238     _initRenderer: function () {
239     },
240 
241     /**
242      * Sets _customSize of ccui.Widget, if ignoreSize is true, the content size is its renderer's contentSize, otherwise the content size is parameter.
243      * and updates size percent by parent content size. At last, updates its children's size and position.
244      * @param {cc.Size|Number} contentSize content size or width of content size
245      * @param {Number} [height]
246      * @override
247      */
248     setContentSize: function(contentSize, height){
249         var locWidth = (height === undefined) ? contentSize.width : contentSize;
250         var locHeight = (height === undefined) ? contentSize.height : height;
251         cc.Node.prototype.setContentSize.call(this, locWidth, locHeight);
252 
253         this._customSize.width = locWidth;
254         this._customSize.height = locHeight;
255 
256         if (this._ignoreSize)
257             this._contentSize = this.getVirtualRendererSize();
258 
259         if (this._running) {
260             var widgetParent = this.getWidgetParent();
261             var pSize = widgetParent ? widgetParent.getContentSize() : this._parent.getContentSize();
262             this._sizePercent.x = (pSize.width > 0.0) ? locWidth / pSize.width : 0.0;
263             this._sizePercent.y = (pSize.height > 0.0) ? locHeight / pSize.height : 0.0;
264         }
265         this._onSizeChanged();
266     },
267 
268     _setWidth: function (w) {
269         cc.Node.prototype._setWidth.call(this, w);
270         this._customSize.width = w;
271         if(this._ignoreSize)
272             this._contentSize = this.getVirtualRendererSize();
273 
274         if (this._running) {
275             var widgetParent = this.getWidgetParent();
276             var locWidth = widgetParent ? widgetParent.width : this._parent.width;
277             this._sizePercent.x = locWidth > 0 ? this._customSize.width / locWidth : 0;
278         }
279         this._onSizeChanged();
280     },
281     _setHeight: function (h) {
282         cc.Node.prototype._setHeight.call(this, h);
283         this._customSize.height = h;
284         if(this._ignoreSize)
285             this._contentSize = this.getVirtualRendererSize();
286 
287         if (this._running) {
288             var widgetParent = this.getWidgetParent();
289             var locH = widgetParent ? widgetParent.height : this._parent.height;
290             this._sizePercent.y = locH > 0 ? this._customSize.height / locH : 0;
291         }
292         this._onSizeChanged();
293     },
294 
295     /**
296      * Changes the percent that is widget's percent size
297      * @param {cc.Point} percent that is widget's percent size, width and height value from 0 to 1.
298      */
299     setSizePercent: function (percent) {
300         this._sizePercent.x = percent.x;
301         this._sizePercent.y = percent.y;
302         var width = this._customSize.width, height = this._customSize.height;
303         if (this._running) {
304             var widgetParent = this.getWidgetParent();
305             if (widgetParent) {
306                 width = widgetParent.width * percent.x;
307                 height = widgetParent.height * percent.y;
308             } else {
309                 width = this._parent.width * percent.x;
310                 height = this._parent.height * percent.y;
311             }
312         }
313         if (this._ignoreSize)
314             this.setContentSize(this.getVirtualRendererSize());
315         else
316             this.setContentSize(width, height);
317 
318         this._customSize.width = width;
319         this._customSize.height = height;
320     },
321 
322     _setWidthPercent: function (percent) {
323         this._sizePercent.x = percent;
324         var width = this._customSize.width;
325         if (this._running) {
326             var widgetParent = this.getWidgetParent();
327             width = (widgetParent ? widgetParent.width : this._parent.width) * percent;
328         }
329         if (this._ignoreSize)
330             this._setWidth(this.getVirtualRendererSize().width);
331         else
332             this._setWidth(width);
333         this._customSize.width = width;
334     },
335     _setHeightPercent: function (percent) {
336         this._sizePercent.y = percent;
337         var height = this._customSize.height;
338         if (this._running) {
339             var widgetParent = this.getWidgetParent();
340             height = (widgetParent ? widgetParent.height : this._parent.height) * percent;
341         }
342         if (this._ignoreSize)
343             this._setHeight(this.getVirtualRendererSize().height);
344         else
345             this._setHeight(height);
346         this._customSize.height = height;
347     },
348 
349     /**
350      * updates its size by size type and its position by position type.
351      * @param {cc.Size} [parentSize] parent size
352      */
353     updateSizeAndPosition: function (parentSize) {
354         if(!parentSize){
355             var widgetParent = this.getWidgetParent();
356             if(widgetParent)
357                 parentSize = widgetParent.getLayoutSize();
358             else
359                 parentSize = this._parent.getContentSize();
360         }
361 
362         switch (this._sizeType) {
363             case ccui.Widget.SIZE_ABSOLUTE:
364                 if(this._ignoreSize)
365                     this.setContentSize(this.getVirtualRendererSize());
366                 else
367                     this.setContentSize(this._customSize);
368                 this._sizePercent.x = (parentSize.width > 0) ? this._customSize.width / parentSize.width : 0;
369                 this._sizePercent.y = (parentSize.height > 0) ? this._customSize.height / parentSize.height : 0;
370                 break;
371             case ccui.Widget.SIZE_PERCENT:
372                 var cSize = cc.size(parentSize.width * this._sizePercent.x , parentSize.height * this._sizePercent.y);
373                 if(this._ignoreSize)
374                     this.setContentSize(this.getVirtualRendererSize());
375                 else
376                     this.setContentSize(cSize);
377                 this._customSize.width = cSize.width;
378                 this._customSize.height = cSize.height;
379                 break;
380             default:
381                 break;
382         }
383         this._onSizeChanged();
384         var absPos = this.getPosition();
385         switch (this._positionType) {
386             case ccui.Widget.POSITION_ABSOLUTE:
387                 if (parentSize.width <= 0 || parentSize.height <= 0) {
388                     this._positionPercent.x = this._positionPercent.y = 0;
389                 } else {
390                     this._positionPercent.x = absPos.x / parentSize.width;
391                     this._positionPercent.y = absPos.y / parentSize.height;
392                 }
393                 break;
394             case ccui.Widget.POSITION_PERCENT:
395                 absPos = cc.p(parentSize.width * this._positionPercent.x, parentSize.height * this._positionPercent.y);
396                 break;
397             default:
398                 break;
399         }
400         if(this._parent instanceof ccui.ImageView){
401             var renderer = this._parent._imageRenderer;
402             if(renderer && !renderer._textureLoaded)
403                 return;
404         }
405         this.setPosition(absPos);
406     },
407 
408     /**TEXTURE_RES_TYPE
409      * Changes the size type of widget.
410      * @param {ccui.Widget.SIZE_ABSOLUTE|ccui.Widget.SIZE_PERCENT} type that is widget's size type
411      */
412     setSizeType: function (type) {
413         this._sizeType = type;
414     },
415 
416     /**
417      * Gets the size type of widget.
418      * @returns {ccui.Widget.SIZE_ABSOLUTE|ccui.Widget.SIZE_PERCENT} that is widget's size type
419      */
420     getSizeType: function () {
421         return this._sizeType;
422     },
423 
424     /**
425      * Ignore the widget size
426      * @param {Boolean} ignore true that widget will ignore it's size, use texture size, false otherwise. Default value is true.
427      */
428     ignoreContentAdaptWithSize: function (ignore) {
429         if(this._ignoreSize == ignore)
430             return;
431 
432         this._ignoreSize = ignore;
433         this.setContentSize( ignore ? this.getVirtualRendererSize() : this._customSize );
434         this._onSizeChanged();
435     },
436 
437     /**
438      * Gets whether ignore the content size (custom size)
439      * @returns {boolean}  true that widget will ignore it's size, use texture size, false otherwise.
440      */
441     isIgnoreContentAdaptWithSize: function () {
442         return this._ignoreSize;
443     },
444 
445     /**
446      * Get custom size of ccui.Widget
447      * @returns {cc.Size}
448      */
449     getCustomSize: function () {
450         return cc.size(this._customSize);
451     },
452 
453     /**
454      * Gets layout size of ccui.Widget.
455      * @returns {cc.Size}
456      */
457     getLayoutSize: function(){
458         return cc.size(this._contentSize);
459     },
460 
461     /**
462      * Returns size percent of ccui.Widget
463      * @returns {cc.Point}
464      */
465     getSizePercent: function () {
466         return cc.p(this._sizePercent);
467     },
468     _getWidthPercent: function () {
469         return this._sizePercent.x;
470     },
471     _getHeightPercent: function () {
472         return this._sizePercent.y;
473     },
474 
475     /**
476      *  Gets world position of ccui.Widget.
477      * @returns {cc.Point} world position of ccui.Widget.
478      */
479     getWorldPosition: function () {
480         return this.convertToWorldSpace(cc.p(this._anchorPoint.x * this._contentSize.width, this._anchorPoint.y * this._contentSize.height));
481     },
482 
483     /**
484      * Gets the Virtual Renderer of widget.
485      * @returns {ccui.Widget}
486      */
487     getVirtualRenderer: function () {
488         return this;
489     },
490 
491     /**
492      * Gets the content size of widget.  Content size is widget's texture size.
493      */
494     getVirtualRendererSize:function(){
495         return cc.size(this._contentSize);
496     },
497 
498     /**
499      * call back function called when size changed.
500      */
501     _onSizeChanged: function () {
502         var locChildren =  this.getChildren();
503         for (var i = 0, len = locChildren.length; i < len; i++) {
504             var child = locChildren[i];
505             if(child instanceof ccui.Widget)
506                 child.updateSizeAndPosition();
507         }
508     },
509 
510     /**
511      * Sets whether the widget is touch enabled. The default value is false, a widget is default to touch disabled
512      * @param {Boolean} enable  true if the widget is touch enabled, false if the widget is touch disabled.
513      */
514     setTouchEnabled: function (enable) {
515         if (this._touchEnabled === enable)
516             return;
517 
518         this._touchEnabled = enable;                                  //TODO need consider remove and re-add.
519         if (this._touchEnabled) {
520             this._touchListener = cc.EventListener.create({
521                 event: cc.EventListener.TOUCH_ONE_BY_ONE,
522                 swallowTouches: true,
523                 onTouchBegan: this.onTouchBegan.bind(this),
524                 onTouchMoved: this.onTouchMoved.bind(this),
525                 onTouchEnded: this.onTouchEnded.bind(this)
526             });
527             cc.eventManager.addListener(this._touchListener, this);
528         } else {
529             cc.eventManager.removeListener(this._touchListener);
530         }
531     },
532 
533     /**
534      * Returns whether or not touch is enabled.
535      * @returns {boolean} true if the widget is touch enabled, false if the widget is touch disabled.
536      */
537     isTouchEnabled: function () {
538         return this._touchEnabled;
539     },
540 
541     /**
542      * Determines if the widget is highlighted
543      * @returns {boolean} true if the widget is highlighted, false if the widget is not highlighted .
544      */
545     isHighlighted: function(){
546         return this._highlight;
547     },
548 
549     /**
550      * Sets whether the widget is highlighted. The default value is false, a widget is default to not highlighted
551      * @param highlight true if the widget is highlighted, false if the widget is not highlighted.
552      */
553     setHighlighted:function(highlight){
554         if (highlight == this._highlight)
555             return;
556         this._highlight = highlight;
557         if (this._bright) {
558             if (this._highlight)
559                 this.setBrightStyle(ccui.Widget.BRIGHT_STYLE_HIGH_LIGHT);
560             else
561                 this.setBrightStyle(ccui.Widget.BRIGHT_STYLE_NORMAL);
562         } else
563             this._onPressStateChangedToDisabled();
564     },
565 
566     /**
567      * Determines if the widget is on focused
568      * @returns {boolean} whether the widget is focused or not
569      */
570     isFocused: function () {
571         return this._focused;
572     },
573 
574     /**
575      * Sets whether the widget is on focused
576      * The default value is false, a widget is default to not on focused
577      * @param {boolean} focus  pass true to let the widget get focus or pass false to let the widget lose focus
578      */
579     setFocused: function (focus) {
580         this._focused = focus;
581         //make sure there is only one focusedWidget
582         if (focus)
583             ccui.Widget._focusedWidget = this;
584     },
585 
586     /**
587      * returns whether the widget could accept focus.
588      * @returns {boolean} true represent the widget could accept focus, false represent the widget couldn't accept focus
589      */
590     isFocusEnabled: function(){
591         return this._focusEnabled;
592     },
593 
594     /**
595      * sets whether the widget could accept focus.
596      * @param {Boolean} enable true represent the widget could accept focus, false represent the widget couldn't accept focus
597      */
598     setFocusEnabled: function(enable){
599         this._focused = enable;
600     },
601 
602     /**
603      * <p>
604      *     When a widget is in a layout, you could call this method to get the next focused widget within a specified direction. <br/>
605      *     If the widget is not in a layout, it will return itself
606      * </p>
607      * @param direction the direction to look for the next focused widget in a layout
608      * @param current  the current focused widget
609      * @return  the next focused widget in a layout
610      */
611     findNextFocusedWidget: function( direction, current){
612         if (null == this.onNextFocusedWidget || null == this.onNextFocusedWidget(direction) ) {
613             var isLayout = current instanceof ccui.Layout;
614             if (this.isFocused() || isLayout) {
615                 var layout = this.getParent();
616                 if (null == layout){
617                     //the outer layout's default behaviour is : loop focus
618                     if (isLayout)
619                         return current.findNextFocusedWidget(direction, current);
620                     return current;
621                 } else
622                     return layout.findNextFocusedWidget(direction, current);
623             } else
624                 return current;
625         } else {
626             var getFocusWidget = this.onNextFocusedWidget(direction);
627             this.dispatchFocusEvent(this, getFocusWidget);
628             return getFocusWidget;
629         }
630     },
631 
632     /**
633      * when a widget calls this method, it will get focus immediately.
634      */
635     requestFocus: function(){
636         if (this == ccui.Widget._focusedWidget)
637             return;
638         this.dispatchFocusEvent(ccui.Widget._focusedWidget, this);
639     },
640 
641     /**
642      * no matter what widget object you call this method on , it will return you the exact one focused widget
643      */
644     getCurrentFocusedWidget: function(){
645         return ccui.Widget._focusedWidget;
646     },
647 
648     /**
649      * call this method with parameter true to enable the Android Dpad focus navigation feature
650      * @note it doesn't implemented on Web
651      * @param {Boolean} enable set true to enable dpad focus navigation, otherwise disable dpad focus navigation
652      */
653     enableDpadNavigation: function(enable){
654     },
655 
656     /**
657      * <p>
658      *    When a widget lose/get focus, this method will be called. Be Caution when you provide your own version,       <br/>
659      *    you must call widget.setFocused(true/false) to change the focus state of the current focused widget;
660      * </p>
661      */
662     onFocusChanged: null,
663 
664     /**
665      * use this function to manually specify the next focused widget regards to each direction
666      */
667     onNextFocusedWidget: null,
668 
669     /**
670      * Sends the touch event to widget's parent, its subclass will override it, e.g. ccui.ScrollView, ccui.PageView
671      * @param {Number}  eventType
672      * @param {ccui.Widget} sender
673      * @param {cc.Touch} touch
674      */
675     interceptTouchEvent: function(eventType, sender, touch){
676         var widgetParent = this.getWidgetParent();
677         if (widgetParent)
678             widgetParent.interceptTouchEvent(eventType,sender,touch);
679     },
680 
681     /**
682      * This method is called when a focus change event happens
683      * @param {ccui.Widget} widgetLostFocus
684      * @param {ccui.Widget} widgetGetFocus
685      */
686     onFocusChange: function(widgetLostFocus, widgetGetFocus){
687         //only change focus when there is indeed a get&lose happens
688         if (widgetLostFocus)
689             widgetLostFocus.setFocused(false);
690         if (widgetGetFocus)
691             widgetGetFocus.setFocused(true);
692     },
693 
694     /**
695      * Dispatch a EventFocus through a EventDispatcher
696      * @param {ccui.Widget} widgetLostFocus
697      * @param {ccui.Widget} widgetGetFocus
698      */
699     dispatchFocusEvent: function(widgetLostFocus, widgetGetFocus){
700         //if the widgetLoseFocus doesn't get focus, it will use the previous focused widget instead
701         if (widgetLostFocus && !widgetLostFocus.isFocused())
702             widgetLostFocus = ccui.Widget._focusedWidget;
703 
704         if (widgetGetFocus != widgetLostFocus){
705             if (widgetGetFocus && widgetGetFocus.onFocusChanged)
706                 widgetGetFocus.onFocusChanged(widgetLostFocus, widgetGetFocus);
707             if (widgetLostFocus && widgetGetFocus.onFocusChanged)
708                 widgetLostFocus.onFocusChanged(widgetLostFocus, widgetGetFocus);
709             cc.eventManager.dispatchEvent(new cc.EventFocus(widgetLostFocus, widgetGetFocus));
710         }
711     },
712 
713     /**
714      *  Sets whether the widget is bright. The default value is true, a widget is default to bright
715      * @param {Boolean} bright true if the widget is bright, false if the widget is dark.
716      */
717     setBright: function (bright) {
718         this._bright = bright;
719         if (this._bright) {
720             this._brightStyle = ccui.Widget.BRIGHT_STYLE_NONE;
721             this.setBrightStyle(ccui.Widget.BRIGHT_STYLE_NORMAL);
722         } else
723             this._onPressStateChangedToDisabled();
724     },
725 
726     /**
727      * To set the bright style of ccui.Widget.
728      * @param {Number} style BRIGHT_NORMAL the widget is normal state, BRIGHT_HIGHLIGHT the widget is height light state.
729      */
730     setBrightStyle: function (style) {
731         if (this._brightStyle == style) {
732             return;
733         }
734         style = style || ccui.Widget.BRIGHT_STYLE_NORMAL;
735         this._brightStyle = style;
736         switch (this._brightStyle) {
737             case ccui.Widget.BRIGHT_STYLE_NORMAL:
738                 this._onPressStateChangedToNormal();
739                 break;
740             case ccui.Widget.BRIGHT_STYLE_HIGH_LIGHT:
741                 this._onPressStateChangedToPressed();
742                 break;
743             default:
744                 break;
745         }
746     },
747 
748     _onPressStateChangedToNormal: function () {
749     },
750 
751     _onPressStateChangedToPressed: function () {
752     },
753 
754     _onPressStateChangedToDisabled: function () {
755     },
756 
757     /**
758      * A call back function when widget lost of focus.
759      */
760     didNotSelectSelf: function () {
761     },
762 
763     /**
764      * <p>
765      *    The callback of touch began event.                                                               <br/>
766      *    If the bounding box of ccui.Widget contains the touch point, it will do the following things:    <br/>
767      *      1. sets highlight state,                                                                       <br/>
768      *      2. sends event to parent widget by interceptTouchEvent                                         <br/>
769      *      3. calls the callback of touch began event.                                                    <br/>
770      *      4. returns true,                                                                               <br/>
771      *    otherwise returns false directly.                                                                <br/>
772      * </p>
773      * @override
774      * @param {cc.Touch} touch
775      * @param {cc.Event} event
776      * @returns {boolean}
777      */
778     onTouchBegan: function (touch, event) {
779         this._hit = false;
780         if (this.isVisible() && this.isEnabled() && this._isAncestorsEnabled() && this._isAncestorsVisible(this) ){
781             var touchPoint = touch.getLocation();
782             this._touchBeganPosition.x = touchPoint.x;
783             this._touchBeganPosition.y = touchPoint.y;
784             if(this.hitTest(this._touchBeganPosition) && this.isClippingParentContainsPoint(this._touchBeganPosition))
785                 this._hit = true;
786         }
787         if (!this._hit) {
788             return false;
789         }
790         this.setHighlighted(true);
791         var widgetParent = this.getWidgetParent();
792         if (widgetParent)
793             widgetParent.interceptTouchEvent(ccui.Widget.TOUCH_BEGAN, this, touch);
794         this._pushDownEvent();
795         return true;
796     },
797 
798     /**
799      * <p>
800      *    The callback of touch moved event.                                                                                                <br/>
801      *    It sets the highlight state by touch, sends event to parent widget by interceptTouchEvent and calls the callback of touch moved event.
802      * </p>
803      * @param {cc.Touch} touch
804      * @param {cc.Event} event
805      */
806     onTouchMoved: function (touch, event) {
807         var touchPoint = touch.getLocation();
808         this._touchMovePosition.x = touchPoint.x;
809         this._touchMovePosition.y = touchPoint.y;
810         this.setHighlighted(this.hitTest(touchPoint));
811         var widgetParent = this.getWidgetParent();
812         if (widgetParent)
813             widgetParent.interceptTouchEvent(ccui.Widget.TOUCH_MOVED, this, touch);
814         this._moveEvent();
815     },
816 
817     /**
818      * <p>
819      *      The callback of touch end event
820      *      It sends event to parent widget by interceptTouchEvent,
821      *      calls the callback of touch end event (highlight= true) or touch canceled event (highlight= false).
822      *      sets the highlight state to false ,
823      * </p>
824      * @param touch
825      * @param event
826      */
827     onTouchEnded: function (touch, event) {
828         var touchPoint = touch.getLocation();
829         this._touchEndPosition.x = touchPoint.x;
830         this._touchEndPosition.y = touchPoint.y;
831         var widgetParent = this.getWidgetParent();
832         if (widgetParent)
833             widgetParent.interceptTouchEvent(ccui.Widget.TOUCH_ENDED, this, touch);
834         var highlight = this._highlight;
835         this.setHighlighted(false);
836         if (highlight)
837             this._releaseUpEvent();
838         else
839             this._cancelUpEvent();
840     },
841 
842     /**
843      * A call back function called when widget is selected, and on touch canceled.
844      * @param {cc.Point} touchPoint
845      */
846     onTouchCancelled: function (touchPoint) {
847         this.setHighlighted(false);
848         this._cancelUpEvent();
849     },
850 
851     /**
852      * A call back function called when widget is selected, and on touch long clicked.
853      * @param {cc.Point} touchPoint
854      */
855     onTouchLongClicked: function (touchPoint) {
856         this.longClickEvent();
857     },
858 
859     //call back function called widget's state changed to dark.
860     _pushDownEvent: function () {
861         if (this._touchEventCallback)
862             this._touchEventCallback(this, ccui.Widget.TOUCH_BEGAN);
863         if (this._touchEventListener && this._touchEventSelector)
864             this._touchEventSelector.call(this._touchEventListener, this, ccui.Widget.TOUCH_BEGAN);
865     },
866 
867     _moveEvent: function () {
868         if (this._touchEventCallback)
869             this._touchEventCallback(this, ccui.Widget.TOUCH_MOVED);
870         if (this._touchEventListener && this._touchEventSelector)
871             this._touchEventSelector.call(this._touchEventListener, this, ccui.Widget.TOUCH_MOVED);
872     },
873 
874     _releaseUpEvent: function () {
875         if (this._touchEventCallback)
876             this._touchEventCallback(this, ccui.Widget.TOUCH_ENDED);
877         if (this._touchEventListener && this._touchEventSelector)
878             this._touchEventSelector.call(this._touchEventListener, this, ccui.Widget.TOUCH_ENDED);
879     },
880 
881     _cancelUpEvent: function () {
882         if (this._touchEventCallback)
883             this._touchEventCallback(this, ccui.Widget.TOUCH_CANCELED);
884         if (this._touchEventListener && this._touchEventSelector)
885             this._touchEventSelector.call(this._touchEventListener, this, ccui.Widget.TOUCH_CANCELED);
886     },
887 
888     longClickEvent: function () {
889         //TODO it will implement in v3.1
890     },
891 
892     /**
893      * Sets the touch event target/selector of the ccui.Widget
894      * @param {Function} selector
895      * @param {Object} target
896      */
897     addTouchEventListener: function (selector, target) {
898         if(target === undefined)
899             this._touchEventCallback = selector;
900         else {
901             this._touchEventSelector = selector;
902             this._touchEventListener = target;
903         }
904     },
905 
906     /**
907      * Checks a point if is in widget's space
908      * @param {cc.Point} pt
909      * @returns {boolean} true if the point is in widget's space, false otherwise.
910      */
911     hitTest: function (pt) {
912         var bb = cc.rect(0,0, this._contentSize.width, this._contentSize.height);
913         return cc.rectContainsPoint(bb, this.convertToNodeSpace(pt));
914     },
915 
916     /**
917      * returns whether clipping parent widget contains point.
918      * @param {cc.Point} pt location point
919      * @returns {Boolean}
920      */
921     isClippingParentContainsPoint: function(pt){
922         this._affectByClipping = false;
923         var parent = this.getParent();
924         var clippingParent = null;
925         while (parent) {
926             if (parent instanceof ccui.Layout) {
927                 if (parent.isClippingEnabled()) {
928                     this._affectByClipping = true;
929                     clippingParent = parent;
930                     break;
931                 }
932             }
933             parent = parent.getParent();
934         }
935 
936         if (!this._affectByClipping)
937             return true;
938 
939         if (clippingParent) {
940             if (clippingParent.hitTest(pt))
941                 return clippingParent.isClippingParentContainsPoint(pt);
942             return false;
943         }
944         return true;
945     },
946 
947     /**
948      * Calls the checkChildInfo of widget's parent, its subclass will override it.
949      * @param {number} handleState
950      * @param {ccui.Widget} sender
951      * @param {cc.Point} touchPoint
952      */
953     checkChildInfo: function (handleState, sender, touchPoint) {
954         var widgetParent = this.getWidgetParent();
955         if (widgetParent)
956             widgetParent.checkChildInfo(handleState, sender, touchPoint);
957     },
958 
959     /**
960      * Changes the position (x,y) of the widget .
961      * The original point (0,0) is at the left-bottom corner of screen.
962      * @override
963      * @param {cc.Point|Number} pos
964      * @param {Number} [posY]
965      */
966     setPosition: function (pos, posY) {
967         if (this._running) {
968             var widgetParent = this.getWidgetParent();
969             if (widgetParent) {
970                 var pSize = widgetParent.getContentSize();
971                 if (pSize.width <= 0 || pSize.height <= 0) {
972                     this._positionPercent.x = 0;
973                     this._positionPercent.y = 0;
974                 } else {
975                     if (posY == undefined) {
976                         this._positionPercent.x = pos / pSize.width;
977                         this._positionPercent.y = posY / pSize.height;
978                     } else {
979                         this._positionPercent.x = pos.x / pSize.width;
980                         this._positionPercent.y = pos.y / pSize.height;
981                     }
982                 }
983             }
984         }
985 
986         cc.Node.prototype.setPosition.call(this, pos, posY);
987     },
988 
989     setPositionX: function (x) {
990         if (this._running) {
991             var widgetParent = this.getWidgetParent();
992             if (widgetParent) {
993                 var pw = widgetParent.width;
994                 if (pw <= 0)
995                     this._positionPercent.x = 0;
996                 else
997                     this._positionPercent.x = x / pw;
998             }
999         }
1000 
1001         cc.Node.prototype.setPositionX.call(this, x);
1002     },
1003     setPositionY: function (y) {
1004         if (this._running) {
1005             var widgetParent = this.getWidgetParent();
1006             if (widgetParent) {
1007                 var ph = widgetParent.height;
1008                 if (ph <= 0)
1009                     this._positionPercent.y = 0;
1010                 else
1011                     this._positionPercent.y = y / ph;
1012             }
1013         }
1014 
1015         cc.Node.prototype.setPositionY.call(this, y);
1016     },
1017 
1018     /**
1019      * Changes the position (x,y) of the widget
1020      * @param {cc.Point} percent
1021      */
1022     setPositionPercent: function (percent) {
1023         this._positionPercent = percent;
1024         if (this._running) {
1025             var widgetParent = this.getWidgetParent();
1026             if (widgetParent) {
1027                 var parentSize = widgetParent.getSize();
1028                 this.setPosition(parentSize.width * this._positionPercent.x, parentSize.height * this._positionPercent.y);
1029             }
1030         }
1031     },
1032     _setXPercent: function (percent) {
1033         this._positionPercent.x = percent;
1034         if (this._running) {
1035             var widgetParent = this.getWidgetParent();
1036             if (widgetParent)
1037                 this.setPositionX(widgetParent.width * percent);
1038         }
1039     },
1040     _setYPercent: function (percent) {
1041         this._positionPercent.y = percent;
1042         if (this._running) {
1043             var widgetParent = this.getWidgetParent();
1044             if (widgetParent)
1045                 this.setPositionY(widgetParent.height * percent);
1046         }
1047     },
1048 
1049     /**
1050      * Gets the percent (x,y) of the widget
1051      * @returns {cc.Point} The percent (x,y) of the widget in OpenGL coordinates
1052      */
1053     getPositionPercent: function () {
1054         return cc.p(this._positionPercent);
1055     },
1056 
1057     _getXPercent: function () {
1058         return this._positionPercent.x;
1059     },
1060     _getYPercent: function () {
1061         return this._positionPercent.y;
1062     },
1063 
1064     /**
1065      * Changes the position type of the widget
1066      * @param {Number} type  the position type of widget
1067      */
1068     setPositionType: function (type) {
1069         this._positionType = type;
1070     },
1071 
1072     /**
1073      * Gets the position type of the widget
1074      * @returns {Number} the position type of widget
1075      */
1076     getPositionType: function () {
1077         return this._positionType;
1078     },
1079 
1080     /**
1081      * Sets whether the widget should be flipped horizontally or not.
1082      * @param {Boolean} flipX true if the widget should be flipped horizontally, false otherwise.
1083      */
1084     setFlippedX: function (flipX) {
1085         this._flippedX = flipX;
1086         this._updateFlippedX();
1087     },
1088 
1089     /**
1090      * <p>
1091      *   Returns the flag which indicates whether the widget is flipped horizontally or not.             <br/>
1092      *   It only flips the texture of the widget, and not the texture of the widget's children.          <br/>
1093      *   Also, flipping the texture doesn't alter the anchorPoint.                                       <br/>
1094      *   If you want to flip the anchorPoint too, and/or to flip the children too use:                   <br/>
1095      *   widget.setScaleX(sprite.getScaleX() * -1);
1096      * </p>
1097      * @returns {Boolean} true if the widget is flipped horizontally, false otherwise.
1098      */
1099     isFlippedX: function () {
1100         return this._flippedX;
1101     },
1102 
1103     /**
1104      * Sets whether the widget should be flipped vertically or not.
1105      * @param {Boolean} flipY  true if the widget should be flipped vertically, false otherwise.
1106      */
1107     setFlippedY: function (flipY) {
1108         this._flippedY = flipY;
1109         this._updateFlippedY();
1110     },
1111 
1112     /**
1113      * <p>
1114      *     Return the flag which indicates whether the widget is flipped vertically or not.                <br/>
1115      *     It only flips the texture of the widget, and not the texture of the widget's children.          <br/>
1116      *     Also, flipping the texture doesn't alter the anchorPoint.                                       <br/>
1117      *     If you want to flip the anchorPoint too, and/or to flip the children too use:                   <br/>
1118      *     widget.setScaleY(widget.getScaleY() * -1);
1119      * </p>
1120      * @returns {Boolean} true if the widget is flipped vertically, false otherwise.
1121      */
1122     isFlippedY: function () {
1123         return this._flippedY;
1124     },
1125 
1126     _updateFlippedX: function () {
1127     },
1128 
1129     _updateFlippedY: function () {
1130     },
1131 
1132     _adaptRenderers: function(){
1133     },
1134 
1135     /**
1136      * Determines if the widget is bright
1137      * @returns {boolean} true if the widget is bright, false if the widget is dark.
1138      */
1139     isBright: function () {
1140         return this._bright;
1141     },
1142 
1143     /**
1144      * Determines if the widget is enabled
1145      * @returns {boolean}
1146      */
1147     isEnabled: function () {
1148         return this._enabled;
1149     },
1150 
1151     /**
1152      * Gets the left boundary position of this widget.
1153      * @returns {number}
1154      */
1155     getLeftBoundary: function () {
1156         return this.getPositionX() - this._getAnchorX() * this._contentSize.width;
1157     },
1158 
1159     /**
1160      * Gets the bottom boundary position of this widget.
1161      * @returns {number}
1162      */
1163     getBottomBoundary: function () {
1164         return this.getPositionY() - this._getAnchorY() * this._contentSize.height;
1165     },
1166 
1167     /**
1168      * Gets the right boundary position of this widget.
1169      * @returns {number}
1170      */
1171     getRightBoundary: function () {
1172         return this.getLeftBoundary() + this._contentSize.width;
1173     },
1174 
1175     /**
1176      * Gets the top boundary position of this widget.
1177      * @returns {number}
1178      */
1179     getTopBoundary: function () {
1180         return this.getBottomBoundary() + this._contentSize.height;
1181     },
1182 
1183     /**
1184      * Gets the position of touch began event.
1185      * @returns {cc.Point}
1186      */
1187     getTouchBeganPosition: function(){
1188          return cc.p(this._touchBeganPosition);
1189     },
1190 
1191     /**
1192      * Gets the position of touch moved event
1193      * @returns {cc.Point}
1194      */
1195     getTouchMovePosition: function(){
1196         return cc.p(this._touchMovePosition);
1197     },
1198 
1199     /**
1200      * Gets the position of touch end event
1201      * @returns {cc.Point}
1202      */
1203     getTouchEndPosition:function(){
1204         return cc.p(this._touchEndPosition);
1205     },
1206 
1207     /**
1208      * get widget type
1209      * @returns {ccui.Widget.TYPE_WIDGET|ccui.Widget.TYPE_CONTAINER}
1210      */
1211     getWidgetType: function () {
1212         return this._widgetType;
1213     },
1214 
1215     /**
1216      * Gets LayoutParameter of widget.
1217      * @param {ccui.LayoutParameter} parameter
1218      */
1219     setLayoutParameter: function (parameter) {
1220         if(!parameter)
1221             return;
1222         this._layoutParameterDictionary[parameter.getLayoutType()] = parameter;
1223         this._layoutParameterType = parameter.getLayoutType();
1224     },
1225 
1226     /**
1227      * Gets layout parameter
1228      * @param {ccui.LayoutParameter.NONE|ccui.LayoutParameter.LINEAR|ccui.LayoutParameter.RELATIVE} type
1229      * @returns {ccui.LayoutParameter}
1230      */
1231     getLayoutParameter: function (type) {
1232         type = type || this._layoutParameterType;
1233         return this._layoutParameterDictionary[type];
1234     },
1235 
1236     /**
1237      * Returns the "class name" of widget.
1238      * @returns {string}
1239      */
1240     getDescription: function () {
1241         return "Widget";
1242     },
1243 
1244     /**
1245      * Clones a new widget.
1246      * @returns {ccui.Widget}
1247      */
1248     clone: function () {
1249         var clonedWidget = this._createCloneInstance();
1250         clonedWidget._copyProperties(this);
1251         clonedWidget._copyClonedWidgetChildren(this);
1252         return clonedWidget;
1253     },
1254 
1255     _createCloneInstance: function () {
1256         return ccui.Widget.create();
1257     },
1258 
1259     _copyClonedWidgetChildren: function (model) {
1260         var widgetChildren = model.getChildren();
1261         for (var i = 0; i < widgetChildren.length; i++) {
1262             var locChild = widgetChildren[i];
1263             if (locChild instanceof ccui.Widget)
1264                 this.addChild(locChild.clone());
1265         }
1266     },
1267 
1268     _copySpecialProperties: function (model) {
1269     },
1270 
1271     _copyProperties: function (widget) {
1272         this.setEnabled(widget.isEnabled());
1273         this.setVisible(widget.isVisible());
1274         this.setBright(widget.isBright());
1275         this.setTouchEnabled(widget.isTouchEnabled());
1276         this.setLocalZOrder(widget.getLocalZOrder());
1277         this.setTag(widget.getTag());
1278         this.setName(widget.getName());
1279         this.setActionTag(widget.getActionTag());
1280 
1281         this._ignoreSize = widget._ignoreSize;
1282 
1283         this.setContentSize(widget._contentSize);
1284         this._customSize.width = widget._customSize.width;
1285         this._customSize.height = widget._customSize.height;
1286 
1287         this._copySpecialProperties(widget);
1288         this._sizeType = widget.getSizeType();
1289         this._sizePercent.x = widget._sizePercent.x;
1290         this._sizePercent.y = widget._sizePercent.y;
1291 
1292         this._positionType = widget._positionType;
1293         this._positionPercent.x = widget._positionPercent.x;
1294         this._positionPercent.y = widget._positionPercent.y;
1295 
1296         this.setPosition(widget.getPosition());
1297         this.setAnchorPoint(widget.getAnchorPoint());
1298         this.setScaleX(widget.getScaleX());
1299         this.setScaleY(widget.getScaleY());
1300         this.setRotation(widget.getRotation());
1301         this.setRotationX(widget.getRotationX());
1302         this.setRotationY(widget.getRotationY());
1303         this.setFlippedX(widget.isFlippedX());
1304         this.setFlippedY(widget.isFlippedY());
1305         this.setColor(widget.getColor());
1306         this.setOpacity(widget.getOpacity());
1307 
1308         this._touchEventCallback = widget._touchEventCallback;
1309         this._touchEventListener = widget._touchEventListener;
1310         this._touchEventSelector = widget._touchEventSelector;
1311         this._focused = widget._focused;
1312         this._focusEnabled = widget._focusEnabled;
1313 
1314         for (var key in widget._layoutParameterDictionary) {
1315             var parameter = widget._layoutParameterDictionary[key];
1316             if (parameter)
1317                 this.setLayoutParameter(parameter.clone());
1318         }
1319         this._onSizeChanged();
1320     },
1321 
1322     /*temp action*/
1323     setActionTag: function (tag) {
1324         this._actionTag = tag;
1325     },
1326 
1327     getActionTag: function () {
1328         return this._actionTag;
1329     },
1330 
1331     /**
1332      * Gets the left boundary position of this widget.
1333      * @deprecated since v3.0, please use getLeftBoundary instead.
1334      * @returns {number}
1335      */
1336     getLeftInParent: function(){
1337         cc.log("getLeftInParent is deprecated. Please use getLeftBoundary instead.");
1338         return this.getLeftBoundary();
1339     },
1340 
1341     /**
1342      * Gets the bottom boundary position of this widget.
1343      * @deprecated since v3.0, please use getBottomBoundary instead.
1344      * @returns {number}
1345      */
1346     getBottomInParent: function(){
1347         cc.log("getBottomInParent is deprecated. Please use getBottomBoundary instead.");
1348         return this.getBottomBoundary();
1349     },
1350 
1351     /**
1352      * Gets the right boundary position of this widget.
1353      * @deprecated since v3.0, please use getRightBoundary instead.
1354      * @returns {number}
1355      */
1356     getRightInParent: function(){
1357         cc.log("getRightInParent is deprecated. Please use getRightBoundary instead.");
1358         return this.getRightBoundary();
1359     },
1360 
1361     /**
1362      * Gets the top boundary position of this widget.
1363      * @deprecated since v3.0, please use getTopBoundary instead.
1364      * @returns {number}
1365      */
1366     getTopInParent: function(){
1367         cc.log("getTopInParent is deprecated. Please use getTopBoundary instead.");
1368         return this.getTopBoundary();
1369     },
1370 
1371     /**
1372      * Gets the touch end point of widget when widget is selected.
1373      * @deprecated since v3.0, please use getTouchEndPosition instead.
1374      * @returns {cc.Point} the touch end point.
1375      */
1376     getTouchEndPos: function () {
1377         cc.log("getTouchEndPos is deprecated. Please use getTouchEndPosition instead.");
1378         return this.getTouchEndPosition();
1379     },
1380 
1381     /**
1382      *Gets the touch move point of widget when widget is selected.
1383      * @deprecated since v3.0, please use getTouchMovePosition instead.
1384      * @returns {cc.Point} the touch move point.
1385      */
1386     getTouchMovePos: function () {
1387         cc.log("getTouchMovePos is deprecated. Please use getTouchMovePosition instead.");
1388         return this.getTouchMovePosition();
1389     },
1390 
1391     /**
1392      * Checks a point if in parent's area.
1393      * @deprecated since v3.0, please use isClippingParentContainsPoint instead.
1394      * @param {cc.Point} pt
1395      * @returns {Boolean}
1396      */
1397     clippingParentAreaContainPoint: function (pt) {
1398         cc.log("clippingParentAreaContainPoint is deprecated. Please use isClippingParentContainsPoint instead.");
1399         this.isClippingParentContainsPoint(pt);
1400     },
1401 
1402     /**
1403      * Gets the touch began point of widget when widget is selected.
1404      * @deprecated since v3.0, please use getTouchBeganPosition instead.
1405      * @returns {cc.Point} the touch began point.
1406      */
1407     getTouchStartPos: function () {
1408         cc.log("getTouchStartPos is deprecated. Please use getTouchBeganPosition instead.");
1409         return this.getTouchBeganPosition();
1410     },
1411 
1412     /**
1413      * Changes the size that is widget's size
1414      * @deprecated since v3.0, please use setContentSize instead.
1415      * @param {cc.Size} size  that is widget's size
1416      */
1417     setSize: function (size) {
1418         this.setContentSize(size);
1419     },
1420 
1421     /**
1422      * Returns size of widget
1423      * @deprecated since v3.0, please use getContentSize instead.
1424      * @returns {cc.Size}
1425      */
1426     getSize: function () {
1427         return this.getContentSize();
1428     },
1429 
1430     /**
1431      * Adds a node for widget (this function is deleted in -x)
1432      * @param {cc.Node} node
1433      * @param {Number} zOrder
1434      * @param {Number} tag
1435      * @deprecated since v3.0, please use addChild instead.
1436      */
1437     addNode: function (node, zOrder, tag) {
1438         if (node instanceof ccui.Widget) {
1439             cc.log("Please use addChild to add a Widget.");
1440             return;
1441         }
1442         cc.Node.prototype.addChild.call(this, node, zOrder, tag);
1443         this._nodes.push(node);
1444     },
1445 
1446     /**
1447      * Gets node by tag
1448      * @deprecated since v3.0, please use getChildByTag instead.
1449      * @param {Number} tag
1450      * @returns {cc.Node}
1451      */
1452     getNodeByTag: function (tag) {
1453         var _nodes = this._nodes;
1454         for (var i = 0; i < _nodes.length; i++) {
1455             var node = _nodes[i];
1456             if (node && node.getTag() == tag) {
1457                 return node;
1458             }
1459         }
1460         return null;
1461     },
1462 
1463     /**
1464      * Returns all children.
1465      * @deprecated since v3.0, please use getChildren instead.
1466      * @returns {Array}
1467      */
1468     getNodes: function () {
1469         return this._nodes;
1470     },
1471 
1472     /**
1473      * Removes a node from ccui.Widget
1474      * @deprecated since v3.0, please use removeChild instead.
1475      * @param {cc.Node} node
1476      * @param {Boolean} cleanup
1477      */
1478     removeNode: function (node, cleanup) {
1479         cc.Node.prototype.removeChild.call(this, node, cleanup);
1480         cc.arrayRemoveObject(this._nodes, node);
1481     },
1482 
1483     /**
1484      * Removes node by tag
1485      * @deprecated since v3.0, please use removeChildByTag instead.
1486      * @param {Number} tag
1487      * @param {Boolean} [cleanup]
1488      */
1489     removeNodeByTag: function (tag, cleanup) {
1490         var node = this.getNodeByTag(tag);
1491         if (!node)
1492             cc.log("cocos2d: removeNodeByTag(tag = %d): child not found!", tag);
1493         else
1494             this.removeNode(node);
1495     },
1496 
1497     /**
1498      * Removes all node
1499      * @deprecated since v3.0, please use removeAllChildren instead.
1500      */
1501     removeAllNodes: function () {
1502         for (var i = 0; i < this._nodes.length; i++) {
1503             var node = this._nodes[i];
1504             cc.Node.prototype.removeChild.call(this, node);
1505         }
1506         this._nodes.length = 0;
1507     },
1508 
1509     _findLayout: function(){
1510         var layout = this._parent;
1511         while(layout){
1512             if(layout._doLayout){
1513                 layout._doLayoutDirty = true;
1514                 break;
1515             }else
1516                 layout = layout._parent;
1517         }
1518     },
1519 
1520     _updateChildrenDisplayedRGBA: function(){
1521         this.setColor(this.getColor());
1522         this.setOpacity(this.getOpacity());
1523     }
1524 });
1525 
1526 var _p = ccui.Widget.prototype;
1527 
1528 // Extended properties
1529 /** @expose */
1530 _p.xPercent;
1531 cc.defineGetterSetter(_p, "xPercent", _p._getXPercent, _p._setXPercent);
1532 /** @expose */
1533 _p.yPercent;
1534 cc.defineGetterSetter(_p, "yPercent", _p._getYPercent, _p._setYPercent);
1535 /** @expose */
1536 _p.widthPercent;
1537 cc.defineGetterSetter(_p, "widthPercent", _p._getWidthPercent, _p._setWidthPercent);
1538 /** @expose */
1539 _p.heightPercent;
1540 cc.defineGetterSetter(_p, "heightPercent", _p._getHeightPercent, _p._setHeightPercent);
1541 /** @expose */
1542 _p.widgetParent;
1543 cc.defineGetterSetter(_p, "widgetParent", _p.getWidgetParent);
1544 /** @expose */
1545 _p.enabled;
1546 cc.defineGetterSetter(_p, "enabled", _p.isEnabled, _p.setEnabled);
1547 /** @expose */
1548 _p.focused;
1549 cc.defineGetterSetter(_p, "focused", _p.isFocused, _p.setFocused);
1550 /** @expose */
1551 _p.sizeType;
1552 cc.defineGetterSetter(_p, "sizeType", _p.getSizeType, _p.setSizeType);
1553 /** @expose */
1554 _p.widgetType;
1555 cc.defineGetterSetter(_p, "widgetType", _p.getWidgetType);
1556 /** @expose */
1557 _p.touchEnabled;
1558 cc.defineGetterSetter(_p, "touchEnabled", _p.isTouchEnabled, _p.setTouchEnabled);
1559 /** @expose */
1560 _p.updateEnabled;
1561 cc.defineGetterSetter(_p, "updateEnabled", _p.isUpdateEnabled, _p.setUpdateEnabled);
1562 /** @expose */
1563 _p.bright;
1564 cc.defineGetterSetter(_p, "bright", _p.isBright, _p.setBright);
1565 /** @expose */
1566 _p.name;
1567 cc.defineGetterSetter(_p, "name", _p.getName, _p.setName);
1568 /** @expose */
1569 _p.actionTag;
1570 cc.defineGetterSetter(_p, "actionTag", _p.getActionTag, _p.setActionTag);
1571 /** @expose */
1572 _p.opacity;
1573 cc.defineGetterSetter(_p, "opacity", _p.getOpacity, _p.setOpacity);
1574 
1575 _p = null;
1576 
1577 /**
1578  * allocates and initializes a UIWidget.
1579  * @deprecated
1580  * @return {ccui.Widget}
1581  * @example
1582  * // example
1583  * var uiWidget = ccui.Widget.create();
1584  */
1585 ccui.Widget.create = function () {
1586     return new ccui.Widget();
1587 };
1588 
1589 ccui.Widget._focusedWidget = null;                        //both layout & widget will be stored in this variable
1590 
1591 /**
1592  * Gets the focused widget of current stage.
1593  * @function
1594  * @returns {null|ccui.Widget}
1595  */
1596 ccui.Widget.getCurrentFocusedWidget = function(){
1597     return ccui.Widget._focusedWidget;
1598 };
1599 
1600 // Constants
1601 //bright style
1602 /**
1603  * None bright style of ccui.Widget.
1604  * @constant
1605  * @type {number}
1606  */
1607 ccui.Widget.BRIGHT_STYLE_NONE = -1;
1608 /**
1609  * Normal bright style of ccui.Widget.
1610  * @constant
1611  * @type {number}
1612  */
1613 ccui.Widget.BRIGHT_STYLE_NORMAL = 0;
1614 /**
1615  * Light bright style of ccui.Widget.
1616  * @constant
1617  * @type {number}
1618  */
1619 ccui.Widget.BRIGHT_STYLE_HIGH_LIGHT = 1;
1620 
1621 //widget type
1622 /**
1623  * The type code of Widget for ccui controls.
1624  * @constant
1625  * @type {number}
1626  */
1627 ccui.Widget.TYPE_WIDGET = 0;
1628 /**
1629  * The type code of Container for ccui controls.
1630  * @constant
1631  * @type {number}
1632  */
1633 ccui.Widget.TYPE_CONTAINER = 1;
1634 
1635 //Focus Direction
1636 /**
1637  * The left of Focus direction for ccui.Widget
1638  * @constant
1639  * @type {number}
1640  */
1641 ccui.Widget.LEFT = 0;
1642 /**
1643  * The right of Focus direction for ccui.Widget
1644  * @constant
1645  * @type {number}
1646  */
1647 ccui.Widget.RIGHT = 1;
1648 /**
1649  * The up of Focus direction for ccui.Widget
1650  * @constant
1651  * @type {number}
1652  */
1653 ccui.Widget.UP = 0;
1654 /**
1655  * The down of Focus direction for ccui.Widget
1656  * @constant
1657  * @type {number}
1658  */
1659 ccui.Widget.DOWN = 1;
1660 
1661 //texture resource type
1662 /**
1663  * The image file texture type of ccui.Widget loads.
1664  * @constant
1665  * @type {number}
1666  */
1667 ccui.Widget.LOCAL_TEXTURE = 0;
1668 /**
1669  * The sprite frame texture type of ccui.Widget loads.
1670  * @constant
1671  * @type {number}
1672  */
1673 ccui.Widget.PLIST_TEXTURE = 1;
1674 
1675 //touch event type
1676 /**
1677  * The touch began type of ccui.Widget's touch event
1678  * @constant
1679  * @type {number}
1680  */
1681 ccui.Widget.TOUCH_BEGAN = 0;
1682 /**
1683  * The touch moved type of ccui.Widget's touch event
1684  * @constant
1685  * @type {number}
1686  */
1687 ccui.Widget.TOUCH_MOVED = 1;
1688 /**
1689  * The touch end type of ccui.Widget's touch event
1690  * @constant
1691  * @type {number}
1692  */
1693 ccui.Widget.TOUCH_ENDED = 2;
1694 /**
1695  * The touch canceled type of ccui.Widget's touch event
1696  * @constant
1697  * @type {number}
1698  */
1699 ccui.Widget.TOUCH_CANCELED = 3;
1700 
1701 //size type
1702 /**
1703  * The absolute of ccui.Widget's size type.
1704  * @constant
1705  * @type {number}
1706  */
1707 ccui.Widget.SIZE_ABSOLUTE = 0;
1708 /**
1709  * The percent of ccui.Widget's size type.
1710  * @constant
1711  * @type {number}
1712  */
1713 ccui.Widget.SIZE_PERCENT = 1;
1714 
1715 //position type
1716 /**
1717  * The absolute of ccui.Widget's position type.
1718  * @constant
1719  * @type {number}
1720  */
1721 ccui.Widget.POSITION_ABSOLUTE = 0;
1722 /**
1723  * The percent of ccui.Widget's position type.
1724  * @constant
1725  * @type {number}
1726  */
1727 ccui.Widget.POSITION_PERCENT = 1;
1728 
1729 /**
1730  * The widget focus event.
1731  * @class
1732  * @extends cc.Event
1733  */
1734 cc.EventFocus = cc.Event.extend(/** @lends cc.EventFocus# */{
1735     _widgetGetFocus: null,
1736     _widgetLoseFocus: null,
1737     /**
1738      * Constructor function.
1739      * @param {ccui.Widget} widgetLoseFocus
1740      * @param {ccui.Widget} widgetGetFocus
1741      */
1742     ctor: function(widgetLoseFocus, widgetGetFocus){
1743         this._widgetGetFocus = widgetGetFocus;
1744         this._widgetLoseFocus = widgetLoseFocus;
1745     }
1746 });