1 /**************************************************************************** 2 Copyright (c) 2010-2012 cocos2d-x.org 3 4 http://www.cocos2d-x.org 5 6 Permission is hereby granted, free of charge, to any person obtaining a copy 7 of this software and associated documentation files (the "Software"), to deal 8 in the Software without restriction, including without limitation the rights 9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 copies of the Software, and to permit persons to whom the Software is 11 furnished to do so, subject to the following conditions: 12 13 The above copyright notice and this permission notice shall be included in 14 all copies or substantial portions of the Software. 15 16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 THE SOFTWARE. 23 ****************************************************************************/ 24 25 /** 26 * slider event type 27 * @type {Obejct} 28 */ 29 ccs.SliderEventType = {percent_changed: 0}; 30 31 ccs.BASEBARRENDERERZ = -3; 32 ccs.PROGRESSBARRENDERERZ = -2; 33 ccs.SLIDBALLRENDERERZ = -1; 34 /** 35 * Base class for ccs.Slider 36 * @class 37 * @extends ccs.Widget 38 */ 39 ccs.Slider = ccs.Widget.extend(/** @lends ccs.Slider# */{ 40 _barRenderer: null, 41 _progressBarRenderer: null, 42 _progressBarTextureSize: null, 43 _slidBallNormalRenderer: null, 44 _slidBallPressedRenderer: null, 45 _slidBallDisabledRenderer: null, 46 _slidBallRenderer: null, 47 _barLength: 0, 48 _percent: 0, 49 _scale9Enabled: false, 50 _prevIgnoreSize: true, 51 _textureFile: "", 52 _progressBarTextureFile: "", 53 _slidBallNormalTextureFile: "", 54 _slidBallPressedTextureFile: "", 55 _slidBallDisabledTextureFile: "", 56 _capInsetsBarRenderer: null, 57 _capInsetsProgressBarRenderer: null, 58 _sliderEventListener: null, 59 _sliderEventSelector: null, 60 _barTexType: null, 61 _progressBarTexType: null, 62 _ballNTexType: null, 63 _ballPTexType: null, 64 _ballDTexType: null, 65 _isTextureLoaded: false, 66 ctor: function () { 67 ccs.Widget.prototype.ctor.call(this); 68 this._barRenderer = null; 69 this._progressBarRenderer = null; 70 this._progressBarTextureSize = cc.size(0, 0); 71 this._slidBallNormalRenderer = null; 72 this._slidBallPressedRenderer = null; 73 this._slidBallDisabledRenderer = null; 74 this._slidBallRenderer = null; 75 this._barLength = 0; 76 this._percent = 0; 77 this._scale9Enabled = false; 78 this._prevIgnoreSize = true; 79 this._textureFile = ""; 80 this._progressBarTextureFile = ""; 81 this._slidBallNormalTextureFile = ""; 82 this._slidBallPressedTextureFile = ""; 83 this._slidBallDisabledTextureFile = ""; 84 this._capInsetsBarRenderer = cc.RectZero(); 85 this._capInsetsProgressBarRenderer = cc.RectZero(); 86 this._sliderEventListener = null; 87 this._sliderEventSelector = null; 88 this._barTexType = ccs.TextureResType.local; 89 this._progressBarTexType = ccs.TextureResType.local; 90 this._ballNTexType = ccs.TextureResType.local; 91 this._ballPTexType = ccs.TextureResType.local; 92 this._ballDTexType = ccs.TextureResType.local; 93 this._isTextureLoaded = false; 94 }, 95 96 init:function(){ 97 if(ccs.Widget.prototype.init.call(this)){ 98 this.setTouchEnabled(true); 99 return true; 100 } 101 return false; 102 }, 103 104 initRenderer: function () { 105 this._barRenderer = cc.Sprite.create(); 106 this._progressBarRenderer = cc.Sprite.create(); 107 this._progressBarRenderer.setAnchorPoint(0.0, 0.5); 108 cc.Node.prototype.addChild.call(this, this._barRenderer, ccs.BASEBARRENDERERZ, -1); 109 cc.Node.prototype.addChild.call(this, this._progressBarRenderer, ccs.PROGRESSBARRENDERERZ, -1); 110 this._slidBallNormalRenderer = cc.Sprite.create(); 111 this._slidBallPressedRenderer = cc.Sprite.create(); 112 this._slidBallPressedRenderer.setVisible(false); 113 this._slidBallDisabledRenderer = cc.Sprite.create(); 114 this._slidBallDisabledRenderer.setVisible(false); 115 this._slidBallRenderer = cc.Node.create(); 116 this._slidBallRenderer.addChild(this._slidBallNormalRenderer); 117 this._slidBallRenderer.addChild(this._slidBallPressedRenderer); 118 this._slidBallRenderer.addChild(this._slidBallDisabledRenderer); 119 cc.Node.prototype.addChild.call(this, this._slidBallRenderer, ccs.SLIDBALLRENDERERZ, -1); 120 }, 121 122 /** 123 * Load texture for slider bar. 124 * @param {String} fileName 125 * @param {ccs.TextureResType} texType 126 */ 127 loadBarTexture: function (fileName, texType) { 128 if (!fileName) { 129 return; 130 } 131 texType = texType || ccs.TextureResType.local; 132 this._textureFile = fileName; 133 this._barTexType = texType; 134 var barRenderer = this._barRenderer; 135 switch (this._barTexType) { 136 case ccs.TextureResType.local: 137 barRenderer.initWithFile(fileName); 138 break; 139 case ccs.TextureResType.plist: 140 barRenderer.initWithSpriteFrameName(fileName); 141 break; 142 default: 143 break; 144 } 145 this.updateRGBAToRenderer(barRenderer); 146 this.barRendererScaleChangedWithSize(); 147 148 if (!barRenderer.textureLoaded()) { 149 barRenderer.addLoadedEventListener(function () { 150 this.barRendererScaleChangedWithSize(); 151 }, this); 152 } 153 }, 154 155 /** 156 * Load dark state texture for slider progress bar. 157 * @param {String} fileName 158 * @param {ccs.TextureResType} texType 159 */ 160 loadProgressBarTexture: function (fileName, texType) { 161 if (!fileName) { 162 return; 163 } 164 texType = texType || ccs.TextureResType.local; 165 this._progressBarTextureFile = fileName; 166 this._progressBarTexType = texType; 167 var progressBarRenderer = this._progressBarRenderer; 168 switch (this._progressBarTexType) { 169 case ccs.TextureResType.local: 170 progressBarRenderer.initWithFile(fileName); 171 break; 172 case ccs.TextureResType.plist: 173 progressBarRenderer.initWithSpriteFrameName(fileName); 174 break; 175 default: 176 break; 177 } 178 this.updateRGBAToRenderer(progressBarRenderer); 179 progressBarRenderer.setAnchorPoint(0.0, 0.5); 180 var locSize = progressBarRenderer.getContentSize(); 181 this._progressBarTextureSize.width = locSize.width; 182 this._progressBarTextureSize.height = locSize.height; 183 this.progressBarRendererScaleChangedWithSize(); 184 185 var textLoaded = progressBarRenderer.textureLoaded(); 186 this._isTextureLoaded = textLoaded; 187 if (!textLoaded) { 188 progressBarRenderer.addLoadedEventListener(function () { 189 this._isTextureLoaded = true; 190 var locSize = progressBarRenderer.getContentSize(); 191 this._progressBarTextureSize.width = locSize.width; 192 this._progressBarTextureSize.height = locSize.height; 193 this.progressBarRendererScaleChangedWithSize(); 194 }, this); 195 } 196 }, 197 198 /** 199 * Sets if slider is using scale9 renderer. 200 * @param {Boolean} able 201 */ 202 setScale9Enabled: function (able) { 203 if (this._scale9Enabled == able) { 204 return; 205 } 206 207 this._scale9Enabled = able; 208 cc.Node.prototype.removeChild.call(this, this._barRenderer, true); 209 cc.Node.prototype.removeChild.call(this, this._progressBarRenderer, true); 210 this._barRenderer = null; 211 this._progressBarRenderer = null; 212 if (this._scale9Enabled) { 213 this._barRenderer = cc.Scale9Sprite.create(); 214 this._progressBarRenderer = cc.Scale9Sprite.create(); 215 } 216 else { 217 this._barRenderer = cc.Sprite.create(); 218 this._progressBarRenderer = cc.Sprite.create(); 219 } 220 this.loadBarTexture(this._textureFile, this._barTexType); 221 this.loadProgressBarTexture(this._progressBarTextureFile, this._progressBarTexType); 222 cc.Node.prototype.addChild.call(this, this._barRenderer, ccs.BASEBARRENDERERZ, -1); 223 cc.Node.prototype.addChild.call(this, this._progressBarRenderer, ccs.PROGRESSBARRENDERERZ, -1); 224 if (this._scale9Enabled) { 225 var ignoreBefore = this._ignoreSize; 226 this.ignoreContentAdaptWithSize(false); 227 this._prevIgnoreSize = ignoreBefore; 228 } 229 else { 230 this.ignoreContentAdaptWithSize(this._prevIgnoreSize); 231 } 232 this.setCapInsetsBarRenderer(this._capInsetsBarRenderer); 233 this.setCapInsetProgressBarRebderer(this._capInsetsProgressBarRenderer); 234 }, 235 236 /** 237 * Get slider is using scale9 renderer or not. 238 * @returns {Boolean} 239 */ 240 isScale9Enabled:function(){ 241 return this._scale9Enabled; 242 }, 243 244 /** 245 * override "ignoreContentAdaptWithSize" method of widget. 246 * @param {Boolean} ignore 247 */ 248 ignoreContentAdaptWithSize: function (ignore) { 249 if (!this._scale9Enabled || (this._scale9Enabled && !ignore)) { 250 ccs.Widget.prototype.ignoreContentAdaptWithSize.call(this, ignore); 251 this._prevIgnoreSize = ignore; 252 } 253 }, 254 255 /** 256 * Sets capinsets for slider, if slider is using scale9 renderer. 257 * @param {cc.Rect} capInsets 258 */ 259 setCapInsets: function (capInsets) { 260 this.setCapInsetsBarRenderer(capInsets); 261 this.setCapInsetProgressBarRebderer(capInsets); 262 }, 263 264 /** 265 * Sets capinsets for slider, if slider is using scale9 renderer. 266 * @param {cc.Rect} capInsets 267 */ 268 setCapInsetsBarRenderer: function (capInsets) { 269 this._capInsetsBarRenderer = capInsets; 270 if (!this._scale9Enabled) { 271 return; 272 } 273 this._barRenderer.setCapInsets(capInsets); 274 }, 275 276 /** 277 * Get cap insets for slider. 278 * @returns {cc.Rect} 279 */ 280 getCapInsetBarRenderer:function(){ 281 return this._capInsetsBarRenderer; 282 }, 283 284 /** 285 * Sets capinsets for slider, if slider is using scale9 renderer. 286 * @param {cc.Rect} capInsets 287 */ 288 setCapInsetProgressBarRebderer: function (capInsets) { 289 this._capInsetsProgressBarRenderer = capInsets; 290 if (!this._scale9Enabled) { 291 return; 292 } 293 this._progressBarRenderer.setCapInsets(capInsets); 294 }, 295 296 /** 297 * Get cap insets for slider. 298 * @returns {cc.Rect} 299 */ 300 getCapInsetProgressBarRebderer:function(){ 301 return this._capInsetsProgressBarRenderer; 302 }, 303 304 /** 305 * Load textures for slider ball. 306 * @param {String} normal 307 * @param {String} pressed 308 * @param {String} disabled 309 * @param {ccs.TextureResType} texType 310 */ 311 loadSlidBallTextures: function (normal, pressed, disabled, texType) { 312 this.loadSlidBallTextureNormal(normal, texType); 313 this.loadSlidBallTexturePressed(pressed, texType); 314 this.loadSlidBallTextureDisabled(disabled, texType); 315 }, 316 317 /** 318 * Load normal state texture for slider ball. 319 * @param {String} normal 320 * @param {ccs.TextureResType} texType 321 */ 322 loadSlidBallTextureNormal: function (normal, texType) { 323 if (!normal) { 324 return; 325 } 326 texType = texType || ccs.TextureResType.local; 327 this._slidBallNormalTextureFile = normal; 328 this._ballNTexType = texType; 329 switch (this._ballNTexType) { 330 case ccs.TextureResType.local: 331 this._slidBallNormalRenderer.initWithFile(normal); 332 break; 333 case ccs.TextureResType.plist: 334 this._slidBallNormalRenderer.initWithSpriteFrameName(normal); 335 break; 336 default: 337 break; 338 } 339 this.updateRGBAToRenderer(this._slidBallNormalRenderer); 340 }, 341 342 /** 343 * Load selected state texture for slider ball. 344 * @param {String} pressed 345 * @param {ccs.TextureResType} texType 346 */ 347 loadSlidBallTexturePressed: function (pressed, texType) { 348 if (!pressed) { 349 return; 350 } 351 texType = texType || ccs.TextureResType.local; 352 this._slidBallPressedTextureFile = pressed; 353 this._ballPTexType = texType; 354 switch (this._ballPTexType) { 355 case ccs.TextureResType.local: 356 this._slidBallPressedRenderer.initWithFile(pressed); 357 break; 358 case ccs.TextureResType.plist: 359 this._slidBallPressedRenderer.initWithSpriteFrameName(pressed); 360 break; 361 default: 362 break; 363 } 364 this.updateRGBAToRenderer(this._slidBallPressedRenderer); 365 }, 366 367 /** 368 * Load dark state texture for slider ball. 369 * @param {String} disabled 370 * @param {ccs.TextureResType} texType 371 */ 372 loadSlidBallTextureDisabled: function (disabled, texType) { 373 if (!disabled) { 374 return; 375 } 376 texType = texType || ccs.TextureResType.local; 377 this._slidBallDisabledTextureFile = disabled; 378 this._ballDTexType = texType; 379 switch (this._ballDTexType) { 380 case ccs.TextureResType.local: 381 this._slidBallDisabledRenderer.initWithFile(disabled); 382 break; 383 case ccs.TextureResType.plist: 384 this._slidBallDisabledRenderer.initWithSpriteFrameName(disabled); 385 break; 386 default: 387 break; 388 } 389 this.updateRGBAToRenderer(this._slidBallDisabledRenderer); 390 }, 391 392 /** 393 * Changes the progress direction of slider. 394 * @param {number} percent 395 */ 396 setPercent: function (percent) { 397 if (percent > 100) { 398 percent = 100; 399 } 400 if (percent < 0) { 401 percent = 0; 402 } 403 this._percent = percent; 404 if(!this._isTextureLoaded){ 405 return; 406 } 407 var dis = this._barLength * (percent / 100.0); 408 this._slidBallRenderer.setPosition(cc.p(-this._barLength / 2.0 + dis, 0.0)); 409 if (this._scale9Enabled) { 410 this._progressBarRenderer.setPreferredSize(cc.size(dis, this._progressBarTextureSize.height)); 411 } 412 else { 413 var x = 0, y = 0; 414 if (this._progressBarTexType == ccs.TextureResType.plist) { 415 var barNode = this._progressBarRenderer; 416 if (barNode) { 417 var to = barNode.getTextureRect()._origin; 418 x = to.x; 419 y = to.y; 420 } 421 } 422 this._progressBarRenderer.setTextureRect(cc.rect(x, y, this._progressBarTextureSize.width * (percent / 100.0), this._progressBarTextureSize.height)); 423 } 424 }, 425 426 onTouchBegan: function (touch , event) { 427 var pass = ccs.Widget.prototype.onTouchBegan.call(this,touch , event); 428 if(this._hitted){ 429 var nsp = this.convertToNodeSpace(this._touchStartPos); 430 this.setPercent(this.getPercentWithBallPos(nsp.x)); 431 this.percentChangedEvent(); 432 } 433 return pass; 434 }, 435 436 onTouchMoved: function (touch , event) { 437 var touchPoint = touch.getLocation(); 438 this._touchMovePos.x = touchPoint.x; 439 this._touchMovePos.y = touchPoint.y; 440 var nsp = this.convertToNodeSpace(touchPoint); 441 this._slidBallRenderer.setPosition(cc.p(nsp.x, 0)); 442 this.setPercent(this.getPercentWithBallPos(nsp.x)); 443 this.percentChangedEvent(); 444 }, 445 446 onTouchEnded: function (touch , event) { 447 ccs.Widget.prototype.onTouchEnded.call(this, touch , event); 448 }, 449 450 onTouchCancelled: function (touch , event) { 451 ccs.Widget.prototype.onTouchCancelled.call(this, touch , event); 452 }, 453 454 /** 455 * get percent with ballPos 456 * @param {cc.Point} px 457 * @returns {number} 458 */ 459 getPercentWithBallPos: function (px) { 460 return (((px - (-this._barLength / 2.0)) / this._barLength) * 100.0); 461 }, 462 463 /** 464 * add event listener 465 * @param {Function} selector 466 * @param {Object} target 467 */ 468 addEventListenerSlider: function (selector, target) { 469 this._sliderEventSelector = selector; 470 this._sliderEventListener = target; 471 }, 472 473 percentChangedEvent: function () { 474 if (this._sliderEventListener && this._sliderEventSelector) { 475 this._sliderEventSelector.call(this._sliderEventListener, this, ccs.SliderEventType.percent_changed); 476 } 477 }, 478 479 /** 480 * Gets the progress direction of slider. 481 * @returns {number} 482 */ 483 getPercent: function () { 484 return this._percent; 485 }, 486 487 onSizeChanged: function () { 488 ccs.Widget.prototype.onSizeChanged.call(this); 489 this.barRendererScaleChangedWithSize(); 490 this.progressBarRendererScaleChangedWithSize(); 491 }, 492 493 /** 494 * override "getContentSize" method of widget. 495 * @returns {cc.Size} 496 */ 497 getContentSize: function () { 498 var locContentSize = this._barRenderer.getContentSize(); 499 return cc.size(locContentSize.width,locContentSize.height); 500 }, 501 502 /** 503 * override "getContentSize" method of widget. 504 * @returns {cc.Node} 505 */ 506 getVirtualRenderer: function () { 507 return this._barRenderer; 508 }, 509 510 barRendererScaleChangedWithSize: function () { 511 if (this._ignoreSize) { 512 this._barRenderer.setScale(1.0); 513 var locSize = this._barRenderer.getContentSize(); 514 this._size.width = locSize.width; 515 this._size.height = locSize.height; 516 this._barLength = locSize.width; 517 } 518 else { 519 this._barLength = this._size.width; 520 if (this._scale9Enabled) { 521 this._barRenderer.setPreferredSize(cc.size(this._size.width,this._size.height)); 522 } 523 else { 524 var btextureSize = this._barRenderer.getContentSize(); 525 if (btextureSize.width <= 0.0 || btextureSize.height <= 0.0) { 526 this._barRenderer.setScale(1.0); 527 return; 528 } 529 var bscaleX = this._size.width / btextureSize.width; 530 var bscaleY = this._size.height / btextureSize.height; 531 this._barRenderer.setScaleX(bscaleX); 532 this._barRenderer.setScaleY(bscaleY); 533 } 534 } 535 this.setPercent(this._percent); 536 }, 537 538 progressBarRendererScaleChangedWithSize: function () { 539 if (this._ignoreSize) { 540 if (!this._scale9Enabled) { 541 var ptextureSize = this._progressBarTextureSize; 542 var pscaleX = this._size.width / ptextureSize.width; 543 var pscaleY = this._size.height / ptextureSize.height; 544 this._progressBarRenderer.setScaleX(pscaleX); 545 this._progressBarRenderer.setScaleY(pscaleY); 546 } 547 } 548 else { 549 if (this._scale9Enabled) { 550 this._progressBarRenderer.setPreferredSize(cc.size(this._size.width,this._size.height)); 551 } 552 else { 553 var ptextureSize = this._progressBarTextureSize; 554 if (ptextureSize.width <= 0.0 || ptextureSize.height <= 0.0) { 555 this._progressBarRenderer.setScale(1.0); 556 return; 557 } 558 var pscaleX = this._size.width / ptextureSize.width; 559 var pscaleY = this._size.height / ptextureSize.height; 560 this._progressBarRenderer.setScaleX(pscaleX); 561 this._progressBarRenderer.setScaleY(pscaleY); 562 } 563 } 564 this._progressBarRenderer.setPosition(cc.p(-this._barLength * 0.5, 0.0)); 565 this.setPercent(this._percent); 566 }, 567 568 onPressStateChangedToNormal: function () { 569 this._slidBallNormalRenderer.setVisible(true); 570 this._slidBallPressedRenderer.setVisible(false); 571 this._slidBallDisabledRenderer.setVisible(false); 572 }, 573 574 onPressStateChangedToPressed: function () { 575 this._slidBallNormalRenderer.setVisible(false); 576 this._slidBallPressedRenderer.setVisible(true); 577 this._slidBallDisabledRenderer.setVisible(false); 578 }, 579 580 onPressStateChangedToDisabled: function () { 581 this._slidBallNormalRenderer.setVisible(false); 582 this._slidBallPressedRenderer.setVisible(false); 583 this._slidBallDisabledRenderer.setVisible(true); 584 }, 585 586 updateTextureColor: function () { 587 this.updateColorToRenderer(this._barRenderer); 588 this.updateColorToRenderer(this._progressBarRenderer); 589 this.updateColorToRenderer(this._slidBallNormalRenderer); 590 this.updateColorToRenderer(this._slidBallPressedRenderer); 591 this.updateColorToRenderer(this._slidBallDisabledRenderer); 592 }, 593 594 updateTextureOpacity: function () { 595 this.updateOpacityToRenderer(this._barRenderer); 596 this.updateOpacityToRenderer(this._progressBarRenderer); 597 this.updateOpacityToRenderer(this._slidBallNormalRenderer); 598 this.updateOpacityToRenderer(this._slidBallPressedRenderer); 599 this.updateOpacityToRenderer(this._slidBallDisabledRenderer); 600 }, 601 602 updateTextureRGBA: function () { 603 this.updateRGBAToRenderer(this._barRenderer); 604 this.updateRGBAToRenderer(this._progressBarRenderer); 605 this.updateRGBAToRenderer(this._slidBallNormalRenderer); 606 this.updateRGBAToRenderer(this._slidBallPressedRenderer); 607 this.updateRGBAToRenderer(this._slidBallDisabledRenderer); 608 }, 609 610 /** 611 * Returns the "class name" of widget. 612 * @returns {string} 613 */ 614 getDescription: function () { 615 return "Slider"; 616 }, 617 618 createCloneInstance: function () { 619 return ccs.Slider.create(); 620 }, 621 622 copySpecialProperties: function (slider) { 623 this._prevIgnoreSize = slider._prevIgnoreSize; 624 this.setScale9Enabled(slider._scale9Enabled); 625 this.loadBarTexture(slider._textureFile, slider._barTexType); 626 this.loadProgressBarTexture(slider._progressBarTextureFile, slider._progressBarTexType); 627 this.loadSlidBallTextureNormal(slider._slidBallNormalTextureFile, slider._ballNTexType); 628 this.loadSlidBallTexturePressed(slider._slidBallPressedTextureFile, slider._ballPTexType); 629 this.loadSlidBallTextureDisabled(slider._slidBallDisabledTextureFile, slider._ballDTexType); 630 this.setPercent(slider.getPercent()); 631 } 632 }); 633 /** 634 * allocates and initializes a UISlider. 635 * @constructs 636 * @return {ccs.Slider} 637 * @example 638 * // example 639 * var uiSlider = ccs.Slider.create(); 640 */ 641 ccs.Slider.create = function () { 642 var uiSlider = new ccs.Slider(); 643 if (uiSlider && uiSlider.init()) { 644 return uiSlider; 645 } 646 return null; 647 };