Control.js 11 KB

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