Toolbar.js 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. /**
  2. * @class L.Draw.Toolbar
  3. * @aka Toolbar
  4. *
  5. * The toolbar class of the API — it is used to create the ui
  6. * This will be depreciated
  7. *
  8. * @example
  9. *
  10. * ```js
  11. * var toolbar = L.Toolbar();
  12. * toolbar.addToolbar(map);
  13. * ```
  14. *
  15. * ### Disabling a toolbar
  16. *
  17. * If you do not want a particular toolbar in your app you can turn it off by setting the toolbar to false.
  18. *
  19. * ```js
  20. * var drawControl = new L.Control.Draw({
  21. * draw: false,
  22. * edit: {
  23. * featureGroup: editableLayers
  24. * }
  25. * });
  26. * ```
  27. *
  28. * ### Disabling a toolbar item
  29. *
  30. * If you want to turn off a particular toolbar item, set it to false. The following disables drawing polygons and
  31. * markers. It also turns off the ability to edit layers.
  32. *
  33. * ```js
  34. * var drawControl = new L.Control.Draw({
  35. * draw: {
  36. * polygon: false,
  37. * marker: false
  38. * },
  39. * edit: {
  40. * featureGroup: editableLayers,
  41. * edit: false
  42. * }
  43. * });
  44. * ```
  45. */
  46. L.Toolbar = L.Class.extend({
  47. includes: [L.Mixin.Events],
  48. // @section Methods for modifying the toolbar
  49. // @method initialize(options): void
  50. // Toolbar constructor
  51. initialize: function (options) {
  52. L.setOptions(this, options);
  53. this._modes = {};
  54. this._actionButtons = [];
  55. this._activeMode = null;
  56. },
  57. // @method enabled(): boolean
  58. // Gets a true/false of whether the toolbar is enabled
  59. enabled: function () {
  60. return this._activeMode !== null;
  61. },
  62. // @method disable(): void
  63. // Disables the toolbar
  64. disable: function () {
  65. if (!this.enabled()) {
  66. return;
  67. }
  68. this._activeMode.handler.disable();
  69. },
  70. // @method addToolbar(map): L.DomUtil
  71. // Adds the toolbar to the map and returns the toolbar dom element
  72. addToolbar: function (map) {
  73. var container = L.DomUtil.create('div', 'leaflet-draw-section'),
  74. buttonIndex = 0,
  75. buttonClassPrefix = this._toolbarClass || '',
  76. modeHandlers = this.getModeHandlers(map),
  77. i;
  78. this._toolbarContainer = L.DomUtil.create('div', 'leaflet-draw-toolbar leaflet-bar');
  79. this._map = map;
  80. for (i = 0; i < modeHandlers.length; i++) {
  81. if (modeHandlers[i].enabled) {
  82. this._initModeHandler(
  83. modeHandlers[i].handler,
  84. this._toolbarContainer,
  85. buttonIndex++,
  86. buttonClassPrefix,
  87. modeHandlers[i].title
  88. );
  89. }
  90. }
  91. // if no buttons were added, do not add the toolbar
  92. if (!buttonIndex) {
  93. return;
  94. }
  95. // Save button index of the last button, -1 as we would have ++ after the last button
  96. this._lastButtonIndex = --buttonIndex;
  97. // Create empty actions part of the toolbar
  98. this._actionsContainer = L.DomUtil.create('ul', 'leaflet-draw-actions');
  99. // Add draw and cancel containers to the control container
  100. container.appendChild(this._toolbarContainer);
  101. container.appendChild(this._actionsContainer);
  102. return container;
  103. },
  104. // @method removeToolbar(): void
  105. // Removes the toolbar and drops the handler event listeners
  106. removeToolbar: function () {
  107. // Dispose each handler
  108. for (var handlerId in this._modes) {
  109. if (this._modes.hasOwnProperty(handlerId)) {
  110. // Unbind handler button
  111. this._disposeButton(
  112. this._modes[handlerId].button,
  113. this._modes[handlerId].handler.enable,
  114. this._modes[handlerId].handler
  115. );
  116. // Make sure is disabled
  117. this._modes[handlerId].handler.disable();
  118. // Unbind handler
  119. this._modes[handlerId].handler
  120. .off('enabled', this._handlerActivated, this)
  121. .off('disabled', this._handlerDeactivated, this);
  122. }
  123. }
  124. this._modes = {};
  125. // Dispose the actions toolbar
  126. for (var i = 0, l = this._actionButtons.length; i < l; i++) {
  127. this._disposeButton(
  128. this._actionButtons[i].button,
  129. this._actionButtons[i].callback,
  130. this
  131. );
  132. }
  133. this._actionButtons = [];
  134. this._actionsContainer = null;
  135. },
  136. _initModeHandler: function (handler, container, buttonIndex, classNamePredix, buttonTitle) {
  137. var type = handler.type;
  138. this._modes[type] = {};
  139. this._modes[type].handler = handler;
  140. this._modes[type].button = this._createButton({
  141. type: type,
  142. title: buttonTitle,
  143. className: classNamePredix + '-' + type,
  144. container: container,
  145. callback: this._modes[type].handler.enable,
  146. context: this._modes[type].handler
  147. });
  148. this._modes[type].buttonIndex = buttonIndex;
  149. this._modes[type].handler
  150. .on('enabled', this._handlerActivated, this)
  151. .on('disabled', this._handlerDeactivated, this);
  152. },
  153. _createButton: function (options) {
  154. var link = L.DomUtil.create('a', options.className || '', options.container);
  155. // Screen reader tag
  156. var sr = L.DomUtil.create('span', 'sr-only', options.container);
  157. link.href = '#';
  158. link.appendChild(sr);
  159. if (options.title) {
  160. link.title = options.title;
  161. sr.innerHTML = options.title;
  162. }
  163. if (options.text) {
  164. link.innerHTML = options.text;
  165. sr.innerHTML = options.text;
  166. }
  167. L.DomEvent
  168. .on(link, 'click', L.DomEvent.stopPropagation)
  169. .on(link, 'mousedown', L.DomEvent.stopPropagation)
  170. .on(link, 'dblclick', L.DomEvent.stopPropagation)
  171. .on(link, 'touchstart', L.DomEvent.stopPropagation)
  172. .on(link, 'click', L.DomEvent.preventDefault)
  173. .on(link, 'click', options.callback, options.context);
  174. return link;
  175. },
  176. _disposeButton: function (button, callback) {
  177. L.DomEvent
  178. .off(button, 'click', L.DomEvent.stopPropagation)
  179. .off(button, 'mousedown', L.DomEvent.stopPropagation)
  180. .off(button, 'dblclick', L.DomEvent.stopPropagation)
  181. .off(button, 'touchstart', L.DomEvent.stopPropagation)
  182. .off(button, 'click', L.DomEvent.preventDefault)
  183. .off(button, 'click', callback);
  184. },
  185. _handlerActivated: function (e) {
  186. // Disable active mode (if present)
  187. this.disable();
  188. // Cache new active feature
  189. this._activeMode = this._modes[e.handler];
  190. L.DomUtil.addClass(this._activeMode.button, 'leaflet-draw-toolbar-button-enabled');
  191. this._showActionsToolbar();
  192. this.fire('enable');
  193. },
  194. _handlerDeactivated: function () {
  195. this._hideActionsToolbar();
  196. L.DomUtil.removeClass(this._activeMode.button, 'leaflet-draw-toolbar-button-enabled');
  197. this._activeMode = null;
  198. this.fire('disable');
  199. },
  200. _createActions: function (handler) {
  201. var container = this._actionsContainer,
  202. buttons = this.getActions(handler),
  203. l = buttons.length,
  204. li, di, dl, button;
  205. // Dispose the actions toolbar (todo: dispose only not used buttons)
  206. for (di = 0, dl = this._actionButtons.length; di < dl; di++) {
  207. this._disposeButton(this._actionButtons[di].button, this._actionButtons[di].callback);
  208. }
  209. this._actionButtons = [];
  210. // Remove all old buttons
  211. while (container.firstChild) {
  212. container.removeChild(container.firstChild);
  213. }
  214. for (var i = 0; i < l; i++) {
  215. if ('enabled' in buttons[i] && !buttons[i].enabled) {
  216. continue;
  217. }
  218. li = L.DomUtil.create('li', '', container);
  219. button = this._createButton({
  220. title: buttons[i].title,
  221. text: buttons[i].text,
  222. container: li,
  223. callback: buttons[i].callback,
  224. context: buttons[i].context
  225. });
  226. this._actionButtons.push({
  227. button: button,
  228. callback: buttons[i].callback
  229. });
  230. }
  231. },
  232. _showActionsToolbar: function () {
  233. var buttonIndex = this._activeMode.buttonIndex,
  234. lastButtonIndex = this._lastButtonIndex,
  235. toolbarPosition = this._activeMode.button.offsetTop - 1;
  236. // Recreate action buttons on every click
  237. this._createActions(this._activeMode.handler);
  238. // Correctly position the cancel button
  239. this._actionsContainer.style.top = toolbarPosition + 'px';
  240. if (buttonIndex === 0) {
  241. L.DomUtil.addClass(this._toolbarContainer, 'leaflet-draw-toolbar-notop');
  242. L.DomUtil.addClass(this._actionsContainer, 'leaflet-draw-actions-top');
  243. }
  244. if (buttonIndex === lastButtonIndex) {
  245. L.DomUtil.addClass(this._toolbarContainer, 'leaflet-draw-toolbar-nobottom');
  246. L.DomUtil.addClass(this._actionsContainer, 'leaflet-draw-actions-bottom');
  247. }
  248. this._actionsContainer.style.display = 'block';
  249. },
  250. _hideActionsToolbar: function () {
  251. this._actionsContainer.style.display = 'none';
  252. L.DomUtil.removeClass(this._toolbarContainer, 'leaflet-draw-toolbar-notop');
  253. L.DomUtil.removeClass(this._toolbarContainer, 'leaflet-draw-toolbar-nobottom');
  254. L.DomUtil.removeClass(this._actionsContainer, 'leaflet-draw-actions-top');
  255. L.DomUtil.removeClass(this._actionsContainer, 'leaflet-draw-actions-bottom');
  256. }
  257. });