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 button controls of Cocos UI.
 28  * @class
 29  * @extends ccui.Widget
 30  *
 31  * @property {String}   titleText               - The content string of the button title
 32  * @property {String}   titleFont               - The content string font of the button title
 33  * @property {Number}   titleFontSize           - The content string font size of the button title
 34  * @property {String}   titleFontName           - The content string font name of the button title
 35  * @property {cc.Color} titleFontColor          - The content string font color of the button title
 36  * @property {Boolean}  pressedActionEnabled    - Indicate whether button has zoom effect when clicked
 37  */
 38 ccui.Button = ccui.Widget.extend(/** @lends ccui.Button# */{
 39     _buttonNormalRenderer: null,
 40     _buttonClickedRenderer: null,
 41     _buttonDisableRenderer: null,
 42     _titleRenderer: null,
 43 
 44     _normalFileName: "",
 45     _clickedFileName: "",
 46     _disabledFileName: "",
 47 
 48     _prevIgnoreSize: true,
 49     _scale9Enabled: false,
 50 
 51     _capInsetsNormal: null,
 52     _capInsetsPressed: null,
 53     _capInsetsDisabled: null,
 54 
 55     _normalTexType: ccui.Widget.LOCAL_TEXTURE,
 56     _pressedTexType: ccui.Widget.LOCAL_TEXTURE,
 57     _disabledTexType: ccui.Widget.LOCAL_TEXTURE,
 58 
 59     _normalTextureSize: null,
 60     _pressedTextureSize: null,
 61     _disabledTextureSize: null,
 62 
 63     pressedActionEnabled: false,
 64     _titleColor: null,
 65     _normalTextureScaleXInSize: 1,
 66     _normalTextureScaleYInSize: 1,
 67     _pressedTextureScaleXInSize: 1,
 68     _pressedTextureScaleYInSize: 1,
 69 
 70     _normalTextureLoaded: false,
 71     _pressedTextureLoaded: false,
 72     _disabledTextureLoaded: false,
 73 
 74     _className: "Button",
 75     _normalTextureAdaptDirty: true,
 76     _pressedTextureAdaptDirty: true,
 77     _disabledTextureAdaptDirty: true,
 78 
 79     _fontName: "Thonburi",
 80     _fontSize: 12,
 81     _type: 0,
 82 
 83     /**
 84      * Allocates and initializes a UIButton.
 85      * Constructor of ccui.Button. override it to extend the construction behavior, remember to call "this._super()" in the extended "ctor" function.
 86      * @param {String} normalImage
 87      * @param {String} [selectedImage=""]
 88      * @param {String} [disableImage=""]
 89      * @param {Number} [texType=ccui.Widget.LOCAL_TEXTURE]
 90      * @example
 91      * // example
 92      * var uiButton = new ccui.Button();
 93      */
 94     ctor: function (normalImage, selectedImage, disableImage, texType) {
 95         this._capInsetsNormal = cc.rect(0, 0, 0, 0);
 96         this._capInsetsPressed = cc.rect(0, 0, 0, 0);
 97         this._capInsetsDisabled = cc.rect(0, 0, 0, 0);
 98         this._normalTextureSize = cc.size(0, 0);
 99         this._pressedTextureSize = cc.size(0, 0);
100         this._disabledTextureSize = cc.size(0, 0);
101         this._titleColor = cc.color.WHITE;
102         ccui.Widget.prototype.ctor.call(this);
103         this.setTouchEnabled(true);
104 
105         texType && this.init(normalImage, selectedImage, disableImage, texType);
106     },
107 
108     /**
109      * Initializes a button. please do not call this function by yourself, you should pass the parameters to constructor to initialize it.
110      * @param {String} normalImage
111      * @param {String} [selectedImage=""]
112      * @param {String} [disableImage=""]
113      * @param {Number} [texType=ccui.Widget.LOCAL_TEXTURE]
114      * @returns {boolean}
115      * @override
116      */
117     init: function (normalImage, selectedImage,disableImage, texType) {
118         if (ccui.Widget.prototype.init.call(this)) {
119             if(normalImage === undefined)
120                 return true;
121             this.loadTextures(normalImage, selectedImage,disableImage, texType);
122         }
123         return false;
124     },
125 
126     _initRenderer: function () {
127         this._buttonNormalRenderer = cc.Sprite.create();
128         this._buttonClickedRenderer = cc.Sprite.create();
129         this._buttonDisableRenderer = cc.Sprite.create();
130         this._titleRenderer = new cc.LabelTTF("");
131         this._titleRenderer.setAnchorPoint(0.5, 0.5);
132 
133         this.addProtectedChild(this._buttonNormalRenderer, ccui.Button.NORMAL_RENDERER_ZORDER, -1);
134         this.addProtectedChild(this._buttonClickedRenderer, ccui.Button.PRESSED_RENDERER_ZORDER, -1);
135         this.addProtectedChild(this._buttonDisableRenderer, ccui.Button.DISABLED_RENDERER_ZORDER, -1);
136         this.addProtectedChild(this._titleRenderer, ccui.Button.TITLE_RENDERER_ZORDER, -1);
137     },
138 
139     /**
140      * Sets if button is using scale9 renderer.
141      * @param {Boolean} able true that using scale9 renderer, false otherwise.
142      */
143     setScale9Enabled: function (able) {
144         if (this._scale9Enabled == able)
145             return;
146 
147         this._brightStyle = ccui.Widget.BRIGHT_STYLE_NONE;
148         this._scale9Enabled = able;
149 
150         this.removeProtectedChild(this._buttonNormalRenderer);
151         this.removeProtectedChild(this._buttonClickedRenderer);
152         this.removeProtectedChild(this._buttonDisableRenderer);
153 
154         if (this._scale9Enabled) {
155             this._buttonNormalRenderer = new ccui.Scale9Sprite();
156             this._buttonClickedRenderer = new ccui.Scale9Sprite();
157             this._buttonDisableRenderer = new ccui.Scale9Sprite();
158         } else {
159             this._buttonNormalRenderer = cc.Sprite.create();
160             this._buttonClickedRenderer = cc.Sprite.create();
161             this._buttonDisableRenderer = cc.Sprite.create();
162         }
163 
164         this.loadTextureNormal(this._normalFileName, this._normalTexType);
165         this.loadTexturePressed(this._clickedFileName, this._pressedTexType);
166         this.loadTextureDisabled(this._disabledFileName, this._disabledTexType);
167 
168         this.addProtectedChild(this._buttonNormalRenderer, ccui.Button.NORMAL_RENDERER_ZORDER, -1);
169         this.addProtectedChild(this._buttonClickedRenderer, ccui.Button.PRESSED_RENDERER_ZORDER, -1);
170         this.addProtectedChild(this._buttonDisableRenderer, ccui.Button.DISABLED_RENDERER_ZORDER, -1);
171         if (this._scale9Enabled) {
172             var ignoreBefore = this._ignoreSize;
173             this.ignoreContentAdaptWithSize(false);
174             this._prevIgnoreSize = ignoreBefore;
175         } else {
176             this.ignoreContentAdaptWithSize(this._prevIgnoreSize);
177         }
178         this.setCapInsetsNormalRenderer(this._capInsetsNormal);
179         this.setCapInsetsPressedRenderer(this._capInsetsPressed);
180         this.setCapInsetsDisabledRenderer(this._capInsetsDisabled);
181         this.setBright(this._bright);
182     },
183 
184     /**
185      *  Returns button is using scale9 renderer or not.
186      * @returns {Boolean}
187      */
188     isScale9Enabled: function () {
189         return this._scale9Enabled;
190     },
191 
192     /**
193      * Sets whether ignore the widget size
194      * @param {Boolean} ignore true that widget will ignore it's size, use texture size, false otherwise. Default value is true.
195      * @override
196      */
197     ignoreContentAdaptWithSize: function (ignore) {
198         if (!this._scale9Enabled || (this._scale9Enabled && !ignore)) {
199             ccui.Widget.prototype.ignoreContentAdaptWithSize.call(this, ignore);
200             this._prevIgnoreSize = ignore;
201         }
202     },
203 
204     /**
205      * Returns the renderer size.
206      * @returns {cc.Size}
207      */
208     getVirtualRendererSize: function(){
209         return cc.size(this._normalTextureSize);
210     },
211 
212     /**
213      * Load textures for button.
214      * @param {String} normal normal state of texture's filename.
215      * @param {String} selected  selected state of texture's filename.
216      * @param {String} disabled  disabled state of texture's filename.
217      * @param {ccui.Widget.LOCAL_TEXTURE|ccui.Widget.PLIST_TEXTURE} texType
218      */
219     loadTextures: function (normal, selected, disabled, texType) {
220         this.loadTextureNormal(normal, texType);
221         this.loadTexturePressed(selected, texType);
222         this.loadTextureDisabled(disabled, texType);
223     },
224 
225     /**
226      * Load normal state texture for button.
227      * @param {String} normal normal state of texture's filename.
228      * @param {ccui.Widget.LOCAL_TEXTURE|ccui.Widget.PLIST_TEXTURE} texType
229      */
230     loadTextureNormal: function (normal, texType) {
231         if (!normal)
232             return;
233         texType = texType || ccui.Widget.LOCAL_TEXTURE;
234         this._normalFileName = normal;
235         this._normalTexType = texType;
236 
237         var self = this;
238         if(!this._buttonNormalRenderer.texture || !this._buttonNormalRenderer.texture.isLoaded()){
239             this._buttonNormalRenderer.addLoadedEventListener(function(){
240 
241                 self._findLayout();
242 
243                 self._normalTextureSize = self._buttonNormalRenderer.getContentSize();
244                 self._updateFlippedX();
245                 self._updateFlippedY();
246                 self._updateChildrenDisplayedRGBA();
247 
248                 self._buttonNormalRenderer.setColor(self.getColor());
249                 self._buttonNormalRenderer.setOpacity(self.getOpacity());
250 
251                 self._updateContentSizeWithTextureSize(self._normalTextureSize);
252                 self._normalTextureLoaded = true;
253                 self._normalTextureAdaptDirty = true;
254             });
255         }
256 
257         if (this._scale9Enabled) {
258             var normalRendererScale9 = this._buttonNormalRenderer;
259             switch (this._normalTexType){
260                 case ccui.Widget.LOCAL_TEXTURE:
261                     normalRendererScale9.initWithFile(normal);
262                     break;
263                 case ccui.Widget.PLIST_TEXTURE:
264                     normalRendererScale9.initWithSpriteFrameName(normal);
265                     break;
266                 default:
267                     break;
268             }
269             normalRendererScale9.setCapInsets(this._capInsetsNormal);
270         } else {
271             var normalRenderer = this._buttonNormalRenderer;
272             switch (this._normalTexType){
273                 case ccui.Widget.LOCAL_TEXTURE:
274                     //SetTexture cannot load resource
275                     normalRenderer.initWithFile(normal);
276                     break;
277                 case ccui.Widget.PLIST_TEXTURE:
278                     //SetTexture cannot load resource
279                     normalRenderer.initWithSpriteFrameName(normal);
280                     break;
281                 default:
282                     break;
283             }
284         }
285         this._normalTextureSize = this._buttonNormalRenderer.getContentSize();
286         this._updateFlippedX();
287         this._updateFlippedY();
288 
289         this._updateChildrenDisplayedRGBA();
290 
291         this._updateContentSizeWithTextureSize(this._normalTextureSize);
292         this._normalTextureLoaded = true;
293         this._normalTextureAdaptDirty = true;
294     },
295 
296     /**
297      * Load selected state texture for button.
298      * @param {String} selected selected state of texture's filename.
299      * @param {ccui.Widget.LOCAL_TEXTURE|ccui.Widget.PLIST_TEXTURE} texType
300      */
301     loadTexturePressed: function (selected, texType) {
302         if (!selected)
303             return;
304         texType = texType || ccui.Widget.LOCAL_TEXTURE;
305         this._clickedFileName = selected;
306         this._pressedTexType = texType;
307 
308         var self = this;
309         if(!this._buttonClickedRenderer.texture || !this._buttonClickedRenderer.texture.isLoaded()){
310             this._buttonClickedRenderer.addLoadedEventListener(function(){
311 
312                 self._findLayout();
313 
314                 self._pressedTextureSize = self._buttonClickedRenderer.getContentSize();
315                 self._updateFlippedX();
316                 self._updateFlippedY();
317                 self._updateChildrenDisplayedRGBA();
318 
319                 self._pressedTextureLoaded = true;
320                 self._pressedTextureAdaptDirty = true;
321             });
322         }
323 
324         if (this._scale9Enabled) {
325             var clickedRendererScale9 = this._buttonClickedRenderer;
326             switch (this._pressedTexType) {
327                 case ccui.Widget.LOCAL_TEXTURE:
328                     clickedRendererScale9.initWithFile(selected);
329                     break;
330                 case ccui.Widget.PLIST_TEXTURE:
331                     clickedRendererScale9.initWithSpriteFrameName(selected);
332                     break;
333                 default:
334                     break;
335             }
336             clickedRendererScale9.setCapInsets(this._capInsetsPressed);
337         } else {
338             var clickedRenderer = this._buttonClickedRenderer;
339             switch (this._pressedTexType) {
340                 case ccui.Widget.LOCAL_TEXTURE:
341                     //SetTexture cannot load resource
342                     clickedRenderer.initWithFile(selected);
343                     break;
344                 case ccui.Widget.PLIST_TEXTURE:
345                     //SetTexture cannot load resource
346                     clickedRenderer.initWithSpriteFrameName(selected);
347                     break;
348                 default:
349                     break;
350             }
351         }
352         this._pressedTextureSize = this._buttonClickedRenderer.getContentSize();
353         this._updateFlippedX();
354         this._updateFlippedY();
355 
356         this._updateChildrenDisplayedRGBA();
357 
358         this._pressedTextureLoaded = true;
359         this._pressedTextureAdaptDirty = true;
360     },
361 
362     /**
363      * Load dark state texture for button.
364      * @param {String} disabled disabled state of texture's filename.
365      * @param {ccui.Widget.LOCAL_TEXTURE|ccui.Widget.PLIST_TEXTURE} texType
366      */
367     loadTextureDisabled: function (disabled, texType) {
368         if (!disabled)
369             return;
370 
371         texType = texType || ccui.Widget.LOCAL_TEXTURE;
372         this._disabledFileName = disabled;
373         this._disabledTexType = texType;
374 
375         var self = this;
376         if(!this._buttonDisableRenderer.texture || !this._buttonDisableRenderer.texture.isLoaded()){
377             this._buttonDisableRenderer.addLoadedEventListener(function() {
378 
379                 self._findLayout();
380 
381                 self._disabledTextureSize = self._buttonDisableRenderer.getContentSize();
382                 self._updateFlippedX();
383                 self._updateFlippedY();
384                 self._updateChildrenDisplayedRGBA();
385 
386                 self._disabledTextureLoaded = true;
387                 self._disabledTextureAdaptDirty = true;
388             });
389         }
390 
391         if (this._scale9Enabled) {
392             var disabledScale9 = this._buttonDisableRenderer;
393             switch (this._disabledTexType) {
394                 case ccui.Widget.LOCAL_TEXTURE:
395                     disabledScale9.initWithFile(disabled);
396                     break;
397                 case ccui.Widget.PLIST_TEXTURE:
398                     disabledScale9.initWithSpriteFrameName(disabled);
399                     break;
400                 default:
401                     break;
402             }
403             disabledScale9.setCapInsets(this._capInsetsDisabled);
404         } else {
405             var disabledRenderer = this._buttonDisableRenderer;
406             switch (this._disabledTexType) {
407                 case ccui.Widget.LOCAL_TEXTURE:
408                     //SetTexture cannot load resource
409                     disabledRenderer.initWithFile(disabled);
410                     break;
411                 case ccui.Widget.PLIST_TEXTURE:
412                     //SetTexture cannot load resource
413                     disabledRenderer.initWithSpriteFrameName(disabled);
414                     break;
415                 default:
416                     break;
417             }
418         }
419         this._disabledTextureSize = this._buttonDisableRenderer.getContentSize();
420         this._updateFlippedX();
421         this._updateFlippedY();
422 
423         this._updateChildrenDisplayedRGBA();
424 
425         this._disabledTextureLoaded = true;
426         this._disabledTextureAdaptDirty = true;
427     },
428 
429     /**
430      * Sets capinsets for button, if button is using scale9 renderer.
431      * @param {cc.Rect} capInsets
432      */
433     setCapInsets: function (capInsets) {
434         this.setCapInsetsNormalRenderer(capInsets);
435         this.setCapInsetsPressedRenderer(capInsets);
436         this.setCapInsetsDisabledRenderer(capInsets);
437     },
438 
439     /**
440      * Sets capinsets for button, if button is using scale9 renderer.
441      * @param {cc.Rect} capInsets
442      */
443     setCapInsetsNormalRenderer: function (capInsets) {
444         if(!capInsets)
445             return;
446         var locInsets = this._capInsetsNormal;
447         locInsets.x = capInsets.x;
448         locInsets.y = capInsets.y;
449         locInsets.width = capInsets.width;
450         locInsets.height = capInsets.height;
451         if (!this._scale9Enabled)
452             return;
453         this._buttonNormalRenderer.setCapInsets(capInsets);
454     },
455 
456     /**
457      *  Returns normal renderer cap insets.
458      * @returns {cc.Rect}
459      */
460     getCapInsetsNormalRenderer:function(){
461         return cc.rect(this._capInsetsNormal);
462     },
463 
464     /**
465      * Sets capinsets for button, if button is using scale9 renderer.
466      * @param {cc.Rect} capInsets
467      */
468     setCapInsetsPressedRenderer: function (capInsets) {
469         if(!capInsets)
470             return;
471         var locInsets = this._capInsetsPressed;
472         locInsets.x = capInsets.x;
473         locInsets.y = capInsets.y;
474         locInsets.width = capInsets.width;
475         locInsets.height = capInsets.height;
476         if (!this._scale9Enabled)
477             return;
478         this._buttonClickedRenderer.setCapInsets(capInsets);
479     },
480 
481     /**
482      *  Returns pressed renderer cap insets.
483      * @returns {cc.Rect}
484      */
485     getCapInsetsPressedRenderer: function () {
486         return cc.rect(this._capInsetsPressed);
487     },
488 
489     /**
490      * Sets capinsets for button, if button is using scale9 renderer.
491      * @param {cc.Rect} capInsets
492      */
493     setCapInsetsDisabledRenderer: function (capInsets) {
494         if(!capInsets)
495             return;
496         var locInsets = this._capInsetsDisabled;
497         locInsets.x = capInsets.x;
498         locInsets.y = capInsets.y;
499         locInsets.width = capInsets.width;
500         locInsets.height = capInsets.height;
501 
502         if (!this._scale9Enabled)
503             return;
504         this._buttonDisableRenderer.setCapInsets(capInsets);
505     },
506 
507     /**
508      * Returns disable renderer cap insets.
509      * @returns {cc.Rect}
510      */
511     getCapInsetsDisabledRenderer: function () {
512         return cc.rect(this._capInsetsDisabled);
513     },
514 
515     _onPressStateChangedToNormal: function () {
516         this._buttonNormalRenderer.setVisible(true);
517         this._buttonClickedRenderer.setVisible(false);
518         this._buttonDisableRenderer.setVisible(false);
519         if (this._pressedTextureLoaded) {
520             if (this.pressedActionEnabled){
521                 this._buttonNormalRenderer.stopAllActions();
522                 this._buttonClickedRenderer.stopAllActions();
523                 var zoomAction = cc.scaleTo(0.05, this._normalTextureScaleXInSize, this._normalTextureScaleYInSize);
524                 this._buttonNormalRenderer.runAction(zoomAction);
525                 this._buttonClickedRenderer.setScale(this._pressedTextureScaleXInSize, this._pressedTextureScaleYInSize);
526             }
527         } else {
528             if (this._scale9Enabled)
529                 this._updateTexturesRGBA();
530             else {
531                 this._buttonNormalRenderer.stopAllActions();
532                 this._buttonNormalRenderer.setScale(this._normalTextureScaleXInSize, this._normalTextureScaleYInSize);
533             }
534         }
535     },
536 
537     _onPressStateChangedToPressed: function () {
538         var locNormalRenderer = this._buttonNormalRenderer;
539         if (this._pressedTextureLoaded) {
540             locNormalRenderer.setVisible(false);
541             this._buttonClickedRenderer.setVisible(true);
542             this._buttonDisableRenderer.setVisible(false);
543             if (this.pressedActionEnabled) {
544                 locNormalRenderer.stopAllActions();
545                 this._buttonClickedRenderer.stopAllActions();
546                 var zoomAction = cc.scaleTo(0.05, this._pressedTextureScaleXInSize + 0.1,this._pressedTextureScaleYInSize + 0.1);
547                 this._buttonClickedRenderer.runAction(zoomAction);
548                 locNormalRenderer.setScale(this._pressedTextureScaleXInSize + 0.1, this._pressedTextureScaleYInSize + 0.1);
549             }
550         } else {
551             locNormalRenderer.setVisible(true);
552             this._buttonClickedRenderer.setVisible(true);
553             this._buttonDisableRenderer.setVisible(false);
554             if (this._scale9Enabled)
555                 locNormalRenderer.setColor(cc.color.GRAY);
556             else {
557                 locNormalRenderer.stopAllActions();
558                 locNormalRenderer.setScale(this._normalTextureScaleXInSize + 0.1, this._normalTextureScaleYInSize + 0.1);
559             }
560         }
561     },
562 
563     _onPressStateChangedToDisabled: function () {
564         this._buttonNormalRenderer.setVisible(false);
565         this._buttonClickedRenderer.setVisible(false);
566         this._buttonDisableRenderer.setVisible(true);
567         this._buttonNormalRenderer.setScale(this._normalTextureScaleXInSize, this._normalTextureScaleYInSize);
568         this._buttonClickedRenderer.setScale(this._pressedTextureScaleXInSize, this._pressedTextureScaleYInSize);
569     },
570 
571     _updateFlippedX: function () {
572         var flip = this._flippedX ? -1.0 : 1.0;
573         this._titleRenderer.setScaleX(flip);
574         if (this._scale9Enabled) {
575             this._buttonNormalRenderer.setScaleX(flip);
576             this._buttonClickedRenderer.setScaleX(flip);
577             this._buttonDisableRenderer.setScaleX(flip);
578         } else {
579             this._buttonNormalRenderer.setFlippedX(this._flippedX);
580             this._buttonClickedRenderer.setFlippedX(this._flippedX);
581             this._buttonDisableRenderer.setFlippedX(this._flippedX);
582         }
583     },
584 
585     _updateFlippedY: function () {
586         var flip = this._flippedY ? -1.0 : 1.0;
587         this._titleRenderer.setScaleY(flip);
588         if (this._scale9Enabled) {
589             this._buttonNormalRenderer.setScaleY(flip);
590             this._buttonClickedRenderer.setScaleY(flip);
591             this._buttonDisableRenderer.setScaleY(flip);
592         } else {
593             this._buttonNormalRenderer.setFlippedY(this._flippedY);
594             this._buttonClickedRenderer.setFlippedY(this._flippedY);
595             this._buttonDisableRenderer.setFlippedY(this._flippedY);
596         }
597     },
598 
599     _updateTexturesRGBA: function(){
600         this._buttonNormalRenderer.setColor(this.getColor());
601         this._buttonClickedRenderer.setColor(this.getColor());
602         this._buttonDisableRenderer.setColor(this.getColor());
603 
604         this._buttonNormalRenderer.setOpacity(this.getOpacity());
605         this._buttonClickedRenderer.setOpacity(this.getOpacity());
606         this._buttonDisableRenderer.setOpacity(this.getOpacity());
607     },
608 
609     _onSizeChanged: function () {
610         ccui.Widget.prototype._onSizeChanged.call(this);
611         this._updateTitleLocation();
612         this._normalTextureAdaptDirty = true;
613         this._pressedTextureAdaptDirty = true;
614         this._disabledTextureAdaptDirty = true;
615     },
616 
617     /**
618      * Gets the Virtual Renderer of widget.
619      * @returns {cc.Node}
620      */
621     getVirtualRenderer: function () {
622         if (this._bright) {
623             switch (this._brightStyle) {
624                 case ccui.Widget.BRIGHT_STYLE_NORMAL:
625                     return this._buttonNormalRenderer;
626                 case ccui.Widget.BRIGHT_STYLE_HIGH_LIGHT:
627                     return this._buttonClickedRenderer;
628                 default:
629                     return null;
630             }
631         } else
632             return this._buttonDisableRenderer;
633     },
634 
635     _normalTextureScaleChangedWithSize: function () {
636         if (this._ignoreSize) {
637             if (!this._scale9Enabled) {
638                 this._buttonNormalRenderer.setScale(1.0);
639                 this._normalTextureScaleXInSize = this._normalTextureScaleYInSize = 1;
640             }
641         } else {
642             if (this._scale9Enabled) {
643                 this._buttonNormalRenderer.setPreferredSize(this._contentSize);
644                 this._normalTextureScaleXInSize = this._normalTextureScaleYInSize = 1;
645             } else {
646                 var textureSize = this._normalTextureSize;
647                 if (textureSize.width <= 0.0 || textureSize.height <= 0.0) {
648                     this._buttonNormalRenderer.setScale(1.0);
649                     return;
650                 }
651                 var scaleX = this._contentSize.width / textureSize.width;
652                 var scaleY = this._contentSize.height / textureSize.height;
653                 this._buttonNormalRenderer.setScaleX(scaleX);
654                 this._buttonNormalRenderer.setScaleY(scaleY);
655                 this._normalTextureScaleXInSize = scaleX;
656                 this._normalTextureScaleYInSize = scaleY;
657             }
658         }
659         this._buttonNormalRenderer.setPosition(this._contentSize.width / 2.0, this._contentSize.height / 2.0);
660     },
661 
662     _pressedTextureScaleChangedWithSize: function () {
663         if (this._ignoreSize) {
664             if (!this._scale9Enabled) {
665                 this._buttonClickedRenderer.setScale(1.0);
666                 this._pressedTextureScaleXInSize = this._pressedTextureScaleYInSize = 1;
667             }
668         } else {
669             if (this._scale9Enabled) {
670                 this._buttonClickedRenderer.setPreferredSize(this._contentSize);
671                 this._pressedTextureScaleXInSize = this._pressedTextureScaleYInSize = 1;
672             } else {
673                 var textureSize = this._pressedTextureSize;
674                 if (textureSize.width <= 0.0 || textureSize.height <= 0.0) {
675                     this._buttonClickedRenderer.setScale(1.0);
676                     return;
677                 }
678                 var scaleX = this._contentSize.width / textureSize.width;
679                 var scaleY = this._contentSize.height / textureSize.height;
680                 this._buttonClickedRenderer.setScaleX(scaleX);
681                 this._buttonClickedRenderer.setScaleY(scaleY);
682                 this._pressedTextureScaleXInSize = scaleX;
683                 this._pressedTextureScaleYInSize = scaleY;
684             }
685         }
686         this._buttonClickedRenderer.setPosition(this._contentSize.width / 2.0, this._contentSize.height / 2.0);
687     },
688 
689     _disabledTextureScaleChangedWithSize: function () {
690         if (this._ignoreSize) {
691             if (!this._scale9Enabled)
692                 this._buttonDisableRenderer.setScale(1.0);
693         } else {
694             if (this._scale9Enabled)
695                 this._buttonDisableRenderer.setPreferredSize(this._contentSize);
696             else {
697                 var textureSize = this._disabledTextureSize;
698                 if (textureSize.width <= 0.0 || textureSize.height <= 0.0) {
699                     this._buttonDisableRenderer.setScale(1.0);
700                     return;
701                 }
702                 var scaleX = this._contentSize.width / textureSize.width;
703                 var scaleY = this._contentSize.height / textureSize.height;
704                 this._buttonDisableRenderer.setScaleX(scaleX);
705                 this._buttonDisableRenderer.setScaleY(scaleY);
706             }
707         }
708         this._buttonDisableRenderer.setPosition(this._contentSize.width / 2.0, this._contentSize.height / 2.0);
709     },
710 
711     _adaptRenderers: function(){
712         if (this._normalTextureAdaptDirty) {
713             this._normalTextureScaleChangedWithSize();
714             this._normalTextureAdaptDirty = false;
715         }
716         if (this._pressedTextureAdaptDirty) {
717             this._pressedTextureScaleChangedWithSize();
718             this._pressedTextureAdaptDirty = false;
719         }
720         if (this._disabledTextureAdaptDirty) {
721             this._disabledTextureScaleChangedWithSize();
722             this._disabledTextureAdaptDirty = false;
723         }
724     },
725 
726     _updateTitleLocation: function(){
727         this._titleRenderer.setPosition(this._contentSize.width * 0.5, this._contentSize.height * 0.5);
728     },
729 
730     /**
731      * Changes if button can be clicked zoom effect.
732      * @param {Boolean} enabled
733      */
734     setPressedActionEnabled: function (enabled) {
735         this.pressedActionEnabled = enabled;
736     },
737 
738     /**
739      * Sets title text to ccui.Button
740      * @param {String} text
741      */
742     setTitleText: function (text) {
743         this._titleRenderer.setString(text);
744     },
745 
746     /**
747      * Returns title text of ccui.Button
748      * @returns {String} text
749      */
750     getTitleText: function () {
751         return this._titleRenderer.getString();
752     },
753 
754     /**
755      * Sets title color to ccui.Button.
756      * @param {cc.Color} color
757      */
758     setTitleColor: function (color) {
759         this._titleColor.r = color.r;
760         this._titleColor.g = color.g;
761         this._titleColor.b = color.b;
762         this._titleRenderer.updateDisplayedColor(color);
763     },
764 
765     /**
766      * Returns title color of ccui.Button
767      * @returns {cc.Color}
768      */
769     getTitleColor: function () {
770         return this._titleRenderer.getColor();
771     },
772 
773     /**
774      * Sets title fontSize to ccui.Button
775      * @param {cc.Size} size
776      */
777     setTitleFontSize: function (size) {
778         this._titleRenderer.setFontSize(size);
779     },
780 
781     /**
782      * Returns title fontSize of ccui.Button.
783      * @returns {cc.Size}
784      */
785     getTitleFontSize: function () {
786         return this._titleRenderer.getFontSize();
787     },
788 
789     /**
790      * Sets title fontName to ccui.Button.
791      * @param {String} fontName
792      */
793     setTitleFontName: function (fontName) {
794         this._titleRenderer.setFontName(fontName);
795         this._fontName = fontName;
796     },
797 
798     /**
799      * Gets title fontName of ccui.Button.
800      * @returns {String}
801      */
802     getTitleFontName: function () {
803         return this._titleRenderer.getFontName();
804     },
805 
806     _setTitleFont: function (font) {
807         this._titleRenderer.font = font;
808     },
809     _getTitleFont: function () {
810         return this._titleRenderer.font;
811     },
812 
813     /**
814      * Returns the "class name" of widget.
815      * @override
816      * @returns {string}
817      */
818     getDescription: function () {
819         return "Button";
820     },
821 
822     _createCloneInstance: function () {
823         return ccui.Button.create();
824     },
825 
826     _copySpecialProperties: function (uiButton) {
827         this._prevIgnoreSize = uiButton._prevIgnoreSize;
828         this.setScale9Enabled(uiButton._scale9Enabled);
829         this.loadTextureNormal(uiButton._normalFileName, uiButton._normalTexType);
830         this.loadTexturePressed(uiButton._clickedFileName, uiButton._pressedTexType);
831         this.loadTextureDisabled(uiButton._disabledFileName, uiButton._disabledTexType);
832         this.setCapInsetsNormalRenderer(uiButton._capInsetsNormal);
833         this.setCapInsetsPressedRenderer(uiButton._capInsetsPressed);
834         this.setCapInsetsDisabledRenderer(uiButton._capInsetsDisabled);
835         this.setTitleText(uiButton.getTitleText());
836         this.setTitleFontName(uiButton.getTitleFontName());
837         this.setTitleFontSize(uiButton.getTitleFontSize());
838         this.setTitleColor(uiButton.getTitleColor());
839         this.setPressedActionEnabled(uiButton.pressedActionEnabled);
840     }
841 });
842 
843 var _p = ccui.Button.prototype;
844 
845 // Extended properties
846 /** @expose */
847 _p.titleText;
848 cc.defineGetterSetter(_p, "titleText", _p.getTitleText, _p.setTitleText);
849 /** @expose */
850 _p.titleFont;
851 cc.defineGetterSetter(_p, "titleFont", _p._getTitleFont, _p._setTitleFont);
852 /** @expose */
853 _p.titleFontSize;
854 cc.defineGetterSetter(_p, "titleFontSize", _p.getTitleFontSize, _p.setTitleFontSize);
855 /** @expose */
856 _p.titleFontName;
857 cc.defineGetterSetter(_p, "titleFontName", _p.getTitleFontName, _p.setTitleFontName);
858 /** @expose */
859 _p.titleColor;
860 cc.defineGetterSetter(_p, "titleColor", _p.getTitleColor, _p.setTitleColor);
861 
862 _p = null;
863 
864 /**
865  * allocates and initializes a UIButton.
866  * @deprecated since v3.0, please use new ccui.Button() instead.
867  * @param {string} [normalImage]    normal state texture name
868  * @param {string} [selectedImage]  selected state texture name
869  * @param {string} [disableImage]   disabled state texture name
870  * @param {string} [texType]
871  * @return {ccui.Button}
872  * @example
873  * // example
874  * var uiButton = ccui.Button.create();
875  */
876 ccui.Button.create = function (normalImage, selectedImage, disableImage, texType) {
877     return new ccui.Button(normalImage, selectedImage, disableImage, texType);
878 };
879 
880 // Constants
881 /**
882  * The normal renderer's zOrder value.
883  * @constant
884  * @type {number}
885  */
886 ccui.Button.NORMAL_RENDERER_ZORDER = -2;
887 /**
888  * The pressed renderer's zOrder value.
889  * @constant
890  * @type {number}
891  */
892 ccui.Button.PRESSED_RENDERER_ZORDER = -2;
893 /**
894  * The disabled renderer's zOrder value.
895  * @constant
896  * @type {number}
897  */
898 ccui.Button.DISABLED_RENDERER_ZORDER = -2;
899 /**
900  * The title renderer's zOrder value.
901  * @constant
902  * @type {number}
903  */
904 ccui.Button.TITLE_RENDERER_ZORDER = -1;
905 
906 /**
907  * @ignore
908  */
909 ccui.Button.SYSTEM = 0;
910 ccui.Button.TTF = 1;
911