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 /** 29 * @ignore 30 */ 31 cc.CONTROL_STEPPER_PARTMINUS = 0; 32 cc.CONTROL_STEPPER_PARTPLUS = 1; 33 cc.CONTROL_STEPPER_PARTNONE = 2; 34 cc.CONTROL_STEPPER_LABELCOLOR_ENABLED = cc.color(55, 55, 55); 35 cc.CONTROL_STEPPER_LABELCOLOR_DISABLED = cc.color(147, 147, 147); 36 cc.CONTROL_STEPPER_LABELFONT = "CourierNewPSMT"; 37 cc.AUTOREPEAT_DELTATIME = 0.15; 38 cc.AUTOREPEAT_INCREASETIME_INCREMENT = 12; 39 40 /** 41 * ControlStepper: Stepper ui component. 42 * @class 43 * @extends cc.Control 44 * 45 * @property {Boolean} wraps - Indicate whether the stepper wraps 46 * @property {Number} value - The value of the stepper control 47 * @property {Number} minValue - The minimum value of the stepper control 48 * @property {Number} maxValue - The maximum value of the stepper control 49 * @property {Number} stepValue - The interval value for each step of the stepper control 50 * @property {Boolean} continuous - <@readonly> Indicate whether the stepper value is continuous 51 * @property {cc.Sprite} minusSprite - The sprite for minus button of the stepper control 52 * @property {cc.Sprite} plusSprite - The sprite for plus button of the stepper control 53 * @property {cc.LabelTTF} minusLabel - The label for minus button of the stepper control 54 * @property {cc.LabelTTF} plusSLabel - The label for plus button of the stepper control 55 */ 56 cc.ControlStepper = cc.Control.extend(/** @lends cc.ControlStepper# */{ 57 _minusSprite:null, 58 _plusSprite:null, 59 _minusLabel:null, 60 _plusLabel:null, 61 _value:0, 62 _continuous:false, 63 _autorepeat:false, 64 _wraps:false, 65 _minimumValue:0, 66 _maximumValue:0, 67 _stepValue:0, 68 _touchInsideFlag:false, 69 _touchedPart:cc.CONTROL_STEPPER_PARTNONE, 70 _autorepeatCount:0, 71 _className:"ControlStepper", 72 ctor:function () { 73 cc.Control.prototype.ctor.call(this); 74 this._minusSprite = null; 75 this._plusSprite = null; 76 this._minusLabel = null; 77 this._plusLabel = null; 78 this._value = 0; 79 this._continuous = false; 80 this._autorepeat = false; 81 this._wraps = false; 82 this._minimumValue = 0; 83 this._maximumValue = 0; 84 this._stepValue = 0; 85 this._touchInsideFlag = false; 86 this._touchedPart = cc.CONTROL_STEPPER_PARTNONE; 87 this._autorepeatCount = 0; 88 }, 89 90 initWithMinusSpriteAndPlusSprite:function (minusSprite, plusSprite) { 91 if(!minusSprite) 92 throw "cc.ControlStepper.initWithMinusSpriteAndPlusSprite(): Minus sprite should be non-null."; 93 if(!plusSprite) 94 throw "cc.ControlStepper.initWithMinusSpriteAndPlusSprite(): Plus sprite should be non-null."; 95 96 if (this.init()) { 97 // Set the default values 98 this._autorepeat = true; 99 this._continuous = true; 100 this._minimumValue = 0; 101 this._maximumValue = 100; 102 this._value = 0; 103 this._stepValue = 1; 104 this._wraps = false; 105 this.ignoreAnchorPointForPosition(false); 106 107 // Add the minus components 108 this.setMinusSprite(minusSprite); 109 this._minusSprite.setPosition(minusSprite.getContentSize().width / 2, minusSprite.getContentSize().height / 2); 110 this.addChild(this._minusSprite); 111 112 this.setMinusLabel(cc.LabelTTF.create("-", cc.CONTROL_STEPPER_LABELFONT, 40, cc.size(40, 40), cc.TEXT_ALIGNMENT_CENTER, cc.VERTICAL_TEXT_ALIGNMENT_CENTER)); 113 this._minusLabel.setColor(cc.CONTROL_STEPPER_LABELCOLOR_DISABLED); 114 this._minusLabel.setPosition(this._minusSprite.getContentSize().width / 2, this._minusSprite.getContentSize().height / 2); 115 this._minusSprite.addChild(this._minusLabel); 116 117 // Add the plus components 118 this.setPlusSprite(plusSprite); 119 this._plusSprite.setPosition(minusSprite.getContentSize().width + plusSprite.getContentSize().width / 2, 120 minusSprite.getContentSize().height / 2); 121 this.addChild(this._plusSprite); 122 123 this.setPlusLabel(cc.LabelTTF.create("+", cc.CONTROL_STEPPER_LABELFONT, 40, cc.size(40, 40), cc.TEXT_ALIGNMENT_CENTER, cc.VERTICAL_TEXT_ALIGNMENT_CENTER)); 124 this._plusLabel.setColor(cc.CONTROL_STEPPER_LABELCOLOR_ENABLED); 125 this._plusLabel.setPosition(this._plusSprite.getContentSize().width / 2, this._plusSprite.getContentSize().height / 2); 126 this._plusSprite.addChild(this._plusLabel); 127 128 // Defines the content size 129 var maxRect = cc.ControlUtils.CCRectUnion(this._minusSprite.getBoundingBox(), this._plusSprite.getBoundingBox()); 130 this.setContentSize(this._minusSprite.getContentSize().width + this._plusSprite.getContentSize().height, maxRect.height); 131 return true; 132 } 133 return false; 134 }, 135 136 //#pragma mark Properties 137 138 setWraps: function (wraps) { 139 this._wraps = wraps; 140 141 if (this._wraps) { 142 this._minusLabel.setColor(cc.CONTROL_STEPPER_LABELCOLOR_ENABLED); 143 this._plusLabel.setColor(cc.CONTROL_STEPPER_LABELCOLOR_ENABLED); 144 } 145 146 this.setValue(this._value); 147 }, 148 149 getWraps: function () { 150 return this._wraps; 151 }, 152 153 setMinimumValue:function (minimumValue) { 154 if (minimumValue >= this._maximumValue) 155 throw "cc.ControlStepper.setMinimumValue(): minimumValue should be numerically less than maximumValue."; 156 157 this._minimumValue = minimumValue; 158 this.setValue(this._value); 159 }, 160 getMinimumValue: function () { 161 return this._minimumValue; 162 }, 163 164 setMaximumValue:function (maximumValue) { 165 if (maximumValue <= this._minimumValue) 166 throw "cc.ControlStepper.setMaximumValue(): maximumValue should be numerically less than maximumValue."; 167 168 this._maximumValue = maximumValue; 169 this.setValue(this._value); 170 }, 171 getMaximumValue: function () { 172 return this._maximumValue; 173 }, 174 175 setValue:function (value) { 176 this.setValueWithSendingEvent(value, true); 177 }, 178 179 getValue:function () { 180 return this._value; 181 }, 182 183 setStepValue:function (stepValue) { 184 if (stepValue <= 0) 185 throw "cc.ControlStepper.setMaximumValue(): stepValue should be numerically greater than 0."; 186 this._stepValue = stepValue; 187 }, 188 189 getStepValue:function () { 190 return this._stepValue; 191 }, 192 193 isContinuous:function () { 194 return this._continuous; 195 }, 196 197 setValueWithSendingEvent:function (value, send) { 198 if (value < this._minimumValue) { 199 value = this._wraps ? this._maximumValue : this._minimumValue; 200 } else if (value > this._maximumValue) { 201 value = this._wraps ? this._minimumValue : this._maximumValue; 202 } 203 204 this._value = value; 205 206 if (!this._wraps) { 207 this._minusLabel.setColor((value == this._minimumValue) ? cc.CONTROL_STEPPER_LABELCOLOR_DISABLED : cc.CONTROL_STEPPER_LABELCOLOR_ENABLED); 208 this._plusLabel.setColor((value == this._maximumValue) ? cc.CONTROL_STEPPER_LABELCOLOR_DISABLED : cc.CONTROL_STEPPER_LABELCOLOR_ENABLED); 209 } 210 211 if (send) { 212 this.sendActionsForControlEvents(cc.CONTROL_EVENT_VALUECHANGED); 213 } 214 }, 215 216 startAutorepeat:function () { 217 this._autorepeatCount = -1; 218 this.schedule(this.update, cc.AUTOREPEAT_DELTATIME, cc.REPEAT_FOREVER, cc.AUTOREPEAT_DELTATIME * 3); 219 }, 220 221 /** Stop the autorepeat. */ 222 stopAutorepeat:function () { 223 this.unschedule(this.update); 224 }, 225 226 update:function (dt) { 227 this._autorepeatCount++; 228 229 if ((this._autorepeatCount < cc.AUTOREPEAT_INCREASETIME_INCREMENT) && (this._autorepeatCount % 3) != 0) 230 return; 231 232 if (this._touchedPart == cc.CONTROL_STEPPER_PARTMINUS) { 233 this.setValueWithSendingEvent(this._value - this._stepValue, this._continuous); 234 } else if (this._touchedPart == cc.CONTROL_STEPPER_PARTPLUS) { 235 this.setValueWithSendingEvent(this._value + this._stepValue, this._continuous); 236 } 237 }, 238 239 //#pragma mark CCControlStepper Private Methods 240 241 updateLayoutUsingTouchLocation:function (location) { 242 if (location.x < this._minusSprite.getContentSize().width 243 && this._value > this._minimumValue) { 244 this._touchedPart = cc.CONTROL_STEPPER_PARTMINUS; 245 this._minusSprite.setColor(cc.color.GRAY); 246 this._plusSprite.setColor(cc.color.WHITE); 247 248 } else if (location.x >= this._minusSprite.getContentSize().width 249 && this._value < this._maximumValue) { 250 this._touchedPart = cc.CONTROL_STEPPER_PARTPLUS; 251 this._minusSprite.setColor(cc.color.WHITE); 252 this._plusSprite.setColor(cc.color.GRAY); 253 254 } else { 255 this._touchedPart = cc.CONTROL_STEPPER_PARTNONE; 256 this._minusSprite.setColor(cc.color.WHITE); 257 this._plusSprite.setColor(cc.color.WHITE); 258 } 259 }, 260 261 262 onTouchBegan:function (touch, event) { 263 if (!this.isTouchInside(touch) || !this.isEnabled() || !this.isVisible()) { 264 return false; 265 } 266 267 var location = this.getTouchLocation(touch); 268 this.updateLayoutUsingTouchLocation(location); 269 this._touchInsideFlag = true; 270 271 if (this._autorepeat) { 272 this.startAutorepeat(); 273 } 274 275 return true; 276 }, 277 278 onTouchMoved:function (touch, event) { 279 if (this.isTouchInside(touch)) { 280 var location = this.getTouchLocation(touch); 281 this.updateLayoutUsingTouchLocation(location); 282 283 if (!this._touchInsideFlag) { 284 this._touchInsideFlag = true; 285 286 if (this._autorepeat) { 287 this.startAutorepeat(); 288 } 289 } 290 } else { 291 this._touchInsideFlag = false; 292 this._touchedPart = cc.CONTROL_STEPPER_PARTNONE; 293 this._minusSprite.setColor(cc.color.WHITE); 294 this._plusSprite.setColor(cc.color.WHITE); 295 if (this._autorepeat) { 296 this.stopAutorepeat(); 297 } 298 } 299 }, 300 301 onTouchEnded:function (touch, event) { 302 this._minusSprite.setColor(cc.color.WHITE); 303 this._plusSprite.setColor(cc.color.WHITE); 304 305 if (this._autorepeat) { 306 this.stopAutorepeat(); 307 } 308 309 if (this.isTouchInside(touch)) { 310 var location = this.getTouchLocation(touch); 311 this.setValue(this._value + ((location.x < this._minusSprite.getContentSize().width) ? (0.0 - this._stepValue) : this._stepValue)); 312 } 313 }, 314 setMinusSprite:function (sprite) { 315 this._minusSprite = sprite; 316 }, 317 getMinusSprite:function () { 318 return this._minusSprite; 319 }, 320 setPlusSprite:function (sprite) { 321 this._plusSprite = sprite; 322 }, 323 getPlusSprite:function () { 324 return this._plusSprite; 325 }, 326 setMinusLabel:function (sprite) { 327 this._minusLabel = sprite; 328 }, 329 getMinusLabel:function () { 330 return this._minusLabel; 331 }, 332 setPlusLabel:function (sprite) { 333 this._plusLabel = sprite; 334 }, 335 getPlusLabel:function () { 336 return this._plusLabel; 337 } 338 }); 339 340 window._p = cc.ControlStepper.prototype; 341 342 // Extedned properties 343 /** @expose */ 344 _p.wraps; 345 cc.defineGetterSetter(_p, "wraps", _p.getWraps, _p.setWraps); 346 /** @expose */ 347 _p.value; 348 cc.defineGetterSetter(_p, "value", _p.getValue, _p.setValue); 349 /** @expose */ 350 _p.minValue; 351 cc.defineGetterSetter(_p, "minValue", _p.getMinimumValue, _p.setMinimumValue); 352 /** @expose */ 353 _p.maxValue; 354 cc.defineGetterSetter(_p, "maxValue", _p.getMaximumValue, _p.setMaximumValue); 355 /** @expose */ 356 _p.stepValue; 357 cc.defineGetterSetter(_p, "stepValue", _p.getStepValue, _p.setStepValue); 358 /** @expose */ 359 _p.continuous; 360 cc.defineGetterSetter(_p, "continuous", _p.isContinuous); 361 /** @expose */ 362 _p.minusSprite; 363 cc.defineGetterSetter(_p, "minusSprite", _p.getMinusSprite, _p.setMinusSprite); 364 /** @expose */ 365 _p.plusSprite; 366 cc.defineGetterSetter(_p, "plusSprite", _p.getPlusSprite, _p.setPlusSprite); 367 /** @expose */ 368 _p.minusLabel; 369 cc.defineGetterSetter(_p, "minusLabel", _p.getMinusLabel, _p.setMinusLabel); 370 /** @expose */ 371 _p.plusLabel; 372 cc.defineGetterSetter(_p, "plusLabel", _p.getPlusLabel, _p.setPlusLabel); 373 374 delete window._p; 375 376 cc.ControlStepper.create = function (minusSprite, plusSprite) { 377 var pRet = new cc.ControlStepper(); 378 if (pRet && pRet.initWithMinusSpriteAndPlusSprite(minusSprite, plusSprite)) { 379 return pRet; 380 } 381 return null; 382 };