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