diff --git a/src/ol/interaction/interaction.js b/src/ol/interaction/interaction.js index ffb2e7bf70..4e5ef9d738 100644 --- a/src/ol/interaction/interaction.js +++ b/src/ol/interaction/interaction.js @@ -12,6 +12,22 @@ goog.require('ol.easing'); * @constructor */ ol.interaction.Interaction = function() { + + /** + * @private + * @type {ol.Map} + */ + this.map_ = null; + +}; + + +/** + * Get the map associated with this interaction. + * @return {ol.Map} Map. + */ +ol.interaction.Interaction.prototype.getMap = function() { + return this.map_; }; @@ -25,6 +41,17 @@ ol.interaction.Interaction.prototype.handleMapBrowserEvent = goog.abstractMethod; +/** + * Remove the interaction from its current map and attach it to the new map. + * Subclasses may set up event handlers to get notified about changes to + * the map here. + * @param {ol.Map} map Map. + */ +ol.interaction.Interaction.prototype.setMap = function(map) { + this.map_ = map; +}; + + /** * @param {ol.Map} map Map. * @param {ol.View2D} view View. diff --git a/src/ol/map.js b/src/ol/map.js index 624da19af3..8c890e1098 100644 --- a/src/ol/map.js +++ b/src/ol/map.js @@ -356,6 +356,14 @@ ol.Map = function(options) { control.setMap(this); }, this); + this.interactions_.forEach( + /** + * @param {ol.interaction.Interaction} interaction Interaction. + */ + function(interaction) { + interaction.setMap(this); + }, this); + this.overlays_.forEach( /** * @param {ol.Overlay} overlay Overlay. @@ -381,6 +389,18 @@ ol.Map.prototype.addControl = function(control) { }; +/** + * Add the given interaction to the map. + * @param {ol.interaction.Interaction} interaction Interaction to add. + */ +ol.Map.prototype.addInteraction = function(interaction) { + var interactions = this.getInteractions(); + goog.asserts.assert(goog.isDef(interactions)); + interactions.push(interaction); + interaction.setMap(this); +}; + + /** * Adds the given layer to the top of this map. * @param {ol.layer.Base} layer Layer. @@ -959,6 +979,24 @@ ol.Map.prototype.removeControl = function(control) { }; +/** + * Remove the given interaction from the map. + * @param {ol.interaction.Interaction} interaction Interaction to remove. + * @return {ol.interaction.Interaction|undefined} The removed interaction (or + * undefined if the interaction was not found). + */ +ol.Map.prototype.removeInteraction = function(interaction) { + var removed; + var interactions = this.getInteractions(); + goog.asserts.assert(goog.isDef(interactions)); + if (goog.isDef(interactions.remove(interaction))) { + interaction.setMap(null); + removed = interaction; + } + return removed; +}; + + /** * Removes the given layer from the map. * @param {ol.layer.Base} layer Layer. diff --git a/test/spec/ol/interaction/interaction.test.js b/test/spec/ol/interaction/interaction.test.js new file mode 100644 index 0000000000..5f2613404a --- /dev/null +++ b/test/spec/ol/interaction/interaction.test.js @@ -0,0 +1,50 @@ +goog.provide('ol.test.interaction.Interaction'); + +describe('ol.interaction.Interaction', function() { + + describe('constructor', function() { + + it('creates a new interaction', function() { + var interaction = new ol.interaction.Interaction(); + expect(interaction).to.be.a(ol.interaction.Interaction); + }); + + }); + + describe('#getMap()', function() { + + it('retrieves the associated map', function() { + var map = new ol.Map({}); + var interaction = new ol.interaction.Interaction(); + interaction.setMap(map); + expect(interaction.getMap()).to.be(map); + }); + + it('returns null if no map', function() { + var interaction = new ol.interaction.Interaction(); + expect(interaction.getMap()).to.be(null); + }); + + }); + + describe('#setMap()', function() { + + it('allows a map to be set', function() { + var map = new ol.Map({}); + var interaction = new ol.interaction.Interaction(); + interaction.setMap(map); + expect(interaction.getMap()).to.be(map); + }); + + it('accepts null', function() { + var interaction = new ol.interaction.Interaction(); + interaction.setMap(null); + expect(interaction.getMap()).to.be(null); + }); + + }); + +}); + +goog.require('ol.Map'); +goog.require('ol.interaction.Interaction'); diff --git a/test/spec/ol/map.test.js b/test/spec/ol/map.test.js index d005b3e44b..e1cdf2dfcc 100644 --- a/test/spec/ol/map.test.js +++ b/test/spec/ol/map.test.js @@ -51,6 +51,52 @@ describe('ol.RendererHints', function() { describe('ol.Map', function() { + describe('contstructor', function() { + it('creates a new map', function() { + var map = new ol.Map({}); + expect(map).to.be.a(ol.Map); + }); + + it('creates a set of default interactions', function() { + var map = new ol.Map({}); + var interactions = map.getInteractions(); + var length = interactions.getLength(); + expect(length).to.be.greaterThan(0); + + for (var i = 0; i < length; ++i) { + expect(interactions.getAt(i).getMap()).to.be(map); + } + }); + }); + + describe('#addInteraction()', function() { + it('adds an interaction to the map', function() { + var map = new ol.Map({}); + var interaction = new ol.interaction.Interaction(); + + var before = map.getInteractions().getLength(); + map.addInteraction(interaction); + var after = map.getInteractions().getLength(); + expect(after).to.be(before + 1); + expect(interaction.getMap()).to.be(map); + }); + }); + + describe('#removeInteraction()', function() { + it('removes an interaction from the map', function() { + var map = new ol.Map({}); + var interaction = new ol.interaction.Interaction(); + + var before = map.getInteractions().getLength(); + map.addInteraction(interaction); + + map.removeInteraction(interaction); + expect(map.getInteractions().getLength()).to.be(before); + + expect(interaction.getMap()).to.be(null); + }); + }); + describe('dispose', function() { var map; @@ -128,5 +174,6 @@ goog.require('ol.Map'); goog.require('ol.RendererHint'); goog.require('ol.RendererHints'); goog.require('ol.interaction'); +goog.require('ol.interaction.Interaction'); goog.require('ol.interaction.DoubleClickZoom'); goog.require('ol.interaction.MouseWheelZoom');