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