/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for * full list of contributors). Published under the 2-clause BSD license. * See license.txt in the OpenLayers distribution or repository for the * full text of the license. */ /** * @requires OpenLayers/BaseTypes/Class.js */ /** * Class: OpenLayers.Control * Controls affect the display or behavior of the map. They allow everything * from panning and zooming to displaying a scale indicator. Controls by * default are added to the map they are contained within however it is * possible to add a control to an external div by passing the div in the * options parameter. * * Example: * The following example shows how to add many of the common controls * to a map. * * > var map = new OpenLayers.Map('map', { controls: [] }); * > * > map.addControl(new OpenLayers.Control.PanZoomBar()); * > map.addControl(new OpenLayers.Control.LayerSwitcher({'ascending':false})); * > map.addControl(new OpenLayers.Control.Permalink()); * > map.addControl(new OpenLayers.Control.Permalink('permalink')); * > map.addControl(new OpenLayers.Control.MousePosition()); * > map.addControl(new OpenLayers.Control.OverviewMap()); * > map.addControl(new OpenLayers.Control.KeyboardDefaults()); * * The next code fragment is a quick example of how to intercept * shift-mouse click to display the extent of the bounding box * dragged out by the user. Usually controls are not created * in exactly this manner. See the source for a more complete * example: * * > var control = new OpenLayers.Control(); * > OpenLayers.Util.extend(control, { * > draw: function () { * > // this Handler.Box will intercept the shift-mousedown * > // before Control.MouseDefault gets to see it * > this.box = new OpenLayers.Handler.Box( control, * > {"done": this.notice}, * > {keyMask: OpenLayers.Handler.MOD_SHIFT}); * > this.box.activate(); * > }, * > * > notice: function (bounds) { * > OpenLayers.Console.userError(bounds); * > } * > }); * > map.addControl(control); * */ OpenLayers.Control = OpenLayers.Class({ /** * Property: id * {String} */ id: null, /** * Property: map * {} this gets set in the addControl() function in * OpenLayers.Map */ map: null, /** * APIProperty: div * {DOMElement} The element that contains the control, if not present the * control is placed inside the map. */ div: null, /** * APIProperty: type * {Number} Controls can have a 'type'. The type determines the type of * interactions which are possible with them when they are placed in an * . */ type: null, /** * Property: allowSelection * {Boolean} By default, controls do not allow selection, because * it may interfere with map dragging. If this is true, OpenLayers * will not prevent selection of the control. * Default is false. */ allowSelection: false, /** * Property: displayClass * {string} This property is used for CSS related to the drawing of the * Control. */ displayClass: "", /** * APIProperty: title * {string} This property is used for showing a tooltip over the * Control. */ title: "", /** * APIProperty: autoActivate * {Boolean} Activate the control when it is added to a map. Default is * false. */ autoActivate: false, /** * APIProperty: active * {Boolean} The control is active (read-only). Use and * to change control state. */ active: null, /** * Property: handlerOptions * {Object} Used to set non-default properties on the control's handler */ handlerOptions: null, /** * Property: handler * {} null */ handler: null, /** * APIProperty: eventListeners * {Object} If set as an option at construction, the eventListeners * object will be registered with . Object * structure must be a listeners object as shown in the example for * the events.on method. */ eventListeners: null, /** * APIProperty: events * {} Events instance for listeners and triggering * control specific events. * * Register a listener for a particular event with the following syntax: * (code) * control.events.register(type, obj, listener); * (end) * * Listeners will be called with a reference to an event object. The * properties of this event depends on exactly what happened. * * All event objects have at least the following properties: * object - {Object} A reference to control.events.object (a reference * to the control). * element - {DOMElement} A reference to control.events.element (which * will be null unless documented otherwise). * * Supported map event types: * activate - Triggered when activated. * deactivate - Triggered when deactivated. */ events: null, /** * Constructor: OpenLayers.Control * Create an OpenLayers Control. The options passed as a parameter * directly extend the control. For example passing the following: * * > var control = new OpenLayers.Control({div: myDiv}); * * Overrides the default div attribute value of null. * * Parameters: * options - {Object} */ initialize: function (options) { // We do this before the extend so that instances can override // className in options. this.displayClass = this.CLASS_NAME.replace("OpenLayers.", "ol").replace(/\./g, ""); OpenLayers.Util.extend(this, options); this.events = new OpenLayers.Events(this); if(this.eventListeners instanceof Object) { this.events.on(this.eventListeners); } if (this.id == null) { this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME + "_"); } }, /** * Method: destroy * The destroy method is used to perform any clean up before the control * is dereferenced. Typically this is where event listeners are removed * to prevent memory leaks. */ destroy: function () { if(this.events) { if(this.eventListeners) { this.events.un(this.eventListeners); } this.events.destroy(); this.events = null; } this.eventListeners = null; // eliminate circular references if (this.handler) { this.handler.destroy(); this.handler = null; } if(this.handlers) { for(var key in this.handlers) { if(this.handlers.hasOwnProperty(key) && typeof this.handlers[key].destroy == "function") { this.handlers[key].destroy(); } } this.handlers = null; } if (this.map) { this.map.removeControl(this); this.map = null; } this.div = null; }, /** * Method: setMap * Set the map property for the control. This is done through an accessor * so that subclasses can override this and take special action once * they have their map variable set. * * Parameters: * map - {} */ setMap: function(map) { this.map = map; if (this.handler) { this.handler.setMap(map); } }, /** * Method: draw * The draw method is called when the control is ready to be displayed * on the page. If a div has not been created one is created. Controls * with a visual component will almost always want to override this method * to customize the look of control. * * Parameters: * px - {} The top-left pixel position of the control * or null. * * Returns: * {DOMElement} A reference to the DIV DOMElement containing the control */ draw: function (px) { if (this.div == null) { this.div = OpenLayers.Util.createDiv(this.id); this.div.className = this.displayClass; if (!this.allowSelection) { this.div.className += " olControlNoSelect"; this.div.setAttribute("unselectable", "on", 0); this.div.onselectstart = OpenLayers.Function.False; } if (this.title != "") { this.div.title = this.title; } } if (px != null) { this.position = px.clone(); } this.moveTo(this.position); return this.div; }, /** * Method: moveTo * Sets the left and top style attributes to the passed in pixel * coordinates. * * Parameters: * px - {} */ moveTo: function (px) { if ((px != null) && (this.div != null)) { this.div.style.left = px.x + "px"; this.div.style.top = px.y + "px"; } }, /** * APIMethod: activate * Explicitly activates a control and it's associated * handler if one has been set. Controls can be * deactivated by calling the deactivate() method. * * Returns: * {Boolean} True if the control was successfully activated or * false if the control was already active. */ activate: function () { if (this.active) { return false; } if (this.handler) { this.handler.activate(); } this.active = true; if(this.map) { OpenLayers.Element.addClass( this.map.viewPortDiv, this.displayClass.replace(/ /g, "") + "Active" ); } this.events.triggerEvent("activate"); return true; }, /** * APIMethod: deactivate * Deactivates a control and it's associated handler if any. The exact * effect of this depends on the control itself. * * Returns: * {Boolean} True if the control was effectively deactivated or false * if the control was already inactive. */ deactivate: function () { if (this.active) { if (this.handler) { this.handler.deactivate(); } this.active = false; if(this.map) { OpenLayers.Element.removeClass( this.map.viewPortDiv, this.displayClass.replace(/ /g, "") + "Active" ); } this.events.triggerEvent("deactivate"); return true; } return false; }, CLASS_NAME: "OpenLayers.Control" }); /** * Constant: OpenLayers.Control.TYPE_BUTTON */ OpenLayers.Control.TYPE_BUTTON = 1; /** * Constant: OpenLayers.Control.TYPE_TOGGLE */ OpenLayers.Control.TYPE_TOGGLE = 2; /** * Constant: OpenLayers.Control.TYPE_TOOL */ OpenLayers.Control.TYPE_TOOL = 3;