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 new Error("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 new Error("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 if(!this._normalImage) 745 return; 746 747 this.width = this._normalImage.width; 748 this.height = this._normalImage.height; 749 this._updateImagesVisibility(); 750 751 if (normalImage.textureLoaded && !normalImage.textureLoaded()) { 752 normalImage.addEventListener("load", function (sender) { 753 this.width = sender.width; 754 this.height = sender.height; 755 }, this); 756 } 757 }, 758 759 /** 760 * return the selected status image(cc.Sprite) of cc.MenuItemSprite 761 * @return {cc.Sprite} 762 */ 763 getSelectedImage: function () { 764 return this._selectedImage; 765 }, 766 767 /** 768 * set the selected status image(cc.Sprite) 769 * @param {cc.Sprite} selectedImage 770 */ 771 setSelectedImage: function (selectedImage) { 772 if (this._selectedImage === selectedImage) 773 return; 774 775 if (selectedImage) { 776 this.addChild(selectedImage, 0, cc.SELECTED_TAG); 777 selectedImage.anchorX = 0; 778 selectedImage.anchorY = 0; 779 } 780 781 if (this._selectedImage) { 782 this.removeChild(this._selectedImage, true); 783 } 784 785 this._selectedImage = selectedImage; 786 this._updateImagesVisibility(); 787 }, 788 789 /** 790 * return the disabled status of cc.MenuItemSprite 791 * @return {cc.Sprite} 792 */ 793 getDisabledImage: function () { 794 return this._disabledImage; 795 }, 796 797 /** 798 * set the disabled status image(cc.Sprite) 799 * @param {cc.Sprite} disabledImage 800 */ 801 setDisabledImage: function (disabledImage) { 802 if (this._disabledImage === disabledImage) 803 return; 804 805 if (disabledImage) { 806 this.addChild(disabledImage, 0, cc.DISABLE_TAG); 807 disabledImage.anchorX = 0; 808 disabledImage.anchorY = 0; 809 } 810 811 if (this._disabledImage) 812 this.removeChild(this._disabledImage, true); 813 814 this._disabledImage = disabledImage; 815 this._updateImagesVisibility(); 816 }, 817 818 /** 819 * initializes cc.MenuItemSprite with a cc.Sprite 820 * @param {cc.Node} normalSprite 821 * @param {cc.Node} selectedSprite 822 * @param {cc.Node} disabledSprite 823 * @param {function|String} callback 824 * @param {cc.Node} target 825 * @return {Boolean} 826 */ 827 initWithNormalSprite: function (normalSprite, selectedSprite, disabledSprite, callback, target) { 828 this.initWithCallback(callback, target); 829 this.setNormalImage(normalSprite); 830 this.setSelectedImage(selectedSprite); 831 this.setDisabledImage(disabledSprite); 832 var locNormalImage = this._normalImage; 833 if (locNormalImage) { 834 this.width = locNormalImage.width; 835 this.height = locNormalImage.height; 836 837 if (locNormalImage.textureLoaded && !locNormalImage.textureLoaded()) { 838 locNormalImage.addEventListener("load", function (sender) { 839 this.width = sender.width; 840 this.height = sender.height; 841 this.setCascadeColorEnabled(true); 842 this.setCascadeOpacityEnabled(true); 843 }, this); 844 } 845 } 846 this.setCascadeColorEnabled(true); 847 this.setCascadeOpacityEnabled(true); 848 return true; 849 }, 850 851 /** 852 * menu item is selected (runs callback) 853 */ 854 selected: function () { 855 cc.MenuItem.prototype.selected.call(this); 856 if (this._normalImage) { 857 if (this._disabledImage) 858 this._disabledImage.visible = false; 859 860 if (this._selectedImage) { 861 this._normalImage.visible = false; 862 this._selectedImage.visible = true; 863 } else 864 this._normalImage.visible = true; 865 } 866 }, 867 868 /** 869 * menu item goes back to unselected state 870 */ 871 unselected: function () { 872 cc.MenuItem.prototype.unselected.call(this); 873 if (this._normalImage) { 874 this._normalImage.visible = true; 875 876 if (this._selectedImage) 877 this._selectedImage.visible = false; 878 879 if (this._disabledImage) 880 this._disabledImage.visible = false; 881 } 882 }, 883 884 /** 885 * set cc.MenuItemSprite enable to receive the touch event 886 * @param {Boolean} bEnabled 887 */ 888 setEnabled: function (bEnabled) { 889 if (this._enabled !== bEnabled) { 890 cc.MenuItem.prototype.setEnabled.call(this, bEnabled); 891 this._updateImagesVisibility(); 892 } 893 }, 894 895 _updateImagesVisibility: function () { 896 var locNormalImage = this._normalImage, locSelImage = this._selectedImage, locDisImage = this._disabledImage; 897 if (this._enabled) { 898 if (locNormalImage) 899 locNormalImage.visible = true; 900 if (locSelImage) 901 locSelImage.visible = false; 902 if (locDisImage) 903 locDisImage.visible = false; 904 } else { 905 if (locDisImage) { 906 if (locNormalImage) 907 locNormalImage.visible = false; 908 if (locSelImage) 909 locSelImage.visible = false; 910 if (locDisImage) 911 locDisImage.visible = true; 912 } else { 913 if (locNormalImage) 914 locNormalImage.visible = true; 915 if (locSelImage) 916 locSelImage.visible = false; 917 } 918 } 919 } 920 }); 921 922 var _p = cc.MenuItemSprite.prototype; 923 924 // Extended properties 925 /** @expose */ 926 _p.normalImage; 927 cc.defineGetterSetter(_p, "normalImage", _p.getNormalImage, _p.setNormalImage); 928 /** @expose */ 929 _p.selectedImage; 930 cc.defineGetterSetter(_p, "selectedImage", _p.getSelectedImage, _p.setSelectedImage); 931 /** @expose */ 932 _p.disabledImage; 933 cc.defineGetterSetter(_p, "disabledImage", _p.getDisabledImage, _p.setDisabledImage); 934 935 /** 936 * create a menu item from sprite 937 * @deprecated since v3.0 please use new cc.MenuItemSprite(normalSprite, selectedSprite, three, four, five) instead 938 * @param {Image} normalSprite normal state image 939 * @param {Image|Null} selectedSprite selected state image 940 * @param {Image|cc.Node|Null} three disabled state image OR target node 941 * @param {String|function|cc.Node|Null} four callback function name in string or actual function, OR target Node 942 * @param {String|function|Null} five callback function name in string or actual function 943 * @return {cc.MenuItemSprite} 944 */ 945 cc.MenuItemSprite.create = function (normalSprite, selectedSprite, three, four, five) { 946 return new cc.MenuItemSprite(normalSprite, selectedSprite, three, four, five || undefined); 947 }; 948 949 /** 950 * cc.MenuItemImage accepts images as items.<br/> 951 * The images has 3 different states:<br/> 952 * - unselected image<br/> 953 * - selected image<br/> 954 * - disabled image<br/> 955 * <br/> 956 * For best results try that all images are of the same size<br/> 957 * @class 958 * @extends cc.MenuItemSprite 959 * @param {string|null} normalImage 960 * @param {string|null} selectedImage 961 * @param {string|null} disabledImage 962 * @param {function|string|null} callback 963 * @param {cc.Node|null} target 964 * @example 965 * var menuItem = new cc.MenuItemImage(normalImage, selectedImage, three, four, five); 966 */ 967 cc.MenuItemImage = cc.MenuItemSprite.extend(/** @lends cc.MenuItemImage# */{ 968 969 /** 970 * Constructor of cc.MenuItemImage 971 * @param {string|null} normalImage 972 * @param {string|null} selectedImage 973 * @param {string|null} disabledImage 974 * @param {function|string|null} callback 975 * @param {cc.Node|null} target 976 */ 977 ctor: function (normalImage, selectedImage, three, four, five) { 978 var normalSprite = null, 979 selectedSprite = null, 980 disabledSprite = null, 981 callback = null, 982 target = null; 983 984 if (normalImage === undefined || normalImage === null) { 985 cc.MenuItemSprite.prototype.ctor.call(this); 986 } 987 else { 988 normalSprite = new cc.Sprite(normalImage); 989 selectedImage && 990 (selectedSprite = new cc.Sprite(selectedImage)); 991 if (four === undefined) { 992 callback = three; 993 } 994 else if (five === undefined) { 995 callback = three; 996 target = four; 997 } 998 else if (five) { 999 disabledSprite = new cc.Sprite(three); 1000 callback = four; 1001 target = five; 1002 } 1003 cc.MenuItemSprite.prototype.ctor.call(this, normalSprite, selectedSprite, disabledSprite, callback, target); 1004 } 1005 }, 1006 1007 /** 1008 * sets the sprite frame for the normal image 1009 * @param {cc.SpriteFrame} frame 1010 */ 1011 setNormalSpriteFrame: function (frame) { 1012 this.setNormalImage(new cc.Sprite(frame)); 1013 }, 1014 1015 /** 1016 * sets the sprite frame for the selected image 1017 * @param {cc.SpriteFrame} frame 1018 */ 1019 setSelectedSpriteFrame: function (frame) { 1020 this.setSelectedImage(new cc.Sprite(frame)); 1021 }, 1022 1023 /** 1024 * sets the sprite frame for the disabled image 1025 * @param {cc.SpriteFrame} frame 1026 */ 1027 setDisabledSpriteFrame: function (frame) { 1028 this.setDisabledImage(new cc.Sprite(frame)); 1029 }, 1030 1031 /** 1032 * initializes a cc.MenuItemImage 1033 * @param {string|null} normalImage 1034 * @param {string|null} selectedImage 1035 * @param {string|null} disabledImage 1036 * @param {function|string|null} callback 1037 * @param {cc.Node|null} target 1038 * @returns {boolean} 1039 */ 1040 initWithNormalImage: function (normalImage, selectedImage, disabledImage, callback, target) { 1041 var normalSprite = null; 1042 var selectedSprite = null; 1043 var disabledSprite = null; 1044 1045 if (normalImage) { 1046 normalSprite = new cc.Sprite(normalImage); 1047 } 1048 if (selectedImage) { 1049 selectedSprite = new cc.Sprite(selectedImage); 1050 } 1051 if (disabledImage) { 1052 disabledSprite = new cc.Sprite(disabledImage); 1053 } 1054 return this.initWithNormalSprite(normalSprite, selectedSprite, disabledSprite, callback, target); 1055 } 1056 }); 1057 1058 /** 1059 * creates a new menu item image 1060 * @deprecated since v3.0, please use new cc.MenuItemImage(normalImage, selectedImage, three, four, five) instead. 1061 * @param {String} normalImage file name for normal state 1062 * @param {String} selectedImage image for selected state 1063 * @param {String|cc.Node} three Disabled image OR callback function 1064 * @param {String|function|Null} [four] callback function, either name in string or pass the whole function OR the target 1065 * @param {cc.Node|String|function|Null} [five] cc.Node target to run callback when clicked 1066 * @return {cc.MenuItemImage} 1067 */ 1068 cc.MenuItemImage.create = function (normalImage, selectedImage, three, four, five) { 1069 return new cc.MenuItemImage(normalImage, selectedImage, three, four, five); 1070 }; 1071 1072 1073 /** 1074 * A simple container class that "toggles" it's inner items<br/> 1075 * The inner items can be any MenuItem 1076 * @class 1077 * @extends cc.MenuItem 1078 * 1079 * @property {Array} subItems - Sub items 1080 * @property {Number} selectedIndex - Index of selected sub item 1081 * 1082 *@example 1083 * // Example 1084 * //create a toggle item with 2 menu items (which you can then toggle between them later) 1085 * var toggler = new cc.MenuItemToggle( new cc.MenuItemFont("On"), new cc.MenuItemFont("Off"), this.callback, this) 1086 * //Note: the first param is the target, the second is the callback function, afterwards, you can pass in any number of menuitems 1087 * 1088 * //if you pass only 1 variable, then it must be a cc.MenuItem 1089 * var notYetToggler = new cc.MenuItemToggle(cc.MenuItemFont("On"));//it is useless right now, until you add more stuff to it 1090 * notYetToggler.addSubItem(new cc.MenuItemFont("Off")); 1091 * //this is useful for constructing a toggler without a callback function (you wish to control the behavior from somewhere else) 1092 */ 1093 cc.MenuItemToggle = cc.MenuItem.extend(/** @lends cc.MenuItemToggle# */{ 1094 subItems: null, 1095 1096 _selectedIndex: 0, 1097 _opacity: null, 1098 _color: null, 1099 1100 /** 1101 * Constructor of cc.MenuItemToggle 1102 */ 1103 ctor: function (/*Multiple arguments follow*/) { 1104 1105 cc.MenuItem.prototype.ctor.call(this); 1106 this._selectedIndex = 0; 1107 this.subItems = []; 1108 this._opacity = 0; 1109 this._color = cc.color.WHITE; 1110 1111 if(arguments.length > 0) 1112 this.initWithItems(Array.prototype.slice.apply(arguments)); 1113 1114 }, 1115 1116 /** 1117 * return the opacity of cc.MenuItemToggle 1118 * @return {Number} 1119 */ 1120 getOpacity: function () { 1121 return this._opacity; 1122 }, 1123 1124 /** 1125 * set the opacity for cc.MenuItemToggle 1126 * @param {Number} opacity 1127 */ 1128 setOpacity: function (opacity) { 1129 this._opacity = opacity; 1130 if (this.subItems && this.subItems.length > 0) { 1131 for (var it = 0; it < this.subItems.length; it++) { 1132 this.subItems[it].opacity = opacity; 1133 } 1134 } 1135 this._color.a = opacity; 1136 }, 1137 1138 /** 1139 * return the color of cc.MenuItemToggle 1140 * @return {cc.Color} 1141 */ 1142 getColor: function () { 1143 var locColor = this._color; 1144 return cc.color(locColor.r, locColor.g, locColor.b, locColor.a); 1145 }, 1146 1147 /** 1148 * set the color for cc.MenuItemToggle 1149 * @param {cc.Color} Color 1150 */ 1151 setColor: function (color) { 1152 var locColor = this._color; 1153 locColor.r = color.r; 1154 locColor.g = color.g; 1155 locColor.b = color.b; 1156 1157 if (this.subItems && this.subItems.length > 0) { 1158 for (var it = 0; it < this.subItems.length; it++) { 1159 this.subItems[it].setColor(color); 1160 } 1161 } 1162 1163 if (color.a !== undefined && !color.a_undefined) { 1164 this.setOpacity(color.a); 1165 } 1166 }, 1167 1168 /** 1169 * return the index of selected 1170 * @return {Number} 1171 */ 1172 getSelectedIndex: function () { 1173 return this._selectedIndex; 1174 }, 1175 1176 /** 1177 * set the seleceted index for cc.MenuItemToggle 1178 * @param {Number} SelectedIndex 1179 */ 1180 setSelectedIndex: function (SelectedIndex) { 1181 if (SelectedIndex !== this._selectedIndex) { 1182 this._selectedIndex = SelectedIndex; 1183 var currItem = this.getChildByTag(cc.CURRENT_ITEM); 1184 if (currItem) 1185 currItem.removeFromParent(false); 1186 1187 var item = this.subItems[this._selectedIndex]; 1188 this.addChild(item, 0, cc.CURRENT_ITEM); 1189 var w = item.width, h = item.height; 1190 this.width = w; 1191 this.height = h; 1192 item.setPosition(w / 2, h / 2); 1193 } 1194 }, 1195 1196 /** 1197 * similar to get children,return the sumItem array. 1198 * @return {Array} 1199 */ 1200 getSubItems: function () { 1201 return this.subItems; 1202 }, 1203 1204 /** 1205 * set the subitem for cc.MenuItemToggle 1206 * @param {cc.MenuItem} subItems 1207 */ 1208 setSubItems: function (subItems) { 1209 this.subItems = subItems; 1210 }, 1211 1212 /** 1213 * initializes a cc.MenuItemToggle with items 1214 * @param {cc.MenuItem} args[0...last-2] the rest in the array are cc.MenuItems 1215 * @param {function|String} args[last-1] the second item in the args array is the callback 1216 * @param {cc.Node} args[last] the first item in the args array is a target 1217 * @return {Boolean} 1218 */ 1219 initWithItems: function (args) { 1220 var l = args.length; 1221 // passing callback. 1222 if (cc.isFunction(args[args.length - 2])) { 1223 this.initWithCallback(args[args.length - 2], args[args.length - 1]); 1224 l = l - 2; 1225 } else if (cc.isFunction(args[args.length - 1])) { 1226 this.initWithCallback(args[args.length - 1], null); 1227 l = l - 1; 1228 } else { 1229 this.initWithCallback(null, null); 1230 } 1231 1232 var locSubItems = this.subItems; 1233 locSubItems.length = 0; 1234 for (var i = 0; i < l; i++) { 1235 if (args[i]) 1236 locSubItems.push(args[i]); 1237 } 1238 this._selectedIndex = cc.UINT_MAX; 1239 this.setSelectedIndex(0); 1240 1241 this.setCascadeColorEnabled(true); 1242 this.setCascadeOpacityEnabled(true); 1243 1244 return true; 1245 }, 1246 1247 /** 1248 * add the subitem for cc.MenuItemToggle 1249 * @param {cc.MenuItem} item 1250 */ 1251 addSubItem: function (item) { 1252 this.subItems.push(item); 1253 }, 1254 1255 /** 1256 * activate the menu item 1257 */ 1258 activate: function () { 1259 // update index 1260 if (this._enabled) { 1261 var newIndex = (this._selectedIndex + 1) % this.subItems.length; 1262 this.setSelectedIndex(newIndex); 1263 } 1264 cc.MenuItem.prototype.activate.call(this); 1265 }, 1266 1267 /** 1268 * menu item is selected (runs callback) 1269 */ 1270 selected: function () { 1271 cc.MenuItem.prototype.selected.call(this); 1272 this.subItems[this._selectedIndex].selected(); 1273 }, 1274 1275 /** 1276 * menu item goes back to unselected state 1277 */ 1278 unselected: function () { 1279 cc.MenuItem.prototype.unselected.call(this); 1280 this.subItems[this._selectedIndex].unselected(); 1281 }, 1282 1283 /** 1284 * set the enable status for cc.MenuItemToggle 1285 * @param {Boolean} enabled 1286 */ 1287 setEnabled: function (enabled) { 1288 if (this._enabled !== enabled) { 1289 cc.MenuItem.prototype.setEnabled.call(this, enabled); 1290 var locItems = this.subItems; 1291 if (locItems && locItems.length > 0) { 1292 for (var it = 0; it < locItems.length; it++) 1293 locItems[it].enabled = enabled; 1294 } 1295 } 1296 }, 1297 1298 /** 1299 * returns the selected item (deprecated in -x, please use getSelectedItem instead.) 1300 * @return {cc.MenuItem} 1301 */ 1302 selectedItem: function () { 1303 return this.subItems[this._selectedIndex]; 1304 }, 1305 1306 /** 1307 * returns the selected item. 1308 * @return {cc.MenuItem} 1309 */ 1310 getSelectedItem: function() { 1311 return this.subItems[this._selectedIndex]; 1312 }, 1313 1314 /** 1315 * * <p> 1316 * Event callback that is invoked every time when cc.MenuItemToggle enters the 'stage'. <br/> 1317 * If the cc.MenuItemToggle enters the 'stage' with a transition, this event is called when the transition starts. <br/> 1318 * During onEnter you can't access a "sister/brother" node. <br/> 1319 * If you override onEnter, you must call its parent's onEnter function with this._super(). 1320 * </p> 1321 */ 1322 onEnter: function () { 1323 cc.Node.prototype.onEnter.call(this); 1324 this.setSelectedIndex(this._selectedIndex); 1325 } 1326 }); 1327 1328 var _p = cc.MenuItemToggle.prototype; 1329 1330 // Extended properties 1331 /** @expose */ 1332 _p.selectedIndex; 1333 cc.defineGetterSetter(_p, "selectedIndex", _p.getSelectedIndex, _p.setSelectedIndex); 1334 1335 1336 /** 1337 * create a simple container class that "toggles" it's inner items<br/> 1338 * The inner items can be any MenuItem 1339 * @deprecated since v3.0 please use new cc.MenuItemToggle(params) instead 1340 * @return {cc.MenuItemToggle} 1341 * @example 1342 */ 1343 cc.MenuItemToggle.create = function (/*Multiple arguments follow*/) { 1344 if ((arguments.length > 0) && (arguments[arguments.length - 1] == null)) 1345 cc.log("parameters should not be ending with null in Javascript"); 1346 var ret = new cc.MenuItemToggle(); 1347 ret.initWithItems(Array.prototype.slice.apply(arguments)); 1348 return ret; 1349 }; 1350