1 /** 2 * 3 * Copyright (c) 2008-2010 Ricardo Quesada 4 * Copyright (c) 2011-2012 cocos2d-x.org 5 * Copyright (c) 2013-2014 Chukong Technologies Inc. 6 * 7 * Copyright 2011 Yannick Loriot. All rights reserved. 8 * http://yannickloriot.com 9 * 10 * Permission is hereby granted, free of charge, to any person obtaining a copy 11 * of this software and associated documentation files (the "Software"), to deal 12 * in the Software without restriction, including without limitation the rights 13 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 * copies of the Software, and to permit persons to whom the Software is 15 * furnished to do so, subject to the following conditions: 16 * 17 * The above copyright notice and this permission notice shall be included in 18 * all copies or substantial portions of the Software. 19 * 20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 26 * THE SOFTWARE. 27 */ 28 29 /** 30 * CCControlSwitch: Switch control ui component 31 * @class 32 * @extend cc.Control 33 */ 34 cc.ControlSwitch = cc.Control.extend(/** @lends cc.ControlSwitch# */{ 35 /** Sprite which represents the view. */ 36 _switchSprite:null, 37 _initialTouchXPosition:0, 38 39 _moved:false, 40 /** A Boolean value that determines the off/on state of the switch. */ 41 _on:false, 42 _className:"ControlSwitch", 43 ctor:function () { 44 cc.Control.prototype.ctor.call(this); 45 }, 46 47 /** Creates a switch with a mask sprite, on/off sprites for on/off states, a thumb sprite and an on/off labels. */ 48 initWithMaskSprite:function (maskSprite, onSprite, offSprite, thumbSprite, onLabel, offLabel) { 49 if(!maskSprite) 50 throw "cc.ControlSwitch.initWithMaskSprite(): maskSprite should be non-null."; 51 if(!onSprite) 52 throw "cc.ControlSwitch.initWithMaskSprite(): onSprite should be non-null."; 53 if(!offSprite) 54 throw "cc.ControlSwitch.initWithMaskSprite(): offSprite should be non-null."; 55 if(!thumbSprite) 56 throw "cc.ControlSwitch.initWithMaskSprite(): thumbSprite should be non-null."; 57 if (this.init()) { 58 this._on = true; 59 60 this._switchSprite = new cc.ControlSwitchSprite(); 61 this._switchSprite.initWithMaskSprite(maskSprite, onSprite, offSprite, thumbSprite, onLabel, offLabel); 62 this._switchSprite.setPosition(this._switchSprite.getContentSize().width / 2, this._switchSprite.getContentSize().height / 2); 63 this.addChild(this._switchSprite); 64 65 this.ignoreAnchorPointForPosition(false); 66 this.setAnchorPoint(0.5, 0.5); 67 this.setContentSize(this._switchSprite.getContentSize()); 68 return true; 69 } 70 return false; 71 }, 72 73 setOn:function (isOn, animated) { 74 animated = animated || false; 75 this._on = isOn; 76 var xPosition = (this._on) ? this._switchSprite.getOnPosition() : this._switchSprite.getOffPosition(); 77 if(animated){ 78 this._switchSprite.runAction(cc.ActionTween.create(0.2, "sliderXPosition", this._switchSprite.getSliderXPosition(),xPosition)); 79 }else{ 80 this._switchSprite.setSliderXPosition(xPosition); 81 } 82 this.sendActionsForControlEvents(cc.CONTROL_EVENT_VALUECHANGED); 83 }, 84 85 isOn:function () { 86 return this._on; 87 }, 88 89 hasMoved:function () { 90 return this._moved; 91 }, 92 93 setEnabled:function (enabled) { 94 this._enabled = enabled; 95 96 this._switchSprite.setOpacity((enabled) ? 255 : 128); 97 }, 98 99 locationFromTouch:function (touch) { 100 var touchLocation = touch.getLocation(); // Get the touch position 101 touchLocation = this.convertToNodeSpace(touchLocation); // Convert to the node space of this class 102 103 return touchLocation; 104 }, 105 106 onTouchBegan:function (touch, event) { 107 if (!this.isTouchInside(touch) || !this.isEnabled()|| !this.isVisible()) { 108 return false; 109 } 110 111 this._moved = false; 112 113 var location = this.locationFromTouch(touch); 114 115 this._initialTouchXPosition = location.x - this._switchSprite.getSliderXPosition(); 116 117 this._switchSprite.getThumbSprite().setColor(cc.color.GRAY); 118 this._switchSprite.needsLayout(); 119 120 return true; 121 }, 122 123 onTouchMoved:function (touch, event) { 124 var location = this.locationFromTouch(touch); 125 location = cc.p(location.x - this._initialTouchXPosition, 0); 126 127 this._moved = true; 128 129 this._switchSprite.setSliderXPosition(location.x); 130 }, 131 132 onTouchEnded:function (touch, event) { 133 var location = this.locationFromTouch(touch); 134 135 this._switchSprite.getThumbSprite().setColor(cc.color.WHITE); 136 137 if (this.hasMoved()) { 138 this.setOn(!(location.x < this._switchSprite.getContentSize().width / 2), true); 139 } else { 140 this.setOn(!this._on, true); 141 } 142 }, 143 144 onTouchCancelled:function (touch, event) { 145 var location = this.locationFromTouch(touch); 146 147 this._switchSprite.getThumbSprite().setColor(cc.color.WHITE); 148 149 if (this.hasMoved()) { 150 this.setOn(!(location.x < this._switchSprite.getContentSize().width / 2), true); 151 } else { 152 this.setOn(!this._on, true); 153 } 154 } 155 }); 156 157 /** Creates a switch with a mask sprite, on/off sprites for on/off states and a thumb sprite. */ 158 cc.ControlSwitch.create = function (maskSprite, onSprite, offSprite, thumbSprite, onLabel, offLabel) { 159 var pRet = new cc.ControlSwitch(); 160 if (pRet && pRet.initWithMaskSprite(maskSprite, onSprite, offSprite, thumbSprite, onLabel, offLabel)) { 161 return pRet; 162 } 163 return null; 164 }; 165 166 /** 167 * ControlSwitchSprite: Sprite switch control ui component 168 * @class 169 * @extend cc.Sprite 170 * 171 * @property {Number} sliderX - Slider's x position 172 * @property {cc.Point} onPos - The position of slider when switch is on 173 * @property {cc.Point} offPos - The position of slider when switch is off 174 * @property {cc.Texture2D} maskTexture - The texture of the mask 175 * @property {cc.Point} texturePos - The position of the texture 176 * @property {cc.Point} maskPos - The position of the mask 177 * @property {cc.Sprite} onSprite - The sprite of switch on 178 * @property {cc.Sprite} offSprite - The sprite of switch off 179 * @property {cc.Sprite} thumbSprite - The thumb sprite of the switch control 180 * @property {cc.LabelTTF} onLabel - The sprite of switch on 181 * @property {cc.LabelTTF} offLabel - The sprite of switch off 182 * @property {Number} onSideWidth - <@readonly> The width of the on side of the switch control 183 * @property {Number} offSideWidth - <@readonly> The width of the off side of the switch control 184 */ 185 cc.ControlSwitchSprite = cc.Sprite.extend({ 186 _sliderXPosition:0, 187 _onPosition:0, 188 _offPosition:0, 189 190 _textureLocation:0, 191 _maskLocation:0, 192 _maskSize:null, 193 194 _onSprite:null, 195 _offSprite:null, 196 _thumbSprite:null, 197 _onLabel:null, 198 _offLabel:null, 199 _clipper:null, 200 _stencil:null, 201 _backRT:null, 202 203 ctor:function () { 204 cc.Sprite.prototype.ctor.call(this); 205 this._sliderXPosition = 0; 206 this._onPosition = 0; 207 this._offPosition = 0; 208 this._maskLocation = 0; 209 this._maskSize = cc.size(0, 0); 210 this._onSprite = null; 211 this._offSprite = null; 212 this._thumbSprite = null; 213 this._onLabel = null; 214 this._offLabel = null; 215 }, 216 217 initWithMaskSprite:function (maskSprite, onSprite, offSprite, thumbSprite, onLabel, offLabel) { 218 if (cc.Sprite.prototype.initWithTexture.call(this, maskSprite.getTexture())) { 219 // Sets the default values 220 this._onPosition = 0; 221 this._offPosition = -onSprite.getContentSize().width + thumbSprite.getContentSize().width / 2; 222 this._sliderXPosition = this._onPosition; 223 224 this.setOnSprite(onSprite); 225 this.setOffSprite(offSprite); 226 this.setThumbSprite(thumbSprite); 227 this.setOnLabel(onLabel); 228 this.setOffLabel(offLabel); 229 230 // Set up the mask with the Mask shader 231 this._stencil = maskSprite; 232 var maskSize = this._maskSize = this._stencil.getContentSize(); 233 this._stencil.setPosition(0, 0); 234 235 // Init clipper for mask 236 this._clipper = cc.ClippingNode.create(); 237 this._clipper.setAnchorPoint(0.5, 0.5); 238 this._clipper.setPosition(maskSize.width / 2, maskSize.height / 2); 239 this._clipper.setStencil(this._stencil); 240 this._backRT = cc.RenderTexture.create(maskSize.width, maskSize.height); 241 this._clipper.addChild(this._backRT.getSprite()); 242 this.addChild(this._clipper); 243 244 this.addChild(this._thumbSprite); 245 246 this.needsLayout(); 247 return true; 248 } 249 return false; 250 }, 251 252 needsLayout:function () { 253 this._onSprite.setPosition(this._onSprite.getContentSize().width / 2 + this._sliderXPosition, 254 this._onSprite.getContentSize().height / 2); 255 this._offSprite.setPosition(this._onSprite.getContentSize().width + this._offSprite.getContentSize().width / 2 + this._sliderXPosition, 256 this._offSprite.getContentSize().height / 2); 257 258 if (this._onLabel) { 259 this._onLabel.setPosition(this._onSprite.getPositionX() - this._thumbSprite.getContentSize().width / 6, 260 this._onSprite.getContentSize().height / 2); 261 } 262 if (this._offLabel) { 263 this._offLabel.setPosition(this._offSprite.getPositionX() + this._thumbSprite.getContentSize().width / 6, 264 this._offSprite.getContentSize().height / 2); 265 } 266 this._thumbSprite.setPosition(this._onSprite.getContentSize().width + this._sliderXPosition, 267 this._maskSize.height / 2); 268 269 this._backRT.begin(); 270 271 this._onSprite.visit(); 272 this._offSprite.visit(); 273 274 if (this._onLabel) 275 this._onLabel.visit(); 276 if (this._offLabel) 277 this._offLabel.visit(); 278 279 this._backRT.end(); 280 281 //this.setFlippedY(true); 282 }, 283 284 setSliderXPosition:function (sliderXPosition) { 285 if (sliderXPosition <= this._offPosition) { 286 // Off 287 sliderXPosition = this._offPosition; 288 } else if (sliderXPosition >= this._onPosition) { 289 // On 290 sliderXPosition = this._onPosition; 291 } 292 293 this._sliderXPosition = sliderXPosition; 294 295 this.needsLayout(); 296 }, 297 getSliderXPosition:function () { 298 return this._sliderXPosition; 299 }, 300 301 _getOnSideWidth:function () { 302 return this._onSprite.getContentSize().width; 303 }, 304 305 _getOffSideWidth:function () { 306 return this._offSprite.getContentSize().height; 307 }, 308 309 updateTweenAction:function (value, key) { 310 cc.log("key = " + key + ", value = " + value); 311 this.setSliderXPosition(value); 312 }, 313 314 setOnPosition:function (onPosition) { 315 this._onPosition = onPosition; 316 }, 317 getOnPosition:function () { 318 return this._onPosition; 319 }, 320 321 setOffPosition:function (offPosition) { 322 this._offPosition = offPosition; 323 }, 324 getOffPosition:function () { 325 return this._offPosition; 326 }, 327 328 setMaskTexture:function (maskTexture) { 329 this._stencil.setTexture(maskTexture); 330 }, 331 getMaskTexture:function () { 332 return this._stencil.getTexture(); 333 }, 334 335 setTextureLocation:function (textureLocation) { 336 this._textureLocation = textureLocation; 337 }, 338 getTextureLocation:function () { 339 return this._textureLocation; 340 }, 341 342 setMaskLocation:function (maskLocation) { 343 this._maskLocation = maskLocation; 344 }, 345 getMaskLocation:function () { 346 return this._maskLocation; 347 }, 348 349 setOnSprite:function (onSprite) { 350 this._onSprite = onSprite; 351 }, 352 getOnSprite:function () { 353 return this._onSprite; 354 }, 355 356 setOffSprite:function (offSprite) { 357 this._offSprite = offSprite; 358 }, 359 getOffSprite:function () { 360 return this._offSprite; 361 }, 362 363 setThumbSprite:function (thumbSprite) { 364 this._thumbSprite = thumbSprite; 365 }, 366 getThumbSprite:function () { 367 return this._thumbSprite; 368 }, 369 370 setOnLabel:function (onLabel) { 371 this._onLabel = onLabel; 372 }, 373 getOnLabel:function () { 374 return this._onLabel; 375 }, 376 377 setOffLabel:function (offLabel) { 378 this._offLabel = offLabel; 379 }, 380 getOffLabel:function () { 381 return this._offLabel; 382 } 383 }); 384 385 var _p = cc.ControlSwitchSprite.prototype; 386 387 /** @expose */ 388 _p.sliderX; 389 cc.defineGetterSetter(_p, "sliderX", _p.getSliderXPosition, _p.setSliderXPosition); 390 /** @expose */ 391 _p.onPos; 392 cc.defineGetterSetter(_p, "onPos", _p.getOnPosition, _p.setOnPosition); 393 /** @expose */ 394 _p.offPos; 395 cc.defineGetterSetter(_p, "offPos", _p.getOffPosition, _p.setOffPosition); 396 /** @expose */ 397 _p.maskTexture; 398 cc.defineGetterSetter(_p, "maskTexture", _p.getMaskTexture, _p.setMaskTexture); 399 /** @expose */ 400 _p.maskPos; 401 cc.defineGetterSetter(_p, "maskPos", _p.getMaskLocation, _p.setMaskLocation); 402 /** @expose */ 403 _p.onSprite; 404 cc.defineGetterSetter(_p, "onSprite", _p.getOnSprite, _p.setOnSprite); 405 /** @expose */ 406 _p.offSprite; 407 cc.defineGetterSetter(_p, "offSprite", _p.getOffSprite, _p.setOffSprite); 408 /** @expose */ 409 _p.thumbSprite; 410 cc.defineGetterSetter(_p, "thumbSprite", _p.getThumbSprite, _p.setThumbSprite); 411 /** @expose */ 412 _p.onLabel; 413 cc.defineGetterSetter(_p, "onLabel", _p.getOnLabel, _p.setOnLabel); 414 /** @expose */ 415 _p.offLabel; 416 cc.defineGetterSetter(_p, "offLabel", _p.getOffLabel, _p.setOffLabel); 417 /** @expose */ 418 _p.onSideWidth; 419 cc.defineGetterSetter(_p, "onSideWidth", _p._getOnSideWidth); 420 /** @expose */ 421 _p.offSideWidth; 422 cc.defineGetterSetter(_p, "offSideWidth", _p._getOffSideWidth); 423 424 _p = null; 425