1 /**************************************************************************** 2 Copyright (c) 2010-2012 cocos2d-x.org 3 Copyright (c) 2008-2010 Ricardo Quesada 4 Copyright (c) 2011 Zynga Inc. 5 6 http://www.cocos2d-x.org 7 8 Permission is hereby granted, free of charge, to any person obtaining a copy 9 of this software and associated documentation files (the "Software"), to deal 10 in the Software without restriction, including without limitation the rights 11 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 copies of the Software, and to permit persons to whom the Software is 13 furnished to do so, subject to the following conditions: 14 15 The above copyright notice and this permission notice shall be included in 16 all copies or substantial portions of the Software. 17 18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 THE SOFTWARE. 25 ****************************************************************************/ 26 27 28 /** 29 * default size for font size 30 * @constant 31 * @type Number 32 */ 33 cc.ITEM_SIZE = 32; 34 35 cc._globalFontSize = cc.ITEM_SIZE; 36 cc._globalFontName = "Arial"; 37 cc._globalFontNameRelease = false; 38 39 /** 40 * default tag for current item 41 * @constant 42 * @type Number 43 */ 44 cc.CURRENT_ITEM = 0xc0c05001; 45 /** 46 * default tag for zoom action tag 47 * @constant 48 * @type Number 49 */ 50 cc.ZOOM_ACTION_TAG = 0xc0c05002; 51 /** 52 * default tag for normal 53 * @constant 54 * @type Number 55 */ 56 cc.NORMAL_TAG = 8801; 57 58 /** 59 * default selected tag 60 * @constant 61 * @type Number 62 */ 63 cc.SELECTED_TAG = 8802; 64 65 /** 66 * default disabled tag 67 * @constant 68 * @type Number 69 */ 70 cc.DISABLE_TAG = 8803; 71 72 /** 73 * Subclass cc.MenuItem (or any subclass) to create your custom cc.MenuItem objects. 74 * @class 75 * @extends cc.NodeRGBA 76 */ 77 cc.MenuItem = cc.NodeRGBA.extend(/** @lends cc.MenuItem# */{ 78 _target:null, 79 _callback:null, 80 _isSelected:false, 81 _isEnabled:false, 82 83 ctor:function(){ 84 cc.NodeRGBA.prototype.ctor.call(this); 85 this._target = null; 86 this._callback = null; 87 this._isSelected = false; 88 this._isEnabled = false; 89 }, 90 91 /** 92 * MenuItem is selected 93 * @return {Boolean} 94 */ 95 isSelected:function () { 96 return this._isSelected; 97 }, 98 99 setOpacityModifyRGB:function (value) { 100 }, 101 102 isOpacityModifyRGB:function () { 103 return false; 104 }, 105 106 /** 107 * set the target/selector of the menu item 108 * @param {function|String} selector 109 * @param {cc.Node} rec 110 * @deprecated 111 */ 112 setTarget:function (selector, rec) { 113 this._target = rec; 114 this._callback = selector; 115 }, 116 117 /** 118 * MenuItem is Enabled 119 * @return {Boolean} 120 */ 121 isEnabled:function () { 122 return this._isEnabled; 123 }, 124 125 /** 126 * set enable value of MenuItem 127 * @param {Boolean} enable 128 */ 129 setEnabled:function (enable) { 130 this._isEnabled = enable; 131 }, 132 133 /** 134 * @param {function|String} callback 135 * @param {cc.Node} target 136 * @return {Boolean} 137 */ 138 initWithCallback:function (callback, target) { 139 this.setAnchorPoint(0.5, 0.5); 140 this._target = target; 141 this._callback = callback; 142 this._isEnabled = true; 143 this._isSelected = false; 144 return true; 145 }, 146 147 /** 148 * return rect value of cc.MenuItem 149 * @return {cc.Rect} 150 */ 151 rect:function () { 152 var locPosition = this._position, locContentSize = this._contentSize, locAnchorPoint = this._anchorPoint; 153 return cc.rect(locPosition._x - locContentSize._width * locAnchorPoint._x, 154 locPosition._y - locContentSize._height * locAnchorPoint._y, 155 locContentSize._width, locContentSize._height); 156 }, 157 158 /** 159 * same as setIsSelected(true) 160 */ 161 selected:function () { 162 this._isSelected = true; 163 }, 164 165 /** 166 * same as setIsSelected(false) 167 */ 168 unselected:function () { 169 this._isSelected = false; 170 }, 171 172 /** 173 * set the callback to the menu item 174 * @param {function|String} callback 175 * @param {cc.Node} target 176 */ 177 setCallback:function (callback, target) { 178 this._target = target; 179 this._callback = callback; 180 }, 181 182 /** 183 * call the selector with target 184 */ 185 activate:function () { 186 if (this._isEnabled) { 187 var locTarget = this._target, locCallback = this._callback; 188 if(!locCallback) 189 return ; 190 if (locTarget && (typeof(locCallback) == "string")) { 191 locTarget[locCallback](this); 192 } else if (locTarget && (typeof(locCallback) == "function")) { 193 locCallback.call(locTarget, this); 194 } else 195 locCallback(this); 196 } 197 } 198 }); 199 200 /** 201 * creates an empty menu item with target and callback<br/> 202 * Not recommended to use the base class, should use more defined menu item classes 203 * @param {function|String} callback callback 204 * @param {cc.Node} target 205 * @return {cc.MenuItem} 206 */ 207 cc.MenuItem.create = function (callback, target) { 208 var ret = new cc.MenuItem(); 209 ret.initWithCallback(callback,target); 210 return ret; 211 }; 212 213 /** 214 * Any cc.Node that supports the cc.LabelProtocol protocol can be added.<br/> 215 * Supported nodes:<br/> 216 * - cc.BitmapFontAtlas<br/> 217 * - cc.LabelAtlas<br/> 218 * - cc.LabelTTF<br/> 219 * @class 220 * @extends cc.MenuItem 221 */ 222 cc.MenuItemLabel = cc.MenuItem.extend(/** @lends cc.MenuItemLabel# */{ 223 _disabledColor: null, 224 _label: null, 225 _orginalScale: 0, 226 _colorBackup: null, 227 228 ctor: function () { 229 cc.MenuItem.prototype.ctor.call(this); 230 this._disabledColor = null; 231 this._label = null; 232 this._orginalScale = 0; 233 this._colorBackup = null; 234 }, 235 236 /** 237 * @return {cc.Color3B} 238 */ 239 getDisabledColor:function () { 240 return this._disabledColor; 241 }, 242 243 /** 244 * @param {cc.Color3B} color 245 */ 246 setDisabledColor:function (color) { 247 this._disabledColor = color; 248 }, 249 250 /** 251 * return label of MenuItemLabel 252 * @return {cc.Node} 253 */ 254 getLabel:function () { 255 return this._label; 256 }, 257 258 /** 259 * @param {cc.Node} label 260 */ 261 setLabel:function (label) { 262 if (label) { 263 this.addChild(label); 264 label.setAnchorPoint(0, 0); 265 this.setContentSize(label.getContentSize()); 266 } 267 268 if (this._label) { 269 this.removeChild(this._label, true); 270 } 271 272 this._label = label; 273 }, 274 275 /** 276 * @param {Boolean} enabled 277 */ 278 setEnabled:function (enabled) { 279 if (this._isEnabled != enabled) { 280 var locLabel = this._label; 281 if (!enabled) { 282 this._colorBackup = locLabel.getColor(); 283 locLabel.setColor(this._disabledColor); 284 } else { 285 locLabel.setColor(this._colorBackup); 286 } 287 } 288 cc.MenuItem.prototype.setEnabled.call(this, enabled); 289 }, 290 291 /** 292 * @param {Number} opacity from 0-255 293 */ 294 setOpacity:function (opacity) { 295 this._label.setOpacity(opacity); 296 }, 297 298 /** 299 * @return {Number} 300 */ 301 getOpacity:function () { 302 return this._label.getOpacity(); 303 }, 304 305 /** 306 * @param {cc.Color3B} color 307 */ 308 setColor:function (color) { 309 this._label.setColor(color); 310 }, 311 312 /** 313 * @return {cc.Color3B} 314 */ 315 getColor:function () { 316 return this._label.getColor(); 317 }, 318 319 /** 320 * @param {cc.Node} label 321 * @param {function|String} selector 322 * @param {cc.Node} target 323 * @return {Boolean} 324 */ 325 initWithLabel:function (label, selector, target) { 326 this.initWithCallback(selector, target); 327 this._originalScale = 1.0; 328 this._colorBackup = cc.white(); 329 this._disabledColor = cc.c3b(126, 126, 126); 330 this.setLabel(label); 331 332 this.setCascadeColorEnabled(true); 333 this.setCascadeOpacityEnabled(true); 334 335 return true; 336 }, 337 338 /** 339 * @param {String} label 340 */ 341 setString:function (label) { 342 this._label.setString(label); 343 this.setContentSize(this._label.getContentSize()); 344 }, 345 346 /** 347 * activate the menu item 348 */ 349 activate:function () { 350 if (this._isEnabled) { 351 this.stopAllActions(); 352 this.setScale(this._originalScale); 353 cc.MenuItem.prototype.activate.call(this); 354 } 355 }, 356 357 /** 358 * menu item is selected (runs callback) 359 */ 360 selected:function () { 361 if (this._isEnabled) { 362 cc.MenuItem.prototype.selected.call(this); 363 364 var action = this.getActionByTag(cc.ZOOM_ACTION_TAG); 365 if (action) 366 this.stopAction(action); 367 else 368 this._originalScale = this.getScale(); 369 370 var zoomAction = cc.ScaleTo.create(0.1, this._originalScale * 1.2); 371 zoomAction.setTag(cc.ZOOM_ACTION_TAG); 372 this.runAction(zoomAction); 373 } 374 }, 375 376 /** 377 * menu item goes back to unselected state 378 */ 379 unselected:function () { 380 if (this._isEnabled) { 381 cc.MenuItem.prototype.unselected.call(this); 382 this.stopActionByTag(cc.ZOOM_ACTION_TAG); 383 var zoomAction = cc.ScaleTo.create(0.1, this._originalScale); 384 zoomAction.setTag(cc.ZOOM_ACTION_TAG); 385 this.runAction(zoomAction); 386 } 387 } 388 }); 389 390 /** 391 * @param {cc.Node} label 392 * @param {function|String|Null} [selector=] 393 * @param {cc.Node|Null} [target=] 394 * @return {cc.MenuItemLabel} 395 */ 396 cc.MenuItemLabel.create = function (label, selector, target) { 397 var ret = new cc.MenuItemLabel(); 398 ret.initWithLabel(label, selector, target); 399 return ret; 400 }; 401 402 /** 403 * Helper class that creates a MenuItemLabel class with a LabelAtlas 404 * @class 405 * @extends cc.MenuItemLabel 406 */ 407 cc.MenuItemAtlasFont = cc.MenuItemLabel.extend(/** @lends cc.MenuItemAtlasFont# */{ 408 /** 409 * @param {String} value 410 * @param {String} charMapFile 411 * @param {Number} itemWidth 412 * @param {Number} itemHeight 413 * @param {String} startCharMap a single character 414 * @param {function|String|Null} callback 415 * @param {cc.Node|Null} target 416 * @return {Boolean} 417 */ 418 initWithString:function (value, charMapFile, itemWidth, itemHeight, startCharMap, callback, target) { 419 if(!value || value.length == 0) 420 throw "cc.MenuItemAtlasFont.initWithString(): value should be non-null and its length should be greater than 0"; 421 422 var label = new cc.LabelAtlas(); 423 label.initWithString(value, charMapFile, itemWidth, itemHeight, startCharMap); 424 if (this.initWithLabel(label, callback, target)) { 425 // do something ? 426 } 427 return true; 428 } 429 }); 430 431 /** 432 * create menu item from string with font 433 * @param {String} value the text to display 434 * @param {String} charMapFile the character map file 435 * @param {Number} itemWidth 436 * @param {Number} itemHeight 437 * @param {String} startCharMap a single character 438 * @param {function|String|Null} [callback=null] 439 * @param {cc.Node|Null} [target=] 440 * @return {cc.MenuItemAtlasFont} 441 * @example 442 * // Example 443 * var item = cc.MenuItemAtlasFont.create('text to display', 'font.fnt', 12, 32, ' ') 444 * 445 * //OR 446 * var item = cc.MenuItemAtlasFont.create('text to display', 'font.fnt', 12, 32, ' ', game.run, game) 447 */ 448 cc.MenuItemAtlasFont.create = function (value, charMapFile, itemWidth, itemHeight, startCharMap, callback, target) { 449 var ret = new cc.MenuItemAtlasFont(); 450 ret.initWithString(value, charMapFile, itemWidth, itemHeight, startCharMap, callback, target); 451 return ret; 452 }; 453 454 /** 455 * Helper class that creates a CCMenuItemLabel class with a Label 456 * @class 457 * @extends cc.MenuItemLabel 458 */ 459 cc.MenuItemFont = cc.MenuItemLabel.extend(/** @lends cc.MenuItemFont# */{ 460 _fontSize:null, 461 _fontName:null, 462 463 ctor:function(){ 464 cc.MenuItemLabel.prototype.ctor.call(this); 465 this._fontSize = 0; 466 this._fontName = ""; 467 }, 468 469 /** 470 * @param {String} value text for the menu item 471 * @param {function|String} callback 472 * @param {cc.Node} target 473 * @return {Boolean} 474 */ 475 initWithString:function (value, callback, target) { 476 if(!value || value.length == 0) 477 throw "Value should be non-null and its length should be greater than 0"; 478 479 this._fontName = cc._globalFontName; 480 this._fontSize = cc._globalFontSize; 481 482 var label = cc.LabelTTF.create(value, this._fontName, this._fontSize); 483 if (this.initWithLabel(label, callback, target)) { 484 // do something ? 485 } 486 return true; 487 }, 488 489 /** 490 * @param {Number} s 491 */ 492 setFontSize:function (s) { 493 this._fontSize = s; 494 this._recreateLabel(); 495 }, 496 497 /** 498 * 499 * @return {Number} 500 */ 501 fontSize:function () { 502 return this._fontSize; 503 }, 504 505 /** 506 * @param {String} name 507 */ 508 setFontName:function (name) { 509 this._fontName = name; 510 this._recreateLabel(); 511 }, 512 513 /** 514 * @return {String} 515 */ 516 fontName:function () { 517 return this._fontName; 518 }, 519 520 _recreateLabel:function () { 521 var label = cc.LabelTTF.create(this._label.getString(), 522 this._fontName, this._fontSize); 523 this.setLabel(label); 524 } 525 }); 526 527 /** 528 * a shared function to set the fontSize for menuitem font 529 * @param {Number} fontSize 530 */ 531 cc.MenuItemFont.setFontSize = function (fontSize) { 532 cc._globalFontSize = fontSize; 533 }; 534 535 /** 536 * a shared function to get the font size for menuitem font 537 * @return {Number} 538 */ 539 cc.MenuItemFont.fontSize = function () { 540 return cc._globalFontSize; 541 }; 542 543 /** 544 * a shared function to set the fontsize for menuitem font 545 * @param name 546 */ 547 cc.MenuItemFont.setFontName = function (name) { 548 if (cc._globalFontNameRelease) { 549 cc._globalFontName = ''; 550 } 551 cc._globalFontName = name; 552 cc._globalFontNameRelease = true; 553 }; 554 555 /** 556 * a shared function to get the font name for menuitem font 557 * @return {String} 558 */ 559 cc.MenuItemFont.fontName = function () { 560 return cc._globalFontName; 561 }; 562 563 /** 564 * create a menu item from string 565 * @param {String} value the text to display 566 * @param {String|function|Null} callback the callback to run, either in function name or pass in the actual function 567 * @param {cc.Node|Null} target the target to run callback 568 * @return {cc.MenuItemFont} 569 * @example 570 * // Example 571 * var item = cc.MenuItemFont.create("Game start", 'start', Game) 572 * //creates a menu item from string "Game start", and when clicked, it will run Game.start() 573 * 574 * var item = cc.MenuItemFont.create("Game start", game.start, Game)//same as above 575 * 576 * var item = cc.MenuItemFont.create("i do nothing")//create a text menu item that does nothing 577 * 578 * //you can set font size and name before or after 579 * cc.MenuItemFont.setFontName('my Fancy Font'); 580 * cc.MenuItemFont.setFontSize(62); 581 */ 582 cc.MenuItemFont.create = function (value, callback, target) { 583 var ret = new cc.MenuItemFont(); 584 ret.initWithString(value, callback, target); 585 return ret; 586 }; 587 588 589 /** 590 * CCMenuItemSprite accepts CCNode<CCRGBAProtocol> objects as items.<br/> 591 * The images has 3 different states:<br/> 592 * - unselected image<br/> 593 * - selected image<br/> 594 * - disabled image<br/> 595 * @class 596 * @extends cc.MenuItem 597 */ 598 cc.MenuItemSprite = cc.MenuItem.extend(/** @lends cc.MenuItemSprite# */{ 599 _normalImage:null, 600 _selectedImage:null, 601 _disabledImage:null, 602 603 ctor: function(){ 604 cc.MenuItem.prototype.ctor.call(this); 605 this._normalImage = null; 606 this._selectedImage = null; 607 this._disabledImage = null; 608 }, 609 610 /** 611 * @return {cc.Sprite} 612 */ 613 getNormalImage:function () { 614 return this._normalImage; 615 }, 616 617 /** 618 * @param {cc.Sprite} normalImage 619 */ 620 setNormalImage:function (normalImage) { 621 if (this._normalImage == normalImage) { 622 return; 623 } 624 if (normalImage) { 625 this.addChild(normalImage, 0, cc.NORMAL_TAG); 626 normalImage.setAnchorPoint(0, 0); 627 } 628 if (this._normalImage) { 629 this.removeChild(this._normalImage, true); 630 } 631 632 this._normalImage = normalImage; 633 this.setContentSize(this._normalImage.getContentSize()); 634 this._updateImagesVisibility(); 635 636 if (normalImage.textureLoaded && !normalImage.textureLoaded()) { 637 normalImage.addLoadedEventListener(function (sender) { 638 this.setContentSize(sender.getContentSize()); 639 }, this); 640 } 641 }, 642 643 /** 644 * @return {cc.Sprite} 645 */ 646 getSelectedImage:function () { 647 return this._selectedImage; 648 }, 649 650 /** 651 * @param {cc.Sprite} selectedImage 652 */ 653 setSelectedImage:function (selectedImage) { 654 if (this._selectedImage == selectedImage) 655 return; 656 657 if (selectedImage) { 658 this.addChild(selectedImage, 0, cc.SELECTED_TAG); 659 selectedImage.setAnchorPoint(0, 0); 660 } 661 662 if (this._selectedImage) { 663 this.removeChild(this._selectedImage, true); 664 } 665 666 this._selectedImage = selectedImage; 667 this._updateImagesVisibility(); 668 }, 669 670 /** 671 * @return {cc.Sprite} 672 */ 673 getDisabledImage:function () { 674 return this._disabledImage; 675 }, 676 677 /** 678 * @param {cc.Sprite} disabledImage 679 */ 680 setDisabledImage:function (disabledImage) { 681 if (this._disabledImage == disabledImage) 682 return; 683 684 if (disabledImage) { 685 this.addChild(disabledImage, 0, cc.DISABLE_TAG); 686 disabledImage.setAnchorPoint(0, 0); 687 } 688 689 if (this._disabledImage) 690 this.removeChild(this._disabledImage, true); 691 692 this._disabledImage = disabledImage; 693 this._updateImagesVisibility(); 694 }, 695 696 /** 697 * @param {cc.Node} normalSprite 698 * @param {cc.Node} selectedSprite 699 * @param {cc.Node} disabledSprite 700 * @param {function|String} callback 701 * @param {cc.Node} target 702 * @return {Boolean} 703 */ 704 initWithNormalSprite:function (normalSprite, selectedSprite, disabledSprite, callback, target) { 705 this.initWithCallback(callback, target); 706 this.setNormalImage(normalSprite); 707 this.setSelectedImage(selectedSprite); 708 this.setDisabledImage(disabledSprite); 709 var locNormalImage = this._normalImage; 710 if (locNormalImage) { 711 this.setContentSize(locNormalImage.getContentSize()); 712 713 if (locNormalImage.textureLoaded && !locNormalImage.textureLoaded()) { 714 locNormalImage.addLoadedEventListener(function (sender) { 715 this.setContentSize(sender.getContentSize()); 716 this.setCascadeColorEnabled(true); 717 this.setCascadeOpacityEnabled(true); 718 }, this); 719 } 720 } 721 this.setCascadeColorEnabled(true); 722 this.setCascadeOpacityEnabled(true); 723 return true; 724 }, 725 726 /** 727 * @param {cc.Color3B} color 728 */ 729 setColor:function (color) { 730 this._normalImage.setColor(color); 731 732 if (this._selectedImage) 733 this._selectedImage.setColor(color); 734 735 if (this._disabledImage) 736 this._disabledImage.setColor(color); 737 }, 738 739 /** 740 * @return {cc.Color3B} 741 */ 742 getColor:function () { 743 return this._normalImage.getColor(); 744 }, 745 746 /** 747 * @param {Number} opacity 0 - 255 748 */ 749 setOpacity:function (opacity) { 750 this._normalImage.setOpacity(opacity); 751 752 if (this._selectedImage) 753 this._selectedImage.setOpacity(opacity); 754 755 if (this._disabledImage) 756 this._disabledImage.setOpacity(opacity); 757 }, 758 759 /** 760 * @return {Number} opacity from 0 - 255 761 */ 762 getOpacity:function () { 763 return this._normalImage.getOpacity(); 764 }, 765 766 /** 767 * menu item is selected (runs callback) 768 */ 769 selected:function () { 770 cc.MenuItem.prototype.selected.call(this); 771 if (this._normalImage) { 772 if (this._disabledImage) 773 this._disabledImage.setVisible(false); 774 775 if (this._selectedImage) { 776 this._normalImage.setVisible(false); 777 this._selectedImage.setVisible(true); 778 } else 779 this._normalImage.setVisible(true); 780 } 781 }, 782 783 /** 784 * menu item goes back to unselected state 785 */ 786 unselected:function () { 787 cc.MenuItem.prototype.unselected.call(this); 788 if (this._normalImage) { 789 this._normalImage.setVisible(true); 790 791 if (this._selectedImage) 792 this._selectedImage.setVisible(false); 793 794 if (this._disabledImage) 795 this._disabledImage.setVisible(false); 796 } 797 }, 798 799 /** 800 * @param {Boolean} bEnabled 801 */ 802 setEnabled:function (bEnabled) { 803 if (this._isEnabled != bEnabled) { 804 cc.MenuItem.prototype.setEnabled.call(this, bEnabled); 805 this._updateImagesVisibility(); 806 } 807 }, 808 809 _updateImagesVisibility:function () { 810 var locNormalImage = this._normalImage, locSelImage = this._selectedImage, locDisImage = this._disabledImage; 811 if (this._isEnabled) { 812 if (locNormalImage) 813 locNormalImage.setVisible(true); 814 if (locSelImage) 815 locSelImage.setVisible(false); 816 if (locDisImage) 817 locDisImage.setVisible(false); 818 } else { 819 if (locDisImage) { 820 if (locNormalImage) 821 locNormalImage.setVisible(false); 822 if (locSelImage) 823 locSelImage.setVisible(false); 824 if (locDisImage) 825 locDisImage.setVisible(true); 826 } else { 827 if (locNormalImage) 828 locNormalImage.setVisible(true); 829 if (locSelImage) 830 locSelImage.setVisible(false); 831 } 832 } 833 } 834 }); 835 836 /** 837 * create a menu item from sprite 838 * @param {Image} normalSprite normal state image 839 * @param {Image|Null} selectedSprite selected state image 840 * @param {Image|cc.Node|Null} three disabled state image OR target node 841 * @param {String|function|cc.Node|Null} four callback function name in string or actual function, OR target Node 842 * @param {String|function|Null} five callback function name in string or actual function 843 * @return {cc.MenuItemSprite} 844 * @example 845 * // Example 846 * var item = cc.MenuItemSprite.create(normalImage)//create a menu item from a sprite with no functionality 847 * 848 * var item = cc.MenuItemSprite.create(normalImage, selectedImage)//create a menu Item, nothing will happen when clicked 849 * 850 * var item = cc.MenuItemSprite.create(normalImage, SelectedImage, disabledImage)//same above, but with disabled state image 851 * 852 * var item = cc.MenuItemSprite.create(normalImage, SelectedImage, 'callback', targetNode)//create a menu item, when clicked runs targetNode.callback() 853 * 854 * var item = cc.MenuItemSprite.create(normalImage, SelectedImage, disabledImage, targetNode.callback, targetNode) 855 * //same as above, but with disabled image, and passing in callback function 856 */ 857 cc.MenuItemSprite.create = function (normalSprite, selectedSprite, three, four, five) { 858 var len = arguments.length; 859 normalSprite = arguments[0]; 860 selectedSprite = arguments[1]; 861 var disabledImage, target, callback; 862 var ret = new cc.MenuItemSprite(); 863 //when you send 4 arguments, five is undefined 864 if (len == 5) { 865 disabledImage = arguments[2]; 866 callback = arguments[3]; 867 target = arguments[4]; 868 } else if (len == 4 && typeof arguments[3] === "function") { 869 disabledImage = arguments[2]; 870 callback = arguments[3]; 871 } else if (len == 4 && typeof arguments[2] === "function") { 872 target = arguments[3]; 873 callback = arguments[2]; 874 } else if (len <= 2) { 875 disabledImage = arguments[2]; 876 } 877 ret.initWithNormalSprite(normalSprite, selectedSprite, disabledImage, callback, target); 878 return ret; 879 }; 880 881 /** 882 * cc.MenuItemImage accepts images as items.<br/> 883 * The images has 3 different states:<br/> 884 * - unselected image<br/> 885 * - selected image<br/> 886 * - disabled image<br/> 887 * <br/> 888 * For best results try that all images are of the same size<br/> 889 * @class 890 * @extends cc.MenuItemSprite 891 */ 892 cc.MenuItemImage = cc.MenuItemSprite.extend(/** @lends cc.MenuItemImage# */{ 893 /** 894 * sets the sprite frame for the normal image 895 * @param {cc.SpriteFrame} frame 896 */ 897 setNormalSpriteFrame:function (frame) { 898 this.setNormalImage(cc.Sprite.createWithSpriteFrame(frame)); 899 }, 900 901 /** 902 * sets the sprite frame for the selected image 903 * @param {cc.SpriteFrame} frame 904 */ 905 setSelectedSpriteFrame:function (frame) { 906 this.setSelectedImage(cc.Sprite.createWithSpriteFrame(frame)); 907 }, 908 909 /** 910 * sets the sprite frame for the disabled image 911 * @param {cc.SpriteFrame} frame 912 */ 913 setDisabledSpriteFrame:function (frame) { 914 this.setDisabledImage(cc.Sprite.createWithSpriteFrame(frame)); 915 }, 916 917 /** 918 * @param {string|null} normalImage 919 * @param {string|null} selectedImage 920 * @param {string|null} disabledImage 921 * @param {function|string|null} callback 922 * @param {cc.Node|null} target 923 * @returns {boolean} 924 */ 925 initWithNormalImage:function (normalImage, selectedImage, disabledImage, callback, target) { 926 var normalSprite = null; 927 var selectedSprite = null; 928 var disabledSprite = null; 929 930 if (normalImage) { 931 normalSprite = cc.Sprite.create(normalImage); 932 } 933 if (selectedImage) { 934 selectedSprite = cc.Sprite.create(selectedImage); 935 } 936 if (disabledImage) { 937 disabledSprite = cc.Sprite.create(disabledImage); 938 } 939 return this.initWithNormalSprite(normalSprite, selectedSprite, disabledSprite, callback, target); 940 } 941 }); 942 943 /** 944 * creates a new menu item image 945 * @param {String} normalImage file name for normal state 946 * @param {String} selectedImage image for selected state 947 * @param {String|cc.Node} three Disabled image OR callback function 948 * @param {String|function|Null} [four] callback function, either name in string or pass the whole function OR the target 949 * @param {cc.Node|String|function|Null} [five] cc.Node target to run callback when clicked 950 * @return {cc.MenuItemImage} 951 * @example 952 * // Example 953 * //create a dom menu item with normal and selected state, when clicked it will run the run function from gameScene object 954 * var item = cc.MenuItemImage.create('normal.png', 'selected.png', 'run', gameScene) 955 * 956 * //same as above, but pass in the actual function and disabled image 957 * var item = cc.MenuItemImage.create('normal.png', 'selected.png', 'disabled.png', gameScene.run, gameScene) 958 */ 959 cc.MenuItemImage.create = function (normalImage, selectedImage, three, four, five) { 960 if (arguments.length == 0) { 961 return cc.MenuItemImage.create(null, null, null, null, null); 962 } 963 if (arguments.length == 3) { 964 return cc.MenuItemImage.create(normalImage, selectedImage, null, three, null); 965 } 966 if (arguments.length == 4) { 967 return cc.MenuItemImage.create(normalImage, selectedImage, null, three, four); 968 } 969 var ret = new cc.MenuItemImage(); 970 if (ret.initWithNormalImage(normalImage, selectedImage, three, four, five)) 971 return ret; 972 return null; 973 }; 974 975 976 /** 977 * A simple container class that "toggles" it's inner items<br/> 978 * The inner items can be any MenuItem 979 * @class 980 * @extends cc.MenuItem 981 */ 982 cc.MenuItemToggle = cc.MenuItem.extend(/** @lends cc.MenuItemToggle# */{ 983 _selectedIndex:0, 984 _subItems:null, 985 _opacity:null, 986 _color:null, 987 988 ctor: function(){ 989 cc.MenuItem.prototype.ctor.call(this); 990 this._selectedIndex = 0; 991 this._subItems = []; 992 this._opacity = 0; 993 this._color = cc.white(); 994 }, 995 996 /** 997 * @return {Number} 998 */ 999 getOpacity:function () { 1000 return this._opacity; 1001 }, 1002 1003 /** 1004 * @param {Number} Opacity 1005 */ 1006 setOpacity:function (Opacity) { 1007 this._opacity = Opacity; 1008 if (this._subItems && this._subItems.length > 0) { 1009 for (var it = 0; it < this._subItems.length; it++) { 1010 this._subItems[it].setOpacity(Opacity); 1011 } 1012 } 1013 }, 1014 1015 /** 1016 * @return {cc.Color3B} 1017 */ 1018 getColor:function () { 1019 return this._color; 1020 }, 1021 1022 /** 1023 * @param {cc.Color3B} Color 1024 */ 1025 setColor:function (Color) { 1026 this._color = Color; 1027 if (this._subItems && this._subItems.length > 0) { 1028 for (var it = 0; it < this._subItems.length; it++) { 1029 this._subItems[it].setColor(Color); 1030 } 1031 } 1032 }, 1033 1034 /** 1035 * @return {Number} 1036 */ 1037 getSelectedIndex:function () { 1038 return this._selectedIndex; 1039 }, 1040 1041 /** 1042 * @param {Number} SelectedIndex 1043 */ 1044 setSelectedIndex:function (SelectedIndex) { 1045 if (SelectedIndex != this._selectedIndex) { 1046 this._selectedIndex = SelectedIndex; 1047 var currItem = this.getChildByTag(cc.CURRENT_ITEM); 1048 if (currItem) 1049 currItem.removeFromParent(false); 1050 1051 var item = this._subItems[this._selectedIndex]; 1052 this.addChild(item, 0, cc.CURRENT_ITEM); 1053 var s = item.getContentSize(); 1054 this.setContentSize(s); 1055 item.setPosition(s.width / 2, s.height / 2); 1056 } 1057 }, 1058 1059 /** 1060 * similar to get children 1061 * @return {cc.MenuItem} 1062 */ 1063 getSubItems:function () { 1064 return this._subItems; 1065 }, 1066 1067 /** 1068 * @param {cc.MenuItem} SubItems 1069 */ 1070 setSubItems:function (SubItems) { 1071 this._subItems = SubItems; 1072 }, 1073 1074 /** 1075 * @param {cc.MenuItem} args[0...last-2] the rest in the array are cc.MenuItems 1076 * @param {function|String} args[last-1] the second item in the args array is the callback 1077 * @param {cc.Node} args[last] the first item in the args array is a target 1078 * @return {Boolean} 1079 */ 1080 initWithItems:function (args) { 1081 var l = args.length; 1082 // passing callback. 1083 if (typeof args[args.length-2] === 'function') { 1084 this.initWithCallback( args[args.length-2], args[args.length-1] ); 1085 l = l-2; 1086 } else if(typeof args[args.length-1] === 'function'){ 1087 this.initWithCallback( args[args.length-1], null ); 1088 l = l-1; 1089 } else { 1090 this.initWithCallback(null, null); 1091 } 1092 1093 var locSubItems = this._subItems; 1094 locSubItems.length = 0; 1095 for (var i = 0; i < l; i++) { 1096 if (args[i]) 1097 locSubItems.push(args[i]); 1098 } 1099 this._selectedIndex = cc.UINT_MAX; 1100 this.setSelectedIndex(0); 1101 1102 this.setCascadeColorEnabled(true); 1103 this.setCascadeOpacityEnabled(true); 1104 1105 return true; 1106 }, 1107 1108 /** 1109 * @param {cc.MenuItem} item 1110 */ 1111 addSubItem:function (item) { 1112 this._subItems.push(item); 1113 }, 1114 1115 /** 1116 * activate the menu item 1117 */ 1118 activate:function () { 1119 // update index 1120 if (this._isEnabled) { 1121 var newIndex = (this._selectedIndex + 1) % this._subItems.length; 1122 this.setSelectedIndex(newIndex); 1123 } 1124 cc.MenuItem.prototype.activate.call(this); 1125 }, 1126 1127 /** 1128 * menu item is selected (runs callback) 1129 */ 1130 selected:function () { 1131 cc.MenuItem.prototype.selected.call(this); 1132 this._subItems[this._selectedIndex].selected(); 1133 }, 1134 1135 /** 1136 * menu item goes back to unselected state 1137 */ 1138 unselected:function () { 1139 cc.MenuItem.prototype.unselected.call(this); 1140 this._subItems[this._selectedIndex].unselected(); 1141 }, 1142 1143 /** 1144 * @param {Boolean} enabled 1145 */ 1146 setEnabled:function (enabled) { 1147 if (this._isEnabled != enabled) { 1148 cc.MenuItem.prototype.setEnabled.call(this, enabled); 1149 var locItems = this._subItems; 1150 if (locItems && locItems.length > 0) { 1151 for (var it = 0; it < locItems.length; it++) 1152 locItems[it].setEnabled(enabled); 1153 } 1154 } 1155 }, 1156 1157 /** 1158 * returns the selected item 1159 * @return {cc.MenuItem} 1160 */ 1161 selectedItem:function () { 1162 return this._subItems[this._selectedIndex]; 1163 }, 1164 1165 onEnter:function () { 1166 cc.Node.prototype.onEnter.call(this); 1167 this.setSelectedIndex(this._selectedIndex); 1168 } 1169 }); 1170 1171 /** 1172 * create a simple container class that "toggles" it's inner items<br/> 1173 * The inner items can be any MenuItem 1174 * @return {cc.MenuItemToggle} 1175 * @example 1176 * // Example 1177 * 1178 * //create a toggle item with 2 menu items (which you can then toggle between them later) 1179 * var toggler = cc.MenuItemToggle.create( cc.MenuItemFont.create("On"), cc.MenuItemFont.create("Off"), this.callback, this) 1180 * //Note: the first param is the target, the second is the callback function, afterwards, you can pass in any number of menuitems 1181 * 1182 * //if you pass only 1 variable, then it must be a cc.MenuItem 1183 * var notYetToggler = cc.MenuItemToggle.create(cc.MenuItemFont.create("On"));//it is useless right now, until you add more stuff to it 1184 * notYetToggler.addSubItem(cc.MenuItemFont.create("Off")); 1185 * //this is useful for constructing a toggler without a callback function (you wish to control the behavior from somewhere else) 1186 */ 1187 cc.MenuItemToggle.create = function (/*Multiple arguments follow*/) { 1188 if((arguments.length > 0) && (arguments[arguments.length-1] == null)) 1189 cc.log("parameters should not be ending with null in Javascript"); 1190 var ret = new cc.MenuItemToggle(); 1191 ret.initWithItems(arguments); 1192 return ret; 1193 }; 1194