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 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(cc.p(0, 0)); 627 } 628 if (this._normalImage) { 629 this.removeChild(this._normalImage, true); 630 } 631 632 this._normalImage = normalImage; 633 if(normalImage.textureLoaded()){ 634 this.setContentSize(this._normalImage.getContentSize()); 635 this._updateImagesVisibility(); 636 } else { 637 normalImage.addLoadedEventListener(function(sender){ 638 this.setContentSize(sender.getContentSize()); 639 this._updateImagesVisibility(); 640 }, this); 641 } 642 }, 643 644 /** 645 * @return {cc.Sprite} 646 */ 647 getSelectedImage:function () { 648 return this._selectedImage; 649 }, 650 651 /** 652 * @param {cc.Sprite} selectedImage 653 */ 654 setSelectedImage:function (selectedImage) { 655 if (this._selectedImage == selectedImage) 656 return; 657 658 if (selectedImage) { 659 this.addChild(selectedImage, 0, cc.SELECTED_TAG); 660 selectedImage.setAnchorPoint(cc.p(0, 0)); 661 } 662 663 if (this._selectedImage) { 664 this.removeChild(this._selectedImage, true); 665 } 666 667 this._selectedImage = selectedImage; 668 if(selectedImage.textureLoaded()){ 669 this._updateImagesVisibility(); 670 } else { 671 selectedImage.addLoadedEventListener(function(sender){ 672 this._updateImagesVisibility(); 673 }, this); 674 } 675 }, 676 677 /** 678 * @return {cc.Sprite} 679 */ 680 getDisabledImage:function () { 681 return this._disabledImage; 682 }, 683 684 /** 685 * @param {cc.Sprite} disabledImage 686 */ 687 setDisabledImage:function (disabledImage) { 688 if (this._disabledImage == disabledImage) 689 return; 690 691 if (disabledImage) { 692 this.addChild(disabledImage, 0, cc.DISABLE_TAG); 693 disabledImage.setAnchorPoint(cc.p(0, 0)); 694 } 695 696 if (this._disabledImage) 697 this.removeChild(this._disabledImage, true); 698 699 this._disabledImage = disabledImage; 700 if(disabledImage.textureLoaded()){ 701 this._updateImagesVisibility(); 702 } else { 703 disabledImage.addLoadedEventListener(function(sender){ 704 this._updateImagesVisibility(); 705 }, this); 706 } 707 }, 708 709 /** 710 * @param {cc.Node} normalSprite 711 * @param {cc.Node} selectedSprite 712 * @param {cc.Node} disabledSprite 713 * @param {function|String} callback 714 * @param {cc.Node} target 715 * @return {Boolean} 716 */ 717 initWithNormalSprite:function (normalSprite, selectedSprite, disabledSprite, callback, target) { 718 this.initWithCallback(callback, target); 719 this.setNormalImage(normalSprite); 720 this.setSelectedImage(selectedSprite); 721 this.setDisabledImage(disabledSprite); 722 var locNormalImage = this._normalImage; 723 if (locNormalImage){ 724 if(locNormalImage.textureLoaded()){ 725 this.setContentSize(locNormalImage.getContentSize()); 726 this.setCascadeColorEnabled(true); 727 this.setCascadeOpacityEnabled(true); 728 } else{ 729 locNormalImage.addLoadedEventListener(function(sender){ 730 this.setContentSize(sender.getContentSize()); 731 this.setCascadeColorEnabled(true); 732 this.setCascadeOpacityEnabled(true); 733 }, this); 734 } 735 } 736 737 738 return true; 739 }, 740 741 /** 742 * @param {cc.Color3B} color 743 */ 744 setColor:function (color) { 745 this._normalImage.setColor(color); 746 747 if (this._selectedImage) 748 this._selectedImage.setColor(color); 749 750 if (this._disabledImage) 751 this._disabledImage.setColor(color); 752 }, 753 754 /** 755 * @return {cc.Color3B} 756 */ 757 getColor:function () { 758 return this._normalImage.getColor(); 759 }, 760 761 /** 762 * @param {Number} opacity 0 - 255 763 */ 764 setOpacity:function (opacity) { 765 this._normalImage.setOpacity(opacity); 766 767 if (this._selectedImage) 768 this._selectedImage.setOpacity(opacity); 769 770 if (this._disabledImage) 771 this._disabledImage.setOpacity(opacity); 772 }, 773 774 /** 775 * @return {Number} opacity from 0 - 255 776 */ 777 getOpacity:function () { 778 return this._normalImage.getOpacity(); 779 }, 780 781 /** 782 * menu item is selected (runs callback) 783 */ 784 selected:function () { 785 cc.MenuItem.prototype.selected.call(this); 786 if (this._normalImage) { 787 if (this._disabledImage) 788 this._disabledImage.setVisible(false); 789 790 if (this._selectedImage) { 791 this._normalImage.setVisible(false); 792 this._selectedImage.setVisible(true); 793 } else 794 this._normalImage.setVisible(true); 795 } 796 }, 797 798 /** 799 * menu item goes back to unselected state 800 */ 801 unselected:function () { 802 cc.MenuItem.prototype.unselected.call(this); 803 if (this._normalImage) { 804 this._normalImage.setVisible(true); 805 806 if (this._selectedImage) 807 this._selectedImage.setVisible(false); 808 809 if (this._disabledImage) 810 this._disabledImage.setVisible(false); 811 } 812 }, 813 814 /** 815 * @param {Boolean} bEnabled 816 */ 817 setEnabled:function (bEnabled) { 818 if (this._isEnabled != bEnabled) { 819 cc.MenuItem.prototype.setEnabled.call(this, bEnabled); 820 this._updateImagesVisibility(); 821 } 822 }, 823 824 _updateImagesVisibility:function () { 825 var locNormalImage = this._normalImage, locSelImage = this._selectedImage, locDisImage = this._disabledImage; 826 if (this._isEnabled) { 827 if (locNormalImage) 828 locNormalImage.setVisible(true); 829 if (locSelImage) 830 locSelImage.setVisible(false); 831 if (locDisImage) 832 locDisImage.setVisible(false); 833 } else { 834 if (locDisImage) { 835 if (locNormalImage) 836 locNormalImage.setVisible(false); 837 if (locSelImage) 838 locSelImage.setVisible(false); 839 if (locDisImage) 840 locDisImage.setVisible(true); 841 } else { 842 if (locNormalImage) 843 locNormalImage.setVisible(true); 844 if (locSelImage) 845 locSelImage.setVisible(false); 846 } 847 } 848 } 849 }); 850 851 /** 852 * create a menu item from sprite 853 * @param {Image} normalSprite normal state image 854 * @param {Image|Null} selectedSprite selected state image 855 * @param {Image|cc.Node|Null} three disabled state image OR target node 856 * @param {String|function|cc.Node|Null} four callback function name in string or actual function, OR target Node 857 * @param {String|function|Null} five callback function name in string or actual function 858 * @return {cc.MenuItemSprite} 859 * @example 860 * // Example 861 * var item = cc.MenuItemSprite.create(normalImage)//create a menu item from a sprite with no functionality 862 * 863 * var item = cc.MenuItemSprite.create(normalImage, selectedImage)//create a menu Item, nothing will happen when clicked 864 * 865 * var item = cc.MenuItemSprite.create(normalImage, SelectedImage, disabledImage)//same above, but with disabled state image 866 * 867 * var item = cc.MenuItemSprite.create(normalImage, SelectedImage, 'callback', targetNode)//create a menu item, when clicked runs targetNode.callback() 868 * 869 * var item = cc.MenuItemSprite.create(normalImage, SelectedImage, disabledImage, targetNode.callback, targetNode) 870 * //same as above, but with disabled image, and passing in callback function 871 */ 872 cc.MenuItemSprite.create = function (normalSprite, selectedSprite, three, four, five) { 873 var len = arguments.length; 874 normalSprite = arguments[0]; 875 selectedSprite = arguments[1]; 876 var disabledImage, target, callback; 877 var ret = new cc.MenuItemSprite(); 878 //when you send 4 arguments, five is undefined 879 if (len == 5) { 880 disabledImage = arguments[2]; 881 callback = arguments[3]; 882 target = arguments[4]; 883 } else if (len == 4 && typeof arguments[3] === "function") { 884 disabledImage = arguments[2]; 885 callback = arguments[3]; 886 } else if (len == 4 && typeof arguments[2] === "function") { 887 target = arguments[3]; 888 callback = arguments[2]; 889 } else if (len <= 2) { 890 disabledImage = arguments[2]; 891 } 892 ret.initWithNormalSprite(normalSprite, selectedSprite, disabledImage, callback, target); 893 return ret; 894 }; 895 896 /** 897 * cc.MenuItemImage accepts images as items.<br/> 898 * The images has 3 different states:<br/> 899 * - unselected image<br/> 900 * - selected image<br/> 901 * - disabled image<br/> 902 * <br/> 903 * For best results try that all images are of the same size<br/> 904 * @class 905 * @extends cc.MenuItemSprite 906 */ 907 cc.MenuItemImage = cc.MenuItemSprite.extend(/** @lends cc.MenuItemImage# */{ 908 /** 909 * sets the sprite frame for the normal image 910 * @param {cc.SpriteFrame} frame 911 */ 912 setNormalSpriteFrame:function (frame) { 913 this.setNormalImage(cc.Sprite.createWithSpriteFrame(frame)); 914 }, 915 916 /** 917 * sets the sprite frame for the selected image 918 * @param {cc.SpriteFrame} frame 919 */ 920 setSelectedSpriteFrame:function (frame) { 921 this.setSelectedImage(cc.Sprite.createWithSpriteFrame(frame)); 922 }, 923 924 /** 925 * sets the sprite frame for the disabled image 926 * @param {cc.SpriteFrame} frame 927 */ 928 setDisabledSpriteFrame:function (frame) { 929 this.setDisabledImage(cc.Sprite.createWithSpriteFrame(frame)); 930 }, 931 932 /** 933 * @param {string|null} normalImage 934 * @param {string|null} selectedImage 935 * @param {string|null} disabledImage 936 * @param {function|string|null} callback 937 * @param {cc.Node|null} target 938 * @returns {boolean} 939 */ 940 initWithNormalImage:function (normalImage, selectedImage, disabledImage, callback, target) { 941 var normalSprite = null; 942 var selectedSprite = null; 943 var disabledSprite = null; 944 945 if (normalImage) { 946 normalSprite = cc.Sprite.create(normalImage); 947 } 948 if (selectedImage) { 949 selectedSprite = cc.Sprite.create(selectedImage); 950 } 951 if (disabledImage) { 952 disabledSprite = cc.Sprite.create(disabledImage); 953 } 954 return this.initWithNormalSprite(normalSprite, selectedSprite, disabledSprite, callback, target); 955 } 956 }); 957 958 /** 959 * creates a new menu item image 960 * @param {String} normalImage file name for normal state 961 * @param {String} selectedImage image for selected state 962 * @param {String|cc.Node} three Disabled image OR allback function 963 * @param {String|function|Null} four callback function, either name in string or pass the whole function OR the target 964 * @param {cc.Node|String|function|Null} five cc.Node target to run callback when clicked 965 * @return {cc.MenuItemImage} 966 * @example 967 * // Example 968 * //create a dom menu item with normal and selected state, when clicked it will run the run function from gameScene object 969 * var item = cc.MenuItemImage.create('normal.png', 'selected.png', 'run', gameScene) 970 * 971 * //same as above, but pass in the actual function and disabled image 972 * var item = cc.MenuItemImage.create('normal.png', 'selected.png', 'disabled.png', gameScene.run, gameScene) 973 */ 974 cc.MenuItemImage.create = function (normalImage, selectedImage, three, four, five) { 975 if (arguments.length == 0) { 976 return cc.MenuItemImage.create(null, null, null, null, null); 977 } 978 if (arguments.length == 3) { 979 return cc.MenuItemImage.create(normalImage, selectedImage, null, three, null); 980 } 981 if (arguments.length == 4) { 982 return cc.MenuItemImage.create(normalImage, selectedImage, null, three, four); 983 } 984 var ret = new cc.MenuItemImage(); 985 if (ret.initWithNormalImage(normalImage, selectedImage, three, four, five)) 986 return ret; 987 return null; 988 }; 989 990 991 /** 992 * A simple container class that "toggles" it's inner items<br/> 993 * The inner items can be any MenuItem 994 * @class 995 * @extends cc.MenuItem 996 */ 997 cc.MenuItemToggle = cc.MenuItem.extend(/** @lends cc.MenuItemToggle# */{ 998 _selectedIndex:0, 999 _subItems:null, 1000 _opacity:null, 1001 _color:null, 1002 1003 ctor: function(){ 1004 cc.MenuItem.prototype.ctor.call(this); 1005 this._selectedIndex = 0; 1006 this._subItems = []; 1007 this._opacity = 0; 1008 this._color = cc.white(); 1009 }, 1010 1011 /** 1012 * @return {Number} 1013 */ 1014 getOpacity:function () { 1015 return this._opacity; 1016 }, 1017 1018 /** 1019 * @param {Number} Opacity 1020 */ 1021 setOpacity:function (Opacity) { 1022 this._opacity = Opacity; 1023 if (this._subItems && this._subItems.length > 0) { 1024 for (var it = 0; it < this._subItems.length; it++) { 1025 this._subItems[it].setOpacity(Opacity); 1026 } 1027 } 1028 }, 1029 1030 /** 1031 * @return {cc.Color3B} 1032 */ 1033 getColor:function () { 1034 return this._color; 1035 }, 1036 1037 /** 1038 * @param {cc.Color3B} Color 1039 */ 1040 setColor:function (Color) { 1041 this._color = Color; 1042 if (this._subItems && this._subItems.length > 0) { 1043 for (var it = 0; it < this._subItems.length; it++) { 1044 this._subItems[it].setColor(Color); 1045 } 1046 } 1047 }, 1048 1049 /** 1050 * @return {Number} 1051 */ 1052 getSelectedIndex:function () { 1053 return this._selectedIndex; 1054 }, 1055 1056 /** 1057 * @param {Number} SelectedIndex 1058 */ 1059 setSelectedIndex:function (SelectedIndex) { 1060 if (SelectedIndex != this._selectedIndex) { 1061 this._selectedIndex = SelectedIndex; 1062 var currItem = this.getChildByTag(cc.CURRENT_ITEM); 1063 if (currItem) 1064 currItem.removeFromParent(false); 1065 1066 var item = this._subItems[this._selectedIndex]; 1067 this.addChild(item, 0, cc.CURRENT_ITEM); 1068 var s = item.getContentSize(); 1069 this.setContentSize(s); 1070 item.setPosition(s.width / 2, s.height / 2); 1071 } 1072 }, 1073 1074 /** 1075 * similar to get children 1076 * @return {cc.MenuItem} 1077 */ 1078 getSubItems:function () { 1079 return this._subItems; 1080 }, 1081 1082 /** 1083 * @param {cc.MenuItem} SubItems 1084 */ 1085 setSubItems:function (SubItems) { 1086 this._subItems = SubItems; 1087 }, 1088 1089 /** 1090 * @param {cc.MenuItem} args[0...last-2] the rest in the array are cc.MenuItems 1091 * @param {function|String} args[last-1] the second item in the args array is the callback 1092 * @param {cc.Node} args[last] the first item in the args array is a target 1093 * @return {Boolean} 1094 */ 1095 initWithItems:function (args) { 1096 var l = args.length; 1097 // passing callback. 1098 if (typeof args[args.length-2] === 'function') { 1099 this.initWithCallback( args[args.length-2], args[args.length-1] ); 1100 l = l-2; 1101 } else if(typeof args[args.length-1] === 'function'){ 1102 this.initWithCallback( args[args.length-1], null ); 1103 l = l-1; 1104 } else { 1105 this.initWithCallback(null, null); 1106 } 1107 1108 this._subItems = []; 1109 for (var i = 0; i < l; i++) { 1110 if (args[i]) 1111 this._subItems.push(args[i]); 1112 } 1113 this._selectedIndex = cc.UINT_MAX; 1114 this.setSelectedIndex(0); 1115 1116 this.setCascadeColorEnabled(true); 1117 this.setCascadeOpacityEnabled(true); 1118 1119 return true; 1120 }, 1121 1122 /** 1123 * @param {cc.MenuItem} item 1124 */ 1125 addSubItem:function (item) { 1126 this._subItems.push(item); 1127 }, 1128 1129 /** 1130 * activate the menu item 1131 */ 1132 activate:function () { 1133 // update index 1134 if (this._isEnabled) { 1135 var newIndex = (this._selectedIndex + 1) % this._subItems.length; 1136 this.setSelectedIndex(newIndex); 1137 } 1138 cc.MenuItem.prototype.activate.call(this); 1139 }, 1140 1141 /** 1142 * menu item is selected (runs callback) 1143 */ 1144 selected:function () { 1145 cc.MenuItem.prototype.selected.call(this); 1146 this._subItems[this._selectedIndex].selected(); 1147 }, 1148 1149 /** 1150 * menu item goes back to unselected state 1151 */ 1152 unselected:function () { 1153 cc.MenuItem.prototype.unselected.call(this); 1154 this._subItems[this._selectedIndex].unselected(); 1155 }, 1156 1157 /** 1158 * @param {Boolean} enabled 1159 */ 1160 setEnabled:function (enabled) { 1161 if (this._isEnabled != enabled) { 1162 cc.MenuItem.prototype.setEnabled.call(this, enabled); 1163 var locItems = this._subItems; 1164 if (locItems && locItems.length > 0) { 1165 for (var it = 0; it < locItems.length; it++) 1166 locItems[it].setEnabled(enabled); 1167 } 1168 } 1169 }, 1170 1171 /** 1172 * returns the selected item 1173 * @return {cc.MenuItem} 1174 */ 1175 selectedItem:function () { 1176 return this._subItems[this._selectedIndex]; 1177 }, 1178 1179 onEnter:function () { 1180 cc.Node.prototype.onEnter.call(this); 1181 this.setSelectedIndex(this._selectedIndex); 1182 } 1183 }); 1184 1185 /** 1186 * create a simple container class that "toggles" it's inner items<br/> 1187 * The inner items can be any MenuItem 1188 * @return {cc.MenuItemToggle} 1189 * @example 1190 * // Example 1191 * 1192 * //create a toggle item with 2 menu items (which you can then toggle between them later) 1193 * var toggler = cc.MenuItemToggle.create( cc.MenuItemFont.create("On"), cc.MenuItemFont.create("Off"), this.callback, this) 1194 * //Note: the first param is the target, the second is the callback function, afterwards, you can pass in any number of menuitems 1195 * 1196 * //if you pass only 1 variable, then it must be a cc.MenuItem 1197 * var notYetToggler = cc.MenuItemToggle.create(cc.MenuItemFont.create("On"));//it is useless right now, until you add more stuff to it 1198 * notYetToggler.addSubItem(cc.MenuItemFont.create("Off")); 1199 * //this is useful for constructing a toggler without a callback function (you wish to control the behavior from somewhere else) 1200 */ 1201 cc.MenuItemToggle.create = function (/*Multiple arguments follow*/) { 1202 if((arguments.length > 0) && (arguments[arguments.length-1] == null)) 1203 cc.log("parameters should not be ending with null in Javascript"); 1204 var ret = new cc.MenuItemToggle(); 1205 ret.initWithItems(arguments); 1206 return ret; 1207 }; 1208