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