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(cc.p(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(cc.p(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 cc.Assert(value != null && value.length != 0, "value length must be greater than 0"); 420 var label = new cc.LabelAtlas(); 421 label.initWithString(value, charMapFile, itemWidth, itemHeight, startCharMap); 422 if (this.initWithLabel(label, callback, target)) { 423 // do something ? 424 } 425 return true; 426 } 427 }); 428 429 /** 430 * create menu item from string with font 431 * @param {String} value the text to display 432 * @param {String} charMapFile the character map file 433 * @param {Number} itemWidth 434 * @param {Number} itemHeight 435 * @param {String} startCharMap a single character 436 * @param {function|String|Null} [callback=null] 437 * @param {cc.Node|Null} [target=] 438 * @return {cc.MenuItemAtlasFont} 439 * @example 440 * // Example 441 * var item = cc.MenuItemAtlasFont.create('text to display', 'font.fnt', 12, 32, ' ') 442 * 443 * //OR 444 * var item = cc.MenuItemAtlasFont.create('text to display', 'font.fnt', 12, 32, ' ', game.run, game) 445 */ 446 cc.MenuItemAtlasFont.create = function (value, charMapFile, itemWidth, itemHeight, startCharMap, callback, target) { 447 var ret = new cc.MenuItemAtlasFont(); 448 ret.initWithString(value, charMapFile, itemWidth, itemHeight, startCharMap, callback, target); 449 return ret; 450 }; 451 452 /** 453 * Helper class that creates a CCMenuItemLabel class with a Label 454 * @class 455 * @extends cc.MenuItemLabel 456 */ 457 cc.MenuItemFont = cc.MenuItemLabel.extend(/** @lends cc.MenuItemFont# */{ 458 _fontSize:null, 459 _fontName:null, 460 461 ctor:function(){ 462 cc.MenuItemLabel.prototype.ctor.call(this); 463 this._fontSize = 0; 464 this._fontName = ""; 465 }, 466 467 /** 468 * @param {String} value text for the menu item 469 * @param {function|String} callback 470 * @param {cc.Node} target 471 * @return {Boolean} 472 */ 473 initWithString:function (value, callback, target) { 474 cc.Assert(value != null && value.length != 0, "Value length must be greater than 0"); 475 476 this._fontName = cc._globalFontName; 477 this._fontSize = cc._globalFontSize; 478 479 var label = cc.LabelTTF.create(value, this._fontName, this._fontSize); 480 if (this.initWithLabel(label, callback, target)) { 481 // do something ? 482 } 483 return true; 484 }, 485 486 /** 487 * @param {Number} s 488 */ 489 setFontSize:function (s) { 490 this._fontSize = s; 491 this._recreateLabel(); 492 }, 493 494 /** 495 * 496 * @return {Number} 497 */ 498 fontSize:function () { 499 return this._fontSize; 500 }, 501 502 /** 503 * @param {String} name 504 */ 505 setFontName:function (name) { 506 this._fontName = name; 507 this._recreateLabel(); 508 }, 509 510 /** 511 * @return {String} 512 */ 513 fontName:function () { 514 return this._fontName; 515 }, 516 517 _recreateLabel:function () { 518 var label = cc.LabelTTF.create(this._label.getString(), 519 this._fontName, this._fontSize); 520 this.setLabel(label); 521 } 522 }); 523 524 /** 525 * a shared function to set the fontSize for menuitem font 526 * @param {Number} fontSize 527 */ 528 cc.MenuItemFont.setFontSize = function (fontSize) { 529 cc._globalFontSize = fontSize; 530 }; 531 532 /** 533 * a shared function to get the font size for menuitem font 534 * @return {Number} 535 */ 536 cc.MenuItemFont.fontSize = function () { 537 return cc._globalFontSize; 538 }; 539 540 /** 541 * a shared function to set the fontsize for menuitem font 542 * @param name 543 */ 544 cc.MenuItemFont.setFontName = function (name) { 545 if (cc._globalFontNameRelease) { 546 cc._globalFontName = ''; 547 } 548 cc._globalFontName = name; 549 cc._globalFontNameRelease = true; 550 }; 551 552 /** 553 * a shared function to get the font name for menuitem font 554 * @return {String} 555 */ 556 cc.MenuItemFont.fontName = function () { 557 return cc._globalFontName; 558 }; 559 560 /** 561 * create a menu item from string 562 * @param {String} value the text to display 563 * @param {String|function|Null} callback the callback to run, either in function name or pass in the actual function 564 * @param {cc.Node|Null} target the target to run callback 565 * @return {cc.MenuItemFont} 566 * @example 567 * // Example 568 * var item = cc.MenuItemFont.create("Game start", 'start', Game) 569 * //creates a menu item from string "Game start", and when clicked, it will run Game.start() 570 * 571 * var item = cc.MenuItemFont.create("Game start", game.start, Game)//same as above 572 * 573 * var item = cc.MenuItemFont.create("i do nothing")//create a text menu item that does nothing 574 * 575 * //you can set font size and name before or after 576 * cc.MenuItemFont.setFontName('my Fancy Font'); 577 * cc.MenuItemFont.setFontSize(62); 578 */ 579 cc.MenuItemFont.create = function (value, callback, target) { 580 var ret = new cc.MenuItemFont(); 581 ret.initWithString(value, callback, target); 582 return ret; 583 }; 584 585 586 /** 587 * CCMenuItemSprite accepts CCNode<CCRGBAProtocol> objects as items.<br/> 588 * The images has 3 different states:<br/> 589 * - unselected image<br/> 590 * - selected image<br/> 591 * - disabled image<br/> 592 * @class 593 * @extends cc.MenuItem 594 */ 595 cc.MenuItemSprite = cc.MenuItem.extend(/** @lends cc.MenuItemSprite# */{ 596 _normalImage:null, 597 _selectedImage:null, 598 _disabledImage:null, 599 600 ctor: function(){ 601 cc.MenuItem.prototype.ctor.call(this); 602 this._normalImage = null; 603 this._selectedImage = null; 604 this._disabledImage = null; 605 }, 606 607 /** 608 * @return {cc.Sprite} 609 */ 610 getNormalImage:function () { 611 return this._normalImage; 612 }, 613 614 /** 615 * @param {cc.Sprite} normalImage 616 */ 617 setNormalImage:function (normalImage) { 618 if (this._normalImage == normalImage) { 619 return; 620 } 621 if (normalImage) { 622 this.addChild(normalImage, 0, cc.NORMAL_TAG); 623 normalImage.setAnchorPoint(cc.p(0, 0)); 624 } 625 if (this._normalImage) { 626 this.removeChild(this._normalImage, true); 627 } 628 629 this._normalImage = normalImage; 630 if(normalImage.textureLoaded()){ 631 this.setContentSize(this._normalImage.getContentSize()); 632 this._updateImagesVisibility(); 633 } else { 634 normalImage.addLoadedEventListener(function(sender){ 635 this.setContentSize(sender.getContentSize()); 636 this._updateImagesVisibility(); 637 }, this); 638 } 639 }, 640 641 /** 642 * @return {cc.Sprite} 643 */ 644 getSelectedImage:function () { 645 return this._selectedImage; 646 }, 647 648 /** 649 * @param {cc.Sprite} selectedImage 650 */ 651 setSelectedImage:function (selectedImage) { 652 if (this._selectedImage == selectedImage) 653 return; 654 655 if (selectedImage) { 656 this.addChild(selectedImage, 0, cc.SELECTED_TAG); 657 selectedImage.setAnchorPoint(cc.p(0, 0)); 658 } 659 660 if (this._selectedImage) { 661 this.removeChild(this._selectedImage, true); 662 } 663 664 this._selectedImage = selectedImage; 665 if(selectedImage.textureLoaded()){ 666 this._updateImagesVisibility(); 667 } else { 668 selectedImage.addLoadedEventListener(function(sender){ 669 this._updateImagesVisibility(); 670 }, this); 671 } 672 }, 673 674 /** 675 * @return {cc.Sprite} 676 */ 677 getDisabledImage:function () { 678 return this._disabledImage; 679 }, 680 681 /** 682 * @param {cc.Sprite} disabledImage 683 */ 684 setDisabledImage:function (disabledImage) { 685 if (this._disabledImage == disabledImage) 686 return; 687 688 if (disabledImage) { 689 this.addChild(disabledImage, 0, cc.DISABLE_TAG); 690 disabledImage.setAnchorPoint(cc.p(0, 0)); 691 } 692 693 if (this._disabledImage) 694 this.removeChild(this._disabledImage, true); 695 696 this._disabledImage = disabledImage; 697 if(disabledImage.textureLoaded()){ 698 this._updateImagesVisibility(); 699 } else { 700 disabledImage.addLoadedEventListener(function(sender){ 701 this._updateImagesVisibility(); 702 }, this); 703 } 704 }, 705 706 /** 707 * @param {cc.Node} normalSprite 708 * @param {cc.Node} selectedSprite 709 * @param {cc.Node} disabledSprite 710 * @param {function|String} callback 711 * @param {cc.Node} target 712 * @return {Boolean} 713 */ 714 initWithNormalSprite:function (normalSprite, selectedSprite, disabledSprite, callback, target) { 715 this.initWithCallback(callback, target); 716 this.setNormalImage(normalSprite); 717 this.setSelectedImage(selectedSprite); 718 this.setDisabledImage(disabledSprite); 719 var locNormalImage = this._normalImage; 720 if (locNormalImage){ 721 if(locNormalImage.textureLoaded()){ 722 this.setContentSize(locNormalImage.getContentSize()); 723 this.setCascadeColorEnabled(true); 724 this.setCascadeOpacityEnabled(true); 725 } else{ 726 locNormalImage.addLoadedEventListener(function(sender){ 727 this.setContentSize(sender.getContentSize()); 728 this.setCascadeColorEnabled(true); 729 this.setCascadeOpacityEnabled(true); 730 }, this); 731 } 732 } 733 734 735 return true; 736 }, 737 738 /** 739 * @param {cc.Color3B} color 740 */ 741 setColor:function (color) { 742 this._normalImage.setColor(color); 743 744 if (this._selectedImage) 745 this._selectedImage.setColor(color); 746 747 if (this._disabledImage) 748 this._disabledImage.setColor(color); 749 }, 750 751 /** 752 * @return {cc.Color3B} 753 */ 754 getColor:function () { 755 return this._normalImage.getColor(); 756 }, 757 758 /** 759 * @param {Number} opacity 0 - 255 760 */ 761 setOpacity:function (opacity) { 762 this._normalImage.setOpacity(opacity); 763 764 if (this._selectedImage) 765 this._selectedImage.setOpacity(opacity); 766 767 if (this._disabledImage) 768 this._disabledImage.setOpacity(opacity); 769 }, 770 771 /** 772 * @return {Number} opacity from 0 - 255 773 */ 774 getOpacity:function () { 775 return this._normalImage.getOpacity(); 776 }, 777 778 /** 779 * menu item is selected (runs callback) 780 */ 781 selected:function () { 782 cc.MenuItem.prototype.selected.call(this); 783 if (this._normalImage) { 784 if (this._disabledImage) 785 this._disabledImage.setVisible(false); 786 787 if (this._selectedImage) { 788 this._normalImage.setVisible(false); 789 this._selectedImage.setVisible(true); 790 } else 791 this._normalImage.setVisible(true); 792 } 793 }, 794 795 /** 796 * menu item goes back to unselected state 797 */ 798 unselected:function () { 799 cc.MenuItem.prototype.unselected.call(this); 800 if (this._normalImage) { 801 this._normalImage.setVisible(true); 802 803 if (this._selectedImage) 804 this._selectedImage.setVisible(false); 805 806 if (this._disabledImage) 807 this._disabledImage.setVisible(false); 808 } 809 }, 810 811 /** 812 * @param {Boolean} bEnabled 813 */ 814 setEnabled:function (bEnabled) { 815 if (this._isEnabled != bEnabled) { 816 cc.MenuItem.prototype.setEnabled.call(this, bEnabled); 817 this._updateImagesVisibility(); 818 } 819 }, 820 821 _updateImagesVisibility:function () { 822 var locNormalImage = this._normalImage, locSelImage = this._selectedImage, locDisImage = this._disabledImage; 823 if (this._isEnabled) { 824 if (locNormalImage) 825 locNormalImage.setVisible(true); 826 if (locSelImage) 827 locSelImage.setVisible(false); 828 if (locDisImage) 829 locDisImage.setVisible(false); 830 } else { 831 if (locDisImage) { 832 if (locNormalImage) 833 locNormalImage.setVisible(false); 834 if (locSelImage) 835 locSelImage.setVisible(false); 836 if (locDisImage) 837 locDisImage.setVisible(true); 838 } else { 839 if (locNormalImage) 840 locNormalImage.setVisible(true); 841 if (locSelImage) 842 locSelImage.setVisible(false); 843 } 844 } 845 } 846 }); 847 848 /** 849 * create a menu item from sprite 850 * @param {Image} normalSprite normal state image 851 * @param {Image|Null} selectedSprite selected state image 852 * @param {Image|cc.Node|Null} three disabled state image OR target node 853 * @param {String|function|cc.Node|Null} four callback function name in string or actual function, OR target Node 854 * @param {String|function|Null} five callback function name in string or actual function 855 * @return {cc.MenuItemSprite} 856 * @example 857 * // Example 858 * var item = cc.MenuItemSprite.create(normalImage)//create a menu item from a sprite with no functionality 859 * 860 * var item = cc.MenuItemSprite.create(normalImage, selectedImage)//create a menu Item, nothing will happen when clicked 861 * 862 * var item = cc.MenuItemSprite.create(normalImage, SelectedImage, disabledImage)//same above, but with disabled state image 863 * 864 * var item = cc.MenuItemSprite.create(normalImage, SelectedImage, 'callback', targetNode)//create a menu item, when clicked runs targetNode.callback() 865 * 866 * var item = cc.MenuItemSprite.create(normalImage, SelectedImage, disabledImage, targetNode.callback, targetNode) 867 * //same as above, but with disabled image, and passing in callback function 868 */ 869 cc.MenuItemSprite.create = function (normalSprite, selectedSprite, three, four, five) { 870 var len = arguments.length; 871 normalSprite = arguments[0]; 872 selectedSprite = arguments[1]; 873 var disabledImage, target, callback; 874 var ret = new cc.MenuItemSprite(); 875 //when you send 4 arguments, five is undefined 876 if (len == 5) { 877 disabledImage = arguments[2]; 878 callback = arguments[3]; 879 target = arguments[4]; 880 } else if (len == 4 && typeof arguments[3] === "function") { 881 disabledImage = arguments[2]; 882 callback = arguments[3]; 883 } else if (len == 4 && typeof arguments[2] === "function") { 884 target = arguments[3]; 885 callback = arguments[2]; 886 } else if (len <= 2) { 887 disabledImage = arguments[2]; 888 } 889 ret.initWithNormalSprite(normalSprite, selectedSprite, disabledImage, callback, target); 890 return ret; 891 }; 892 893 /** 894 * cc.MenuItemImage accepts images as items.<br/> 895 * The images has 3 different states:<br/> 896 * - unselected image<br/> 897 * - selected image<br/> 898 * - disabled image<br/> 899 * <br/> 900 * For best results try that all images are of the same size<br/> 901 * @class 902 * @extends cc.MenuItemSprite 903 */ 904 cc.MenuItemImage = cc.MenuItemSprite.extend(/** @lends cc.MenuItemImage# */{ 905 /** 906 * sets the sprite frame for the normal image 907 * @param {cc.SpriteFrame} frame 908 */ 909 setNormalSpriteFrame:function (frame) { 910 this.setNormalImage(cc.Sprite.createWithSpriteFrame(frame)); 911 }, 912 913 /** 914 * sets the sprite frame for the selected image 915 * @param {cc.SpriteFrame} frame 916 */ 917 setSelectedSpriteFrame:function (frame) { 918 this.setSelectedImage(cc.Sprite.createWithSpriteFrame(frame)); 919 }, 920 921 /** 922 * sets the sprite frame for the disabled image 923 * @param {cc.SpriteFrame} frame 924 */ 925 setDisabledSpriteFrame:function (frame) { 926 this.setDisabledImage(cc.Sprite.createWithSpriteFrame(frame)); 927 }, 928 929 /** 930 * @param {string|null} normalImage 931 * @param {string|null} selectedImage 932 * @param {string|null} disabledImage 933 * @param {function|string|null} callback 934 * @param {cc.Node|null} target 935 * @returns {boolean} 936 */ 937 initWithNormalImage:function (normalImage, selectedImage, disabledImage, callback, target) { 938 var normalSprite = null; 939 var selectedSprite = null; 940 var disabledSprite = null; 941 942 if (normalImage) { 943 normalSprite = cc.Sprite.create(normalImage); 944 } 945 if (selectedImage) { 946 selectedSprite = cc.Sprite.create(selectedImage); 947 } 948 if (disabledImage) { 949 disabledSprite = cc.Sprite.create(disabledImage); 950 } 951 return this.initWithNormalSprite(normalSprite, selectedSprite, disabledSprite, callback, target); 952 } 953 }); 954 955 /** 956 * creates a new menu item image 957 * @param {String} normalImage file name for normal state 958 * @param {String} selectedImage image for selected state 959 * @param {String|cc.Node} three Disabled image OR allback function 960 * @param {String|function|Null} four callback function, either name in string or pass the whole function OR the target 961 * @param {cc.Node|String|function|Null} five cc.Node target to run callback when clicked 962 * @return {cc.MenuItemImage} 963 * @example 964 * // Example 965 * //create a dom menu item with normal and selected state, when clicked it will run the run function from gameScene object 966 * var item = cc.MenuItemImage.create('normal.png', 'selected.png', 'run', gameScene) 967 * 968 * //same as above, but pass in the actual function and disabled image 969 * var item = cc.MenuItemImage.create('normal.png', 'selected.png', 'disabled.png', gameScene.run, gameScene) 970 */ 971 cc.MenuItemImage.create = function (normalImage, selectedImage, three, four, five) { 972 if (arguments.length == 0) { 973 return cc.MenuItemImage.create(null, null, null, null, null); 974 } 975 if (arguments.length == 3) { 976 return cc.MenuItemImage.create(normalImage, selectedImage, null, three, null); 977 } 978 if (arguments.length == 4) { 979 return cc.MenuItemImage.create(normalImage, selectedImage, null, three, four); 980 } 981 var ret = new cc.MenuItemImage(); 982 if (ret.initWithNormalImage(normalImage, selectedImage, three, four, five)) 983 return ret; 984 return null; 985 }; 986 987 988 /** 989 * A simple container class that "toggles" it's inner items<br/> 990 * The inner items can be any MenuItem 991 * @class 992 * @extends cc.MenuItem 993 */ 994 cc.MenuItemToggle = cc.MenuItem.extend(/** @lends cc.MenuItemToggle# */{ 995 _selectedIndex:0, 996 _subItems:null, 997 _opacity:null, 998 _color:null, 999 1000 ctor: function(){ 1001 cc.MenuItem.prototype.ctor.call(this); 1002 this._selectedIndex = 0; 1003 this._subItems = []; 1004 this._opacity = 0; 1005 this._color = cc.white(); 1006 }, 1007 1008 /** 1009 * @return {Number} 1010 */ 1011 getOpacity:function () { 1012 return this._opacity; 1013 }, 1014 1015 /** 1016 * @param {Number} Opacity 1017 */ 1018 setOpacity:function (Opacity) { 1019 this._opacity = Opacity; 1020 if (this._subItems && this._subItems.length > 0) { 1021 for (var it = 0; it < this._subItems.length; it++) { 1022 this._subItems[it].setOpacity(Opacity); 1023 } 1024 } 1025 }, 1026 1027 /** 1028 * @return {cc.Color3B} 1029 */ 1030 getColor:function () { 1031 return this._color; 1032 }, 1033 1034 /** 1035 * @param {cc.Color3B} Color 1036 */ 1037 setColor:function (Color) { 1038 this._color = Color; 1039 if (this._subItems && this._subItems.length > 0) { 1040 for (var it = 0; it < this._subItems.length; it++) { 1041 this._subItems[it].setColor(Color); 1042 } 1043 } 1044 }, 1045 1046 /** 1047 * @return {Number} 1048 */ 1049 getSelectedIndex:function () { 1050 return this._selectedIndex; 1051 }, 1052 1053 /** 1054 * @param {Number} SelectedIndex 1055 */ 1056 setSelectedIndex:function (SelectedIndex) { 1057 if (SelectedIndex != this._selectedIndex) { 1058 this._selectedIndex = SelectedIndex; 1059 var currItem = this.getChildByTag(cc.CURRENT_ITEM); 1060 if (currItem) 1061 currItem.removeFromParent(false); 1062 1063 var item = this._subItems[this._selectedIndex]; 1064 this.addChild(item, 0, cc.CURRENT_ITEM); 1065 var s = item.getContentSize(); 1066 this.setContentSize(s); 1067 item.setPosition(s.width / 2, s.height / 2); 1068 } 1069 }, 1070 1071 /** 1072 * similar to get children 1073 * @return {cc.MenuItem} 1074 */ 1075 getSubItems:function () { 1076 return this._subItems; 1077 }, 1078 1079 /** 1080 * @param {cc.MenuItem} SubItems 1081 */ 1082 setSubItems:function (SubItems) { 1083 this._subItems = SubItems; 1084 }, 1085 1086 /** 1087 * @param {cc.MenuItem} args[0...last-2] the rest in the array are cc.MenuItems 1088 * @param {function|String} args[last-1] the second item in the args array is the callback 1089 * @param {cc.Node} args[last] the first item in the args array is a target 1090 * @return {Boolean} 1091 */ 1092 initWithItems:function (args) { 1093 var l = args.length; 1094 // passing callback. 1095 if (typeof args[args.length-2] === 'function') { 1096 this.initWithCallback( args[args.length-2], args[args.length-1] ); 1097 l = l-2; 1098 } else if(typeof args[args.length-1] === 'function'){ 1099 this.initWithCallback( args[args.length-1], null ); 1100 l = l-1; 1101 } else { 1102 this.initWithCallback(null, null); 1103 } 1104 1105 this._subItems = []; 1106 for (var i = 0; i < l; i++) { 1107 if (args[i]) 1108 this._subItems.push(args[i]); 1109 } 1110 this._selectedIndex = cc.UINT_MAX; 1111 this.setSelectedIndex(0); 1112 1113 this.setCascadeColorEnabled(true); 1114 this.setCascadeOpacityEnabled(true); 1115 1116 return true; 1117 }, 1118 1119 /** 1120 * @param {cc.MenuItem} item 1121 */ 1122 addSubItem:function (item) { 1123 this._subItems.push(item); 1124 }, 1125 1126 /** 1127 * activate the menu item 1128 */ 1129 activate:function () { 1130 // update index 1131 if (this._isEnabled) { 1132 var newIndex = (this._selectedIndex + 1) % this._subItems.length; 1133 this.setSelectedIndex(newIndex); 1134 } 1135 cc.MenuItem.prototype.activate.call(this); 1136 }, 1137 1138 /** 1139 * menu item is selected (runs callback) 1140 */ 1141 selected:function () { 1142 cc.MenuItem.prototype.selected.call(this); 1143 this._subItems[this._selectedIndex].selected(); 1144 }, 1145 1146 /** 1147 * menu item goes back to unselected state 1148 */ 1149 unselected:function () { 1150 cc.MenuItem.prototype.unselected.call(this); 1151 this._subItems[this._selectedIndex].unselected(); 1152 }, 1153 1154 /** 1155 * @param {Boolean} enabled 1156 */ 1157 setEnabled:function (enabled) { 1158 if (this._isEnabled != enabled) { 1159 cc.MenuItem.prototype.setEnabled.call(this, enabled); 1160 var locItems = this._subItems; 1161 if (locItems && locItems.length > 0) { 1162 for (var it = 0; it < locItems.length; it++) 1163 locItems[it].setEnabled(enabled); 1164 } 1165 } 1166 }, 1167 1168 /** 1169 * returns the selected item 1170 * @return {cc.MenuItem} 1171 */ 1172 selectedItem:function () { 1173 return this._subItems[this._selectedIndex]; 1174 }, 1175 1176 onEnter:function () { 1177 cc.Node.prototype.onEnter.call(this); 1178 this.setSelectedIndex(this._selectedIndex); 1179 } 1180 }); 1181 1182 /** 1183 * create a simple container class that "toggles" it's inner items<br/> 1184 * The inner items can be any MenuItem 1185 * @return {cc.MenuItemToggle} 1186 * @example 1187 * // Example 1188 * 1189 * //create a toggle item with 2 menu items (which you can then toggle between them later) 1190 * var toggler = cc.MenuItemToggle.create( cc.MenuItemFont.create("On"), cc.MenuItemFont.create("Off"), this.callback, this) 1191 * //Note: the first param is the target, the second is the callback function, afterwards, you can pass in any number of menuitems 1192 * 1193 * //if you pass only 1 variable, then it must be a cc.MenuItem 1194 * var notYetToggler = cc.MenuItemToggle.create(cc.MenuItemFont.create("On"));//it is useless right now, until you add more stuff to it 1195 * notYetToggler.addSubItem(cc.MenuItemFont.create("Off")); 1196 * //this is useful for constructing a toggler without a callback function (you wish to control the behavior from somewhere else) 1197 */ 1198 cc.MenuItemToggle.create = function (/*Multiple arguments follow*/) { 1199 if((arguments.length > 0) && (arguments[arguments.length-1] == null)) 1200 cc.log("parameters should not be ending with null in Javascript"); 1201 var ret = new cc.MenuItemToggle(); 1202 ret.initWithItems(arguments); 1203 return ret; 1204 }; 1205