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