Created
December 6, 2011 18:10
-
-
Save wei-lee/1439235 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Ext.gesture.Manager = new Ext.AbstractManager({ | |
| //first, add more events | |
| eventNames: { | |
| 'touchstart': 'start', | |
| 'touchmove': 'move', | |
| 'touchend': 'end', | |
| 'mousedown': 'mousestart', | |
| 'mouseup': 'mouseend' | |
| }, | |
| defaultPreventedMouseEvents: [], | |
| clickMoveThreshold: 5, | |
| init: function () { | |
| this.targets = []; | |
| this.followTouches = []; | |
| this.currentGestures = []; | |
| this.currentTargets = []; | |
| var touchScreen = false; | |
| this.listenerWrappers = { | |
| start: Ext.createDelegate(this.onTouchStart, this), | |
| move: Ext.createDelegate(this.onTouchMove, this), | |
| end: Ext.createDelegate(this.onTouchEnd, this), | |
| mouse: Ext.createDelegate(this.onMouseEvent, this), | |
| //and more wrappers | |
| mousestart: Ext.createDelegate(this.onMouseStart, this), | |
| mouseend: Ext.createDelegate(this.onMouseEnd, this) | |
| }; | |
| this.attachListeners(); | |
| }, | |
| freeze: function () { | |
| this.isFrozen = true; | |
| }, | |
| thaw: function () { | |
| this.isFrozen = false; | |
| }, | |
| getEventSimulator: function () { | |
| if (!this.eventSimulator) { | |
| this.eventSimulator = new Ext.util.EventSimulator(); | |
| } | |
| return this.eventSimulator; | |
| }, | |
| attachListeners: function () { | |
| Ext.iterate(this.eventNames, function (key, name) { | |
| //switch key and name to add more event listeners | |
| //document.addEventListener(name, this.listenerWrappers[key], false); | |
| document.addEventListener(key, this.listenerWrappers[name], false); | |
| }, this); | |
| if (Ext.supports.Touch) { | |
| this.defaultPreventedMouseEvents.forEach(function (name) { | |
| document.addEventListener(name, this.listenerWrappers['mouse'], true); | |
| }, this); | |
| } | |
| }, | |
| detachListeners: function () { | |
| Ext.iterate(this.eventNames, function (key, name) { | |
| //same again | |
| //document.removeEventListener(name, this.listenerWrappers[key], false); | |
| document.removeEventListener(key, this.listenerWrappers[name], false); | |
| }, this); | |
| if (Ext.supports.Touch) { | |
| this.defaultPreventedMouseEvents.forEach(function (name) { | |
| document.removeEventListener(name, this.listenerWrappers['mouse'], true); | |
| }, this); | |
| } | |
| }, | |
| onMouseEvent: function (e) { | |
| if (!e.isSimulated) { | |
| e.preventDefault(); | |
| e.stopPropagation(); | |
| } | |
| }, | |
| //more mouse event handlers | |
| onMouseStart: function (e) { | |
| if (!this.touchStartFired) { | |
| this.onTouchStart(e, true); | |
| } else { | |
| this.touchStartFired = false; | |
| } | |
| }, | |
| onMouseEnd: function (e) { | |
| if (!this.touchEndFired) { | |
| this.onTouchEnd(e, true); | |
| } else { | |
| this.touchEndFired = false; | |
| } | |
| }, | |
| onTouchStart: function (e, noset) { | |
| var targets = [], | |
| target = e.target; | |
| if (e.stopped === true) { | |
| return; | |
| } | |
| if (Ext.is.Android) { | |
| if (!(target.tagName && ['input', 'textarea', 'select'].indexOf(target.tagName.toLowerCase()) !== -1)) { | |
| e.preventDefault(); | |
| } | |
| } | |
| if (this.isFrozen) { | |
| return; | |
| } | |
| if (this.startEvent) { | |
| this.onTouchEnd(e); | |
| } | |
| this.locks = {}; | |
| this.currentTargets = [target]; | |
| while (target) { | |
| if (this.targets.indexOf(target) !== -1) { | |
| targets.unshift(target); | |
| } | |
| target = target.parentNode; | |
| this.currentTargets.push(target); | |
| } | |
| this.startEvent = e; | |
| this.startPoint = Ext.util.Point.fromEvent(e); | |
| this.lastMovePoint = null; | |
| this.isClick = true; | |
| this.touchMoveFired = false; | |
| if (noset === undefined || noset === false) { | |
| this.touchStartFired = true; | |
| } | |
| this.handleTargets(targets, e); | |
| }, | |
| onTouchMove: function (e) { | |
| if (!Ext.is.Android) { | |
| e.preventDefault(); | |
| } | |
| if (!this.startEvent) { | |
| return; | |
| } | |
| if (Ext.is.Desktop) { | |
| e.target = this.startEvent.target; | |
| } | |
| if (this.isFrozen) { | |
| return; | |
| } | |
| var gestures = this.currentGestures, | |
| gesture, touch = e.changedTouches ? e.changedTouches[0] : e; | |
| this.lastMovePoint = Ext.util.Point.fromEvent(e); | |
| if (Ext.supports.Touch && this.isClick && !this.lastMovePoint.isWithin(this.startPoint, this.clickMoveThreshold)) { | |
| this.isClick = false; | |
| } | |
| for (var i = 0; i < gestures.length; i++) { | |
| if (e.stopped) { | |
| break; | |
| } | |
| gesture = gestures[i]; | |
| if (gesture.listenForMove) { | |
| gesture.onTouchMove(e, touch); | |
| } | |
| } | |
| this.touchMoveFired = true; | |
| }, | |
| onTouchEnd: function (e, noset) { | |
| if (Ext.is.Blackberry) { | |
| //e.preventDefault(); | |
| } | |
| if (this.isFrozen) { | |
| return; | |
| } | |
| var gestures = this.currentGestures.slice(0), | |
| ln = gestures.length, | |
| i, gesture, endPoint, needsAnotherMove = false, | |
| touch = e.changedTouches ? e.changedTouches[0] : e; | |
| if (this.startPoint) { | |
| endPoint = Ext.util.Point.fromEvent(e); | |
| if (!(this.lastMovePoint || this.startPoint)['equals'](endPoint)) { | |
| needsAnotherMove = true; | |
| } | |
| } | |
| for (i = 0; i < ln; i++) { | |
| gesture = gestures[i]; | |
| if (!e.stopped && gesture.listenForEnd) { | |
| if (needsAnotherMove) { | |
| gesture.onTouchMove(e, touch); | |
| } | |
| gesture.onTouchEnd(e, touch); | |
| } | |
| this.stopGesture(gesture); | |
| } | |
| if (Ext.supports.Touch && this.isClick) { | |
| this.isClick = false; | |
| this.getEventSimulator().fire('click', this.startEvent.target, touch); | |
| } | |
| if (noset === undefined || noset === false) { | |
| this.touchEndFired = true; | |
| } | |
| if (this.touchMoveFired) { | |
| this.touchEndFired = false; | |
| } | |
| this.lastMovePoint = null; | |
| this.followTouches = []; | |
| this.startedChangedTouch = false; | |
| this.currentTargets = []; | |
| this.startEvent = null; | |
| this.startPoint = null; | |
| }, | |
| //no changes after here | |
| handleTargets: function (targets, e) { | |
| var ln = targets.length, | |
| i; | |
| this.startedChangedTouch = false; | |
| this.startedTouches = Ext.supports.Touch ? e.touches : [e]; | |
| for (i = 0; i < ln; i++) { | |
| if (e.stopped) { | |
| break; | |
| } | |
| this.handleTarget(targets[i], e, true); | |
| } | |
| for (i = ln - 1; i >= 0; i--) { | |
| if (e.stopped) { | |
| break; | |
| } | |
| this.handleTarget(targets[i], e, false); | |
| } | |
| if (this.startedChangedTouch) { | |
| this.followTouches = this.followTouches.concat((Ext.supports.Touch && e.targetTouches) ? Ext.toArray(e.targetTouches) : [e]); | |
| } | |
| }, | |
| handleTarget: function (target, e, capture) { | |
| var gestures = Ext.Element.data(target, 'x-gestures') || [], | |
| ln = gestures.length, | |
| i, gesture; | |
| for (i = 0; i < ln; i++) { | |
| gesture = gestures[i]; | |
| if (( !! gesture.capture === !! capture) && (this.followTouches.length < gesture.touches) && ((Ext.supports.Touch && e.targetTouches) ? (e.targetTouches.length === gesture.touches) : true)) { | |
| this.startedChangedTouch = true; | |
| this.startGesture(gesture); | |
| if (gesture.listenForStart) { | |
| gesture.onTouchStart(e, e.changedTouches ? e.changedTouches[0] : e); | |
| } | |
| if (e.stopped) { | |
| break; | |
| } | |
| } | |
| } | |
| }, | |
| startGesture: function (gesture) { | |
| gesture.started = true; | |
| this.currentGestures.push(gesture); | |
| }, | |
| stopGesture: function (gesture) { | |
| gesture.started = false; | |
| this.currentGestures.remove(gesture); | |
| }, | |
| addEventListener: function (target, eventName, listener, options) { | |
| target = Ext.getDom(target); | |
| options = options || {}; | |
| var targets = this.targets, | |
| name = this.getGestureName(eventName), | |
| gestures = Ext.Element.data(target, 'x-gestures'), | |
| gesture; | |
| if (!gestures) { | |
| gestures = []; | |
| Ext.Element.data(target, 'x-gestures', gestures); | |
| } | |
| if (!name) { | |
| throw new Error('Trying to subscribe to unknown event ' + eventName); | |
| } | |
| if (targets.indexOf(target) === -1) { | |
| this.targets.push(target); | |
| } | |
| gesture = this.get(target.id + '-' + name); | |
| if (!gesture) { | |
| gesture = this.create(Ext.apply({}, options, { | |
| target: target, | |
| type: name | |
| })); | |
| gestures.push(gesture); | |
| } | |
| gesture.addListener(eventName, listener); | |
| if (this.startedChangedTouch && this.currentTargets.contains(target) && !gesture.started && !options.subsequent) { | |
| this.startGesture(gesture); | |
| if (gesture.listenForStart) { | |
| gesture.onTouchStart(this.startEvent, this.startedTouches[0]); | |
| } | |
| } | |
| }, | |
| removeEventListener: function (target, eventName, listener) { | |
| target = Ext.getDom(target); | |
| var name = this.getGestureName(eventName), | |
| gestures = Ext.Element.data(target, 'x-gestures') || [], | |
| gesture; | |
| gesture = this.get(target.id + '-' + name); | |
| if (gesture) { | |
| gesture.removeListener(eventName, listener); | |
| for (name in gesture.listeners) { | |
| return; | |
| } | |
| gesture.destroy(); | |
| gestures.remove(gesture); | |
| Ext.Element.data(target, 'x-gestures', gestures); | |
| } | |
| }, | |
| getGestureName: function (ename) { | |
| return this.names && this.names[ename]; | |
| }, | |
| registerType: function (type, cls) { | |
| var handles = cls.prototype.handles, | |
| i, ln; | |
| this.types[type] = cls; | |
| cls[this.typeName] = type; | |
| if (!handles) { | |
| handles = cls.prototype.handles = [type]; | |
| } | |
| this.names = this.names || {}; | |
| for (i = 0, ln = handles.length; i < ln; i++) { | |
| this.names[handles[i]] = type; | |
| } | |
| } | |
| }); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment