1 /**
  2  * CCControlButton.m
  3  *
  4  * Copyright (c) 2008-2010 Ricardo Quesada
  5  * Copyright (c) 2011-2012 cocos2d-x.org
  6  * Copyright (c) 2013-2014 Chukong Technologies Inc.
  7  * Copyright 2011 Yannick Loriot.
  8  * http://yannickloriot.com
  9  *
 10  * Permission is hereby granted, free of charge, to any person obtaining a copy
 11  * of this software and associated documentation files (the "Software"), to deal
 12  * in the Software without restriction, including without limitation the rights
 13  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 14  * copies of the Software, and to permit persons to whom the Software is
 15  * furnished to do so, subject to the following conditions:
 16  *
 17  * The above copyright notice and this permission notice shall be included in
 18  * all copies or substantial portions of the Software.
 19  *
 20  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 21  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 22  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 23  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 24  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 25  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 26  * THE SOFTWARE.
 27  */
 28 
 29 /**
 30  * @ignore
 31  */
 32 cc.CONTROL_ZOOM_ACTION_TAG = 0xCCCB0001;
 33 
 34 /**
 35  * CCControlButton: Button control for Cocos2D.
 36  * @class
 37  * @extends cc.Control
 38  *
 39  * @property {Boolean}  adjustBackgroundImage   - Indicate whether the background image will be adjusted
 40  * @property {Boolean}  zoomOnTouchDown         - Indicate whether the button will be zoomed while touch down
 41  * @property {cc.Size}  preferredSize           - The preferred size of the control button
 42  * @property {Boolean}  labelAnchor             - The anchor point for the label of the control button
 43  */
 44 cc.ControlButton = cc.Control.extend(/** @lends cc.ControlButton# */{
 45     _doesAdjustBackgroundImage: false,
 46     zoomOnTouchDown: false,
 47     _preferredSize: null,
 48     _labelAnchorPoint: null,
 49     _currentTitle: null,
 50     _currentTitleColor: null,
 51     _titleLabel: null,
 52     _backgroundSprite: null,
 53     _opacity: 0,
 54     _isPushed: false,
 55     _titleDispatchTable: null,
 56     _titleColorDispatchTable: null,
 57     _titleLabelDispatchTable: null,
 58     _backgroundSpriteDispatchTable: null,
 59     _parentInited: false,
 60 
 61     _marginV: 0,
 62     _marginH: 0,
 63     _className: "ControlButton",
 64 
 65     ctor: function () {
 66         cc.Control.prototype.ctor.call(this);
 67         this._preferredSize = cc.size(0, 0);
 68         this._labelAnchorPoint = cc.p(0, 0);
 69         this._currentTitle = "";
 70         this._currentTitleColor = cc.color.WHITE;
 71         this._titleDispatchTable = {};
 72         this._titleColorDispatchTable = {};
 73         this._titleLabelDispatchTable = {};
 74         this._backgroundSpriteDispatchTable = {};
 75     },
 76 
 77     init: function () {
 78         return this.initWithLabelAndBackgroundSprite(cc.LabelTTF.create("", "Arial", 12), cc.Scale9Sprite.create());
 79     },
 80 
 81     needsLayout: function () {
 82         if (!this._parentInited) {
 83             return;
 84         }
 85         // Hide the background and the label
 86         if (this._titleLabel)
 87             this._titleLabel.setVisible(false);
 88         if (this._backgroundSprite)
 89             this._backgroundSprite.setVisible(false);
 90 
 91         // Update anchor of all labels
 92         this.setLabelAnchorPoint(this._labelAnchorPoint);
 93 
 94         // Update the label to match with the current state
 95         //CC_SAFE_RELEASE(this._currentTitle)
 96         var locState = this._state;
 97 
 98         this._currentTitle = this.getTitleForState(locState);
 99         this._currentTitleColor = this.getTitleColorForState(locState);
100         this._titleLabel = this.getTitleLabelForState(locState);
101 
102         var label = this._titleLabel;
103         if (label && label.setString)
104             label.setString(this._currentTitle);
105         if (label && label.RGBAProtocol)
106             label.setColor(this._currentTitleColor);
107 
108         var locContentSize = this.getContentSize();
109         if (label)
110             label.setPosition(locContentSize.width / 2, locContentSize.height / 2);
111 
112         // Update the background sprite
113         this._backgroundSprite = this.getBackgroundSpriteForState(locState);
114         var locBackgroundSprite = this._backgroundSprite;
115         if (locBackgroundSprite)
116             locBackgroundSprite.setPosition(locContentSize.width / 2, locContentSize.height / 2);
117 
118         // Get the title label size
119         var titleLabelSize = cc.size(0, 0);
120         if (label) {
121             var boundingBox = label.getBoundingBox();
122             titleLabelSize.width = boundingBox.width;
123             titleLabelSize.height = boundingBox.height;
124         }
125         // Adjust the background image if necessary
126         if (this._doesAdjustBackgroundImage) {
127             // Add the margins
128             if (locBackgroundSprite)
129                 locBackgroundSprite.setContentSize(titleLabelSize.width + this._marginH * 2, titleLabelSize.height + this._marginV * 2);
130         } else {
131             //TODO: should this also have margins if one of the preferred sizes is relaxed?
132             if (locBackgroundSprite) {
133                 var preferredSize = locBackgroundSprite.getPreferredSize();
134                 preferredSize = cc.size(preferredSize.width, preferredSize.height);
135                 if (preferredSize.width <= 0)
136                     preferredSize.width = titleLabelSize.width;
137                 if (preferredSize.height <= 0)
138                     preferredSize.height = titleLabelSize.height;
139 
140                 locBackgroundSprite.setContentSize(preferredSize);
141             }
142         }
143 
144         // Set the content size
145         var rectTitle = label ? label.getBoundingBox() : cc.rect(0, 0, 0, 0);
146         var rectBackground = locBackgroundSprite ? locBackgroundSprite.getBoundingBox() : cc.rect(0, 0, 0, 0);
147         var maxRect = cc.rectUnion(rectTitle, rectBackground);
148         this.setContentSize(maxRect.width, maxRect.height);
149         locContentSize = this.getContentSize();
150         if (label) {
151             label.setPosition(locContentSize.width / 2, locContentSize.height / 2);
152             label.setVisible(true);
153         }
154         if (locBackgroundSprite) {
155             locBackgroundSprite.setPosition(locContentSize.width / 2, locContentSize.height / 2);
156             locBackgroundSprite.setVisible(true);
157         }
158     },
159 
160     initWithLabelAndBackgroundSprite: function (label, backgroundSprite) {
161         if (!label || !label.RGBAProtocol)
162             throw "cc.ControlButton.initWithLabelAndBackgroundSprite(): label should be non-null";
163         if (!backgroundSprite)
164             throw "cc.ControlButton.initWithLabelAndBackgroundSprite(): backgroundSprite should be non-null";
165         if (cc.Control.prototype.init.call(this, true)) {
166             this._parentInited = true;
167 
168             // Initialize the button state tables
169             this._titleDispatchTable = {};
170             this._titleColorDispatchTable = {};
171             this._titleLabelDispatchTable = {};
172             this._backgroundSpriteDispatchTable = {};
173 
174             this._isPushed = false;
175             this.zoomOnTouchDown = true;
176 
177             this._currentTitle = null;
178 
179             // Adjust the background image by default
180             this.setAdjustBackgroundImage(true);
181             this.setPreferredSize(cc.size(0, 0));
182 
183             // Zooming button by default
184             this.zoomOnTouchDown = true;
185 
186             // Set the default anchor point
187             this.ignoreAnchorPointForPosition(false);
188             this.setAnchorPoint(0.5, 0.5);
189 
190             // Set the nodes
191             this._titleLabel = label;
192             this._backgroundSprite = backgroundSprite;
193 
194             // Set the default color and opacity
195             this.setOpacity(255);
196             this.setOpacityModifyRGB(true);
197 
198             // Initialize the dispatch table
199             var tempString = label.getString();
200             //tempString.autorelease();
201             this.setTitleForState(tempString, cc.CONTROL_STATE_NORMAL);
202             this.setTitleColorForState(label.getColor(), cc.CONTROL_STATE_NORMAL);
203             this.setTitleLabelForState(label, cc.CONTROL_STATE_NORMAL);
204             this.setBackgroundSpriteForState(backgroundSprite, cc.CONTROL_STATE_NORMAL);
205 
206             this._state = cc.CONTROL_STATE_NORMAL;
207 
208             //default margins
209             this._marginH = 24;
210             this._marginV = 12;
211 
212             this._labelAnchorPoint = cc.p(0.5, 0.5);
213 
214             this.setPreferredSize(cc.size(0, 0));
215 
216             // Layout update
217             this.needsLayout();
218             return true;
219         }//couldn't init the CCControl
220         else
221             return false;
222     },
223 
224     initWithTitleAndFontNameAndFontSize: function (title, fontName, fontSize) {
225         var label = cc.LabelTTF.create(title, fontName, fontSize);
226         return this.initWithLabelAndBackgroundSprite(label, cc.Scale9Sprite.create());
227     },
228 
229     initWithBackgroundSprite: function (sprite) {
230         var label = cc.LabelTTF.create("", "Arial", 30);//
231         return this.initWithLabelAndBackgroundSprite(label, sprite);
232     },
233 
234     /**
235      * Adjust the background image. YES by default. If the property is set to NO, the background will use the prefered size of the background image.
236      * @return {Boolean}
237      */
238     doesAdjustBackgroundImage: function () {
239         return this._doesAdjustBackgroundImage;
240     },
241 
242     setAdjustBackgroundImage: function (adjustBackgroundImage) {
243         this._doesAdjustBackgroundImage = adjustBackgroundImage;
244         this.needsLayout();
245     },
246 
247     /** Adjust the button zooming on touchdown. Default value is YES. */
248     getZoomOnTouchDown: function () {
249         return this.zoomOnTouchDown;
250     },
251 
252     setZoomOnTouchDown: function (zoomOnTouchDown) {
253         return this.zoomOnTouchDown = zoomOnTouchDown;
254     },
255 
256     /** The prefered size of the button, if label is larger it will be expanded. */
257     getPreferredSize: function () {
258         return this._preferredSize;
259     },
260 
261     setPreferredSize: function (size) {
262         if (size.width === 0 && size.height === 0) {
263             this._doesAdjustBackgroundImage = true;
264         } else {
265             this._doesAdjustBackgroundImage = false;
266             var locTable = this._backgroundSpriteDispatchTable;
267             for (var itemKey in locTable)
268                 locTable[itemKey].setPreferredSize(size);
269         }
270         this._preferredSize = size;
271         this.needsLayout();
272     },
273 
274     getLabelAnchorPoint: function () {
275         return this._labelAnchorPoint;
276     },
277     setLabelAnchorPoint: function (labelAnchorPoint) {
278         this._labelAnchorPoint = labelAnchorPoint;
279         if (this._titleLabel)
280             this._titleLabel.setAnchorPoint(labelAnchorPoint);
281     },
282 
283     /**
284      * The current title that is displayed on the button.
285      * @return {string}
286      */
287     _getCurrentTitle: function () {
288         return this._currentTitle;
289     },
290 
291     /** The current color used to display the title. */
292     _getCurrentTitleColor: function () {
293         return this._currentTitleColor;
294     },
295 
296     /* Override setter to affect a background sprite too */
297     getOpacity: function () {
298         return this._opacity;
299     },
300 
301     setOpacity: function (opacity) {
302         // XXX fixed me if not correct
303         cc.Control.prototype.setOpacity.call(this, opacity);
304         /*this._opacity = opacity;
305          var controlChildren = this.getChildren();
306          for (var i = 0; i < controlChildren.length; i++) {
307          var selChild = controlChildren[i];
308          if (selChild && selChild.RGBAProtocol)
309          selChild.setOpacity(opacity);
310          }*/
311         var locTable = this._backgroundSpriteDispatchTable;
312         for (var itemKey in locTable)
313             locTable[itemKey].setOpacity(opacity);
314     },
315 
316     setColor: function (color) {
317         cc.Control.prototype.setColor.call(this, color);
318         var locTable = this._backgroundSpriteDispatchTable;
319         for (var key in locTable)
320             locTable[key].setColor(color);
321     },
322 
323     getColor: function () {
324         var locRealColor = this._realColor;
325         return cc.color(locRealColor.r, locRealColor.g, locRealColor.b, locRealColor.a);
326     },
327 
328 
329     /** Flag to know if the button is currently pushed.  */
330     isPushed: function () {
331         return this._isPushed;
332     },
333 
334     /* Define the button margin for Top/Bottom edge */
335     _getVerticalMargin: function () {
336         return this._marginV;
337     },
338     /* Define the button margin for Left/Right edge */
339     _getHorizontalOrigin: function () {
340         return this._marginH;
341     },
342 
343     /**
344      * set the margins at once (so we only have to do one call of needsLayout)
345      * @param {Number} marginH
346      * @param {Number} marginV
347      */
348     setMargins: function (marginH, marginV) {
349         this._marginV = marginV;
350         this._marginH = marginH;
351         this.needsLayout();
352     },
353 
354     setEnabled: function (enabled) {
355         cc.Control.prototype.setEnabled.call(this, enabled);
356         this.needsLayout();
357     },
358     setSelected: function (enabled) {
359         cc.Control.prototype.setSelected.call(this, enabled);
360         this.needsLayout();
361     },
362 
363     setHighlighted: function (enabled) {
364         this._state = enabled ? cc.CONTROL_STATE_HIGHLIGHTED : cc.CONTROL_STATE_NORMAL;
365 
366         cc.Control.prototype.setHighlighted.call(this, enabled);
367         var action = this.getActionByTag(cc.CONTROL_ZOOM_ACTION_TAG);
368         if (action)
369             this.stopAction(action);
370 
371         this.needsLayout();
372         if (this.zoomOnTouchDown) {
373             var scaleValue = (this.isHighlighted() && this.isEnabled() && !this.isSelected()) ? 1.1 : 1.0;
374             var zoomAction = cc.ScaleTo.create(0.05, scaleValue);
375             zoomAction.setTag(cc.CONTROL_ZOOM_ACTION_TAG);
376             this.runAction(zoomAction);
377         }
378     },
379 
380     onTouchBegan: function (touch, event) {
381         if (!this.isTouchInside(touch) || !this.isEnabled() || !this.isVisible() || !this.hasVisibleParents())
382             return false;
383 
384         this._isPushed = true;
385         this.setHighlighted(true);
386         this.sendActionsForControlEvents(cc.CONTROL_EVENT_TOUCH_DOWN);
387         return true;
388     },
389 
390     onTouchMoved: function (touch, event) {
391         if (!this._enabled || !this._isPushed || this._selected) {
392             if (this._highlighted)
393                 this.setHighlighted(false);
394             return;
395         }
396 
397         var isTouchMoveInside = this.isTouchInside(touch);
398         if (isTouchMoveInside && !this._highlighted) {
399             this.setHighlighted(true);
400             this.sendActionsForControlEvents(cc.CONTROL_EVENT_TOUCH_DRAG_ENTER);
401         } else if (isTouchMoveInside && this._highlighted) {
402             this.sendActionsForControlEvents(cc.CONTROL_EVENT_TOUCH_DRAG_INSIDE);
403         } else if (!isTouchMoveInside && this._highlighted) {
404             this.setHighlighted(false);
405             this.sendActionsForControlEvents(cc.CONTROL_EVENT_TOUCH_DRAG_EXIT);
406         } else if (!isTouchMoveInside && !this._highlighted) {
407             this.sendActionsForControlEvents(cc.CONTROL_EVENT_TOUCH_DRAG_OUTSIDE);
408         }
409     },
410     onTouchEnded: function (touch, event) {
411         this._isPushed = false;
412         this.setHighlighted(false);
413 
414         if (this.isTouchInside(touch)) {
415             this.sendActionsForControlEvents(cc.CONTROL_EVENT_TOUCH_UP_INSIDE);
416         } else {
417             this.sendActionsForControlEvents(cc.CONTROL_EVENT_TOUCH_UP_OUTSIDE);
418         }
419     },
420 
421     onTouchCancelled: function (touch, event) {
422         this._isPushed = false;
423         this.setHighlighted(false);
424         this.sendActionsForControlEvents(cc.CONTROL_EVENT_TOUCH_CANCEL);
425     },
426 
427     /**
428      * Returns the title used for a state.
429      *
430      * @param {Number} state The state that uses the title. Possible values are described in "CCControlState".
431      * @return {string} The title for the specified state.
432      */
433     getTitleForState: function (state) {
434         var locTable = this._titleDispatchTable;
435         if (locTable) {
436             if (locTable[state])
437                 return locTable[state];
438             return locTable[cc.CONTROL_STATE_NORMAL];
439         }
440         return "";
441     },
442 
443     /**
444      * <p>
445      * Sets the title string to use for the specified state.                                                  <br/>
446      * If a property is not specified for a state, the default is to use the CCButtonStateNormal value.
447      * </p>
448      * @param {string} title The title string to use for the specified state.
449      * @param {Number} state The state that uses the specified title. The values are described in "CCControlState".
450      */
451     setTitleForState: function (title, state) {
452         this._titleDispatchTable[state] = title || "";
453 
454         // If the current state if equal to the given state we update the layout
455         if (this.getState() == state)
456             this.needsLayout();
457     },
458 
459     /**
460      * Returns the title color used for a state.
461      *
462      * @param {Number} state The state that uses the specified color. The values are described in "CCControlState".
463      * @return {cc.Color} The color of the title for the specified state.
464      */
465     getTitleColorForState: function (state) {
466         var colorObject = this._titleColorDispatchTable[state];
467         if (colorObject)
468             return colorObject;
469         colorObject = this._titleColorDispatchTable[cc.CONTROL_STATE_NORMAL];
470         if (colorObject)
471             return colorObject;
472         return cc.color.WHITE;
473     },
474 
475     /**
476      * Sets the color of the title to use for the specified state.
477      *
478      * @param {cc.Color} color The color of the title to use for the specified state.
479      * @param {Number} state The state that uses the specified color. The values are described in "CCControlState".
480      */
481     setTitleColorForState: function (color, state) {
482         //ccColor3B* colorValue=&color;
483         this._titleColorDispatchTable[state] = color;
484 
485         // If the current state if equal to the given state we update the layout
486         if (this.getState() == state)
487             this.needsLayout();
488     },
489 
490     /**
491      * Returns the title label used for a state.
492      *
493      * @param state The state that uses the title label. Possible values are described in "CCControlState".
494      * @return {cc.Node} the title label used for a state.
495      */
496     getTitleLabelForState: function (state) {
497         var locTable = this._titleLabelDispatchTable;
498         if (locTable[state])
499             return locTable[state];
500 
501         return locTable[cc.CONTROL_STATE_NORMAL];
502     },
503 
504     /**
505      * <p>Sets the title label to use for the specified state.                                          <br/>
506      * If a property is not specified for a state, the default is to use the CCButtonStateNormal value. </p>
507      *
508      * @param {cc.Node} titleLabel The title label to use for the specified state.
509      * @param {Number} state The state that uses the specified title. The values are described in "CCControlState".
510      */
511     setTitleLabelForState: function (titleLabel, state) {
512         var locTable = this._titleLabelDispatchTable;
513         if (locTable[state]) {
514             var previousLabel = locTable[state];
515             if (previousLabel)
516                 this.removeChild(previousLabel, true);
517         }
518 
519         locTable[state] = titleLabel;
520         titleLabel.setVisible(false);
521         titleLabel.setAnchorPoint(0.5, 0.5);
522         this.addChild(titleLabel, 1);
523 
524         // If the current state if equal to the given state we update the layout
525         if (this.getState() == state)
526             this.needsLayout();
527     },
528 
529     /**
530      * Sets the title TTF filename to use for the specified state.
531      * @param {string} fntFile
532      * @param {Number} state
533      */
534     setTitleTTFForState: function (fntFile, state) {
535         var title = this.getTitleForState(state);
536         if (!title)
537             title = "";
538         this.setTitleLabelForState(cc.LabelTTF.create(title, fntFile, 12), state);
539     },
540 
541     /**
542      * return the title TTF filename to use for the specified state.
543      * @param {Number} state
544      * @returns {string}
545      */
546     getTitleTTFForState: function (state) {
547         var labelTTF = this.getTitleLabelForState(state);
548         if ((labelTTF != null) && (labelTTF instanceof  cc.LabelTTF)) {
549             return labelTTF.getFontName();
550         } else {
551             return "";
552         }
553     },
554 
555     /**
556      * @param {Number} size
557      * @param {Number} state
558      */
559     setTitleTTFSizeForState: function (size, state) {
560         var labelTTF = this.getTitleLabelForState(state);
561         if ((labelTTF != null) && (labelTTF instanceof  cc.LabelTTF)) {
562             labelTTF.setFontSize(size);
563         }
564     },
565 
566     /**
567      * return the font size of LabelTTF to use for the specified state
568      * @param {Number} state
569      * @returns {Number}
570      */
571     getTitleTTFSizeForState: function (state) {
572         var labelTTF = this.getTitleLabelForState(state);
573         if ((labelTTF != null) && (labelTTF instanceof  cc.LabelTTF)) {
574             return labelTTF.getFontSize();
575         }
576         return 0;
577     },
578 
579     /**
580      * Sets the font of the label, changes the label to a CCLabelBMFont if necessary.
581      * @param {string} fntFile The name of the font to change to
582      * @param {Number} state The state that uses the specified fntFile. The values are described in "CCControlState".
583      */
584     setTitleBMFontForState: function (fntFile, state) {
585         var title = this.getTitleForState(state);
586         if (!title)
587             title = "";
588         this.setTitleLabelForState(cc.LabelBMFont.create(title, fntFile), state);
589     },
590 
591     getTitleBMFontForState: function (state) {
592         var labelBMFont = this.getTitleLabelForState(state);
593         if ((labelBMFont != null) && (labelBMFont instanceof  cc.LabelBMFont)) {
594             return labelBMFont.getFntFile();
595         }
596         return "";
597     },
598 
599     /**
600      * Returns the background sprite used for a state.
601      *
602      * @param {Number} state The state that uses the background sprite. Possible values are described in "CCControlState".
603      */
604     getBackgroundSpriteForState: function (state) {
605         var locTable = this._backgroundSpriteDispatchTable;
606         if (locTable[state]) {
607             return locTable[state];
608         }
609         return locTable[cc.CONTROL_STATE_NORMAL];
610     },
611 
612     /**
613      * Sets the background sprite to use for the specified button state.
614      *
615      * @param {Scale9Sprite} sprite The background sprite to use for the specified state.
616      * @param {Number} state The state that uses the specified image. The values are described in "CCControlState".
617      */
618     setBackgroundSpriteForState: function (sprite, state) {
619         var locTable = this._backgroundSpriteDispatchTable;
620         if (locTable[state]) {
621             var previousSprite = locTable[state];
622             if (previousSprite)
623                 this.removeChild(previousSprite, true);
624         }
625 
626         locTable[state] = sprite;
627         sprite.setVisible(false);
628         sprite.setAnchorPoint(0.5, 0.5);
629         this.addChild(sprite);
630 
631         var locPreferredSize = this._preferredSize;
632         if (locPreferredSize.width !== 0 || locPreferredSize.height !== 0) {
633             sprite.setPreferredSize(locPreferredSize);
634         }
635 
636         // If the current state if equal to the given state we update the layout
637         if (this._state === state)
638             this.needsLayout();
639     },
640 
641     /**
642      * Sets the background spriteFrame to use for the specified button state.
643      *
644      * @param {SpriteFrame} spriteFrame The background spriteFrame to use for the specified state.
645      * @param {Number} state The state that uses the specified image. The values are described in "CCControlState".
646      */
647     setBackgroundSpriteFrameForState: function (spriteFrame, state) {
648         var sprite = cc.Scale9Sprite.createWithSpriteFrame(spriteFrame);
649         this.setBackgroundSpriteForState(sprite, state);
650     }
651 });
652 
653 var _p = cc.ControlButton.prototype;
654 
655 // Extended properties
656 /** @expose */
657 _p.adjustBackground;
658 cc.defineGetterSetter(_p, "adjustBackground", _p.getAdjustBackgroundImage, _p.setAdjustBackgroundImage);
659 /** @expose */
660 _p.preferredSize;
661 cc.defineGetterSetter(_p, "preferredSize", _p.getPreferredSize, _p.setPreferredSize);
662 /** @expose */
663 _p.labelAnchor;
664 cc.defineGetterSetter(_p, "labelAnchor", _p.getLabelAnchorPoint, _p.setLabelAnchorPoint);
665 
666 _p = null;
667 
668 cc.ControlButton.create = function (label, backgroundSprite) {
669     var controlButton;
670     if (arguments.length == 0) {
671         controlButton = new cc.ControlButton();
672         if (controlButton && controlButton.init()) {
673             return controlButton;
674         }
675         return null;
676     } else if (arguments.length == 1) {
677         controlButton = new cc.ControlButton();
678         controlButton.initWithBackgroundSprite(arguments[0]);
679     } else if (arguments.length == 2) {
680         controlButton = new cc.ControlButton();
681         controlButton.initWithLabelAndBackgroundSprite(label, backgroundSprite);
682     } else if (arguments.length == 3) {
683         controlButton = new cc.ControlButton();
684         controlButton.initWithTitleAndFontNameAndFontSize(arguments[0], arguments[1], arguments[2]);
685     }
686     return controlButton;
687 };
688 
689 
690