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