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