1 /** 2 * Copyright (c) 2008-2010 Ricardo Quesada 3 * Copyright (c) 2011-2012 cocos2d-x.org 4 * Copyright (c) 2013-2014 Chukong Technologies Inc. 5 * 6 * http://www.cocos2d-x.org 7 * 8 * Copyright 2012 Yannick Loriot. All rights reserved. 9 * http://yannickloriot.com 10 * 11 * Permission is hereby granted, free of charge, to any person obtaining a copy 12 * of this software and associated documentation files (the "Software"), to deal 13 * in the Software without restriction, including without limitation the rights 14 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 15 * copies of the Software, and to permit persons to whom the Software is 16 * furnished to do so, subject to the following conditions: 17 * 18 * The above copyright notice and this permission notice shall be included in 19 * all copies or substantial portions of the Software. 20 * 21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 22 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 23 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 24 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 25 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 26 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 27 * THE SOFTWARE. 28 * 29 */ 30 31 /** 32 * CCControlPotentiometer: Potentiometer control for Cocos2D. 33 * @class 34 * @extends cc.Control 35 * 36 * @property {Number} value - The current value of the potentionmeter 37 * @property {Number} minValue - The minimum value of the potentionmeter 38 * @property {Number} maxValue - The maximum value of the potentionmeter 39 * @property {cc.ProgressTimer} progressTimer - The progress timer of the potentionmeter 40 * @property {cc.Sprite} thumbSprite - The thumb sprite of the potentionmeter 41 * @property {cc.Point} prevLocation - The previous location of the potentionmeter 42 */ 43 cc.ControlPotentiometer = cc.Control.extend(/** @lends cc.ControlPotentiometer# */{ 44 _thumbSprite:null, 45 _progressTimer:null, 46 _previousLocation:null, 47 /** Contains the receiver’s current value. */ 48 _value:0, 49 /** Contains the minimum value of the receiver. 50 * The default value of this property is 0.0. */ 51 _minimumValue:0, 52 /** Contains the maximum value of the receiver. 53 * The default value of this property is 1.0. */ 54 _maximumValue:1, 55 _className:"ControlPotentiometer", 56 57 /** 58 * 59 * @param {cc.Sprite} trackSprite 60 * @param {cc.ProgressTimer} progressTimer 61 * @param {cc.Sprite} thumbSprite 62 * @return {Boolean} 63 */ 64 initWithTrackSprite_ProgressTimer_ThumbSprite:function (trackSprite, progressTimer, thumbSprite) { 65 if (this.init()) { 66 this.setProgressTimer(progressTimer); 67 this.setThumbSprite(thumbSprite); 68 this._thumbSprite.setPosition(progressTimer.getPosition()); 69 70 this.addChild(thumbSprite, 2); 71 this.addChild(progressTimer, 1); 72 this.addChild(trackSprite); 73 74 this.setContentSize(trackSprite.getContentSize()); 75 76 // Init default values 77 this._minimumValue = 0.0; 78 this._maximumValue = 1.0; 79 this.setValue(this._minimumValue); 80 return true; 81 } 82 return false; 83 }, 84 85 setEnabled:function (enabled) { 86 this.setEnabled(enabled); 87 if (this._thumbSprite != NULL) { 88 this._thumbSprite.setOpacity((enabled) ? 255 : 128); 89 } 90 }, 91 92 setValue:function (value) { 93 // set new value with sentinel 94 if (value < this._minimumValue) { 95 value = this._minimumValue; 96 } 97 98 if (value > this._maximumValue) { 99 value = this._maximumValue; 100 } 101 102 this._value = value; 103 104 // Update thumb and progress position for new value 105 var percent = (value - this._minimumValue) / (this._maximumValue - this._minimumValue); 106 this._progressTimer.setPercentage(percent * 100.0); 107 this._thumbSprite.setRotation(percent * 360.0); 108 109 this.sendActionsForControlEvents(cc.CONTROL_EVENT_VALUECHANGED); 110 }, 111 112 getValue:function () { 113 return this._value; 114 }, 115 116 setMinimumValue:function (minimumValue) { 117 this._minimumValue = minimumValue; 118 119 if (this._minimumValue >= this._maximumValue) { 120 this._maximumValue = this._minimumValue + 1.0; 121 } 122 123 this.setValue(this._maximumValue); 124 }, 125 126 getMinimumValue:function () { 127 return this._minimumValue; 128 }, 129 130 setMaximumValue:function (maximumValue) { 131 this._maximumValue = maximumValue; 132 133 if (this._maximumValue <= this._minimumValue) { 134 this._minimumValue = this._maximumValue - 1.0; 135 } 136 137 this.setValue(this._minimumValue); 138 }, 139 140 getMaximumValue:function () { 141 return this._maximumValue; 142 }, 143 144 isTouchInside:function (touch) { 145 var touchLocation = this.getTouchLocation(touch); 146 147 var distance = this.distanceBetweenPointAndPoint(this._progressTimer.getPosition(), touchLocation); 148 149 return distance < Math.min(this.getContentSize().width / 2, this.getContentSize().height / 2); 150 }, 151 152 onTouchBegan:function (touch, event) { 153 if (!this.isTouchInside(touch) || !this.isEnabled() || !this.isVisible()) { 154 return false; 155 } 156 157 this._previousLocation = this.getTouchLocation(touch); 158 159 this.potentiometerBegan(this._previousLocation); 160 161 return true; 162 }, 163 164 onTouchMoved:function (touch, event) { 165 var location = this.getTouchLocation(touch); 166 167 this.potentiometerMoved(location); 168 }, 169 170 onTouchEnded:function (touch, event) { 171 this.potentiometerEnded(cc.p(0, 0)); 172 }, 173 174 /** 175 * the distance between the point1 and point2 176 * @param {cc.Point} point1 177 * @param {cc.Point} point2 178 * @return {Number} 179 */ 180 distanceBetweenPointAndPoint:function (point1, point2) { 181 var dx = point1.x - point2.x; 182 var dy = point1.y - point2.y; 183 return Math.sqrt(dx * dx + dy * dy); 184 }, 185 186 /** 187 * the angle in degree between line1 and line2. 188 * @param {cc.Point} beginLineA 189 * @param {cc.Point} endLineA 190 * @param {cc.Point} beginLineB 191 * @param {cc.Point} endLineB 192 * @return {Number} 193 */ 194 angleInDegreesBetweenLineFromPoint_toPoint_toLineFromPoint_toPoint:function (beginLineA, endLineA, beginLineB, endLineB) { 195 var a = endLineA.x - beginLineA.x; 196 var b = endLineA.y - beginLineA.y; 197 var c = endLineB.x - beginLineB.x; 198 var d = endLineB.y - beginLineB.y; 199 200 var atanA = Math.atan2(a, b); 201 var atanB = Math.atan2(c, d); 202 203 // convert radiants to degrees 204 return (atanA - atanB) * 180 / Math.PI; 205 }, 206 207 potentiometerBegan:function (location) { 208 this.setSelected(true); 209 this.getThumbSprite().setColor(cc.color.GRAY); 210 }, 211 212 potentiometerMoved:function (location) { 213 var angle = this.angleInDegreesBetweenLineFromPoint_toPoint_toLineFromPoint_toPoint(this._progressTimer.getPosition(), location, this._progressTimer.getPosition(), this._previousLocation); 214 215 // fix value, if the 12 o'clock position is between location and previousLocation 216 if (angle > 180) { 217 angle -= 360; 218 } 219 else if (angle < -180) { 220 angle += 360; 221 } 222 223 this.setValue(this._value + angle / 360.0 * (this._maximumValue - this._minimumValue)); 224 225 this._previousLocation = location; 226 }, 227 228 potentiometerEnded:function (location) { 229 this.getThumbSprite().setColor(cc.color.WHITE); 230 this.setSelected(false); 231 }, 232 setThumbSprite:function (sprite) { 233 this._thumbSprite = sprite; 234 }, 235 getThumbSprite:function () { 236 return this._thumbSprite; 237 }, 238 setProgressTimer:function (sprite) { 239 this._progressTimer = sprite; 240 }, 241 getProgressTimer:function () { 242 return this._progressTimer; 243 }, 244 setPreviousLocation:function (point) { 245 this._previousLocation = point; 246 }, 247 getPreviousLocation:function () { 248 return this._previousLocation; 249 } 250 }); 251 252 var _p = cc.ControlPotentiometer.prototype; 253 254 // Extended properties 255 /** @expose */ 256 _p.value; 257 cc.defineGetterSetter(_p, "value", _p.getValue, _p.setValue); 258 /** @expose */ 259 _p.minValue; 260 cc.defineGetterSetter(_p, "minValue", _p.getMinimumValue, _p.setMinimumValue); 261 /** @expose */ 262 _p.maxValue; 263 cc.defineGetterSetter(_p, "maxValue", _p.getMaximumValue, _p.setMaximumValue); 264 /** @expose */ 265 _p.progressTimer; 266 cc.defineGetterSetter(_p, "progressTimer", _p.getProgressTimer, _p.setProgressTimer); 267 /** @expose */ 268 _p.thumbSprite; 269 cc.defineGetterSetter(_p, "thumbSprite", _p.getThumbSprite, _p.setThumbSprite); 270 /** @expose */ 271 _p.prevLocation; 272 cc.defineGetterSetter(_p, "prevLocation", _p.getPreviousLocation, _p.setPreviousLocation); 273 274 _p = null; 275 276 cc.ControlPotentiometer.create = function (backgroundFile, progressFile, thumbFile) { 277 var pRet = new cc.ControlPotentiometer(); 278 if (pRet) { 279 // Prepare track for potentiometer 280 var backgroundSprite = cc.Sprite.create(backgroundFile); 281 282 // Prepare thumb for potentiometer 283 var thumbSprite = cc.Sprite.create(thumbFile); 284 285 // Prepare progress for potentiometer 286 var progressTimer = cc.ProgressTimer.create(cc.Sprite.create(progressFile)); 287 if (pRet.initWithTrackSprite_ProgressTimer_ThumbSprite(backgroundSprite, progressTimer, thumbSprite)) { 288 return pRet; 289 } 290 } 291 return null; 292 };