1 /**************************************************************************** 2 Copyright (c) 2010-2014 cocos2d-x.org 3 4 http://www.cocos2d-x.org 5 6 Permission is hereby granted, free of charge, to any person obtaining a copy 7 of this software and associated documentation files (the "Software"), to deal 8 in the Software without restriction, including without limitation the rights 9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 copies of the Software, and to permit persons to whom the Software is 11 furnished to do so, subject to the following conditions: 12 13 The above copyright notice and this permission notice shall be included in 14 all copies or substantial portions of the Software. 15 16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 22 THE SOFTWARE. 23 ****************************************************************************/ 24 25 /** 26 * <p> 27 * The base class of event listener. <br/> 28 * If you need custom listener which with different callback, you need to inherit this class. <br/> 29 * For instance, you could refer to EventListenerAcceleration, EventListenerKeyboard, <br/> 30 * EventListenerTouchOneByOne, EventListenerCustom. 31 * </p> 32 * @class 33 * @extends cc.Class 34 */ 35 cc.EventListener = cc.Class.extend(/** @lends cc.EventListener# */{ 36 _onEvent: null, // Event callback function 37 _type: 0, // Event listener type 38 _listenerID: null, // Event listener ID 39 _registered: false, // Whether the listener has been added to dispatcher. 40 41 _fixedPriority: 0, // The higher the number, the higher the priority, 0 is for scene graph base priority. 42 _node: null, // scene graph based priority 43 _paused: false, // Whether the listener is paused 44 45 /** 46 * Initializes event with type and callback function 47 * @param {number} type 48 * @param {string} listenerID 49 * @param {function} callback 50 */ 51 ctor: function (type, listenerID, callback) { 52 this._onEvent = callback; 53 this._type = type || 0; 54 this._listenerID = listenerID || ""; 55 }, 56 57 _setPaused: function (paused) { 58 this._paused = paused; 59 }, 60 61 _isPaused: function () { 62 return this._paused; 63 }, 64 65 _setRegistered: function (registered) { 66 this._registered = registered; 67 }, 68 69 _isRegistered: function () { 70 return this._registered; 71 }, 72 73 _getType: function () { 74 return this._type; 75 }, 76 77 _getListenerID: function () { 78 return this._listenerID; 79 }, 80 81 _setFixedPriority: function (fixedPriority) { 82 this._fixedPriority = fixedPriority; 83 }, 84 85 _getFixedPriority: function () { 86 return this._fixedPriority; 87 }, 88 89 _setSceneGraphPriority: function (node) { 90 this._node = node; 91 }, 92 93 _getSceneGraphPriority: function () { 94 return this._node; 95 }, 96 97 /** 98 * Checks whether the listener is available. 99 * @returns {boolean} 100 */ 101 checkAvailable: function () { 102 return this._onEvent != null; 103 }, 104 105 /** 106 * Clones the listener, its subclasses have to override this method. 107 * @returns {cc.EventListener} 108 */ 109 clone: function () { 110 return null; 111 }, 112 113 /** 114 * Currently JavaScript Bindings (JSB), in some cases, needs to use retain and release. This is a bug in JSB, 115 * and the ugly workaround is to use retain/release. So, these 2 methods were added to be compatible with JSB. 116 * This is a hack, and should be removed once JSB fixes the retain/release bug 117 */ 118 retain:function () { 119 }, 120 release:function () { 121 } 122 }); 123 124 // event listener type 125 cc.EventListener.UNKNOWN = 0; 126 cc.EventListener.TOUCH_ONE_BY_ONE = 1; 127 cc.EventListener.TOUCH_ALL_AT_ONCE = 2; 128 cc.EventListener.KEYBOARD = 3; 129 cc.EventListener.MOUSE = 4; 130 cc.EventListener.ACCELERATION = 5; 131 cc.EventListener.CUSTOM = 6; 132 133 cc._EventListenerCustom = cc.EventListener.extend({ 134 _onCustomEvent: null, 135 ctor: function (listenerId, callback) { 136 this._onCustomEvent = callback; 137 var selfPointer = this; 138 var listener = function (event) { 139 if (selfPointer._onCustomEvent != null) 140 selfPointer._onCustomEvent(event); 141 }; 142 143 cc.EventListener.prototype.ctor.call(this, cc.EventListener.CUSTOM, listenerId, listener); 144 }, 145 146 checkAvailable: function () { 147 return (cc.EventListener.prototype.checkAvailable.call(this) && this._onCustomEvent != null); 148 }, 149 150 clone: function () { 151 return new cc._EventListenerCustom(this._listenerID, this._onCustomEvent); 152 } 153 }); 154 155 cc._EventListenerCustom.create = function (eventName, callback) { 156 return new cc._EventListenerCustom(eventName, callback); 157 }; 158 159 cc._EventListenerAcceleration = cc.EventListener.extend({ 160 _onAccelerationEvent: null, 161 ctor: function (callback) { 162 this._onAccelerationEvent = callback; 163 var selfPointer = this; 164 var listener = function (event) { 165 selfPointer._onAccelerationEvent(event._acc, event); 166 }; 167 cc.EventListener.prototype.ctor.call(this, cc.EventListener.ACCELERATION, cc._EventListenerAcceleration.LISTENER_ID, listener); 168 }, 169 170 checkAvailable: function () { 171 if (!this._onAccelerationEvent) 172 throw "cc._EventListenerAcceleration.checkAvailable(): _onAccelerationEvent must be non-nil"; 173 return true; 174 }, 175 176 clone: function () { 177 return new cc._EventListenerAcceleration(this._onAccelerationEvent); 178 } 179 }); 180 181 cc._EventListenerAcceleration.LISTENER_ID = "__cc_acceleration"; 182 183 cc._EventListenerAcceleration.create = function (callback) { 184 return new cc._EventListenerAcceleration(callback); 185 }; 186 187 cc._EventListenerKeyboard = cc.EventListener.extend({ 188 onKeyPressed: null, 189 onKeyReleased: null, 190 191 ctor: function () { 192 var selfPointer = this; 193 var listener = function (event) { 194 if (event._isPressed) { 195 if (selfPointer.onKeyPressed) 196 selfPointer.onKeyPressed(event._keyCode, event); 197 } else { 198 if (selfPointer.onKeyReleased) 199 selfPointer.onKeyReleased(event._keyCode, event); 200 } 201 }; 202 cc.EventListener.prototype.ctor.call(this, cc.EventListener.KEYBOARD, cc._EventListenerKeyboard.LISTENER_ID, listener); 203 }, 204 205 clone: function () { 206 var eventListener = new cc._EventListenerKeyboard(); 207 eventListener.onKeyPressed = this.onKeyPressed; 208 eventListener.onKeyReleased = this.onKeyReleased; 209 return eventListener; 210 }, 211 212 checkAvailable: function () { 213 if (this.onKeyPressed == null && this.onKeyReleased == null) { 214 cc.log("cc._EventListenerKeyboard.checkAvailable(): Invalid EventListenerKeyboard!"); 215 return false; 216 } 217 return true; 218 } 219 }); 220 221 cc._EventListenerKeyboard.LISTENER_ID = "__cc_keyboard"; 222 223 cc._EventListenerKeyboard.create = function () { 224 return new cc._EventListenerKeyboard(); 225 }; 226 227 cc._EventListenerMouse = cc.EventListener.extend({ 228 onMouseDown: null, 229 onMouseUp: null, 230 onMouseMove: null, 231 onMouseScroll: null, 232 233 ctor: function () { 234 var selfPointer = this; 235 var listener = function (event) { 236 var eventType = cc.EventMouse; 237 switch (event._eventType) { 238 case eventType.DOWN: 239 if (selfPointer.onMouseDown) 240 selfPointer.onMouseDown(event); 241 break; 242 case eventType.UP: 243 if (selfPointer.onMouseUp) 244 selfPointer.onMouseUp(event); 245 break; 246 case eventType.MOVE: 247 if (selfPointer.onMouseMove) 248 selfPointer.onMouseMove(event); 249 break; 250 case eventType.SCROLL: 251 if (selfPointer.onMouseScroll) 252 selfPointer.onMouseScroll(event); 253 break; 254 default: 255 break; 256 } 257 }; 258 cc.EventListener.prototype.ctor.call(this, cc.EventListener.MOUSE, cc._EventListenerMouse.LISTENER_ID, listener); 259 }, 260 261 clone: function () { 262 var eventListener = new cc._EventListenerMouse(); 263 eventListener.onMouseDown = this.onMouseDown; 264 eventListener.onMouseUp = this.onMouseUp; 265 eventListener.onMouseMove = this.onMouseMove; 266 eventListener.onMouseScroll = this.onMouseScroll; 267 return eventListener; 268 }, 269 270 checkAvailable: function () { 271 return true; 272 } 273 }); 274 275 cc._EventListenerMouse.LISTENER_ID = "__cc_mouse"; 276 277 cc._EventListenerMouse.create = function () { 278 return new cc._EventListenerMouse(); 279 }; 280 281 cc._EventListenerTouchOneByOne = cc.EventListener.extend({ 282 _claimedTouches: null, 283 swallowTouches: false, 284 onTouchBegan: null, 285 onTouchMoved: null, 286 onTouchEnded: null, 287 onTouchCancelled: null, 288 289 ctor: function () { 290 cc.EventListener.prototype.ctor.call(this, cc.EventListener.TOUCH_ONE_BY_ONE, cc._EventListenerTouchOneByOne.LISTENER_ID, null); 291 this._claimedTouches = []; 292 }, 293 294 setSwallowTouches: function (needSwallow) { 295 this.swallowTouches = needSwallow; 296 }, 297 298 clone: function () { 299 var eventListener = new cc._EventListenerTouchOneByOne(); 300 eventListener.onTouchBegan = this.onTouchBegan; 301 eventListener.onTouchMoved = this.onTouchMoved; 302 eventListener.onTouchEnded = this.onTouchEnded; 303 eventListener.onTouchCancelled = this.onTouchCancelled; 304 eventListener.swallowTouches = this.swallowTouches; 305 return eventListener; 306 }, 307 308 checkAvailable: function () { 309 if(!this.onTouchBegan){ 310 cc.log("cc._EventListenerTouchOneByOne.checkAvailable(): Invalid EventListenerTouchOneByOne!"); 311 return false; 312 } 313 return true; 314 } 315 }); 316 317 cc._EventListenerTouchOneByOne.LISTENER_ID = "__cc_touch_one_by_one"; 318 319 cc._EventListenerTouchOneByOne.create = function () { 320 return new cc._EventListenerTouchOneByOne(); 321 }; 322 323 cc._EventListenerTouchAllAtOnce = cc.EventListener.extend({ 324 onTouchesBegan: null, 325 onTouchesMoved: null, 326 onTouchesEnded: null, 327 onTouchesCancelled: null, 328 329 ctor: function(){ 330 cc.EventListener.prototype.ctor.call(this, cc.EventListener.TOUCH_ALL_AT_ONCE, cc._EventListenerTouchAllAtOnce.LISTENER_ID, null); 331 }, 332 333 clone: function(){ 334 var eventListener = new cc._EventListenerTouchAllAtOnce(); 335 eventListener.onTouchesBegan = this.onTouchesBegan; 336 eventListener.onTouchesMoved = this.onTouchesMoved; 337 eventListener.onTouchesEnded = this.onTouchesEnded; 338 eventListener.onTouchesCancelled = this.onTouchesCancelled; 339 return eventListener; 340 }, 341 342 checkAvailable: function(){ 343 if (this.onTouchesBegan == null && this.onTouchesMoved == null 344 && this.onTouchesEnded == null && this.onTouchesCancelled == null) { 345 cc.log("cc._EventListenerTouchAllAtOnce.checkAvailable(): Invalid EventListenerTouchAllAtOnce!"); 346 return false; 347 } 348 return true; 349 } 350 }); 351 352 cc._EventListenerTouchAllAtOnce.LISTENER_ID = "__cc_touch_all_at_once"; 353 354 cc._EventListenerTouchAllAtOnce.create = function(){ 355 return new cc._EventListenerTouchAllAtOnce(); 356 }; 357 358 /** 359 * Create a EventListener object by json object 360 * @param {object} argObj a json object 361 * @returns {cc.EventListener} 362 * @example 363 * cc.EventListener.create({ 364 * event: cc.EventListener.TOUCH_ONE_BY_ONE, 365 * swallowTouches: true, 366 * onTouchBegan: function (touch, event) { 367 * //do something 368 * return true; 369 * } 370 * }); 371 */ 372 cc.EventListener.create = function(argObj){ 373 if(!argObj || !argObj.event){ 374 throw "Invalid parameter."; 375 } 376 var listenerType = argObj.event; 377 delete argObj.event; 378 379 var listener = null; 380 if(listenerType === cc.EventListener.TOUCH_ONE_BY_ONE) 381 listener = new cc._EventListenerTouchOneByOne(); 382 else if(listenerType === cc.EventListener.TOUCH_ALL_AT_ONCE) 383 listener = new cc._EventListenerTouchAllAtOnce(); 384 else if(listenerType === cc.EventListener.MOUSE) 385 listener = new cc._EventListenerMouse(); 386 else if(listenerType === cc.EventListener.CUSTOM){ 387 listener = new cc._EventListenerCustom(argObj.eventName, argObj.callback); 388 delete argObj.eventName; 389 delete argObj.callback; 390 } else if(listenerType === cc.EventListener.KEYBOARD) 391 listener = new cc._EventListenerKeyboard(); 392 else if(listenerType === cc.EventListener.ACCELERATION){ 393 listener = new cc._EventListenerAcceleration(argObj.callback); 394 delete argObj.callback; 395 } 396 397 for(var key in argObj) { 398 listener[key] = argObj[key]; 399 } 400 401 return listener; 402 };