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