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