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