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