1 /** 2 * Copyright (c) 2012 cocos2d-x.org 3 * http://www.cocos2d-x.org 4 * 5 * Copyright 2012 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 28 cc.CONTROL_STEPPER_PARTMINUS = 0; 29 cc.CONTROL_STEPPER_PARTPLUS = 1; 30 cc.CONTROL_STEPPER_PARTNONE = 2; 31 cc.CONTROL_STEPPER_LABELCOLOR_ENABLED = cc.c3b(55, 55, 55); 32 cc.CONTROL_STEPPER_LABELCOLOR_DISABLED = cc.c3b(147, 147, 147); 33 cc.CONTROL_STEPPER_LABELFONT = "CourierNewPSMT"; 34 cc.AUTOREPEAT_DELTATIME = 0.15; 35 cc.AUTOREPEAT_INCREASETIME_INCREMENT = 12; 36 37 /** 38 * ControlStepper control for Cocos2D. 39 * @class 40 * @extends cc.Control 41 */ 42 cc.ControlStepper = cc.Control.extend({ 43 _minusSprite:null, 44 _plusSprite:null, 45 _minusLabel:null, 46 _plusLabel:null, 47 _value:0, 48 _continuous:false, 49 _autorepeat:false, 50 _wraps:false, 51 _minimumValue:0, 52 _maximumValue:0, 53 _stepValue:0, 54 _touchInsideFlag:false, 55 _touchedPart:cc.CONTROL_STEPPER_PARTNONE, 56 _autorepeatCount:0, 57 ctor:function () { 58 cc.Control.prototype.ctor.call(this); 59 this._minusSprite = null; 60 this._plusSprite = null; 61 this._minusLabel = null; 62 this._plusLabel = null; 63 this._value = 0; 64 this._continuous = false; 65 this._autorepeat = false; 66 this._wraps = false; 67 this._minimumValue = 0; 68 this._maximumValue = 0; 69 this._stepValue = 0; 70 this._touchInsideFlag = false; 71 this._touchedPart = cc.CONTROL_STEPPER_PARTNONE; 72 this._autorepeatCount = 0; 73 }, 74 75 initWithMinusSpriteAndPlusSprite:function (minusSprite, plusSprite) { 76 if(!minusSprite) 77 throw "cc.ControlStepper.initWithMinusSpriteAndPlusSprite(): Minus sprite should be non-null."; 78 if(!plusSprite) 79 throw "cc.ControlStepper.initWithMinusSpriteAndPlusSprite(): Plus sprite should be non-null."; 80 81 if (this.init()) { 82 this.setTouchEnabled(true); 83 84 // Set the default values 85 this._autorepeat = true; 86 this._continuous = true; 87 this._minimumValue = 0; 88 this._maximumValue = 100; 89 this._value = 0; 90 this._stepValue = 1; 91 this._wraps = false; 92 this.ignoreAnchorPointForPosition(false); 93 94 // Add the minus components 95 this.setMinusSprite(minusSprite); 96 this._minusSprite.setPosition(minusSprite.getContentSize().width / 2, minusSprite.getContentSize().height / 2); 97 this.addChild(this._minusSprite); 98 99 this.setMinusLabel(cc.LabelTTF.create("-", cc.CONTROL_STEPPER_LABELFONT, 40, cc.size(40, 40), cc.TEXT_ALIGNMENT_CENTER, cc.VERTICAL_TEXT_ALIGNMENT_CENTER)); 100 this._minusLabel.setColor(cc.CONTROL_STEPPER_LABELCOLOR_DISABLED); 101 this._minusLabel.setPosition(this._minusSprite.getContentSize().width / 2, this._minusSprite.getContentSize().height / 2); 102 this._minusSprite.addChild(this._minusLabel); 103 104 // Add the plus components 105 this.setPlusSprite(plusSprite); 106 this._plusSprite.setPosition(minusSprite.getContentSize().width + plusSprite.getContentSize().width / 2, 107 minusSprite.getContentSize().height / 2); 108 this.addChild(this._plusSprite); 109 110 this.setPlusLabel(cc.LabelTTF.create("+", cc.CONTROL_STEPPER_LABELFONT, 40, cc.size(40, 40), cc.TEXT_ALIGNMENT_CENTER, cc.VERTICAL_TEXT_ALIGNMENT_CENTER)); 111 this._plusLabel.setColor(cc.CONTROL_STEPPER_LABELCOLOR_ENABLED); 112 this._plusLabel.setPosition(this._plusSprite.getContentSize().width / 2, this._plusSprite.getContentSize().height / 2); 113 this._plusSprite.addChild(this._plusLabel); 114 115 // Defines the content size 116 var maxRect = cc.ControlUtils.CCRectUnion(this._minusSprite.getBoundingBox(), this._plusSprite.getBoundingBox()); 117 this.setContentSize(this._minusSprite.getContentSize().width + this._plusSprite.getContentSize().height, maxRect._size.height); 118 return true; 119 } 120 return false; 121 }, 122 123 //#pragma mark Properties 124 125 setWraps:function (wraps) { 126 this._wraps = wraps; 127 128 if (this._wraps) { 129 this._minusLabel.setColor(cc.CONTROL_STEPPER_LABELCOLOR_ENABLED); 130 this._plusLabel.setColor(cc.CONTROL_STEPPER_LABELCOLOR_ENABLED); 131 } 132 133 this.setValue(this._value); 134 }, 135 136 setMinimumValue:function (minimumValue) { 137 if (minimumValue >= this._maximumValue) 138 throw "cc.ControlStepper.setMinimumValue(): minimumValue should be numerically less than maximumValue."; 139 140 this._minimumValue = minimumValue; 141 this.setValue(this._value); 142 }, 143 144 setMaximumValue:function (maximumValue) { 145 if (maximumValue <= this._minimumValue) 146 throw "cc.ControlStepper.setMaximumValue(): maximumValue should be numerically less than maximumValue."; 147 148 this._maximumValue = maximumValue; 149 this.setValue(this._value); 150 }, 151 152 setValue:function (value) { 153 this.setValueWithSendingEvent(value, true); 154 }, 155 156 getValue:function () { 157 return this._value; 158 }, 159 160 setStepValue:function (stepValue) { 161 if (stepValue <= 0) 162 throw "cc.ControlStepper.setMaximumValue(): stepValue should be numerically greater than 0."; 163 this._stepValue = stepValue; 164 }, 165 166 isContinuous:function () { 167 return this._continuous; 168 }, 169 170 setValueWithSendingEvent:function (value, send) { 171 if (value < this._minimumValue) { 172 value = this._wraps ? this._maximumValue : this._minimumValue; 173 } else if (value > this._maximumValue) { 174 value = this._wraps ? this._minimumValue : this._maximumValue; 175 } 176 177 this._value = value; 178 179 if (!this._wraps) { 180 this._minusLabel.setColor((value == this._minimumValue) ? cc.CONTROL_STEPPER_LABELCOLOR_DISABLED : cc.CONTROL_STEPPER_LABELCOLOR_ENABLED); 181 this._plusLabel.setColor((value == this._maximumValue) ? cc.CONTROL_STEPPER_LABELCOLOR_DISABLED : cc.CONTROL_STEPPER_LABELCOLOR_ENABLED); 182 } 183 184 if (send) { 185 this.sendActionsForControlEvents(cc.CONTROL_EVENT_VALUECHANGED); 186 } 187 }, 188 189 startAutorepeat:function () { 190 this._autorepeatCount = -1; 191 this.schedule(this.update, cc.AUTOREPEAT_DELTATIME, cc.REPEAT_FOREVER, cc.AUTOREPEAT_DELTATIME * 3); 192 }, 193 194 /** Stop the autorepeat. */ 195 stopAutorepeat:function () { 196 this.unschedule(this.update); 197 }, 198 199 update:function (dt) { 200 this._autorepeatCount++; 201 202 if ((this._autorepeatCount < cc.AUTOREPEAT_INCREASETIME_INCREMENT) && (this._autorepeatCount % 3) != 0) 203 return; 204 205 if (this._touchedPart == cc.CONTROL_STEPPER_PARTMINUS) { 206 this.setValueWithSendingEvent(this._value - this._stepValue, this._continuous); 207 } else if (this._touchedPart == cc.CONTROL_STEPPER_PARTPLUS) { 208 this.setValueWithSendingEvent(this._value + this._stepValue, this._continuous); 209 } 210 }, 211 212 //#pragma mark CCControlStepper Private Methods 213 214 updateLayoutUsingTouchLocation:function (location) { 215 if (location.x < this._minusSprite.getContentSize().width 216 && this._value > this._minimumValue) { 217 this._touchedPart = cc.CONTROL_STEPPER_PARTMINUS; 218 this._minusSprite.setColor(cc.gray()); 219 this._plusSprite.setColor(cc.white()); 220 221 } else if (location.x >= this._minusSprite.getContentSize().width 222 && this._value < this._maximumValue) { 223 this._touchedPart = cc.CONTROL_STEPPER_PARTPLUS; 224 this._minusSprite.setColor(cc.white()); 225 this._plusSprite.setColor(cc.gray()); 226 227 } else { 228 this._touchedPart = cc.CONTROL_STEPPER_PARTNONE; 229 this._minusSprite.setColor(cc.white()); 230 this._plusSprite.setColor(cc.white()); 231 } 232 }, 233 234 235 onTouchBegan:function (touch, event) { 236 if (!this.isTouchInside(touch) || !this.isEnabled() || !this.isVisible()) { 237 return false; 238 } 239 240 var location = this.getTouchLocation(touch); 241 this.updateLayoutUsingTouchLocation(location); 242 this._touchInsideFlag = true; 243 244 if (this._autorepeat) { 245 this.startAutorepeat(); 246 } 247 248 return true; 249 }, 250 251 onTouchMoved:function (touch, event) { 252 if (this.isTouchInside(touch)) { 253 var location = this.getTouchLocation(touch); 254 this.updateLayoutUsingTouchLocation(location); 255 256 if (!this._touchInsideFlag) { 257 this._touchInsideFlag = true; 258 259 if (this._autorepeat) { 260 this.startAutorepeat(); 261 } 262 } 263 } else { 264 this._touchInsideFlag = false; 265 this._touchedPart = cc.CONTROL_STEPPER_PARTNONE; 266 this._minusSprite.setColor(cc.white()); 267 this._plusSprite.setColor(cc.white()); 268 if (this._autorepeat) { 269 this.stopAutorepeat(); 270 } 271 } 272 }, 273 274 onTouchEnded:function (touch, event) { 275 this._minusSprite.setColor(cc.white()); 276 this._plusSprite.setColor(cc.white()); 277 278 if (this._autorepeat) { 279 this.stopAutorepeat(); 280 } 281 282 if (this.isTouchInside(touch)) { 283 var location = this.getTouchLocation(touch); 284 this.setValue(this._value + ((location.x < this._minusSprite.getContentSize().width) ? (0.0 - this._stepValue) : this._stepValue)); 285 } 286 }, 287 setMinusSprite:function (sprite) { 288 this._minusSprite = sprite; 289 }, 290 getMinusSprite:function () { 291 return this._minusSprite; 292 }, 293 setPlusSprite:function (sprite) { 294 this._plusSprite = sprite; 295 }, 296 getPlusSprite:function () { 297 return this._plusSprite; 298 }, 299 setMinusLabel:function (sprite) { 300 this._minusLabel = sprite; 301 }, 302 getMinusLabel:function () { 303 return this._minusLabel; 304 }, 305 setPlusLabel:function (sprite) { 306 this._plusLabel = sprite; 307 }, 308 getPlusLabel:function () { 309 return this._plusLabel; 310 } 311 }); 312 313 cc.ControlStepper.create = function (minusSprite, plusSprite) { 314 var pRet = new cc.ControlStepper(); 315 if (pRet && pRet.initWithMinusSpriteAndPlusSprite(minusSprite, plusSprite)) { 316 return pRet; 317 } 318 return null; 319 };