diff --git a/src/ol.js b/src/ol.js index afba95fb92..c4ae4425f3 100644 --- a/src/ol.js +++ b/src/ol.js @@ -2,9 +2,8 @@ goog.provide("ol"); goog.require('ol.bounds'); goog.require('ol.control.Control'); goog.require('ol.control.Navigation'); -goog.require('ol.event'); +goog.require('ol.event.Drag'); goog.require('ol.event.Events'); -goog.require('ol.event.Sequence'); goog.require("ol.map"); goog.require("ol.loc"); goog.require("ol.feature"); diff --git a/src/ol/Map.js b/src/ol/Map.js index 0723ed1903..a2a4742a15 100644 --- a/src/ol/Map.js +++ b/src/ol/Map.js @@ -78,7 +78,9 @@ ol.Map = function() { * @private * @type {ol.event.Events} */ - this.events_ = new ol.event.Events(this); + this.events_ = new ol.event.Events( + this, undefined, false, ['Drag'] + ); /** * @private diff --git a/src/ol/control/Navigation.js b/src/ol/control/Navigation.js index 648ec8979c..e7eadacd57 100644 --- a/src/ol/control/Navigation.js +++ b/src/ol/control/Navigation.js @@ -20,18 +20,6 @@ ol.control.Navigation = function(opt_autoActivate) { this.autoActivate_ = goog.isDef(opt_autoActivate) ? opt_autoActivate : true; - /** - * type {number} - * @private - */ - this.oldX = undefined; - - /** - * type {number} - * @private - */ - this.oldY = undefined; - }; goog.inherits(ol.control.Navigation, ol.control.Control); @@ -54,10 +42,8 @@ ol.control.Navigation.prototype.deactivate = function() { }; /** - * @param {Event} evt + * @param {ol.event.DragEvent} evt */ ol.control.Navigation.prototype.moveMap = function(evt) { - this.getMap().moveByPx(evt.clientX - oldX, evt.clientY - oldY); - oldX = evt.clientX; - oldY = evt.clientY; + this.getMap().moveByPx(evt.dx, evt.dy); }; \ No newline at end of file diff --git a/src/ol/event/Drag.js b/src/ol/event/Drag.js index 8a27523f08..ea7d4e6933 100644 --- a/src/ol/event/Drag.js +++ b/src/ol/event/Drag.js @@ -1,57 +1,119 @@ goog.provide('ol.event.Drag'); +goog.provide('ol.event.DragEvent'); -goog.require('ol.event.Sequence'); +goog.require('ol.event.ISequence'); +goog.require('goog.functions'); goog.require('goog.fx.Dragger'); +goog.require('goog.fx.DragEvent'); goog.require('goog.fx.Dragger.EventType'); +goog.require('goog.functions'); /** * @constructor - * @extends {ol.event.Sequence} + * @param {Element} target The element that will be dragged. + * @extends {goog.fx.Dragger} + * @implements {ol.event.ISequence} * @export */ -ol.event.Drag = function() { +ol.event.Drag = function(target) { + goog.base(this, target); - goog.base(this); + /** + * @private + * @type {number} clientX of the previous event + */ + this.previousX_ = 0; - /** @inheritDoc */ - this.eventType_ = { - DRAGSTART: 'dragstart', - DRAG: 'drag', - DRAGEND: 'dragend' - }; - - var providedEvents = this.getProvidedEvents(), - oldX, oldY; - - providedEvents[this.eventType_.DRAGSTART] = {}; - providedEvents[this.eventType_.DRAGSTART] - [goog.fx.Dragger.EventType.START] = function(evt) { - oldX = evt.screenX; - oldY = evt.screenY; - }; - - providedEvents[this.eventType_.DRAG] = {}; - providedEvents[this.eventType_.DRAG] - [goog.fx.Dragger.EventType.DRAG] = function(evt) { - evt.dx = evt.screenX - oldX; - evt.dy = evt.screenY - oldY; - oldX = evt.screenX; - oldY = evt.screenY; - }; - - providedEvents[this.eventType_.DRAGEND] = {}; - providedEvents[this.eventType_.DRAGEND] - [goog.fx.Dragger.EventType.END] = true; + /** + * @private + * @type {number} clientY of the previous event + */ + this.previousY_ = 0; +}; +goog.inherits(ol.event.Drag, goog.fx.Dragger); + +/** + * @param {string|goog.fx.DragEvent} e + * @return {boolean} If anyone called preventDefault on the event object (or + * if any of the handlers returns false this will also return false. + */ +ol.event.Drag.prototype.dispatchEvent = function(e) { + if (e instanceof goog.fx.DragEvent) { + if (e.type === goog.fx.Dragger.EventType.START) { + e.type = ol.event.Drag.EventType.DRAGSTART; + } else if (e.type === goog.fx.Dragger.EventType.END) { + e.type = ol.event.Drag.EventType.DRAGEND; + } + } + return goog.base(this, 'dispatchEvent', e); }; -goog.inherits(ol.event.Drag, ol.event.Sequence); /** @inheritDoc */ -ol.event.Drag.prototype.setElement = function(element) { - goog.base(this, 'setElement', element); - if (goog.isDefAndNotNull(element)) { - this.dragger_ = new goog.fx.Dragger(element); - } else if (this.dragger_) { - this.dragger_.dispose(); - } +ol.event.Drag.prototype.startDrag = function(e) { + this.previousX_ = e.clientX; + this.previousY_ = e.clientY; + e.type = ol.event.Drag.EventType.DRAGSTART; + goog.base(this, 'startDrag', e); +}; + +/** @inheritDoc */ +ol.event.Drag.prototype.doDrag = function(e, x, y, dragFromScroll) { + e.dx = e.clientX - this.previousX_; + e.dy = e.clientX - this.previousY_; + goog.base(this, 'doDrag', e, x, y, dragFromScroll); +}; + +/** @override */ +ol.event.Drag.prototype.defaultAction = function(x, y) {}; + +/** @inheritDoc */ +ol.event.Drag.prototype.getEventTypes = function() { + return ol.event.Drag.EventType; +}; + +/** @inheritDoc */ +ol.event.Drag.prototype.destroy = ol.event.Drag.prototype.dispose; + + +/** + * Object representing a drag event + * + * @param {string} type Event type. + * @param {goog.fx.Dragger} dragobj Drag object initiating event. + * @param {number} clientX X-coordinate relative to the viewport. + * @param {number} clientY Y-coordinate relative to the viewport. + * @param {goog.events.BrowserEvent} browserEvent Object representing the + * browser event that caused this drag event. + * @constructor + * @extends {goog.fx.DragEvent} + */ +ol.event.DragEvent = function(type, dragobj, clientX, clientY, browserEvent) { + + goog.base(this, type, dragobj, clientX, clientY, browserEvent); + + /** + * The move delta in X direction since the previous drag event + * + * @type {number} + */ + this.dx = 0; + + /** + * The move delta in Y direction since the previous drag event + * + * @type {number} + */ + this.dy = 0; +}; +goog.inherits(ol.event.DragEvent, goog.fx.DragEvent); + + +/** + * @type {Object.} + */ +ol.event.Drag.EventType = { + DRAGSTART: 'dragstart', + DRAG: goog.fx.Dragger.EventType.DRAG, + DRAGEND: 'dragend' }; \ No newline at end of file diff --git a/src/ol/event/Events.js b/src/ol/event/Events.js index c31f8f8fd9..4551744213 100644 --- a/src/ol/event/Events.js +++ b/src/ol/event/Events.js @@ -6,7 +6,6 @@ goog.require('goog.events.EventType'); goog.require('goog.events.EventTarget'); goog.require('goog.events.Listener'); goog.require('goog.style'); -goog.require('goog.fx.Dragger'); /** * Determine whether event was caused by a single touch @@ -45,8 +44,8 @@ ol.event.isMultiTouch = function(evt) { * property on the event object that is passed, which represents the * relative position of the pointer to the {@code element}. Default is * false. - * @param {Array.=} opt_sequences Event sequences to register with this - * events instance. + * @param {Array.=} opt_sequences Event sequences to register with + * this Events instance. * @export */ ol.event.Events = function(object, opt_element, opt_includeXY, opt_sequences) { @@ -75,24 +74,21 @@ ol.event.Events = function(object, opt_element, opt_includeXY, opt_sequences) { /** * @private - * @type {!Array.} + * @type {Array.} + */ + this.sequenceProviders_ = goog.isDef(opt_sequences) ? opt_sequences : []; + + /** + * @private + * @type {Array.} */ this.sequences_ = []; - this.setElement(opt_element); - this.setSequences(opt_sequences); -}; -goog.inherits(ol.event.Events, goog.events.EventTarget); - -/** - * @param {Array.} sequences - */ -ol.event.Events.prototype.setSequences = function(sequences) { - this.sequences_ = sequences || []; - for (var i=0, ii=this.sequences_.length; i=0; --i) { + this.sequences_[i].destroy(); + } + this.sequences_ = []; +}; + +/** + * @return {Object.} + */ +ol.event.Events.prototype.getBrowserEventTypes = function() { + var types = {}; + goog.object.extend(types, goog.events.EventType); + for (var i=this.sequences_.length-1; i>=0; --i) { + goog.object.extend(types, this.sequences_[i].getEventTypes()); + } + return types; }; /** @@ -202,21 +227,21 @@ ol.event.Events.prototype.unregister = function(type, listener, opt_scope) { * Trigger a specified registered event. * * @param {string} type The type of the event to trigger. - * @param {Object} evt The event object that will be passed to listeners. + * @param {Object=} opt_evt The event object that will be passed to listeners. * * @return {boolean} The last listener return. If a listener returns false, * the chain of listeners will stop getting called. * @export */ -ol.event.Events.prototype.triggerEvent = function(type, evt) { +ol.event.Events.prototype.triggerEvent = function(type, opt_evt) { var returnValue, listeners = goog.events.getListeners(this, type, true) .concat(goog.events.getListeners(this, type, false)); if (arguments.length === 1) { - evt = {type: type}; + opt_evt = {type: type}; } for (var i=0, ii=listeners.length; i} element + */ +ol.event.ISequence.prototype.getEventTypes = function() {}; + +/** + * Destroys the sequence + */ +ol.event.ISequence.prototype.destroy = function() {}; diff --git a/test/spec/ol/Events.test.js b/test/spec/ol/Events.test.js index 26fa7be2c9..cae3c193f4 100644 --- a/test/spec/ol/Events.test.js +++ b/test/spec/ol/Events.test.js @@ -123,29 +123,36 @@ describe("ol.event.Events", function() { events.destroy(); }); - it("can map browser events to sequences", function() { + it("can be extended with event sequences", function() { var element = document.createElement("div"), - events = new ol.event.Events("foo", element), + events = new ol.event.Events("foo", element, false, ["Drag"]), mockEvt; // mock dom object goog.object.extend(element, new goog.events.EventTarget()); log = []; - events.register('start', logFn); + events.register('dragstart', logFn); events.register('drag', logFn); - events.register('end', logFn); + events.register('dragend', logFn); - mockEvt = new goog.events.BrowserEvent({type: "start", button: null}); + mockEvt = new goog.events.BrowserEvent({ + type: "dragstart", button: null + }); element.dispatchEvent(mockEvt); - mockEvt = new goog.events.BrowserEvent({type: "drag", button: null}); + mockEvt = new goog.events.BrowserEvent({ + type: "drag", button: null + }); element.dispatchEvent(mockEvt); - mockEvt = new goog.events.BrowserEvent({type: "end", button: null}); + mockEvt = new goog.events.BrowserEvent({ + type: "dragend", button: null + }); element.dispatchEvent(mockEvt); - expect(log[0].evt.type).toBe("start"); + expect(log.length).toBe(3); + expect(log[0].evt.type).toBe("dragstart"); expect(log[1].evt.type).toBe("drag"); - expect(log[2].evt.type).toBe("end"); + expect(log[2].evt.type).toBe("dragend"); events.destroy(); });