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 * converted to Javascript / cocos2d-x by Angus C 28 */ 29 30 /** 31 * @ignore 32 */ 33 cc.SLIDER_MARGIN_H = 24; 34 cc.SLIDER_MARGIN_V = 8; 35 36 /** 37 * ControlSlider: Slider ui component. 38 * @class 39 * @extends cc.Control 40 * 41 * @property {Number} value - The value of the slider 42 * @property {Number} minValue - The minimum value of the slider 43 * @property {Number} maxValue - The maximum value of the slider 44 * @property {Number} minAllowedValue - The minimum allowed value of the slider 45 * @property {Number} maxAllowedValue - The maximum allowed value of the slider 46 * @property {Number} thumbSprite - <@readonly> Brightness value of the picker 47 * @property {cc.Sprite} progressSprite - <@readonly> The background sprite 48 * @property {cc.Sprite} backgroundSprite - <@readonly> The overlay sprite 49 */ 50 cc.ControlSlider = cc.Control.extend(/** @lends cc.ControlSlider# */{ 51 _value:0, 52 _minimumValue:0, 53 _maximumValue:0, 54 _minimumAllowedValue:0, 55 _maximumAllowedValue:0, 56 57 _thumbSprite:null, 58 _progressSprite:null, 59 _backgroundSprite:null, 60 _className:"ControlSlider", 61 62 getValue:function () { 63 return this._value; 64 }, 65 setValue:function (value) { 66 //clamp between the two bounds 67 value = Math.max(value, this._minimumValue); 68 value = Math.min(value, this._maximumValue); 69 this._value = value; 70 this.needsLayout(); 71 this.sendActionsForControlEvents(cc.CONTROL_EVENT_VALUECHANGED); 72 }, 73 74 getMinimumValue:function () { 75 return this._minimumValue; 76 }, 77 setMinimumValue:function (minimumValue) { 78 this._minimumValue = minimumValue; 79 this._minimumAllowedValue = minimumValue; 80 if (this._minimumValue >= this._maximumValue) 81 this._maximumValue = this._minimumValue + 1.0; 82 this.setValue(this._value); 83 }, 84 85 getMaximumValue:function () { 86 return this._maximumValue; 87 }, 88 setMaximumValue:function (maximumValue) { 89 this._maximumValue = maximumValue; 90 this._maximumAllowedValue = maximumValue; 91 if (this._maximumValue <= this._minimumValue) 92 this._minimumValue = this._maximumValue - 1.0; 93 this.setValue(this._value); 94 }, 95 isTouchInside:function (touch) { 96 var touchLocation = touch.getLocation(); 97 touchLocation = this.getParent().convertToNodeSpace(touchLocation); 98 99 var rect = this.getBoundingBox(); 100 rect.width += this._thumbSprite.getContentSize().width; 101 rect.x -= this._thumbSprite.getContentSize().width / 2; 102 103 return cc.rectContainsPoint(rect, touchLocation); 104 }, 105 locationFromTouch:function (touch) { 106 var touchLocation = touch.getLocation(); // Get the touch position 107 touchLocation = this.convertToNodeSpace(touchLocation); // Convert to the node space of this class 108 109 if (touchLocation.x < 0) { 110 touchLocation.x = 0; 111 } else if (touchLocation.x > this._backgroundSprite.getContentSize().width) { 112 touchLocation.x = this._backgroundSprite.getContentSize().width; 113 } 114 115 return touchLocation; 116 }, 117 getMinimumAllowedValue:function () { 118 return this._minimumAllowedValue; 119 }, 120 setMinimumAllowedValue:function (val) { 121 this._minimumAllowedValue = val; 122 }, 123 124 getMaximumAllowedValue:function () { 125 return this._maximumAllowedValue; 126 }, 127 128 setMaximumAllowedValue:function (val) { 129 this._maximumAllowedValue = val; 130 }, 131 132 getThumbSprite:function () { 133 return this._thumbSprite; 134 }, 135 getProgressSprite:function () { 136 return this._progressSprite; 137 }, 138 getBackgroundSprite:function () { 139 return this._backgroundSprite; 140 }, 141 142 /** 143 * Initializes a slider with a background sprite, a progress bar and a thumb 144 * item. 145 * 146 * @param {cc.Sprite} backgroundSprite CCSprite, that is used as a background. 147 * @param {cc.Sprite} progressSprite CCSprite, that is used as a progress bar. 148 * @param {cc.Sprite} thumbSprite CCMenuItem, that is used as a thumb. 149 */ 150 initWithSprites:function (backgroundSprite, progressSprite, thumbSprite) { 151 if (cc.Control.prototype.init.call(this)) { 152 this.ignoreAnchorPointForPosition(false); 153 154 this._backgroundSprite = backgroundSprite; 155 this._progressSprite = progressSprite; 156 this._thumbSprite = thumbSprite; 157 158 // Defines the content size 159 var maxRect = cc.ControlUtils.CCRectUnion(backgroundSprite.getBoundingBox(), thumbSprite.getBoundingBox()); 160 this.setContentSize(maxRect.width, maxRect.height); 161 162 // Add the slider background 163 this._backgroundSprite.setAnchorPoint(0.5, 0.5); 164 this._backgroundSprite.setPosition(maxRect.width / 2, maxRect.height / 2); 165 this.addChild(this._backgroundSprite); 166 167 // Add the progress bar 168 this._progressSprite.setAnchorPoint(0.0, 0.5); 169 this._progressSprite.setPosition(0, maxRect.height / 2); 170 this.addChild(this._progressSprite); 171 172 // Add the slider thumb 173 this._thumbSprite.setPosition(0, maxRect.height / 2); 174 this.addChild(this._thumbSprite); 175 176 // Init default values 177 this._minimumValue = 0.0; 178 this._maximumValue = 1.0; 179 this.setValue(this._minimumValue); 180 return true; 181 } else 182 return false; 183 }, 184 185 setEnabled:function (enabled) { 186 cc.Control.prototype.setEnabled.call(this, enabled); 187 if (this._thumbSprite) { 188 this._thumbSprite.setOpacity(enabled ? 255 : 128); 189 } 190 }, 191 192 sliderBegan:function (location) { 193 this.setSelected(true); 194 this.getThumbSprite().setColor(cc.color.GRAY); 195 this.setValue(this.valueForLocation(location)); 196 }, 197 sliderMoved:function (location) { 198 this.setValue(this.valueForLocation(location)); 199 }, 200 sliderEnded:function (location) { 201 if (this.isSelected()) { 202 this.setValue(this.valueForLocation(this._thumbSprite.getPosition())); 203 } 204 this._thumbSprite.setColor(cc.color.WHITE); 205 this.setSelected(false); 206 }, 207 208 getTouchLocationInControl:function (touch) { 209 var touchLocation = touch.getLocation(); // Get the touch position 210 touchLocation = this.convertToNodeSpace(touchLocation); // Convert to the node space of this class 211 212 if (touchLocation.x < 0) { 213 touchLocation.x = 0; 214 } else if (touchLocation.x > this._backgroundSprite.getContentSize().width + cc.SLIDER_MARGIN_H) { 215 touchLocation.x = this._backgroundSprite.getContentSize().width + cc.SLIDER_MARGIN_H; 216 } 217 return touchLocation; 218 }, 219 220 onTouchBegan:function (touch, event) { 221 if (!this.isTouchInside(touch)|| !this.isEnabled() || !this.isVisible()) 222 return false; 223 224 var location = this.locationFromTouch(touch); 225 this.sliderBegan(location); 226 return true; 227 }, 228 onTouchMoved:function (touch, event) { 229 var location = this.locationFromTouch(touch); 230 this.sliderMoved(location); 231 }, 232 onTouchEnded:function (touch, event) { 233 this.sliderEnded(cc.p(0,0)); 234 }, 235 needsLayout:function(){ 236 var percent = (this._value - this._minimumValue) / (this._maximumValue - this._minimumValue); 237 this._thumbSprite.setPositionX(percent * this._backgroundSprite.getContentSize().width); 238 239 // Stretches content proportional to newLevel 240 var textureRect = this._progressSprite.getTextureRect(); 241 textureRect = cc.rect(textureRect.x, textureRect.y, this._thumbSprite.getPositionX(), textureRect.height); 242 this._progressSprite.setTextureRect(textureRect, this._progressSprite.isTextureRectRotated()); 243 }, 244 /** Returns the value for the given location. */ 245 valueForLocation:function (location) { 246 var percent = location.x / this._backgroundSprite.getContentSize().width; 247 return Math.max(Math.min(this._minimumValue + percent * (this._maximumValue - this._minimumValue), this._maximumAllowedValue), this._minimumAllowedValue); 248 } 249 }); 250 251 window._p = cc.ControlSlider.prototype; 252 253 // Extended properties 254 /** @expose */ 255 _p.value; 256 cc.defineGetterSetter(_p, "value", _p.getValue, _p.setValue); 257 /** @expose */ 258 _p.minValue; 259 cc.defineGetterSetter(_p, "minValue", _p.getMinimumValue, _p.setMinimumValue); 260 /** @expose */ 261 _p.maxValue; 262 cc.defineGetterSetter(_p, "maxValue", _p.getMaximumValue, _p.setMaximumValue); 263 /** @expose */ 264 _p.minAllowedValue; 265 cc.defineGetterSetter(_p, "minAllowedValue", _p.getMinimumAllowedValue, _p.setMinimumAllowedValue); 266 /** @expose */ 267 _p.maxAllowedValue; 268 cc.defineGetterSetter(_p, "maxAllowedValue", _p.getMaximumAllowedValue, _p.setMaximumAllowedValue); 269 /** @expose */ 270 _p.thumbSprite; 271 cc.defineGetterSetter(_p, "thumbSprite", _p.getThumbSprite); 272 /** @expose */ 273 _p.progressSprite; 274 cc.defineGetterSetter(_p, "progressSprite", _p.getProgressSprite); 275 /** @expose */ 276 _p.backgroundSprite; 277 cc.defineGetterSetter(_p, "backgroundSprite", _p.getBackgroundSprite); 278 279 delete window._p; 280 281 /** 282 * Creates a slider with a given background sprite and a progress bar and a 283 * thumb item. 284 * 285 * @see initWithBackgroundSprite:progressSprite:thumbMenuItem: 286 */ 287 cc.ControlSlider.create = function (bgFile, progressFile, thumbFile) { 288 if (typeof(bgFile) == "string") { 289 // Prepare background for slider 290 bgFile = cc.Sprite.create(bgFile); 291 292 // Prepare progress for slider 293 progressFile = cc.Sprite.create(progressFile); 294 295 // Prepare thumb (menuItem) for slider 296 thumbFile = cc.Sprite.create(thumbFile); 297 } 298 299 var pRet = new cc.ControlSlider(); 300 pRet.initWithSprites(bgFile, progressFile, thumbFile); 301 return pRet; 302 303 };