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 ctor:function (backgroundFile, progressFile, thumbFile) { 58 cc.Control.prototype.ctor.call(this); 59 if (thumbFile != undefined) { 60 // Prepare track for potentiometer 61 var backgroundSprite = new cc.Sprite(backgroundFile); 62 63 // Prepare thumb for potentiometer 64 var thumbSprite = new cc.Sprite(thumbFile); 65 66 // Prepare progress for potentiometer 67 var progressTimer = new cc.ProgressTimer(new cc.Sprite(progressFile)); 68 this.initWithTrackSprite_ProgressTimer_ThumbSprite(backgroundSprite, progressTimer, thumbSprite); 69 } 70 }, 71 72 /** 73 * 74 * @param {cc.Sprite} trackSprite 75 * @param {cc.ProgressTimer} progressTimer 76 * @param {cc.Sprite} thumbSprite 77 * @return {Boolean} 78 */ 79 initWithTrackSprite_ProgressTimer_ThumbSprite:function (trackSprite, progressTimer, thumbSprite) { 80 if (this.init()) { 81 this.setProgressTimer(progressTimer); 82 this.setThumbSprite(thumbSprite); 83 this._thumbSprite.setPosition(progressTimer.getPosition()); 84 85 this.addChild(thumbSprite, 2); 86 this.addChild(progressTimer, 1); 87 this.addChild(trackSprite); 88 89 this.setContentSize(trackSprite.getContentSize()); 90 91 // Init default values 92 this._minimumValue = 0.0; 93 this._maximumValue = 1.0; 94 this.setValue(this._minimumValue); 95 return true; 96 } 97 return false; 98 }, 99 100 setEnabled:function (enabled) { 101 this.setEnabled(enabled); 102 if (this._thumbSprite !== null) { 103 this._thumbSprite.setOpacity((enabled) ? 255 : 128); 104 } 105 }, 106 107 setValue:function (value) { 108 // set new value with sentinel 109 if (value < this._minimumValue) { 110 value = this._minimumValue; 111 } 112 113 if (value > this._maximumValue) { 114 value = this._maximumValue; 115 } 116 117 this._value = value; 118 119 // Update thumb and progress position for new value 120 var percent = (value - this._minimumValue) / (this._maximumValue - this._minimumValue); 121 this._progressTimer.setPercentage(percent * 100.0); 122 this._thumbSprite.setRotation(percent * 360.0); 123 124 this.sendActionsForControlEvents(cc.CONTROL_EVENT_VALUECHANGED); 125 }, 126 127 getValue:function () { 128 return this._value; 129 }, 130 131 setMinimumValue:function (minimumValue) { 132 this._minimumValue = minimumValue; 133 134 if (this._minimumValue >= this._maximumValue) { 135 this._maximumValue = this._minimumValue + 1.0; 136 } 137 138 this.setValue(this._maximumValue); 139 }, 140 141 getMinimumValue:function () { 142 return this._minimumValue; 143 }, 144 145 setMaximumValue:function (maximumValue) { 146 this._maximumValue = maximumValue; 147 148 if (this._maximumValue <= this._minimumValue) { 149 this._minimumValue = this._maximumValue - 1.0; 150 } 151 152 this.setValue(this._minimumValue); 153 }, 154 155 getMaximumValue:function () { 156 return this._maximumValue; 157 }, 158 159 isTouchInside:function (touch) { 160 var touchLocation = this.getTouchLocation(touch); 161 162 var distance = this.distanceBetweenPointAndPoint(this._progressTimer.getPosition(), touchLocation); 163 164 return distance < Math.min(this.getContentSize().width / 2, this.getContentSize().height / 2); 165 }, 166 167 onTouchBegan:function (touch, event) { 168 if (!this.isTouchInside(touch) || !this.isEnabled() || !this.isVisible()) { 169 return false; 170 } 171 172 this._previousLocation = this.getTouchLocation(touch); 173 174 this.potentiometerBegan(this._previousLocation); 175 176 return true; 177 }, 178 179 onTouchMoved:function (touch, event) { 180 var location = this.getTouchLocation(touch); 181 182 this.potentiometerMoved(location); 183 }, 184 185 onTouchEnded:function (touch, event) { 186 this.potentiometerEnded(cc.p(0, 0)); 187 }, 188 189 /** 190 * the distance between the point1 and point2 191 * @param {cc.Point} point1 192 * @param {cc.Point} point2 193 * @return {Number} 194 */ 195 distanceBetweenPointAndPoint:function (point1, point2) { 196 var dx = point1.x - point2.x; 197 var dy = point1.y - point2.y; 198 return Math.sqrt(dx * dx + dy * dy); 199 }, 200 201 /** 202 * the angle in degree between line1 and line2. 203 * @param {cc.Point} beginLineA 204 * @param {cc.Point} endLineA 205 * @param {cc.Point} beginLineB 206 * @param {cc.Point} endLineB 207 * @return {Number} 208 */ 209 angleInDegreesBetweenLineFromPoint_toPoint_toLineFromPoint_toPoint:function (beginLineA, endLineA, beginLineB, endLineB) { 210 var a = endLineA.x - beginLineA.x; 211 var b = endLineA.y - beginLineA.y; 212 var c = endLineB.x - beginLineB.x; 213 var d = endLineB.y - beginLineB.y; 214 215 var atanA = Math.atan2(a, b); 216 var atanB = Math.atan2(c, d); 217 218 // convert radiants to degrees 219 return (atanA - atanB) * 180 / Math.PI; 220 }, 221 222 potentiometerBegan:function (location) { 223 this.setSelected(true); 224 this.getThumbSprite().setColor(cc.color.GRAY); 225 }, 226 227 potentiometerMoved:function (location) { 228 var angle = this.angleInDegreesBetweenLineFromPoint_toPoint_toLineFromPoint_toPoint(this._progressTimer.getPosition(), location, this._progressTimer.getPosition(), this._previousLocation); 229 230 // fix value, if the 12 o'clock position is between location and previousLocation 231 if (angle > 180) { 232 angle -= 360; 233 } 234 else if (angle < -180) { 235 angle += 360; 236 } 237 238 this.setValue(this._value + angle / 360.0 * (this._maximumValue - this._minimumValue)); 239 240 this._previousLocation = location; 241 }, 242 243 potentiometerEnded:function (location) { 244 this.getThumbSprite().setColor(cc.color.WHITE); 245 this.setSelected(false); 246 }, 247 setThumbSprite:function (sprite) { 248 this._thumbSprite = sprite; 249 }, 250 getThumbSprite:function () { 251 return this._thumbSprite; 252 }, 253 setProgressTimer:function (sprite) { 254 this._progressTimer = sprite; 255 }, 256 getProgressTimer:function () { 257 return this._progressTimer; 258 }, 259 setPreviousLocation:function (point) { 260 this._previousLocation = point; 261 }, 262 getPreviousLocation:function () { 263 return this._previousLocation; 264 } 265 }); 266 267 var _p = cc.ControlPotentiometer.prototype; 268 269 // Extended properties 270 /** @expose */ 271 _p.value; 272 cc.defineGetterSetter(_p, "value", _p.getValue, _p.setValue); 273 /** @expose */ 274 _p.minValue; 275 cc.defineGetterSetter(_p, "minValue", _p.getMinimumValue, _p.setMinimumValue); 276 /** @expose */ 277 _p.maxValue; 278 cc.defineGetterSetter(_p, "maxValue", _p.getMaximumValue, _p.setMaximumValue); 279 /** @expose */ 280 _p.progressTimer; 281 cc.defineGetterSetter(_p, "progressTimer", _p.getProgressTimer, _p.setProgressTimer); 282 /** @expose */ 283 _p.thumbSprite; 284 cc.defineGetterSetter(_p, "thumbSprite", _p.getThumbSprite, _p.setThumbSprite); 285 /** @expose */ 286 _p.prevLocation; 287 cc.defineGetterSetter(_p, "prevLocation", _p.getPreviousLocation, _p.setPreviousLocation); 288 289 _p = null; 290 291 /** 292 * @deprecated 293 * @param backgroundFile 294 * @param progressFile 295 * @param thumbFile 296 * @returns {ControlPotentiometer} 297 */ 298 cc.ControlPotentiometer.create = function (backgroundFile, progressFile, thumbFile) { 299 return new cc.ControlPotentiometer(backgroundFile, progressFile, thumbFile); 300 };