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