Control.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. /* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
  2. * full list of contributors). Published under the 2-clause BSD license.
  3. * See license.txt in the OpenLayers distribution or repository for the
  4. * full text of the license. */
  5. /**
  6. * @requires OpenLayers/BaseTypes/Class.js
  7. */
  8. /**
  9. * Class: OpenLayers.Control
  10. * Controls affect the display or behavior of the map. They allow everything
  11. * from panning and zooming to displaying a scale indicator. Controls by
  12. * default are added to the map they are contained within however it is
  13. * possible to add a control to an external div by passing the div in the
  14. * options parameter.
  15. *
  16. * Example:
  17. * The following example shows how to add many of the common controls
  18. * to a map.
  19. *
  20. * > var map = new OpenLayers.Map('map', { controls: [] });
  21. * >
  22. * > map.addControl(new OpenLayers.Control.PanZoomBar());
  23. * > map.addControl(new OpenLayers.Control.LayerSwitcher({'ascending':false}));
  24. * > map.addControl(new OpenLayers.Control.Permalink());
  25. * > map.addControl(new OpenLayers.Control.Permalink('permalink'));
  26. * > map.addControl(new OpenLayers.Control.MousePosition());
  27. * > map.addControl(new OpenLayers.Control.OverviewMap());
  28. * > map.addControl(new OpenLayers.Control.KeyboardDefaults());
  29. *
  30. * The next code fragment is a quick example of how to intercept
  31. * shift-mouse click to display the extent of the bounding box
  32. * dragged out by the user. Usually controls are not created
  33. * in exactly this manner. See the source for a more complete
  34. * example:
  35. *
  36. * > var control = new OpenLayers.Control();
  37. * > OpenLayers.Util.extend(control, {
  38. * > draw: function () {
  39. * > // this Handler.Box will intercept the shift-mousedown
  40. * > // before Control.MouseDefault gets to see it
  41. * > this.box = new OpenLayers.Handler.Box( control,
  42. * > {"done": this.notice},
  43. * > {keyMask: OpenLayers.Handler.MOD_SHIFT});
  44. * > this.box.activate();
  45. * > },
  46. * >
  47. * > notice: function (bounds) {
  48. * > OpenLayers.Console.userError(bounds);
  49. * > }
  50. * > });
  51. * > map.addControl(control);
  52. *
  53. */
  54. OpenLayers.Control = OpenLayers.Class({
  55. /**
  56. * Property: id
  57. * {String}
  58. */
  59. id: null,
  60. /**
  61. * Property: map
  62. * {<OpenLayers.Map>} this gets set in the addControl() function in
  63. * OpenLayers.Map
  64. */
  65. map: null,
  66. /**
  67. * APIProperty: div
  68. * {DOMElement} The element that contains the control, if not present the
  69. * control is placed inside the map.
  70. */
  71. div: null,
  72. /**
  73. * APIProperty: type
  74. * {Number} Controls can have a 'type'. The type determines the type of
  75. * interactions which are possible with them when they are placed in an
  76. * <OpenLayers.Control.Panel>.
  77. */
  78. type: null,
  79. /**
  80. * Property: allowSelection
  81. * {Boolean} By default, controls do not allow selection, because
  82. * it may interfere with map dragging. If this is true, OpenLayers
  83. * will not prevent selection of the control.
  84. * Default is false.
  85. */
  86. allowSelection: false,
  87. /**
  88. * Property: displayClass
  89. * {string} This property is used for CSS related to the drawing of the
  90. * Control.
  91. */
  92. displayClass: "",
  93. /**
  94. * APIProperty: title
  95. * {string} This property is used for showing a tooltip over the
  96. * Control.
  97. */
  98. title: "",
  99. /**
  100. * APIProperty: autoActivate
  101. * {Boolean} Activate the control when it is added to a map. Default is
  102. * false.
  103. */
  104. autoActivate: false,
  105. /**
  106. * APIProperty: active
  107. * {Boolean} The control is active (read-only). Use <activate> and
  108. * <deactivate> to change control state.
  109. */
  110. active: null,
  111. /**
  112. * Property: handlerOptions
  113. * {Object} Used to set non-default properties on the control's handler
  114. */
  115. handlerOptions: null,
  116. /**
  117. * Property: handler
  118. * {<OpenLayers.Handler>} null
  119. */
  120. handler: null,
  121. /**
  122. * APIProperty: eventListeners
  123. * {Object} If set as an option at construction, the eventListeners
  124. * object will be registered with <OpenLayers.Events.on>. Object
  125. * structure must be a listeners object as shown in the example for
  126. * the events.on method.
  127. */
  128. eventListeners: null,
  129. /**
  130. * APIProperty: events
  131. * {<OpenLayers.Events>} Events instance for listeners and triggering
  132. * control specific events.
  133. *
  134. * Register a listener for a particular event with the following syntax:
  135. * (code)
  136. * control.events.register(type, obj, listener);
  137. * (end)
  138. *
  139. * Listeners will be called with a reference to an event object. The
  140. * properties of this event depends on exactly what happened.
  141. *
  142. * All event objects have at least the following properties:
  143. * object - {Object} A reference to control.events.object (a reference
  144. * to the control).
  145. * element - {DOMElement} A reference to control.events.element (which
  146. * will be null unless documented otherwise).
  147. *
  148. * Supported map event types:
  149. * activate - Triggered when activated.
  150. * deactivate - Triggered when deactivated.
  151. */
  152. events: null,
  153. /**
  154. * Constructor: OpenLayers.Control
  155. * Create an OpenLayers Control. The options passed as a parameter
  156. * directly extend the control. For example passing the following:
  157. *
  158. * > var control = new OpenLayers.Control({div: myDiv});
  159. *
  160. * Overrides the default div attribute value of null.
  161. *
  162. * Parameters:
  163. * options - {Object}
  164. */
  165. initialize: function (options) {
  166. // We do this before the extend so that instances can override
  167. // className in options.
  168. this.displayClass =
  169. this.CLASS_NAME.replace("OpenLayers.", "ol").replace(/\./g, "");
  170. OpenLayers.Util.extend(this, options);
  171. this.events = new OpenLayers.Events(this);
  172. if(this.eventListeners instanceof Object) {
  173. this.events.on(this.eventListeners);
  174. }
  175. if (this.id == null) {
  176. this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME + "_");
  177. }
  178. },
  179. /**
  180. * Method: destroy
  181. * The destroy method is used to perform any clean up before the control
  182. * is dereferenced. Typically this is where event listeners are removed
  183. * to prevent memory leaks.
  184. */
  185. destroy: function () {
  186. if(this.events) {
  187. if(this.eventListeners) {
  188. this.events.un(this.eventListeners);
  189. }
  190. this.events.destroy();
  191. this.events = null;
  192. }
  193. this.eventListeners = null;
  194. // eliminate circular references
  195. if (this.handler) {
  196. this.handler.destroy();
  197. this.handler = null;
  198. }
  199. if(this.handlers) {
  200. for(var key in this.handlers) {
  201. if(this.handlers.hasOwnProperty(key) &&
  202. typeof this.handlers[key].destroy == "function") {
  203. this.handlers[key].destroy();
  204. }
  205. }
  206. this.handlers = null;
  207. }
  208. if (this.map) {
  209. this.map.removeControl(this);
  210. this.map = null;
  211. }
  212. this.div = null;
  213. },
  214. /**
  215. * Method: setMap
  216. * Set the map property for the control. This is done through an accessor
  217. * so that subclasses can override this and take special action once
  218. * they have their map variable set.
  219. *
  220. * Parameters:
  221. * map - {<OpenLayers.Map>}
  222. */
  223. setMap: function(map) {
  224. this.map = map;
  225. if (this.handler) {
  226. this.handler.setMap(map);
  227. }
  228. },
  229. /**
  230. * Method: draw
  231. * The draw method is called when the control is ready to be displayed
  232. * on the page. If a div has not been created one is created. Controls
  233. * with a visual component will almost always want to override this method
  234. * to customize the look of control.
  235. *
  236. * Parameters:
  237. * px - {<OpenLayers.Pixel>} The top-left pixel position of the control
  238. * or null.
  239. *
  240. * Returns:
  241. * {DOMElement} A reference to the DIV DOMElement containing the control
  242. */
  243. draw: function (px) {
  244. if (this.div == null) {
  245. this.div = OpenLayers.Util.createDiv(this.id);
  246. this.div.className = this.displayClass;
  247. if (!this.allowSelection) {
  248. this.div.className += " olControlNoSelect";
  249. this.div.setAttribute("unselectable", "on", 0);
  250. this.div.onselectstart = OpenLayers.Function.False;
  251. }
  252. if (this.title != "") {
  253. this.div.title = this.title;
  254. }
  255. }
  256. if (px != null) {
  257. this.position = px.clone();
  258. }
  259. this.moveTo(this.position);
  260. return this.div;
  261. },
  262. /**
  263. * Method: moveTo
  264. * Sets the left and top style attributes to the passed in pixel
  265. * coordinates.
  266. *
  267. * Parameters:
  268. * px - {<OpenLayers.Pixel>}
  269. */
  270. moveTo: function (px) {
  271. if ((px != null) && (this.div != null)) {
  272. this.div.style.left = px.x + "px";
  273. this.div.style.top = px.y + "px";
  274. }
  275. },
  276. /**
  277. * APIMethod: activate
  278. * Explicitly activates a control and it's associated
  279. * handler if one has been set. Controls can be
  280. * deactivated by calling the deactivate() method.
  281. *
  282. * Returns:
  283. * {Boolean} True if the control was successfully activated or
  284. * false if the control was already active.
  285. */
  286. activate: function () {
  287. if (this.active) {
  288. return false;
  289. }
  290. if (this.handler) {
  291. this.handler.activate();
  292. }
  293. this.active = true;
  294. if(this.map) {
  295. OpenLayers.Element.addClass(
  296. this.map.viewPortDiv,
  297. this.displayClass.replace(/ /g, "") + "Active"
  298. );
  299. }
  300. this.events.triggerEvent("activate");
  301. return true;
  302. },
  303. /**
  304. * APIMethod: deactivate
  305. * Deactivates a control and it's associated handler if any. The exact
  306. * effect of this depends on the control itself.
  307. *
  308. * Returns:
  309. * {Boolean} True if the control was effectively deactivated or false
  310. * if the control was already inactive.
  311. */
  312. deactivate: function () {
  313. if (this.active) {
  314. if (this.handler) {
  315. this.handler.deactivate();
  316. }
  317. this.active = false;
  318. if(this.map) {
  319. OpenLayers.Element.removeClass(
  320. this.map.viewPortDiv,
  321. this.displayClass.replace(/ /g, "") + "Active"
  322. );
  323. }
  324. this.events.triggerEvent("deactivate");
  325. return true;
  326. }
  327. return false;
  328. },
  329. CLASS_NAME: "OpenLayers.Control"
  330. });
  331. /**
  332. * Constant: OpenLayers.Control.TYPE_BUTTON
  333. */
  334. OpenLayers.Control.TYPE_BUTTON = 1;
  335. /**
  336. * Constant: OpenLayers.Control.TYPE_TOGGLE
  337. */
  338. OpenLayers.Control.TYPE_TOGGLE = 2;
  339. /**
  340. * Constant: OpenLayers.Control.TYPE_TOOL
  341. */
  342. OpenLayers.Control.TYPE_TOOL = 3;