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