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