DragFeature.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  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/Control.js
  7. * @requires OpenLayers/Handler/Drag.js
  8. * @requires OpenLayers/Handler/Feature.js
  9. */
  10. /**
  11. * Class: OpenLayers.Control.DragFeature
  12. * The DragFeature control moves a feature with a drag of the mouse. Create a
  13. * new control with the <OpenLayers.Control.DragFeature> constructor.
  14. *
  15. * Inherits From:
  16. * - <OpenLayers.Control>
  17. */
  18. OpenLayers.Control.DragFeature = OpenLayers.Class(OpenLayers.Control, {
  19. /**
  20. * APIProperty: geometryTypes
  21. * {Array(String)} To restrict dragging to a limited set of geometry types,
  22. * send a list of strings corresponding to the geometry class names.
  23. */
  24. geometryTypes: null,
  25. /**
  26. * APIProperty: onStart
  27. * {Function} Define this function if you want to know when a drag starts.
  28. * The function should expect to receive two arguments: the feature
  29. * that is about to be dragged and the pixel location of the mouse.
  30. *
  31. * Parameters:
  32. * feature - {<OpenLayers.Feature.Vector>} The feature that is about to be
  33. * dragged.
  34. * pixel - {<OpenLayers.Pixel>} The pixel location of the mouse.
  35. */
  36. onStart: function(feature, pixel) {},
  37. /**
  38. * APIProperty: onDrag
  39. * {Function} Define this function if you want to know about each move of a
  40. * feature. The function should expect to receive two arguments: the
  41. * feature that is being dragged and the pixel location of the mouse.
  42. *
  43. * Parameters:
  44. * feature - {<OpenLayers.Feature.Vector>} The feature that was dragged.
  45. * pixel - {<OpenLayers.Pixel>} The pixel location of the mouse.
  46. */
  47. onDrag: function(feature, pixel) {},
  48. /**
  49. * APIProperty: onComplete
  50. * {Function} Define this function if you want to know when a feature is
  51. * done dragging. The function should expect to receive two arguments:
  52. * the feature that is being dragged and the pixel location of the
  53. * mouse.
  54. *
  55. * Parameters:
  56. * feature - {<OpenLayers.Feature.Vector>} The feature that was dragged.
  57. * pixel - {<OpenLayers.Pixel>} The pixel location of the mouse.
  58. */
  59. onComplete: function(feature, pixel) {},
  60. /**
  61. * APIProperty: onEnter
  62. * {Function} Define this function if you want to know when the mouse
  63. * goes over a feature and thereby makes this feature a candidate
  64. * for dragging.
  65. *
  66. * Parameters:
  67. * feature - {<OpenLayers.Feature.Vector>} The feature that is ready
  68. * to be dragged.
  69. */
  70. onEnter: function(feature) {},
  71. /**
  72. * APIProperty: onLeave
  73. * {Function} Define this function if you want to know when the mouse
  74. * goes out of the feature that was dragged.
  75. *
  76. * Parameters:
  77. * feature - {<OpenLayers.Feature.Vector>} The feature that was dragged.
  78. */
  79. onLeave: function(feature) {},
  80. /**
  81. * APIProperty: documentDrag
  82. * {Boolean} If set to true, mouse dragging will continue even if the
  83. * mouse cursor leaves the map viewport. Default is false.
  84. */
  85. documentDrag: false,
  86. /**
  87. * Property: layer
  88. * {<OpenLayers.Layer.Vector>}
  89. */
  90. layer: null,
  91. /**
  92. * Property: feature
  93. * {<OpenLayers.Feature.Vector>}
  94. */
  95. feature: null,
  96. /**
  97. * Property: dragCallbacks
  98. * {Object} The functions that are sent to the drag handler for callback.
  99. */
  100. dragCallbacks: {},
  101. /**
  102. * Property: featureCallbacks
  103. * {Object} The functions that are sent to the feature handler for callback.
  104. */
  105. featureCallbacks: {},
  106. /**
  107. * Property: lastPixel
  108. * {<OpenLayers.Pixel>}
  109. */
  110. lastPixel: null,
  111. /**
  112. * Constructor: OpenLayers.Control.DragFeature
  113. * Create a new control to drag features.
  114. *
  115. * Parameters:
  116. * layer - {<OpenLayers.Layer.Vector>} The layer containing features to be
  117. * dragged.
  118. * options - {Object} Optional object whose properties will be set on the
  119. * control.
  120. */
  121. initialize: function(layer, options) {
  122. OpenLayers.Control.prototype.initialize.apply(this, [options]);
  123. this.layer = layer;
  124. this.handlers = {
  125. drag: new OpenLayers.Handler.Drag(
  126. this, OpenLayers.Util.extend({
  127. down: this.downFeature,
  128. move: this.moveFeature,
  129. up: this.upFeature,
  130. out: this.cancel,
  131. done: this.doneDragging
  132. }, this.dragCallbacks), {
  133. documentDrag: this.documentDrag
  134. }
  135. ),
  136. feature: new OpenLayers.Handler.Feature(
  137. this, this.layer, OpenLayers.Util.extend({
  138. // 'click' and 'clickout' callback are for the mobile
  139. // support: no 'over' or 'out' in touch based browsers.
  140. click: this.clickFeature,
  141. clickout: this.clickoutFeature,
  142. over: this.overFeature,
  143. out: this.outFeature
  144. }, this.featureCallbacks),
  145. {geometryTypes: this.geometryTypes}
  146. )
  147. };
  148. },
  149. /**
  150. * Method: clickFeature
  151. * Called when the feature handler detects a click-in on a feature.
  152. *
  153. * Parameters:
  154. * feature - {<OpenLayers.Feature.Vector>}
  155. */
  156. clickFeature: function(feature) {
  157. if (this.handlers.feature.touch && !this.over && this.overFeature(feature)) {
  158. this.handlers.drag.dragstart(this.handlers.feature.evt);
  159. // to let the events propagate to the feature handler (click callback)
  160. this.handlers.drag.stopDown = false;
  161. }
  162. },
  163. /**
  164. * Method: clickoutFeature
  165. * Called when the feature handler detects a click-out on a feature.
  166. *
  167. * Parameters:
  168. * feature - {<OpenLayers.Feature.Vector>}
  169. */
  170. clickoutFeature: function(feature) {
  171. if (this.handlers.feature.touch && this.over) {
  172. this.outFeature(feature);
  173. this.handlers.drag.stopDown = true;
  174. }
  175. },
  176. /**
  177. * APIMethod: destroy
  178. * Take care of things that are not handled in superclass
  179. */
  180. destroy: function() {
  181. this.layer = null;
  182. OpenLayers.Control.prototype.destroy.apply(this, []);
  183. },
  184. /**
  185. * APIMethod: activate
  186. * Activate the control and the feature handler.
  187. *
  188. * Returns:
  189. * {Boolean} Successfully activated the control and feature handler.
  190. */
  191. activate: function() {
  192. return (this.handlers.feature.activate() &&
  193. OpenLayers.Control.prototype.activate.apply(this, arguments));
  194. },
  195. /**
  196. * APIMethod: deactivate
  197. * Deactivate the control and all handlers.
  198. *
  199. * Returns:
  200. * {Boolean} Successfully deactivated the control.
  201. */
  202. deactivate: function() {
  203. // the return from the handlers is unimportant in this case
  204. this.handlers.drag.deactivate();
  205. this.handlers.feature.deactivate();
  206. this.feature = null;
  207. this.dragging = false;
  208. this.lastPixel = null;
  209. OpenLayers.Element.removeClass(
  210. this.map.viewPortDiv, this.displayClass + "Over"
  211. );
  212. return OpenLayers.Control.prototype.deactivate.apply(this, arguments);
  213. },
  214. /**
  215. * Method: overFeature
  216. * Called when the feature handler detects a mouse-over on a feature.
  217. * This activates the drag handler.
  218. *
  219. * Parameters:
  220. * feature - {<OpenLayers.Feature.Vector>} The selected feature.
  221. *
  222. * Returns:
  223. * {Boolean} Successfully activated the drag handler.
  224. */
  225. overFeature: function(feature) {
  226. var activated = false;
  227. if(!this.handlers.drag.dragging) {
  228. this.feature = feature;
  229. this.handlers.drag.activate();
  230. activated = true;
  231. this.over = true;
  232. OpenLayers.Element.addClass(this.map.viewPortDiv, this.displayClass + "Over");
  233. this.onEnter(feature);
  234. } else {
  235. if(this.feature.id == feature.id) {
  236. this.over = true;
  237. } else {
  238. this.over = false;
  239. }
  240. }
  241. return activated;
  242. },
  243. /**
  244. * Method: downFeature
  245. * Called when the drag handler detects a mouse-down.
  246. *
  247. * Parameters:
  248. * pixel - {<OpenLayers.Pixel>} Location of the mouse event.
  249. */
  250. downFeature: function(pixel) {
  251. this.lastPixel = pixel;
  252. this.onStart(this.feature, pixel);
  253. },
  254. /**
  255. * Method: moveFeature
  256. * Called when the drag handler detects a mouse-move. Also calls the
  257. * optional onDrag method.
  258. *
  259. * Parameters:
  260. * pixel - {<OpenLayers.Pixel>} Location of the mouse event.
  261. */
  262. moveFeature: function(pixel) {
  263. var res = this.map.getResolution();
  264. this.feature.geometry.move(res * (pixel.x - this.lastPixel.x),
  265. res * (this.lastPixel.y - pixel.y));
  266. this.layer.drawFeature(this.feature);
  267. this.lastPixel = pixel;
  268. this.onDrag(this.feature, pixel);
  269. },
  270. /**
  271. * Method: upFeature
  272. * Called when the drag handler detects a mouse-up.
  273. *
  274. * Parameters:
  275. * pixel - {<OpenLayers.Pixel>} Location of the mouse event.
  276. */
  277. upFeature: function(pixel) {
  278. if(!this.over) {
  279. this.handlers.drag.deactivate();
  280. }
  281. },
  282. /**
  283. * Method: doneDragging
  284. * Called when the drag handler is done dragging.
  285. *
  286. * Parameters:
  287. * pixel - {<OpenLayers.Pixel>} The last event pixel location. If this event
  288. * came from a mouseout, this may not be in the map viewport.
  289. */
  290. doneDragging: function(pixel) {
  291. this.onComplete(this.feature, pixel);
  292. },
  293. /**
  294. * Method: outFeature
  295. * Called when the feature handler detects a mouse-out on a feature.
  296. *
  297. * Parameters:
  298. * feature - {<OpenLayers.Feature.Vector>} The feature that the mouse left.
  299. */
  300. outFeature: function(feature) {
  301. if(!this.handlers.drag.dragging) {
  302. this.over = false;
  303. this.handlers.drag.deactivate();
  304. OpenLayers.Element.removeClass(
  305. this.map.viewPortDiv, this.displayClass + "Over"
  306. );
  307. this.onLeave(feature);
  308. this.feature = null;
  309. } else {
  310. if(this.feature.id == feature.id) {
  311. this.over = false;
  312. }
  313. }
  314. },
  315. /**
  316. * Method: cancel
  317. * Called when the drag handler detects a mouse-out (from the map viewport).
  318. */
  319. cancel: function() {
  320. this.handlers.drag.deactivate();
  321. this.over = false;
  322. },
  323. /**
  324. * Method: setMap
  325. * Set the map property for the control and all handlers.
  326. *
  327. * Parameters:
  328. * map - {<OpenLayers.Map>} The control's map.
  329. */
  330. setMap: function(map) {
  331. this.handlers.drag.setMap(map);
  332. this.handlers.feature.setMap(map);
  333. OpenLayers.Control.prototype.setMap.apply(this, arguments);
  334. },
  335. CLASS_NAME: "OpenLayers.Control.DragFeature"
  336. });