diff --git a/build/deps.js b/build/deps.js
index 92051758d..df71f6a33 100644
--- a/build/deps.js
+++ b/build/deps.js
@@ -45,8 +45,6 @@ var deps = {
CommonUI: {
src: [
- 'Control.Draw.js',
- 'Toolbar.js',
'Tooltip.js'
],
desc: 'Common UI components used.',
@@ -55,7 +53,10 @@ var deps = {
DrawUI: {
src: [
- 'draw/DrawToolbar.js'
+ 'draw/DrawToolbar.js',
+ 'draw/control/Draw.Control.Cancel.js',
+ 'draw/control/Draw.Control.RemoveLastPoint.js',
+ 'draw/control/DrawToolbar.Control.js'
],
desc: 'Draw toolbar.',
deps: ['DrawHandlers', 'CommonUI']
@@ -64,8 +65,12 @@ var deps = {
EditUI: {
src: [
'edit/EditToolbar.js',
- 'edit/handler/EditToolbar.Edit.js',
- 'edit/handler/EditToolbar.Delete.js'
+ 'edit/control/Edit.Control.Edit.js',
+ 'edit/control/Edit.Control.Delete.js',
+ 'edit/control/EditToolbar.Control.js',
+ 'edit/popup/Edit.Popup.Edit.js',
+ 'edit/popup/Edit.Popup.Delete.js',
+ 'edit/popup/EditToolbar.Popup.js'
],
desc: 'Edit toolbar.',
deps: ['EditHandlers', 'CommonUI']
diff --git a/dist/leaflet.draw.css b/dist/leaflet.draw.css
index 7bc9978d1..e760d50ec 100644
--- a/dist/leaflet.draw.css
+++ b/dist/leaflet.draw.css
@@ -6,8 +6,8 @@
position: relative;
}
-.leaflet-draw-toolbar {
- margin-top: 12px;
+.leaflet-draw-toolbar.leaflet-control-toolbar {
+ margin: 0;
}
.leaflet-draw-toolbar-top {
@@ -22,12 +22,12 @@
border-bottom-right-radius: 0;
}
-.leaflet-draw-toolbar a {
+.leaflet-draw-toolbar > li > a {
background-image: url('images/spritesheet.png');
background-repeat: no-repeat;
}
-.leaflet-retina .leaflet-draw-toolbar a {
+.leaflet-retina .leaflet-draw-toolbar > li > a {
background-image: url('images/spritesheet-2x.png');
background-size: 270px 30px;
}
diff --git a/examples/basic.html b/examples/basic.html
index 52b71a456..1a84b48bd 100644
--- a/examples/basic.html
+++ b/examples/basic.html
@@ -4,10 +4,11 @@
Leaflet.draw drawing and editing tools
+
-
+
@@ -15,6 +16,7 @@
+
@@ -32,12 +34,21 @@
-
+
+
+
+
+
+
+
-
-
+
+
+
+
+
@@ -55,7 +66,7 @@
L.drawLocal.draw.toolbar.buttons.polygon = 'Draw a sexy polygon!';
var drawControl = new L.Control.Draw({
- position: 'topright',
+ position: 'topleft',
draw: {
polyline: {
metric: true
@@ -83,7 +94,7 @@
remove: false
}
});
- map.addControl(drawControl);
+ drawControl.addTo(map);
map.on('draw:created', function (e) {
var type = e.layerType,
diff --git a/examples/full.html b/examples/full.html
index 2ef223619..d09f22c7d 100644
--- a/examples/full.html
+++ b/examples/full.html
@@ -3,43 +3,52 @@
Leaflet.draw vector editing handlers
-
-
-
+
-
-
+
+
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
+
+
+
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/libs/leaflet.toolbar-src.js b/examples/libs/leaflet.toolbar-src.js
new file mode 100644
index 000000000..11ade5be6
--- /dev/null
+++ b/examples/libs/leaflet.toolbar-src.js
@@ -0,0 +1,363 @@
+(function(window, document, undefined) {
+
+"use strict";
+
+L.Toolbar = L.Class.extend({
+ statics: {
+ baseClass: 'leaflet-toolbar'
+ },
+
+ includes: L.Mixin.Events,
+
+ options: {
+ className: '',
+ filter: function() { return true; },
+ actions: []
+ },
+
+ initialize: function(options) {
+ L.setOptions(this, options);
+ this._toolbar_type = this.constructor._toolbar_class_id;
+ },
+
+ addTo: function(map) {
+ this._arguments = [].slice.call(arguments);
+
+ map.addLayer(this);
+
+ return this;
+ },
+
+ onAdd: function(map) {
+ var currentToolbar = map._toolbars[this._toolbar_type];
+
+ if (this._calculateDepth() === 0) {
+ if (currentToolbar) { map.removeLayer(currentToolbar); }
+ map._toolbars[this._toolbar_type] = this;
+ }
+ },
+
+ onRemove: function(map) {
+ /*
+ * TODO: Cleanup event listeners.
+ * For some reason, this throws:
+ * "Uncaught TypeError: Cannot read property 'dragging' of null"
+ * on this._marker when a toolbar icon is clicked.
+ */
+ // for (var i = 0, l = this._disabledEvents.length; i < l; i++) {
+ // L.DomEvent.off(this._ul, this._disabledEvents[i], L.DomEvent.stopPropagation);
+ // }
+
+ if (this._calculateDepth() === 0) {
+ delete map._toolbars[this._toolbar_type];
+ }
+ },
+
+ appendToContainer: function(container) {
+ var baseClass = this.constructor.baseClass + '-' + this._calculateDepth(),
+ className = baseClass + ' ' + this.options.className,
+ Action, action,
+ i, j, l, m;
+
+ this._container = container;
+ this._ul = L.DomUtil.create('ul', className, container);
+
+ /* Ensure that clicks, drags, etc. don't bubble up to the map. */
+ this._disabledEvents = ['click', 'mousemove', 'dblclick'];
+
+ for (j = 0, m = this._disabledEvents.length; j < m; j++) {
+ L.DomEvent.on(this._ul, this._disabledEvents[j], L.DomEvent.stopPropagation);
+ }
+
+ /* Instantiate each toolbar action and add its corresponding toolbar icon. */
+ for (i = 0, l = this.options.actions.length; i < l; i++) {
+ Action = this._getActionConstructor(this.options.actions[i]);
+
+ action = new Action();
+ action._createIcon(this, this._ul, this._arguments);
+ }
+ },
+
+ _getActionConstructor: function(Action) {
+ var args = this._arguments,
+ toolbar = this;
+
+ return Action.extend({
+ initialize: function() {
+ Action.prototype.initialize.apply(this, args);
+ },
+ enable: function() {
+ /* Ensure that only one action in a toolbar will be active at a time. */
+ if (toolbar._active) { toolbar._active.disable(); }
+ toolbar._active = this;
+
+ Action.prototype.enable.call(this);
+ }
+ });
+ },
+
+ /* Used to hide subToolbars without removing them from the map. */
+ _hide: function() {
+ this._ul.style.display = 'none';
+ },
+
+ /* Used to show subToolbars without removing them from the map. */
+ _show: function() {
+ this._ul.style.display = 'block';
+ },
+
+ _calculateDepth: function() {
+ var depth = 0,
+ toolbar = this.parentToolbar;
+
+ while (toolbar) {
+ depth += 1;
+ toolbar = toolbar.parentToolbar;
+ }
+
+ return depth;
+ }
+});
+
+L.toolbar = {};
+
+var toolbar_class_id = 0;
+
+L.Toolbar.extend = function extend(props) {
+ var statics = L.extend({}, props.statics, {
+ "_toolbar_class_id": toolbar_class_id
+ });
+
+ toolbar_class_id += 1;
+ L.extend(props, { statics: statics });
+
+ return L.Class.extend.call(this, props);
+};
+
+L.Map.addInitHook(function() {
+ this._toolbars = {};
+});
+
+L.ToolbarAction = L.Handler.extend({
+ statics: {
+ baseClass: 'leaflet-toolbar-icon'
+ },
+
+ options: {
+ toolbarIcon: {
+ html: '',
+ className: '',
+ tooltip: ''
+ },
+ subToolbar: new L.Toolbar()
+ },
+
+ initialize: function(options) {
+ var defaultIconOptions = L.ToolbarAction.prototype.options.toolbarIcon;
+
+ L.setOptions(this, options);
+ this.options.toolbarIcon = L.extend({}, defaultIconOptions, this.options.toolbarIcon);
+ },
+
+ enable: function() {
+ if (this._enabled) { return; }
+ this._enabled = true;
+
+ if (this.addHooks) { this.addHooks(); }
+ },
+
+ disable: function() {
+ if (!this._enabled) { return; }
+ this._enabled = false;
+
+ if (this.removeHooks) { this.removeHooks(); }
+ },
+
+ _createIcon: function(toolbar, container, args) {
+ var iconOptions = this.options.toolbarIcon;
+
+ this.toolbar = toolbar;
+ this._icon = L.DomUtil.create('li', '', container);
+ this._link = L.DomUtil.create('a', '', this._icon);
+
+ this._link.innerHTML = iconOptions.html;
+ this._link.setAttribute('href', '#');
+ this._link.setAttribute('title', iconOptions.tooltip);
+
+ L.DomUtil.addClass(this._link, this.constructor.baseClass);
+ if (iconOptions.className) {
+ L.DomUtil.addClass(this._link, iconOptions.className);
+ }
+
+ L.DomEvent.on(this._link, 'click', this.enable, this);
+
+ /* Add secondary toolbar */
+ this._addSubToolbar(toolbar, this._icon, args);
+ },
+
+ _addSubToolbar: function(toolbar, container, args) {
+ var subToolbar = this.options.subToolbar,
+ addHooks = this.addHooks,
+ removeHooks = this.removeHooks;
+
+ /* For calculating the nesting depth. */
+ subToolbar.parentToolbar = toolbar;
+
+ if (subToolbar.options.actions.length > 0) {
+ /* Make a copy of args so as not to pollute the args array used by other actions. */
+ args = [].slice.call(args);
+ args.push(this);
+
+ subToolbar.addTo.apply(subToolbar, args);
+ subToolbar.appendToContainer(container);
+
+ this.addHooks = function(map) {
+ if (typeof addHooks === 'function') { addHooks.call(this, map); }
+ subToolbar._show();
+ };
+
+ this.removeHooks = function(map) {
+ if (typeof removeHooks === 'function') { removeHooks.call(this, map); }
+ subToolbar._hide();
+ };
+ }
+ }
+});
+
+L.toolbarAction = function toolbarAction(options) {
+ return new L.ToolbarAction(options);
+};
+
+L.ToolbarAction.extendOptions = function(options) {
+ return this.extend({ options: options });
+};
+
+L.Toolbar.Control = L.Toolbar.extend({
+ statics: {
+ baseClass: 'leaflet-control-toolbar ' + L.Toolbar.baseClass
+ },
+
+ initialize: function(options) {
+ L.Toolbar.prototype.initialize.call(this, options);
+
+ this._control = new L.Control.Toolbar(this.options);
+ },
+
+ onAdd: function(map) {
+ this._control.addTo(map);
+
+ L.Toolbar.prototype.onAdd.call(this, map);
+
+ this.appendToContainer(this._control.getContainer());
+ },
+
+ onRemove: function(map) {
+ L.Toolbar.prototype.onRemove.call(this, map);
+ this._control.removeFrom(map);
+ }
+});
+
+L.Control.Toolbar = L.Control.extend({
+ onAdd: function() {
+ return L.DomUtil.create('div', '');
+ }
+});
+
+L.toolbar.control = function(options) {
+ return new L.Toolbar.Control(options);
+};
+
+// A convenience class for built-in popup toolbars.
+
+L.Toolbar.Popup = L.Toolbar.extend({
+ statics: {
+ baseClass: 'leaflet-popup-toolbar ' + L.Toolbar.baseClass
+ },
+
+ options: {
+ anchor: [0, 0]
+ },
+
+ initialize: function(latlng, options) {
+ L.Toolbar.prototype.initialize.call(this, options);
+
+ /*
+ * Developers can't pass a DivIcon in the options for L.Toolbar.Popup
+ * (the use of DivIcons is an implementation detail which may change).
+ */
+ this._marker = new L.Marker(latlng, {
+ icon : new L.DivIcon({
+ className: this.options.className,
+ iconAnchor: [0, 0]
+ })
+ });
+ },
+
+ onAdd: function(map) {
+ this._map = map;
+ this._marker.addTo(map);
+
+ L.Toolbar.prototype.onAdd.call(this, map);
+
+ this.appendToContainer(this._marker._icon);
+
+ this._setStyles();
+ },
+
+ onRemove: function(map) {
+ map.removeLayer(this._marker);
+
+ L.Toolbar.prototype.onRemove.call(this, map);
+
+ delete this._map;
+ },
+
+ setLatLng: function(latlng) {
+ this._marker.setLatLng(latlng);
+
+ return this;
+ },
+
+ _setStyles: function() {
+ var container = this._container,
+ toolbar = this._ul,
+ anchor = L.point(this.options.anchor),
+ icons = toolbar.querySelectorAll('.leaflet-toolbar-icon'),
+ buttonHeights = [],
+ toolbarWidth = 0,
+ toolbarHeight,
+ tipSize,
+ tipAnchor;
+
+ /* Calculate the dimensions of the toolbar. */
+ for (var i = 0, l = icons.length; i < l; i++) {
+ if (icons[i].parentNode.parentNode === toolbar) {
+ buttonHeights.push(parseInt(L.DomUtil.getStyle(icons[i], 'height'), 10));
+ toolbarWidth += Math.ceil(parseFloat(L.DomUtil.getStyle(icons[i], 'width')));
+ }
+ }
+ toolbar.style.width = toolbarWidth + 'px';
+
+ /* Create and place the toolbar tip. */
+ this._tipContainer = L.DomUtil.create('div', 'leaflet-toolbar-tip-container', container);
+ this._tipContainer.style.width = toolbarWidth + 'px';
+
+ this._tip = L.DomUtil.create('div', 'leaflet-toolbar-tip', this._tipContainer);
+
+ /* Set the tipAnchor point. */
+ toolbarHeight = Math.max.apply(undefined, buttonHeights);
+ tipSize = parseInt(L.DomUtil.getStyle(this._tip, 'width'), 10);
+ tipAnchor = new L.Point(toolbarWidth/2, toolbarHeight + 0.7071*tipSize);
+
+ /* The anchor option allows app developers to adjust the toolbar's position. */
+ container.style.marginLeft = (anchor.x - tipAnchor.x) + 'px';
+ container.style.marginTop = (anchor.y - tipAnchor.y) + 'px';
+ }
+});
+
+L.toolbar.popup = function(options) {
+ return new L.Toolbar.Popup(options);
+};
+
+
+})(window, document);
\ No newline at end of file
diff --git a/examples/libs/leaflet.toolbar.css b/examples/libs/leaflet.toolbar.css
new file mode 100644
index 000000000..790981fc3
--- /dev/null
+++ b/examples/libs/leaflet.toolbar.css
@@ -0,0 +1,117 @@
+/* Variables and Mixins */
+/* Generic L.Toolbar */
+.leaflet-toolbar-0 {
+ list-style: none;
+ padding-left: 0;
+ box-shadow: 0 1px 5px rgba(0, 0, 0, 0.65);
+}
+.leaflet-toolbar-0 > li {
+ position: relative;
+}
+.leaflet-toolbar-0 > li > .leaflet-toolbar-icon {
+ display: block;
+ width: 26px;
+ height: 26px;
+ line-height: 26px;
+ margin-right: 0;
+ padding-right: 0;
+ border-right: 0;
+ text-align: center;
+ text-decoration: none;
+ background-color: #ffffff;
+}
+.leaflet-toolbar-0 > li > .leaflet-toolbar-icon:hover {
+ background-color: #f4f4f4;
+}
+.leaflet-toolbar-0 .leaflet-toolbar-1 {
+ display: none;
+ list-style: none;
+}
+.leaflet-toolbar-tip-container {
+ margin: 0 auto;
+ height: 12px;
+ position: relative;
+ overflow: hidden;
+}
+.leaflet-toolbar-tip {
+ width: 12px;
+ height: 12px;
+ margin: -6px auto 0;
+ background-color: #ffffff;
+ box-shadow: 0 1px 5px rgba(0, 0, 0, 0.65);
+ -webkit-transform: rotate(45deg);
+ -ms-transform: rotate(45deg);
+ transform: rotate(45deg);
+}
+/* L.Toolbar.Control */
+.leaflet-control-toolbar {
+ /* Secondary Toolbar */
+}
+.leaflet-control-toolbar > li > .leaflet-toolbar-icon {
+ border-bottom: 1px solid #ccc;
+}
+.leaflet-control-toolbar > li:first-child > .leaflet-toolbar-icon {
+ border-top-left-radius: 4px;
+ border-top-right-radius: 4px;
+}
+.leaflet-control-toolbar > li:last-child > .leaflet-toolbar-icon {
+ border-bottom-left-radius: 4px;
+ border-bottom-right-radius: 4px;
+ border-bottom-width: 0;
+}
+.leaflet-control-toolbar .leaflet-toolbar-1 {
+ margin: 0;
+ padding: 0;
+ position: absolute;
+ left: 26px;
+ /* leaflet-draw-toolbar.left + leaflet-draw-toolbar.width */
+ top: 0;
+ white-space: nowrap;
+ height: 26px;
+}
+.leaflet-control-toolbar .leaflet-toolbar-1 > li {
+ display: inline-block;
+}
+.leaflet-control-toolbar .leaflet-toolbar-1 > li > .leaflet-toolbar-icon {
+ display: block;
+ background-color: #919187;
+ border-left: 1px solid #aaa;
+ color: #fff;
+ font: 11px/19px "Helvetica Neue", Arial, Helvetica, sans-serif;
+ line-height: 26px;
+ text-decoration: none;
+ padding-left: 10px;
+ padding-right: 10px;
+ height: 26px;
+}
+.leaflet-control-toolbar .leaflet-toolbar-1 > li > .leaflet-toolbar-icon:hover {
+ background-color: #a0a098;
+}
+/* L.Toolbar.Popup */
+.leaflet-popup-toolbar {
+ position: relative;
+}
+.leaflet-popup-toolbar > li {
+ float: left;
+}
+.leaflet-popup-toolbar > li:first-child > .leaflet-toolbar-icon {
+ border-top-left-radius: 4px;
+ border-bottom-left-radius: 4px;
+}
+.leaflet-popup-toolbar > li:last-child > .leaflet-toolbar-icon {
+ border-top-right-radius: 4px;
+ border-bottom-right-radius: 4px;
+ border-bottom-width: 0;
+}
+.leaflet-popup-toolbar .leaflet-toolbar-1 {
+ position: absolute;
+ top: 26px;
+ left: 0;
+ padding-left: 0;
+}
+.leaflet-popup-toolbar .leaflet-toolbar-1 > li > .leaflet-toolbar-icon {
+ position: relative;
+ float: left;
+ width: 26px;
+ height: 26px;
+}
diff --git a/package.json b/package.json
index 59f4e9c51..a4ff0d2e9 100644
--- a/package.json
+++ b/package.json
@@ -11,7 +11,8 @@
"happen": "~0.1.3",
"karma": "^0.12.19",
"karma-mocha": "~0.1.0",
- "karma-coverage": "~0.1.3"
+ "karma-coverage": "~0.1.3",
+ "leaflet-toolbar": "~0.1.2"
},
"main": "dist/leaflet.draw.js",
"directories": {
diff --git a/spec/karma.conf.js b/spec/karma.conf.js
index 903ade0a9..7284f52a5 100644
--- a/spec/karma.conf.js
+++ b/spec/karma.conf.js
@@ -3,6 +3,7 @@ module.exports = function (config) {
var libSources = require(__dirname+'/../build/build.js').getFiles();
var leafletSources = require(__dirname+'/../node_modules/leaflet/build/build.js').getFiles();
+ var leafletToolbar = __dirname+'/../node_modules/leaflet-toolbar/dist/leaflet.toolbar-src.js';
for (var i=0; i < leafletSources.length; i++) {
leafletSources[i] = __dirname+"/../node_modules/leaflet/" + leafletSources[i];
@@ -12,7 +13,7 @@ module.exports = function (config) {
"spec/before.js",
"spec/sinon.js",
"spec/expect.js"
- ].concat(leafletSources, libSources, [
+ ].concat(leafletSources, leafletToolbar, libSources, [
"spec/after.js",
"node_modules/happen/happen.js",
"spec/suites/SpecHelper.js",
diff --git a/spec/suites/DrawControlSpec.js b/spec/suites/DrawControlSpec.js
deleted file mode 100644
index cd15d5041..000000000
--- a/spec/suites/DrawControlSpec.js
+++ /dev/null
@@ -1,14 +0,0 @@
-describe("Control.Draw", function () {
- var map, control, container;
-
- beforeEach(function () {
- map = L.map(document.createElement('div'));
- control = new L.Control.Draw({});
- map.addControl(control);
- container = control.getContainer();
- });
-
- it("exists", function () {
- expect(container.innerHTML).to.be.ok();
- });
-});
diff --git a/spec/suites/DrawToolbarSpec.js b/spec/suites/DrawToolbarSpec.js
new file mode 100644
index 000000000..49dda9f49
--- /dev/null
+++ b/spec/suites/DrawToolbarSpec.js
@@ -0,0 +1,7 @@
+describe("DrawToolbar.Control", function () {
+ var map, control, container;
+
+ beforeEach(function () {
+ map = L.map(document.createElement('div'));
+ });
+});
diff --git a/spec/suites/EditSpec.js b/spec/suites/EditSpec.js
index 7c6ce22e1..f19f59c65 100644
--- a/spec/suites/EditSpec.js
+++ b/spec/suites/EditSpec.js
@@ -41,9 +41,8 @@ describe("L.Edit", function () {
beforeEach(function () {
drawnItems = new L.FeatureGroup().addTo(map);
- edit = new L.EditToolbar.Edit(map, {
- featureGroup: drawnItems,
- selectedPathOptions: L.EditToolbar.prototype.options.edit.selectedPathOptions
+ edit = new L.Edit.Control.Edit(map, {
+ featureGroup: drawnItems
});
poly = new L.Polyline(L.latLng(41, -87), L.latLng(42, -88));
});
diff --git a/src/Control.Draw.js b/src/Control.Draw.js
index 909d0aa8a..4ae2c6d14 100644
--- a/src/Control.Draw.js
+++ b/src/Control.Draw.js
@@ -11,29 +11,28 @@ L.Control.Draw = L.Control.extend({
throw new Error('Leaflet.draw 0.2.3+ requires Leaflet 0.7.0+. Download latest from https://github.com/Leaflet/Leaflet/');
}
+ L.setOptions(this, options);
+
L.Control.prototype.initialize.call(this, options);
- var toolbar;
+ var position = { position: this.options.position },
+ drawOptions = L.Util.extend(this.options.draw, position),
+ editOptions = L.Util.extend(this.options.edit, position),
+ id, toolbar;
this._toolbars = {};
// Initialize toolbars
- if (L.DrawToolbar && this.options.draw) {
- toolbar = new L.DrawToolbar(this.options.draw);
-
- this._toolbars[L.DrawToolbar.TYPE] = toolbar;
-
- // Listen for when toolbar is enabled
- this._toolbars[L.DrawToolbar.TYPE].on('enable', this._toolbarEnabled, this);
+ if (L.DrawToolbar.Control && this.options.draw) {
+ toolbar = new L.DrawToolbar.Control(drawOptions);
+ id = L.stamp(toolbar);
+ this._toolbars[id] = toolbar;
}
- if (L.EditToolbar && this.options.edit) {
- toolbar = new L.EditToolbar(this.options.edit);
-
- this._toolbars[L.EditToolbar.TYPE] = toolbar;
-
- // Listen for when toolbar is enabled
- this._toolbars[L.EditToolbar.TYPE].on('enable', this._toolbarEnabled, this);
+ if (L.EditToolbar.Control && this.options.edit) {
+ toolbar = new L.EditToolbar.Control(editOptions);
+ id = L.stamp(toolbar);
+ this._toolbars[id] = toolbar;
}
},
@@ -45,49 +44,27 @@ L.Control.Draw = L.Control.extend({
for (var toolbarId in this._toolbars) {
if (this._toolbars.hasOwnProperty(toolbarId)) {
- toolbarContainer = this._toolbars[toolbarId].addToolbar(map);
-
- if (toolbarContainer) {
- // Add class to the first toolbar to remove the margin
- if (!addedTopClass) {
- if (!L.DomUtil.hasClass(toolbarContainer, topClassName)) {
- L.DomUtil.addClass(toolbarContainer.childNodes[0], topClassName);
- }
- addedTopClass = true;
- }
-
- container.appendChild(toolbarContainer);
- }
+ this._toolbars[toolbarId].addTo(map);
}
}
return container;
},
- onRemove: function () {
+ onRemove: function (map) {
for (var toolbarId in this._toolbars) {
if (this._toolbars.hasOwnProperty(toolbarId)) {
- this._toolbars[toolbarId].removeToolbar();
+ map.removeLayer(this._toolbars[toolbarId]);
}
}
},
setDrawingOptions: function (options) {
for (var toolbarId in this._toolbars) {
- if (this._toolbars[toolbarId] instanceof L.DrawToolbar) {
+ if (this._toolbars[toolbarId] instanceof L.DrawToolbar.Control) {
this._toolbars[toolbarId].setOptions(options);
}
}
- },
-
- _toolbarEnabled: function (e) {
- var enabledToolbar = e.target;
-
- for (var toolbarId in this._toolbars) {
- if (this._toolbars[toolbarId] !== enabledToolbar) {
- this._toolbars[toolbarId].disable();
- }
- }
}
});
@@ -101,4 +78,4 @@ L.Map.addInitHook(function () {
this.drawControl = new L.Control.Draw();
this.addControl(this.drawControl);
}
-});
+});
\ No newline at end of file
diff --git a/src/Leaflet.draw.js b/src/Leaflet.draw.js
index 92932c568..21e635a9f 100644
--- a/src/Leaflet.draw.js
+++ b/src/Leaflet.draw.js
@@ -95,4 +95,4 @@ L.drawLocal = {
}
}
}
-};
+};
\ No newline at end of file
diff --git a/src/Toolbar.js b/src/Toolbar.js
deleted file mode 100644
index 671e13ad3..000000000
--- a/src/Toolbar.js
+++ /dev/null
@@ -1,244 +0,0 @@
-L.Toolbar = L.Class.extend({
- includes: [L.Mixin.Events],
-
- initialize: function (options) {
- L.setOptions(this, options);
-
- this._modes = {};
- this._actionButtons = [];
- this._activeMode = null;
- },
-
- enabled: function () {
- return this._activeMode !== null;
- },
-
- disable: function () {
- if (!this.enabled()) { return; }
-
- this._activeMode.handler.disable();
- },
-
- addToolbar: function (map) {
- var container = L.DomUtil.create('div', 'leaflet-draw-section'),
- buttonIndex = 0,
- buttonClassPrefix = this._toolbarClass || '',
- modeHandlers = this.getModeHandlers(map),
- i;
-
- this._toolbarContainer = L.DomUtil.create('div', 'leaflet-draw-toolbar leaflet-bar');
- this._map = map;
-
- for (i = 0; i < modeHandlers.length; i++) {
- if (modeHandlers[i].enabled) {
- this._initModeHandler(
- modeHandlers[i].handler,
- this._toolbarContainer,
- buttonIndex++,
- buttonClassPrefix,
- modeHandlers[i].title
- );
- }
- }
-
- // if no buttons were added, do not add the toolbar
- if (!buttonIndex) {
- return;
- }
-
- // Save button index of the last button, -1 as we would have ++ after the last button
- this._lastButtonIndex = --buttonIndex;
-
- // Create empty actions part of the toolbar
- this._actionsContainer = L.DomUtil.create('ul', 'leaflet-draw-actions');
-
- // Add draw and cancel containers to the control container
- container.appendChild(this._toolbarContainer);
- container.appendChild(this._actionsContainer);
-
- return container;
- },
-
- removeToolbar: function () {
- // Dispose each handler
- for (var handlerId in this._modes) {
- if (this._modes.hasOwnProperty(handlerId)) {
- // Unbind handler button
- this._disposeButton(
- this._modes[handlerId].button,
- this._modes[handlerId].handler.enable,
- this._modes[handlerId].handler
- );
-
- // Make sure is disabled
- this._modes[handlerId].handler.disable();
-
- // Unbind handler
- this._modes[handlerId].handler
- .off('enabled', this._handlerActivated, this)
- .off('disabled', this._handlerDeactivated, this);
- }
- }
- this._modes = {};
-
- // Dispose the actions toolbar
- for (var i = 0, l = this._actionButtons.length; i < l; i++) {
- this._disposeButton(
- this._actionButtons[i].button,
- this._actionButtons[i].callback,
- this
- );
- }
- this._actionButtons = [];
- this._actionsContainer = null;
- },
-
- _initModeHandler: function (handler, container, buttonIndex, classNamePredix, buttonTitle) {
- var type = handler.type;
-
- this._modes[type] = {};
-
- this._modes[type].handler = handler;
-
- this._modes[type].button = this._createButton({
- title: buttonTitle,
- className: classNamePredix + '-' + type,
- container: container,
- callback: this._modes[type].handler.enable,
- context: this._modes[type].handler
- });
-
- this._modes[type].buttonIndex = buttonIndex;
-
- this._modes[type].handler
- .on('enabled', this._handlerActivated, this)
- .on('disabled', this._handlerDeactivated, this);
- },
-
- _createButton: function (options) {
- var link = L.DomUtil.create('a', options.className || '', options.container);
- link.href = '#';
-
- if (options.text) {
- link.innerHTML = options.text;
- }
-
- if (options.title) {
- link.title = options.title;
- }
-
- L.DomEvent
- .on(link, 'click', L.DomEvent.stopPropagation)
- .on(link, 'mousedown', L.DomEvent.stopPropagation)
- .on(link, 'dblclick', L.DomEvent.stopPropagation)
- .on(link, 'click', L.DomEvent.preventDefault)
- .on(link, 'click', options.callback, options.context);
-
- return link;
- },
-
- _disposeButton: function (button, callback) {
- L.DomEvent
- .off(button, 'click', L.DomEvent.stopPropagation)
- .off(button, 'mousedown', L.DomEvent.stopPropagation)
- .off(button, 'dblclick', L.DomEvent.stopPropagation)
- .off(button, 'click', L.DomEvent.preventDefault)
- .off(button, 'click', callback);
- },
-
- _handlerActivated: function (e) {
- // Disable active mode (if present)
- this.disable();
-
- // Cache new active feature
- this._activeMode = this._modes[e.handler];
-
- L.DomUtil.addClass(this._activeMode.button, 'leaflet-draw-toolbar-button-enabled');
-
- this._showActionsToolbar();
-
- this.fire('enable');
- },
-
- _handlerDeactivated: function () {
- this._hideActionsToolbar();
-
- L.DomUtil.removeClass(this._activeMode.button, 'leaflet-draw-toolbar-button-enabled');
-
- this._activeMode = null;
-
- this.fire('disable');
- },
-
- _createActions: function (handler) {
- var container = this._actionsContainer,
- buttons = this.getActions(handler),
- l = buttons.length,
- li, di, dl, button;
-
- // Dispose the actions toolbar (todo: dispose only not used buttons)
- for (di = 0, dl = this._actionButtons.length; di < dl; di++) {
- this._disposeButton(this._actionButtons[di].button, this._actionButtons[di].callback);
- }
- this._actionButtons = [];
-
- // Remove all old buttons
- while (container.firstChild) {
- container.removeChild(container.firstChild);
- }
-
- for (var i = 0; i < l; i++) {
- if ('enabled' in buttons[i] && !buttons[i].enabled) {
- continue;
- }
-
- li = L.DomUtil.create('li', '', container);
-
- button = this._createButton({
- title: buttons[i].title,
- text: buttons[i].text,
- container: li,
- callback: buttons[i].callback,
- context: buttons[i].context
- });
-
- this._actionButtons.push({
- button: button,
- callback: buttons[i].callback
- });
- }
- },
-
- _showActionsToolbar: function () {
- var buttonIndex = this._activeMode.buttonIndex,
- lastButtonIndex = this._lastButtonIndex,
- toolbarPosition = this._activeMode.button.offsetTop - 1;
-
- // Recreate action buttons on every click
- this._createActions(this._activeMode.handler);
-
- // Correctly position the cancel button
- this._actionsContainer.style.top = toolbarPosition + 'px';
-
- if (buttonIndex === 0) {
- L.DomUtil.addClass(this._toolbarContainer, 'leaflet-draw-toolbar-notop');
- L.DomUtil.addClass(this._actionsContainer, 'leaflet-draw-actions-top');
- }
-
- if (buttonIndex === lastButtonIndex) {
- L.DomUtil.addClass(this._toolbarContainer, 'leaflet-draw-toolbar-nobottom');
- L.DomUtil.addClass(this._actionsContainer, 'leaflet-draw-actions-bottom');
- }
-
- this._actionsContainer.style.display = 'block';
- },
-
- _hideActionsToolbar: function () {
- this._actionsContainer.style.display = 'none';
-
- L.DomUtil.removeClass(this._toolbarContainer, 'leaflet-draw-toolbar-notop');
- L.DomUtil.removeClass(this._toolbarContainer, 'leaflet-draw-toolbar-nobottom');
- L.DomUtil.removeClass(this._actionsContainer, 'leaflet-draw-actions-top');
- L.DomUtil.removeClass(this._actionsContainer, 'leaflet-draw-actions-bottom');
- }
-});
diff --git a/src/draw/DrawToolbar.js b/src/draw/DrawToolbar.js
index 812f10bd3..63cb4abd8 100644
--- a/src/draw/DrawToolbar.js
+++ b/src/draw/DrawToolbar.js
@@ -1,87 +1 @@
-L.DrawToolbar = L.Toolbar.extend({
-
- statics: {
- TYPE: 'draw'
- },
-
- options: {
- polyline: {},
- polygon: {},
- rectangle: {},
- circle: {},
- marker: {}
- },
-
- initialize: function (options) {
- // Ensure that the options are merged correctly since L.extend is only shallow
- for (var type in this.options) {
- if (this.options.hasOwnProperty(type)) {
- if (options[type]) {
- options[type] = L.extend({}, this.options[type], options[type]);
- }
- }
- }
-
- this._toolbarClass = 'leaflet-draw-draw';
- L.Toolbar.prototype.initialize.call(this, options);
- },
-
- getModeHandlers: function (map) {
- return [
- {
- enabled: this.options.polyline,
- handler: new L.Draw.Polyline(map, this.options.polyline),
- title: L.drawLocal.draw.toolbar.buttons.polyline
- },
- {
- enabled: this.options.polygon,
- handler: new L.Draw.Polygon(map, this.options.polygon),
- title: L.drawLocal.draw.toolbar.buttons.polygon
- },
- {
- enabled: this.options.rectangle,
- handler: new L.Draw.Rectangle(map, this.options.rectangle),
- title: L.drawLocal.draw.toolbar.buttons.rectangle
- },
- {
- enabled: this.options.circle,
- handler: new L.Draw.Circle(map, this.options.circle),
- title: L.drawLocal.draw.toolbar.buttons.circle
- },
- {
- enabled: this.options.marker,
- handler: new L.Draw.Marker(map, this.options.marker),
- title: L.drawLocal.draw.toolbar.buttons.marker
- }
- ];
- },
-
- // Get the actions part of the toolbar
- getActions: function (handler) {
- return [
- {
- enabled: handler.deleteLastVertex,
- title: L.drawLocal.draw.toolbar.undo.title,
- text: L.drawLocal.draw.toolbar.undo.text,
- callback: handler.deleteLastVertex,
- context: handler
- },
- {
- title: L.drawLocal.draw.toolbar.actions.title,
- text: L.drawLocal.draw.toolbar.actions.text,
- callback: this.disable,
- context: this
- }
- ];
- },
-
- setOptions: function (options) {
- L.setOptions(this, options);
-
- for (var type in this._modes) {
- if (this._modes.hasOwnProperty(type) && options.hasOwnProperty(type)) {
- this._modes[type].handler.setOptions(options[type]);
- }
- }
- }
-});
+L.DrawToolbar = {};
\ No newline at end of file
diff --git a/src/draw/control/Draw.Control.Cancel.js b/src/draw/control/Draw.Control.Cancel.js
new file mode 100644
index 000000000..91667e7cf
--- /dev/null
+++ b/src/draw/control/Draw.Control.Cancel.js
@@ -0,0 +1,18 @@
+L.Draw = L.Draw || {};
+L.Draw.Control = L.Draw.Control || {};
+
+L.Draw.Control.Cancel = L.ToolbarAction.extend({
+ options: {
+ toolbarIcon: { html: 'Cancel' }
+ },
+
+ initialize: function (map, drawing) {
+ this.drawing = drawing;
+ L.ToolbarAction.prototype.initialize.call(this);
+ },
+
+ addHooks: function () {
+ this.drawing.disable();
+ this.disable();
+ }
+});
\ No newline at end of file
diff --git a/src/draw/control/Draw.Control.RemoveLastPoint.js b/src/draw/control/Draw.Control.RemoveLastPoint.js
new file mode 100644
index 000000000..291d8179c
--- /dev/null
+++ b/src/draw/control/Draw.Control.RemoveLastPoint.js
@@ -0,0 +1,18 @@
+L.Draw = L.Draw || {};
+L.Draw.Control = L.Draw.Control || {};
+
+L.Draw.Control.RemoveLastPoint = L.ToolbarAction.extend({
+ options: {
+ toolbarIcon: { html: 'Delete last point' }
+ },
+
+ initialize: function (map, drawing) {
+ this.drawing = drawing;
+ L.ToolbarAction.prototype.initialize.call(this);
+ },
+
+ addHooks: function () {
+ this.drawing.deleteLastVertex();
+ this.disable();
+ }
+});
\ No newline at end of file
diff --git a/src/draw/control/Draw.Control.ToolbarAction.js b/src/draw/control/Draw.Control.ToolbarAction.js
new file mode 100644
index 000000000..639c889c5
--- /dev/null
+++ b/src/draw/control/Draw.Control.ToolbarAction.js
@@ -0,0 +1,91 @@
+L.Draw = L.Draw || {};
+L.Draw.Control = L.Draw.Control || {};
+
+L.Draw.Control.ToolbarAction = L.ToolbarAction.extend({
+ options: {},
+
+ initialize: function (map, options) {
+ this.drawHandler = new options.DrawAction(map, options);
+
+ this.drawHandler
+ .on('enabled', this.enable, this)
+ .on('disabled', this.disable, this);
+
+ L.ToolbarAction.prototype.initialize.call(this, options);
+ },
+
+ enable: function () {
+ if (this._enabled) { return; }
+
+ L.ToolbarAction.prototype.enable.call(this);
+
+ this.drawHandler.enable();
+ },
+
+ disable: function () {
+ if (!this._enabled) { return; }
+
+ L.ToolbarAction.prototype.disable.call(this);
+
+ this.drawHandler.disable();
+ }
+});
+
+L.Draw.Control.Circle = L.Draw.Control.ToolbarAction.extend({
+ options: {
+ subToolbar: new L.Toolbar({ actions: [L.Draw.Control.Cancel] }),
+
+ toolbarIcon: {
+ className: 'leaflet-draw-draw-circle',
+ tooltip: L.drawLocal.draw.toolbar.buttons.circle
+ }
+ }
+});
+
+L.Draw.Control.Marker = L.Draw.Control.ToolbarAction.extend({
+ options: {
+ subToolbar: new L.Toolbar({ actions: [L.Draw.Control.Cancel] }),
+
+ toolbarIcon: {
+ className: 'leaflet-draw-draw-marker',
+ tooltip: L.drawLocal.draw.toolbar.buttons.marker
+ }
+ }
+});
+
+L.Draw.Control.Polyline = L.Draw.Control.ToolbarAction.extend({
+ options: {
+ subToolbar: new L.Toolbar({ actions: [L.Draw.Control.Cancel, L.Draw.Control.RemoveLastPoint] }),
+
+ toolbarIcon: {
+ className: 'leaflet-draw-draw-polyline',
+ tooltip: L.drawLocal.draw.toolbar.buttons.polyline
+ }
+ },
+
+ deleteLastVertex: function () {
+ this._drawHandler.deleteLastVertex();
+ }
+});
+
+L.Draw.Control.Polygon = L.Draw.Control.Polyline .extend({
+ options: {
+ subToolbar: new L.Toolbar({ actions: [L.Draw.Control.Cancel, L.Draw.Control.RemoveLastPoint] }),
+
+ toolbarIcon: {
+ className: 'leaflet-draw-draw-polygon',
+ tooltip: L.drawLocal.draw.toolbar.buttons.polygon
+ }
+ }
+});
+
+L.Draw.Control.Rectangle = L.Draw.Control.ToolbarAction.extend({
+ options: {
+ subToolbar: new L.Toolbar({ actions: [L.Draw.Control.Cancel] }),
+
+ toolbarIcon: {
+ className: 'leaflet-draw-draw-rectangle',
+ tooltip: L.drawLocal.draw.toolbar.buttons.rectangle
+ }
+ }
+});
\ No newline at end of file
diff --git a/src/draw/control/DrawToolbar.Control.js b/src/draw/control/DrawToolbar.Control.js
new file mode 100644
index 000000000..6a9de1390
--- /dev/null
+++ b/src/draw/control/DrawToolbar.Control.js
@@ -0,0 +1,167 @@
+L.DrawToolbar.Control = L.Toolbar.Control.extend({
+ options: {
+ className: 'leaflet-draw-toolbar',
+ polyline: {},
+ polygon: {},
+ rectangle: {},
+ circle: {},
+ marker: {}
+ },
+
+ initialize: function (options) {
+ L.setOptions(this, options);
+
+ this._actions = {};
+ this.options.actions = {};
+
+ if (this.options.polygon) {
+ this.options.actions.polygon = {
+ action: L.Draw.Control.Polygon,
+ options: L.Util.extend(this.options.polygon, { DrawAction: L.Draw.Polygon })
+ }
+ }
+
+ if (this.options.polyline) {
+ this.options.actions.polyline = {
+ action: L.Draw.Control.Polyline,
+ options: L.Util.extend(this.options.polyline, { DrawAction: L.Draw.Polyline })
+ }
+ }
+
+ if (this.options.circle) {
+ this.options.actions.circle = {
+ action: L.Draw.Control.Circle,
+ options: L.Util.extend(this.options.circle, { DrawAction: L.Draw.Circle })
+ }
+ }
+
+ if (this.options.rectangle) {
+ this.options.actions.rectangle = {
+ action: L.Draw.Control.Rectangle,
+ options: L.Util.extend(this.options.rectangle, { DrawAction: L.Draw.Rectangle })
+ }
+ }
+
+ if (this.options.marker) {
+ this.options.actions.marker = {
+ action: L.Draw.Control.Marker,
+ options: L.Util.extend(this.options.marker, { DrawAction: L.Draw.Marker })
+ }
+ }
+
+ L.Toolbar.Control.prototype.initialize.call(this, options);
+ },
+
+ // Sets an actions options just in case we want to change options half way through.
+ setOptions: function (options) {
+ L.setOptions(this, options);
+
+ for (var type in this._actions) {
+ if (this._actions.hasOwnProperty(type) && options.hasOwnProperty(type)) {
+ this._actions[type].drawHandler.setOptions(options[type]);
+ }
+ }
+ }
+});
+
+L.Toolbar.Control.prototype.appendToContainer = function (container) {
+ var baseClass = this.constructor.baseClass + '-' + this._calculateDepth(),
+ className = baseClass + ' ' + this.options.className,
+ Action, action,
+ i, j, l, m;
+
+ this._container = container;
+ this._ul = L.DomUtil.create('ul', className, container);
+
+ /* Ensure that clicks, drags, etc. don't bubble up to the map. */
+ this._disabledEvents = ['click', 'mousemove', 'dblclick'];
+
+ for (j = 0, m = this._disabledEvents.length; j < m; j++) {
+ L.DomEvent.on(this._ul, this._disabledEvents[j], L.DomEvent.stopPropagation);
+ }
+
+ /* Instantiate each toolbar action and add its corresponding toolbar icon. */
+ for (var actionIndex in this.options.actions) {
+ Action = this._getActionConstructor(this.options.actions[actionIndex].action, this.options.actions[actionIndex].options);
+
+ this._actions[actionIndex] = new Action();
+ this._actions[actionIndex]._createIcon(this, this._ul, this._arguments);
+ }
+};
+
+L.Toolbar.Control.prototype._getActionConstructor = function (Action, actionOptions) {
+ var map = this._arguments[0],
+ args = [map, actionOptions],
+ toolbar = this;
+
+ return Action.extend({
+ initialize: function() {
+ Action.prototype.initialize.apply(this, args);
+ },
+ enable: function() {
+ if (toolbar._active == this) {
+ return;
+ }
+
+ /* Ensure that only one action in a toolbar will be active at a time. */
+ if (toolbar._active) {
+ toolbar._active.disable();
+ }
+ toolbar._active = this;
+
+ Action.prototype.enable.call(this);
+ },
+ disable: function () {
+ toolbar._active = null;
+
+ Action.prototype.disable.call(this);
+ }
+ });
+};
+
+/* Include sub-toolbars. */
+/*L.setOptions(L.Draw.Polygon.prototype, {
+ subToolbar: new L.Toolbar({ actions: [L.Draw.Control.Cancel, L.Draw.Control.RemoveLastPoint] }),
+
+ toolbarIcon: {
+ className: 'leaflet-draw-draw-polygon',
+ tooltip: L.drawLocal.draw.toolbar.buttons.polygon
+ }
+});
+
+L.setOptions(L.Draw.Polyline.prototype, {
+ subToolbar: new L.Toolbar({ actions: [L.Draw.Control.Cancel, L.Draw.Control.RemoveLastPoint] }),
+
+ toolbarIcon: {
+ className: 'leaflet-draw-draw-polyline',
+ tooltip: L.drawLocal.draw.toolbar.buttons.polyline
+ }
+});
+
+L.setOptions(L.Draw.Marker.prototype, {
+ subToolbar: new L.Toolbar({ actions: [L.Draw.Control.Cancel] }),
+
+ toolbarIcon: {
+ className: 'leaflet-draw-draw-marker',
+ tooltip: L.drawLocal.draw.toolbar.buttons.marker
+ }
+});
+
+L.setOptions(L.Draw.Rectangle.prototype, {
+ subToolbar: new L.Toolbar({ actions: [L.Draw.Control.Cancel] }),
+
+ toolbarIcon: {
+ className: 'leaflet-draw-draw-rectangle',
+ tooltip: L.drawLocal.draw.toolbar.buttons.rectangle
+ }
+});
+
+L.setOptions(L.Draw.Circle.prototype, {
+ subToolbar: new L.Toolbar({ actions: [L.Draw.Control.Cancel] }),
+
+ toolbarIcon: {
+ className: 'leaflet-draw-draw-circle',
+ tooltip: L.drawLocal.draw.toolbar.buttons.circle
+ }
+});*/
+
diff --git a/src/draw/handler/Draw.Feature.js b/src/draw/handler/Draw.Feature.js
index 1465fba34..4d497df94 100644
--- a/src/draw/handler/Draw.Feature.js
+++ b/src/draw/handler/Draw.Feature.js
@@ -4,15 +4,16 @@ L.Draw.Feature = L.Handler.extend({
includes: L.Mixin.Events,
initialize: function (map, options) {
- this._map = map;
+ L.Handler.prototype.initialize.call(this, map);
+
this._container = map._container;
this._overlayPane = map._panes.overlayPane;
this._popupPane = map._panes.popupPane;
// Merge default shapeOptions options with custom shapeOptions
- if (options && options.shapeOptions) {
+ /*if (options && options.shapeOptions) {
options.shapeOptions = L.Util.extend({}, this.options.shapeOptions, options.shapeOptions);
- }
+ }*/
L.setOptions(this, options);
},
diff --git a/src/draw/handler/Draw.Rectangle.js b/src/draw/handler/Draw.Rectangle.js
index d83120f27..cae8b7531 100644
--- a/src/draw/handler/Draw.Rectangle.js
+++ b/src/draw/handler/Draw.Rectangle.js
@@ -14,7 +14,7 @@ L.Draw.Rectangle = L.Draw.SimpleShape.extend({
fillOpacity: 0.2,
clickable: true
},
- metric: true // Whether to use the metric meaurement system or imperial
+ metric: true // Whether to use the metric meaurement system or imperial,
},
initialize: function (map, options) {
diff --git a/src/edit/EditToolbar.js b/src/edit/EditToolbar.js
index 143be1656..9c4cef3e6 100644
--- a/src/edit/EditToolbar.js
+++ b/src/edit/EditToolbar.js
@@ -1,154 +1 @@
-/*L.Map.mergeOptions({
- editControl: true
-});*/
-
-L.EditToolbar = L.Toolbar.extend({
- statics: {
- TYPE: 'edit'
- },
-
- options: {
- edit: {
- selectedPathOptions: {
- color: '#fe57a1', /* Hot pink all the things! */
- opacity: 0.6,
- dashArray: '10, 10',
-
- fill: true,
- fillColor: '#fe57a1',
- fillOpacity: 0.1,
-
- // Whether to user the existing layers color
- maintainColor: false
- }
- },
- remove: {},
- featureGroup: null /* REQUIRED! TODO: perhaps if not set then all layers on the map are selectable? */
- },
-
- initialize: function (options) {
- // Need to set this manually since null is an acceptable value here
- if (options.edit) {
- if (typeof options.edit.selectedPathOptions === 'undefined') {
- options.edit.selectedPathOptions = this.options.edit.selectedPathOptions;
- }
- options.edit.selectedPathOptions = L.extend({}, this.options.edit.selectedPathOptions, options.edit.selectedPathOptions);
- }
-
- if (options.remove) {
- options.remove = L.extend({}, this.options.remove, options.remove);
- }
-
- this._toolbarClass = 'leaflet-draw-edit';
- L.Toolbar.prototype.initialize.call(this, options);
-
- this._selectedFeatureCount = 0;
- },
-
- getModeHandlers: function (map) {
- var featureGroup = this.options.featureGroup;
- return [
- {
- enabled: this.options.edit,
- handler: new L.EditToolbar.Edit(map, {
- featureGroup: featureGroup,
- selectedPathOptions: this.options.edit.selectedPathOptions
- }),
- title: L.drawLocal.edit.toolbar.buttons.edit
- },
- {
- enabled: this.options.remove,
- handler: new L.EditToolbar.Delete(map, {
- featureGroup: featureGroup
- }),
- title: L.drawLocal.edit.toolbar.buttons.remove
- }
- ];
- },
-
- getActions: function () {
- return [
- {
- title: L.drawLocal.edit.toolbar.actions.save.title,
- text: L.drawLocal.edit.toolbar.actions.save.text,
- callback: this._save,
- context: this
- },
- {
- title: L.drawLocal.edit.toolbar.actions.cancel.title,
- text: L.drawLocal.edit.toolbar.actions.cancel.text,
- callback: this.disable,
- context: this
- }
- ];
- },
-
- addToolbar: function (map) {
- var container = L.Toolbar.prototype.addToolbar.call(this, map);
-
- this._checkDisabled();
-
- this.options.featureGroup.on('layeradd layerremove', this._checkDisabled, this);
-
- return container;
- },
-
- removeToolbar: function () {
- this.options.featureGroup.off('layeradd layerremove', this._checkDisabled, this);
-
- L.Toolbar.prototype.removeToolbar.call(this);
- },
-
- disable: function () {
- if (!this.enabled()) { return; }
-
- this._activeMode.handler.revertLayers();
-
- L.Toolbar.prototype.disable.call(this);
- },
-
- _save: function () {
- this._activeMode.handler.save();
- this._activeMode.handler.disable();
- },
-
- _checkDisabled: function () {
- var featureGroup = this.options.featureGroup,
- hasLayers = featureGroup.getLayers().length !== 0,
- button;
-
- if (this.options.edit) {
- button = this._modes[L.EditToolbar.Edit.TYPE].button;
-
- if (hasLayers) {
- L.DomUtil.removeClass(button, 'leaflet-disabled');
- } else {
- L.DomUtil.addClass(button, 'leaflet-disabled');
- }
-
- button.setAttribute(
- 'title',
- hasLayers ?
- L.drawLocal.edit.toolbar.buttons.edit
- : L.drawLocal.edit.toolbar.buttons.editDisabled
- );
- }
-
- if (this.options.remove) {
- button = this._modes[L.EditToolbar.Delete.TYPE].button;
-
- if (hasLayers) {
- L.DomUtil.removeClass(button, 'leaflet-disabled');
- } else {
- L.DomUtil.addClass(button, 'leaflet-disabled');
- }
-
- button.setAttribute(
- 'title',
- hasLayers ?
- L.drawLocal.edit.toolbar.buttons.remove
- : L.drawLocal.edit.toolbar.buttons.removeDisabled
- );
- }
- }
-});
+L.EditToolbar = {};
\ No newline at end of file
diff --git a/src/edit/handler/EditToolbar.Delete.js b/src/edit/control/Edit.Control.Delete.js
similarity index 86%
rename from src/edit/handler/EditToolbar.Delete.js
rename to src/edit/control/Edit.Control.Delete.js
index d23252137..4c1b48c92 100644
--- a/src/edit/handler/EditToolbar.Delete.js
+++ b/src/edit/control/Edit.Control.Delete.js
@@ -1,24 +1,32 @@
-L.EditToolbar.Delete = L.Handler.extend({
+L.Edit = L.Edit || {};
+L.Edit.Control = L.Edit.Control || {};
+
+L.Edit.Control.Delete = L.ToolbarAction.extend({
statics: {
TYPE: 'remove' // not delete as delete is reserved in js
},
+ options: {
+ toolbarIcon: { className: 'leaflet-draw-edit-remove' }
+ },
+
includes: L.Mixin.Events,
initialize: function (map, options) {
- L.Handler.prototype.initialize.call(this, map);
+ L.ToolbarAction.prototype.initialize.call(this, map);
L.Util.setOptions(this, options);
// Store the selectable layer group for ease of access
this._deletableLayers = this.options.featureGroup;
+ this._map = map;
if (!(this._deletableLayers instanceof L.FeatureGroup)) {
throw new Error('options.featureGroup must be a L.FeatureGroup');
}
// Save the type so super can fire, need to do this as cannot do this.TYPE :(
- this.type = L.EditToolbar.Delete.TYPE;
+ this.type = this.constructor.TYPE;
},
enable: function () {
@@ -29,7 +37,7 @@ L.EditToolbar.Delete = L.Handler.extend({
this._map.fire('draw:deletestart', { handler: this.type });
- L.Handler.prototype.enable.call(this);
+ L.ToolbarAction.prototype.enable.call(this);
this._deletableLayers
.on('layeradd', this._enableLayerDelete, this)
@@ -43,7 +51,7 @@ L.EditToolbar.Delete = L.Handler.extend({
.off('layeradd', this._enableLayerDelete, this)
.off('layerremove', this._disableLayerDelete, this);
- L.Handler.prototype.disable.call(this);
+ L.ToolbarAction.prototype.disable.call(this);
this._map.fire('draw:deletestop', { handler: this.type });
@@ -57,7 +65,7 @@ L.EditToolbar.Delete = L.Handler.extend({
map.getContainer().focus();
this._deletableLayers.eachLayer(this._enableLayerDelete, this);
- this._deletedLayers = new L.LayerGroup();
+ this._deletedLayers = new L.layerGroup();
this._tooltip = new L.Tooltip(this._map);
this._tooltip.updateContent({ text: L.drawLocal.edit.handlers.remove.tooltip.text });
diff --git a/src/edit/handler/EditToolbar.Edit.js b/src/edit/control/Edit.Control.Edit.js
similarity index 87%
rename from src/edit/handler/EditToolbar.Edit.js
rename to src/edit/control/Edit.Control.Edit.js
index fcbd04378..b29259279 100644
--- a/src/edit/handler/EditToolbar.Edit.js
+++ b/src/edit/control/Edit.Control.Edit.js
@@ -1,17 +1,37 @@
-L.EditToolbar.Edit = L.Handler.extend({
+L.Edit = L.Edit || {};
+L.Edit.Control = L.Edit.Control || {};
+
+L.Edit.Control.Edit = L.ToolbarAction.extend({
statics: {
TYPE: 'edit'
},
+ options: {
+ selectedPathOptions: {
+ color: '#fe57a1', /* Hot pink all the things! */
+ opacity: 0.6,
+ dashArray: '10, 10',
+
+ fill: true,
+ fillColor: '#fe57a1',
+ fillOpacity: 0.1,
+
+ // Whether to user the existing layers color
+ maintainColor: false
+ },
+ toolbarIcon: { className: 'leaflet-draw-edit-edit' }
+ },
+
includes: L.Mixin.Events,
initialize: function (map, options) {
- L.Handler.prototype.initialize.call(this, map);
+ L.ToolbarAction.prototype.initialize.call(this, map);
L.setOptions(this, options);
// Store the selectable layer group for ease of access
- this._featureGroup = options.featureGroup;
+ this._featureGroup = this.options.featureGroup;
+ this._map = map;
if (!(this._featureGroup instanceof L.FeatureGroup)) {
throw new Error('options.featureGroup must be a L.FeatureGroup');
@@ -20,7 +40,7 @@ L.EditToolbar.Edit = L.Handler.extend({
this._uneditedLayerProps = {};
// Save the type so super can fire, need to do this as cannot do this.TYPE :(
- this.type = L.EditToolbar.Edit.TYPE;
+ this.type = this.constructor.TYPE;
},
enable: function () {
@@ -33,7 +53,7 @@ L.EditToolbar.Edit = L.Handler.extend({
this._map.fire('draw:editstart', { handler: this.type });
//allow drawLayer to be updated before beginning edition.
- L.Handler.prototype.enable.call(this);
+ L.ToolbarAction.prototype.enable.call(this);
this._featureGroup
.on('layeradd', this._enableLayerEdit, this)
.on('layerremove', this._disableLayerEdit, this);
@@ -44,7 +64,7 @@ L.EditToolbar.Edit = L.Handler.extend({
this._featureGroup
.off('layeradd', this._enableLayerEdit, this)
.off('layerremove', this._disableLayerEdit, this);
- L.Handler.prototype.disable.call(this);
+ L.ToolbarAction.prototype.disable.call(this);
this._map.fire('draw:editstop', { handler: this.type });
this.fire('disabled', {handler: this.type});
},
diff --git a/src/edit/control/EditToolbar.Control.js b/src/edit/control/EditToolbar.Control.js
new file mode 100644
index 000000000..1e32d0080
--- /dev/null
+++ b/src/edit/control/EditToolbar.Control.js
@@ -0,0 +1,72 @@
+L.EditToolbar.Control = L.Toolbar.Control.extend({
+ options: {
+ className: 'leaflet-draw-toolbar',
+ edit: {},
+ remove: {},
+ featureGroup: null /* REQUIRED! TODO: perhaps if not set then all layers on the map are selectable? */
+ },
+
+ initialize: function (options) {
+ L.setOptions(this, options);
+
+ this._actions = {};
+ this.options.actions = {};
+
+ if (this.options.edit) {
+ this.options.actions.edit = {
+ action: L.Edit.Control.Edit,
+ options: L.Util.extend(this.options.edit, { featureGroup: this.options.featureGroup })
+ }
+ }
+
+ if (this.options.remove) {
+ this.options.actions.remove = {
+ action: L.Edit.Control.Delete,
+ options: L.Util.extend(this.options.edit, { featureGroup: this.options.featureGroup })
+ }
+ }
+
+ L.Toolbar.Control.prototype.initialize.call(this, options);
+ }
+});
+
+L.EditToolbar.Save = L.ToolbarAction.extend({
+ options: {
+ toolbarIcon: { html: 'Save' }
+ },
+
+ initialize: function (map, editing) {
+ this.editing = editing;
+ L.ToolbarAction.prototype.initialize.call(this);
+ },
+
+ addHooks: function () {
+ this.editing.save();
+ this.editing.disable();
+ }
+});
+
+L.EditToolbar.Undo = L.ToolbarAction.extend({
+ options: {
+ toolbarIcon: { html: 'Undo' }
+ },
+
+ initialize: function (map, editing) {
+ this.editing = editing;
+ L.ToolbarAction.prototype.initialize.call(this);
+ },
+
+ addHooks: function () {
+ this.editing.revertLayers();
+ this.editing.disable();
+ }
+});
+
+/* Enable save and undo functionality for edit and delete modes. */
+L.setOptions(L.Edit.Control.Delete.prototype, {
+ subToolbar: new L.Toolbar({ actions: [L.EditToolbar.Save, L.EditToolbar.Undo] })
+});
+
+L.setOptions(L.Edit.Control.Edit.prototype, {
+ subToolbar: new L.Toolbar({ actions: [L.EditToolbar.Save, L.EditToolbar.Undo] })
+});
\ No newline at end of file
diff --git a/src/edit/handler/Edit.Poly.js b/src/edit/handler/Edit.Poly.js
index 3ee4e2128..ac91718cf 100644
--- a/src/edit/handler/Edit.Poly.js
+++ b/src/edit/handler/Edit.Poly.js
@@ -257,7 +257,7 @@ L.Edit.Poly = L.Handler.extend({
L.Polyline.addInitHook(function () {
- // Check to see if handler has already been initialized. This is to support versions of Leaflet that still have L.Handler.PolyEdit
+ // Check to see if handler has already been initialized. This is to support versions of Leaflet that still have L.ToolbarAction.PolyEdit
if (this.editing) {
return;
}
diff --git a/src/edit/popup/Edit.Popup.Delete.js b/src/edit/popup/Edit.Popup.Delete.js
new file mode 100644
index 000000000..16f14564e
--- /dev/null
+++ b/src/edit/popup/Edit.Popup.Delete.js
@@ -0,0 +1,20 @@
+L.Edit = L.Edit || {};
+L.Edit.Popup = L.Edit.Popup || {};
+
+L.Edit.Popup.Delete = L.ToolbarAction.extend({
+ options: {
+ toolbarIcon: { className: 'leaflet-draw-edit-remove' }
+ },
+
+ initialize: function (map, shape, options) {
+ this._map = map;
+ this._shape = shape;
+
+ L.ToolbarAction.prototype.initialize.call(this, map, options);
+ },
+
+ addHooks: function () {
+ this._map.removeLayer(this._shape);
+ this._map.removeLayer(this.toolbar);
+ }
+});
diff --git a/src/edit/popup/Edit.Popup.Edit.js b/src/edit/popup/Edit.Popup.Edit.js
new file mode 100644
index 000000000..d5b0036bb
--- /dev/null
+++ b/src/edit/popup/Edit.Popup.Edit.js
@@ -0,0 +1,29 @@
+L.Edit = L.Edit || {};
+L.Edit.Popup = L.Edit.Popup || {};
+
+L.Edit.Popup.Edit = L.ToolbarAction.extend({
+ options: {
+ toolbarIcon: { className: 'leaflet-draw-edit-edit' }
+ },
+
+ initialize: function (map, shape, options) {
+ this._map = map;
+
+ this._shape = shape;
+ this._shape.options.editing = this._shape.options.editing || {};
+
+ L.ToolbarAction.prototype.initialize.call(this, map, options);
+ },
+
+ enable: function () {
+ var map = this._map,
+ shape = this._shape;
+
+ shape.editing.enable();
+ map.removeLayer(this.toolbar);
+
+ map.on('click', function () {
+ shape.editing.disable();
+ });
+ }
+});
\ No newline at end of file
diff --git a/src/edit/popup/EditToolbar.Popup.js b/src/edit/popup/EditToolbar.Popup.js
new file mode 100644
index 000000000..8dd6ed123
--- /dev/null
+++ b/src/edit/popup/EditToolbar.Popup.js
@@ -0,0 +1,19 @@
+L.EditToolbar.Popup = L.Toolbar.Popup.extend({
+ options: {
+ actions: [
+ L.Edit.Popup.Edit,
+ L.Edit.Popup.Delete
+ ]
+ },
+
+ onAdd: function (map) {
+ var shape = this._arguments[1];
+
+ if (shape instanceof L.Marker) {
+ /* Adjust the toolbar position so that it doesn't cover the marker. */
+ this.options.anchor = L.point(shape.options.icon.options.popupAnchor);
+ }
+
+ L.Toolbar.Popup.prototype.onAdd.call(this, map);
+ }
+});
\ No newline at end of file