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