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 initRenderer: function () { 97 this._barRenderer = cc.Sprite.create(); 98 this._progressBarRenderer = cc.Sprite.create(); 99 this._progressBarRenderer.setAnchorPoint(0.0, 0.5); 100 cc.NodeRGBA.prototype.addChild.call(this, this._barRenderer, ccs.BASEBARRENDERERZ, -1); 101 cc.NodeRGBA.prototype.addChild.call(this, this._progressBarRenderer, ccs.PROGRESSBARRENDERERZ, -1); 102 this._slidBallNormalRenderer = cc.Sprite.create(); 103 this._slidBallPressedRenderer = cc.Sprite.create(); 104 this._slidBallPressedRenderer.setVisible(false); 105 this._slidBallDisabledRenderer = cc.Sprite.create(); 106 this._slidBallDisabledRenderer.setVisible(false); 107 this._slidBallRenderer = cc.Node.create(); 108 this._slidBallRenderer.addChild(this._slidBallNormalRenderer); 109 this._slidBallRenderer.addChild(this._slidBallPressedRenderer); 110 this._slidBallRenderer.addChild(this._slidBallDisabledRenderer); 111 cc.NodeRGBA.prototype.addChild.call(this, this._slidBallRenderer, ccs.SLIDBALLRENDERERZ, -1); 112 }, 113 114 /** 115 * Load texture for slider bar. 116 * @param {String} fileName 117 * @param {ccs.TextureResType} texType 118 */ 119 loadBarTexture: function (fileName, texType) { 120 if (!fileName) { 121 return; 122 } 123 texType = texType || ccs.TextureResType.local; 124 this._textureFile = fileName; 125 this._barTexType = texType; 126 var barRenderer = this._barRenderer; 127 switch (this._barTexType) { 128 case ccs.TextureResType.local: 129 barRenderer.initWithFile(fileName); 130 break; 131 case ccs.TextureResType.plist: 132 barRenderer.initWithSpriteFrameName(fileName); 133 break; 134 default: 135 break; 136 } 137 this._updateDisplay(); 138 this.barRendererScaleChangedWithSize(); 139 140 if (!barRenderer.textureLoaded()) { 141 barRenderer.addLoadedEventListener(function () { 142 this.barRendererScaleChangedWithSize(); 143 }, this); 144 } 145 }, 146 147 /** 148 * Load dark state texture for slider progress bar. 149 * @param {String} fileName 150 * @param {ccs.TextureResType} texType 151 */ 152 loadProgressBarTexture: function (fileName, texType) { 153 if (!fileName) { 154 return; 155 } 156 texType = texType || ccs.TextureResType.local; 157 this._progressBarTextureFile = fileName; 158 this._progressBarTexType = texType; 159 var progressBarRenderer = this._progressBarRenderer; 160 switch (this._progressBarTexType) { 161 case ccs.TextureResType.local: 162 progressBarRenderer.initWithFile(fileName); 163 break; 164 case ccs.TextureResType.plist: 165 progressBarRenderer.initWithSpriteFrameName(fileName); 166 break; 167 default: 168 break; 169 } 170 this._updateDisplay(); 171 progressBarRenderer.setAnchorPoint(0.0, 0.5); 172 var locSize = progressBarRenderer.getContentSize(); 173 this._progressBarTextureSize.width = locSize.width; 174 this._progressBarTextureSize.height = locSize.height; 175 this.progressBarRendererScaleChangedWithSize(); 176 177 var textLoaded = progressBarRenderer.textureLoaded(); 178 this._isTextureLoaded = textLoaded; 179 if (!textLoaded) { 180 progressBarRenderer.addLoadedEventListener(function () { 181 this._isTextureLoaded = true; 182 var locSize = progressBarRenderer.getContentSize(); 183 this._progressBarTextureSize.width = locSize.width; 184 this._progressBarTextureSize.height = locSize.height; 185 this.progressBarRendererScaleChangedWithSize(); 186 }, this); 187 } 188 }, 189 190 _updateDisplay:function(){ 191 this.updateDisplayedColor(this.getColor()); 192 this.updateDisplayedOpacity(this.getOpacity()); 193 }, 194 195 /** 196 * Sets if slider is using scale9 renderer. 197 * @param {Boolean} able 198 */ 199 setScale9Enabled: function (able) { 200 if (this._scale9Enabled == able) { 201 return; 202 } 203 204 this._scale9Enabled = able; 205 cc.NodeRGBA.prototype.removeChild.call(this, this._barRenderer, true); 206 cc.NodeRGBA.prototype.removeChild.call(this, this._progressBarRenderer, true); 207 this._barRenderer = null; 208 this._progressBarRenderer = null; 209 if (this._scale9Enabled) { 210 this._barRenderer = cc.Scale9Sprite.create(); 211 this._progressBarRenderer = cc.Scale9Sprite.create(); 212 } 213 else { 214 this._barRenderer = cc.Sprite.create(); 215 this._progressBarRenderer = cc.Sprite.create(); 216 } 217 this.loadBarTexture(this._textureFile, this._barTexType); 218 this.loadProgressBarTexture(this._progressBarTextureFile, this._progressBarTexType); 219 cc.NodeRGBA.prototype.addChild.call(this, this._barRenderer, ccs.BASEBARRENDERERZ, -1); 220 cc.NodeRGBA.prototype.addChild.call(this, this._progressBarRenderer, ccs.PROGRESSBARRENDERERZ, -1); 221 if (this._scale9Enabled) { 222 var ignoreBefore = this._ignoreSize; 223 this.ignoreContentAdaptWithSize(false); 224 this._prevIgnoreSize = ignoreBefore; 225 } 226 else { 227 this.ignoreContentAdaptWithSize(this._prevIgnoreSize); 228 } 229 this.setCapInsetsBarRenderer(this._capInsetsBarRenderer); 230 this.setCapInsetProgressBarRebderer(this._capInsetsProgressBarRenderer); 231 }, 232 233 /** 234 * override "ignoreContentAdaptWithSize" method of widget. 235 * @param {Boolean} ignore 236 */ 237 ignoreContentAdaptWithSize: function (ignore) { 238 if (!this._scale9Enabled || (this._scale9Enabled && !ignore)) { 239 ccs.Widget.prototype.ignoreContentAdaptWithSize.call(this, ignore); 240 this._prevIgnoreSize = ignore; 241 } 242 }, 243 244 /** 245 * Sets capinsets for slider, if slider is using scale9 renderer. 246 * @param {cc.Rect} capInsets 247 */ 248 setCapInsets: function (capInsets) { 249 this.setCapInsetsBarRenderer(capInsets); 250 this.setCapInsetProgressBarRebderer(capInsets); 251 }, 252 253 /** 254 * Sets capinsets for slider, if slider is using scale9 renderer. 255 * @param {cc.Rect} capInsets 256 */ 257 setCapInsetsBarRenderer: function (capInsets) { 258 this._capInsetsBarRenderer = capInsets; 259 if (!this._scale9Enabled) { 260 return; 261 } 262 this._barRenderer.setCapInsets(capInsets); 263 }, 264 265 /** 266 * Sets capinsets for slider, if slider is using scale9 renderer. 267 * @param {cc.Rect} capInsets 268 */ 269 setCapInsetProgressBarRebderer: function (capInsets) { 270 this._capInsetsProgressBarRenderer = capInsets; 271 if (!this._scale9Enabled) { 272 return; 273 } 274 this._progressBarRenderer.setCapInsets(capInsets); 275 }, 276 277 /** 278 * Load textures for slider ball. 279 * @param {String} normal 280 * @param {String} pressed 281 * @param {String} disabled 282 * @param {ccs.TextureResType} texType 283 */ 284 loadSlidBallTextures: function (normal, pressed, disabled, texType) { 285 this.loadSlidBallTextureNormal(normal, texType); 286 this.loadSlidBallTexturePressed(pressed, texType); 287 this.loadSlidBallTextureDisabled(disabled, texType); 288 }, 289 290 /** 291 * Load normal state texture for slider ball. 292 * @param {String} normal 293 * @param {ccs.TextureResType} texType 294 */ 295 loadSlidBallTextureNormal: function (normal, texType) { 296 if (!normal) { 297 return; 298 } 299 texType = texType || ccs.TextureResType.local; 300 this._slidBallNormalTextureFile = normal; 301 this._ballNTexType = texType; 302 switch (this._ballNTexType) { 303 case ccs.TextureResType.local: 304 this._slidBallNormalRenderer.initWithFile(normal); 305 break; 306 case ccs.TextureResType.plist: 307 this._slidBallNormalRenderer.initWithSpriteFrameName(normal); 308 break; 309 default: 310 break; 311 } 312 this._updateDisplay(); 313 }, 314 315 /** 316 * Load selected state texture for slider ball. 317 * @param {String} pressed 318 * @param {ccs.TextureResType} texType 319 */ 320 loadSlidBallTexturePressed: function (pressed, texType) { 321 if (!pressed) { 322 return; 323 } 324 texType = texType || ccs.TextureResType.local; 325 this._slidBallPressedTextureFile = pressed; 326 this._ballPTexType = texType; 327 switch (this._ballPTexType) { 328 case ccs.TextureResType.local: 329 this._slidBallPressedRenderer.initWithFile(pressed); 330 break; 331 case ccs.TextureResType.plist: 332 this._slidBallPressedRenderer.initWithSpriteFrameName(pressed); 333 break; 334 default: 335 break; 336 } 337 this._updateDisplay(); 338 }, 339 340 /** 341 * Load dark state texture for slider ball. 342 * @param {String} disabled 343 * @param {ccs.TextureResType} texType 344 */ 345 loadSlidBallTextureDisabled: function (disabled, texType) { 346 if (!disabled) { 347 return; 348 } 349 texType = texType || ccs.TextureResType.local; 350 this._slidBallDisabledTextureFile = disabled; 351 this._ballDTexType = texType; 352 switch (this._ballDTexType) { 353 case ccs.TextureResType.local: 354 this._slidBallDisabledRenderer.initWithFile(disabled); 355 break; 356 case ccs.TextureResType.plist: 357 this._slidBallDisabledRenderer.initWithSpriteFrameName(disabled); 358 break; 359 default: 360 break; 361 } 362 this._updateDisplay(); 363 }, 364 365 /** 366 * Changes the progress direction of slider. 367 * @param {number} percent 368 */ 369 setPercent: function (percent) { 370 if (percent > 100) { 371 percent = 100; 372 } 373 if (percent < 0) { 374 percent = 0; 375 } 376 this._percent = percent; 377 if(!this._isTextureLoaded){ 378 return; 379 } 380 var dis = this._barLength * (percent / 100.0); 381 this._slidBallRenderer.setPosition(cc.p(-this._barLength / 2.0 + dis, 0.0)); 382 if (this._scale9Enabled) { 383 this._progressBarRenderer.setPreferredSize(cc.size(dis, this._progressBarTextureSize.height)); 384 } 385 else { 386 var x = 0, y = 0; 387 if (this._progressBarTexType == ccs.TextureResType.plist) { 388 var barNode = this._progressBarRenderer; 389 if (barNode) { 390 var to = barNode.getTextureRect()._origin; 391 x = to.x; 392 y = to.y; 393 } 394 } 395 this._progressBarRenderer.setTextureRect(cc.rect(x, y, this._progressBarTextureSize.width * (percent / 100.0), this._progressBarTextureSize.height)); 396 } 397 }, 398 399 onTouchBegan: function (touch , event) { 400 var pass = ccs.Widget.prototype.onTouchBegan.call(this,touch , event); 401 if(this._hitted){ 402 var nsp = this.convertToNodeSpace(this._touchStartPos); 403 this.setPercent(this.getPercentWithBallPos(nsp.x)); 404 this.percentChangedEvent(); 405 } 406 return pass; 407 }, 408 409 onTouchMoved: function (touch , event) { 410 var touchPoint = touch.getLocation(); 411 this._touchMovePos.x = touchPoint.x; 412 this._touchMovePos.y = touchPoint.y; 413 var nsp = this.convertToNodeSpace(touchPoint); 414 this._slidBallRenderer.setPosition(cc.p(nsp.x, 0)); 415 this.setPercent(this.getPercentWithBallPos(nsp.x)); 416 this.percentChangedEvent(); 417 }, 418 419 onTouchEnded: function (touch , event) { 420 ccs.Widget.prototype.onTouchEnded.call(this, touch , event); 421 }, 422 423 onTouchCancelled: function (touch , event) { 424 ccs.Widget.prototype.onTouchCancelled.call(this, touch , event); 425 }, 426 427 /** 428 * get percent with ballPos 429 * @param {cc.Point} px 430 * @returns {number} 431 */ 432 getPercentWithBallPos: function (px) { 433 return (((px - (-this._barLength / 2.0)) / this._barLength) * 100.0); 434 }, 435 436 /** 437 * add event listener 438 * @param {Function} selector 439 * @param {Object} target 440 */ 441 addEventListenerSlider: function (selector, target) { 442 this._sliderEventSelector = selector; 443 this._sliderEventListener = target; 444 }, 445 446 percentChangedEvent: function () { 447 if (this._sliderEventListener && this._sliderEventSelector) { 448 this._sliderEventSelector.call(this._sliderEventListener, this, ccs.SliderEventType.percent_changed); 449 } 450 }, 451 452 /** 453 * Gets the progress direction of slider. 454 * @returns {number} 455 */ 456 getPercent: function () { 457 return this._percent; 458 }, 459 460 onSizeChanged: function () { 461 ccs.Widget.prototype.onSizeChanged.call(this); 462 this.barRendererScaleChangedWithSize(); 463 this.progressBarRendererScaleChangedWithSize(); 464 }, 465 466 /** 467 * override "getContentSize" method of widget. 468 * @returns {cc.Size} 469 */ 470 getContentSize: function () { 471 var locContentSize = this._barRenderer.getContentSize(); 472 return cc.size(locContentSize.width,locContentSize.height); 473 }, 474 475 /** 476 * override "getContentSize" method of widget. 477 * @returns {cc.Node} 478 */ 479 getVirtualRenderer: function () { 480 return this._barRenderer; 481 }, 482 483 barRendererScaleChangedWithSize: function () { 484 if (this._ignoreSize) { 485 this._barRenderer.setScale(1.0); 486 var locSize = this._barRenderer.getContentSize(); 487 this._size.width = locSize.width; 488 this._size.height = locSize.height; 489 this._barLength = locSize.width; 490 } 491 else { 492 this._barLength = this._size.width; 493 if (this._scale9Enabled) { 494 this._barRenderer.setPreferredSize(cc.size(this._size.width,this._size.height)); 495 } 496 else { 497 var btextureSize = this._barRenderer.getContentSize(); 498 if (btextureSize.width <= 0.0 || btextureSize.height <= 0.0) { 499 this._barRenderer.setScale(1.0); 500 return; 501 } 502 var bscaleX = this._size.width / btextureSize.width; 503 var bscaleY = this._size.height / btextureSize.height; 504 this._barRenderer.setScaleX(bscaleX); 505 this._barRenderer.setScaleY(bscaleY); 506 } 507 } 508 this.setPercent(this._percent); 509 }, 510 511 progressBarRendererScaleChangedWithSize: function () { 512 if (this._ignoreSize) { 513 if (!this._scale9Enabled) { 514 var ptextureSize = this._progressBarTextureSize; 515 var pscaleX = this._size.width / ptextureSize.width; 516 var pscaleY = this._size.height / ptextureSize.height; 517 this._progressBarRenderer.setScaleX(pscaleX); 518 this._progressBarRenderer.setScaleY(pscaleY); 519 } 520 } 521 else { 522 if (this._scale9Enabled) { 523 this._progressBarRenderer.setPreferredSize(cc.size(this._size.width,this._size.height)); 524 } 525 else { 526 var ptextureSize = this._progressBarTextureSize; 527 if (ptextureSize.width <= 0.0 || ptextureSize.height <= 0.0) { 528 this._progressBarRenderer.setScale(1.0); 529 return; 530 } 531 var pscaleX = this._size.width / ptextureSize.width; 532 var pscaleY = this._size.height / ptextureSize.height; 533 this._progressBarRenderer.setScaleX(pscaleX); 534 this._progressBarRenderer.setScaleY(pscaleY); 535 } 536 } 537 this._progressBarRenderer.setPosition(cc.p(-this._barLength * 0.5, 0.0)); 538 this.setPercent(this._percent); 539 }, 540 541 onPressStateChangedToNormal: function () { 542 this._slidBallNormalRenderer.setVisible(true); 543 this._slidBallPressedRenderer.setVisible(false); 544 this._slidBallDisabledRenderer.setVisible(false); 545 }, 546 547 onPressStateChangedToPressed: function () { 548 this._slidBallNormalRenderer.setVisible(false); 549 this._slidBallPressedRenderer.setVisible(true); 550 this._slidBallDisabledRenderer.setVisible(false); 551 }, 552 553 onPressStateChangedToDisabled: function () { 554 this._slidBallNormalRenderer.setVisible(false); 555 this._slidBallPressedRenderer.setVisible(false); 556 this._slidBallDisabledRenderer.setVisible(true); 557 }, 558 559 /** 560 * Returns the "class name" of widget. 561 * @returns {string} 562 */ 563 getDescription: function () { 564 return "Slider"; 565 }, 566 567 createCloneInstance: function () { 568 return ccs.Slider.create(); 569 }, 570 571 copySpecialProperties: function (slider) { 572 this._prevIgnoreSize = slider._prevIgnoreSize; 573 this.setScale9Enabled(slider._scale9Enabled); 574 this.loadBarTexture(slider._textureFile, slider._barTexType); 575 this.loadProgressBarTexture(slider._progressBarTextureFile, slider._progressBarTexType); 576 this.loadSlidBallTextureNormal(slider._slidBallNormalTextureFile, slider._ballNTexType); 577 this.loadSlidBallTexturePressed(slider._slidBallPressedTextureFile, slider._ballPTexType); 578 this.loadSlidBallTextureDisabled(slider._slidBallDisabledTextureFile, slider._ballDTexType); 579 this.setPercent(slider.getPercent()); 580 } 581 }); 582 /** 583 * allocates and initializes a UISlider. 584 * @constructs 585 * @return {ccs.Slider} 586 * @example 587 * // example 588 * var uiSlider = ccs.Slider.create(); 589 */ 590 ccs.Slider.create = function () { 591 var uiSlider = new ccs.Slider(); 592 if (uiSlider && uiSlider.init()) { 593 return uiSlider; 594 } 595 return null; 596 };