From 67aeb9bb2090f173f211008f5216370d84eb0366 Mon Sep 17 00:00:00 2001 From: Justin Manley Date: Thu, 27 Nov 2014 00:26:22 -0500 Subject: [PATCH 01/32] Inherit each draw and edithandler from L.ToolbarHandler. Refactor build dependencies to include an external dependency to L.Toolbar plugin. --- build/deps.js | 26 +++-- src/draw/handler/Draw.Feature.js | 6 +- src/edit/EditToolbar.js | 155 +------------------------ src/edit/handler/Edit.Marker.js | 2 +- src/edit/handler/Edit.Poly.js | 4 +- src/edit/handler/Edit.SimpleShape.js | 2 +- src/edit/handler/EditToolbar.Delete.js | 8 +- src/edit/handler/EditToolbar.Edit.js | 12 +- 8 files changed, 37 insertions(+), 178 deletions(-) diff --git a/build/deps.js b/build/deps.js index 92051758d..45234fc2d 100644 --- a/build/deps.js +++ b/build/deps.js @@ -6,6 +6,13 @@ var deps = { desc: 'The core of the plugin. Currently only includes the version.' }, + Toolbar: { + src: [ + '../node_modules/leaflet-toolbar/dist/Leaflet.Toolbar.js' + ], + desc: 'External dependencies (Leaflet plugins). Curently only includes Leaflet.Toolbar.' + }, + DrawHandlers: { src: [ 'draw/handler/Draw.Feature.js', @@ -17,7 +24,7 @@ var deps = { 'draw/handler/Draw.Marker.js' ], desc: 'Drawing handlers for: polylines, polygons, rectangles, circles and markers.', - deps: ['Core'] + deps: ['Core', 'Toolbar'] }, EditHandlers: { @@ -29,7 +36,7 @@ var deps = { 'edit/handler/Edit.Circle.js' ], desc: 'Editing handlers for: polylines, polygons, rectangles, and circles.', - deps: ['Core'] + deps: ['Core', 'Toolbar'] }, Extensions: { @@ -53,13 +60,14 @@ var deps = { deps: ['Extensions'] }, - DrawUI: { - src: [ - 'draw/DrawToolbar.js' - ], - desc: 'Draw toolbar.', - deps: ['DrawHandlers', 'CommonUI'] - }, + // TODO: Rewrite. + // DrawUI: { + // src: [ + // 'draw/DrawToolbar.js' + // ], + // desc: 'Draw toolbar.', + // deps: ['DrawHandlers', 'CommonUI'] + // }, EditUI: { src: [ diff --git a/src/draw/handler/Draw.Feature.js b/src/draw/handler/Draw.Feature.js index 1465fba34..04bdb5765 100644 --- a/src/draw/handler/Draw.Feature.js +++ b/src/draw/handler/Draw.Feature.js @@ -1,6 +1,6 @@ L.Draw = {}; -L.Draw.Feature = L.Handler.extend({ +L.Draw.Feature = L.ToolbarHandler.extend({ includes: L.Mixin.Events, initialize: function (map, options) { @@ -19,7 +19,7 @@ L.Draw.Feature = L.Handler.extend({ enable: function () { if (this._enabled) { return; } - L.Handler.prototype.enable.call(this); + L.ToolbarHandler.prototype.enable.call(this); this.fire('enabled', { handler: this.type }); @@ -29,7 +29,7 @@ L.Draw.Feature = L.Handler.extend({ disable: function () { if (!this._enabled) { return; } - L.Handler.prototype.disable.call(this); + L.ToolbarHandler.prototype.disable.call(this); this._map.fire('draw:drawstop', { layerType: this.type }); 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/Edit.Marker.js b/src/edit/handler/Edit.Marker.js index 252fa8605..9732ce132 100644 --- a/src/edit/handler/Edit.Marker.js +++ b/src/edit/handler/Edit.Marker.js @@ -1,6 +1,6 @@ L.Edit = L.Edit || {}; -L.Edit.Marker = L.Handler.extend({ +L.Edit.Marker = L.ToolbarHandler.extend({ initialize: function (marker, options) { this._marker = marker; L.setOptions(this, options); diff --git a/src/edit/handler/Edit.Poly.js b/src/edit/handler/Edit.Poly.js index 3ee4e2128..4fce72c2c 100644 --- a/src/edit/handler/Edit.Poly.js +++ b/src/edit/handler/Edit.Poly.js @@ -4,7 +4,7 @@ L.Edit = L.Edit || {}; * L.Edit.Poly is an editing handler for polylines and polygons. */ -L.Edit.Poly = L.Handler.extend({ +L.Edit.Poly = L.ToolbarHandler.extend({ options: { icon: new L.DivIcon({ iconSize: new L.Point(8, 8), @@ -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.ToolbarHandler.PolyEdit if (this.editing) { return; } diff --git a/src/edit/handler/Edit.SimpleShape.js b/src/edit/handler/Edit.SimpleShape.js index f00ce3142..562bfbed2 100644 --- a/src/edit/handler/Edit.SimpleShape.js +++ b/src/edit/handler/Edit.SimpleShape.js @@ -1,6 +1,6 @@ L.Edit = L.Edit || {}; -L.Edit.SimpleShape = L.Handler.extend({ +L.Edit.SimpleShape = L.ToolbarHandler.extend({ options: { moveIcon: new L.DivIcon({ iconSize: new L.Point(8, 8), diff --git a/src/edit/handler/EditToolbar.Delete.js b/src/edit/handler/EditToolbar.Delete.js index d23252137..2bc6f3904 100644 --- a/src/edit/handler/EditToolbar.Delete.js +++ b/src/edit/handler/EditToolbar.Delete.js @@ -1,4 +1,4 @@ -L.EditToolbar.Delete = L.Handler.extend({ +L.EditToolbar.Delete = L.ToolbarHandler.extend({ statics: { TYPE: 'remove' // not delete as delete is reserved in js }, @@ -6,7 +6,7 @@ L.EditToolbar.Delete = L.Handler.extend({ includes: L.Mixin.Events, initialize: function (map, options) { - L.Handler.prototype.initialize.call(this, map); + L.ToolbarHandler.prototype.initialize.call(this, map); L.Util.setOptions(this, options); @@ -29,7 +29,7 @@ L.EditToolbar.Delete = L.Handler.extend({ this._map.fire('draw:deletestart', { handler: this.type }); - L.Handler.prototype.enable.call(this); + L.ToolbarHandler.prototype.enable.call(this); this._deletableLayers .on('layeradd', this._enableLayerDelete, this) @@ -43,7 +43,7 @@ L.EditToolbar.Delete = L.Handler.extend({ .off('layeradd', this._enableLayerDelete, this) .off('layerremove', this._disableLayerDelete, this); - L.Handler.prototype.disable.call(this); + L.ToolbarHandler.prototype.disable.call(this); this._map.fire('draw:deletestop', { handler: this.type }); diff --git a/src/edit/handler/EditToolbar.Edit.js b/src/edit/handler/EditToolbar.Edit.js index fcbd04378..8269c985b 100644 --- a/src/edit/handler/EditToolbar.Edit.js +++ b/src/edit/handler/EditToolbar.Edit.js @@ -1,12 +1,16 @@ -L.EditToolbar.Edit = L.Handler.extend({ +L.EditToolbar.Edit = L.ToolbarHandler.extend({ statics: { TYPE: 'edit' }, + options: { + selectedPathOptions: true + }, + includes: L.Mixin.Events, initialize: function (map, options) { - L.Handler.prototype.initialize.call(this, map); + L.ToolbarHandler.prototype.initialize.call(this, map); L.setOptions(this, options); @@ -33,7 +37,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.ToolbarHandler.prototype.enable.call(this); this._featureGroup .on('layeradd', this._enableLayerEdit, this) .on('layerremove', this._disableLayerEdit, this); @@ -44,7 +48,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.ToolbarHandler.prototype.disable.call(this); this._map.fire('draw:editstop', { handler: this.type }); this.fire('disabled', {handler: this.type}); }, From 6f65a44149d200cb20a92aaf771e5e862e315aa8 Mon Sep 17 00:00:00 2001 From: Justin Manley Date: Thu, 27 Nov 2014 00:32:34 -0500 Subject: [PATCH 02/32] Add leaflet-toolbar as a dependency in package.json. --- package.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/package.json b/package.json index 59f4e9c51..4a0a8b337 100644 --- a/package.json +++ b/package.json @@ -2,6 +2,9 @@ "name": "leaflet-draw", "version": "0.2.3", "description": "Vector drawing plugin for Leaflet", + "dependencies": { + "leaflet-toolbar": "manleyjster#leaflet-toolbar" + }, "devDependencies": { "leaflet": "~0.7.0", "jshint": "~2.3.0", From 38992c4c631addcf521f941f14f865ed7b39a4ed Mon Sep 17 00:00:00 2001 From: Justin Manley Date: Thu, 27 Nov 2014 00:37:51 -0500 Subject: [PATCH 03/32] Fix error in Leaflet.Toolbar dependency in package.json. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 4a0a8b337..5f1b60ba6 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "0.2.3", "description": "Vector drawing plugin for Leaflet", "dependencies": { - "leaflet-toolbar": "manleyjster#leaflet-toolbar" + "leaflet-toolbar": "manleyjster/Leaflet.Toolbar" }, "devDependencies": { "leaflet": "~0.7.0", From 98963667bc1cb73f759599f0fccf550c924bc3f8 Mon Sep 17 00:00:00 2001 From: Justin Manley Date: Sat, 3 Jan 2015 12:05:40 -0500 Subject: [PATCH 04/32] Remove build dependency on Leaflet.Toolbar (assume that app developers will load Leaflet.Toolbar separately, before Leaflet.draw). --- build/deps.js | 39 ++++++++++++++++++--------------------- 1 file changed, 18 insertions(+), 21 deletions(-) diff --git a/build/deps.js b/build/deps.js index 45234fc2d..af30f233e 100644 --- a/build/deps.js +++ b/build/deps.js @@ -6,13 +6,6 @@ var deps = { desc: 'The core of the plugin. Currently only includes the version.' }, - Toolbar: { - src: [ - '../node_modules/leaflet-toolbar/dist/Leaflet.Toolbar.js' - ], - desc: 'External dependencies (Leaflet plugins). Curently only includes Leaflet.Toolbar.' - }, - DrawHandlers: { src: [ 'draw/handler/Draw.Feature.js', @@ -24,7 +17,7 @@ var deps = { 'draw/handler/Draw.Marker.js' ], desc: 'Drawing handlers for: polylines, polygons, rectangles, circles and markers.', - deps: ['Core', 'Toolbar'] + deps: ['Core'] }, EditHandlers: { @@ -36,7 +29,7 @@ var deps = { 'edit/handler/Edit.Circle.js' ], desc: 'Editing handlers for: polylines, polygons, rectangles, and circles.', - deps: ['Core', 'Toolbar'] + deps: ['Core'] }, Extensions: { @@ -52,28 +45,32 @@ var deps = { CommonUI: { src: [ - 'Control.Draw.js', - 'Toolbar.js', 'Tooltip.js' ], desc: 'Common UI components used.', deps: ['Extensions'] }, - // TODO: Rewrite. - // DrawUI: { - // src: [ - // 'draw/DrawToolbar.js' - // ], - // desc: 'Draw toolbar.', - // deps: ['DrawHandlers', 'CommonUI'] - // }, + DrawUI: { + src: [ + 'draw/DrawToolbar.js', + 'draw/control/Draw.Cancel.js', + 'draw/control/Draw.RemoveLastPoint.js', + 'draw/control/DrawToolbar.Control.js' + ], + desc: 'Draw toolbar.', + deps: ['DrawHandlers', 'CommonUI'] + }, 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'] From c030219b9079bfad56d28090d1f6df2887b28907 Mon Sep 17 00:00:00 2001 From: Justin Manley Date: Sat, 3 Jan 2015 12:07:29 -0500 Subject: [PATCH 05/32] Remove test L.Draw.Control and add skeleton spec for DrawToolbar.Control. --- spec/suites/DrawControlSpec.js | 14 -------------- spec/suites/DrawToolbarSpec.js | 7 +++++++ 2 files changed, 7 insertions(+), 14 deletions(-) delete mode 100644 spec/suites/DrawControlSpec.js create mode 100644 spec/suites/DrawToolbarSpec.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')); + }); +}); From 68d0ccb587117f7ba62cd921d2feb1330c43354f Mon Sep 17 00:00:00 2001 From: Justin Manley Date: Sat, 3 Jan 2015 12:13:12 -0500 Subject: [PATCH 06/32] Modify each draw handler to extend L.ToolbarAction (rather than L.Handler). Specify icon and tooltip in the options for each draw handler. --- src/draw/handler/Draw.Circle.js | 3 ++- src/draw/handler/Draw.Feature.js | 9 +++++---- src/draw/handler/Draw.Marker.js | 3 ++- src/draw/handler/Draw.Polygon.js | 3 ++- src/draw/handler/Draw.Polyline.js | 3 ++- src/draw/handler/Draw.Rectangle.js | 3 ++- 6 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/draw/handler/Draw.Circle.js b/src/draw/handler/Draw.Circle.js index 5b3ca29fc..f4b003f06 100644 --- a/src/draw/handler/Draw.Circle.js +++ b/src/draw/handler/Draw.Circle.js @@ -15,7 +15,8 @@ L.Draw.Circle = L.Draw.SimpleShape.extend({ clickable: true }, showRadius: true, - metric: true // Whether to use the metric meaurement system or imperial + metric: true, // Whether to use the metric meaurement system or imperial + toolbarIcon: { className: 'leaflet-draw-draw-circle', tooltip: 'Draw a circle.' } }, initialize: function (map, options) { diff --git a/src/draw/handler/Draw.Feature.js b/src/draw/handler/Draw.Feature.js index 04bdb5765..49574c9c0 100644 --- a/src/draw/handler/Draw.Feature.js +++ b/src/draw/handler/Draw.Feature.js @@ -1,6 +1,6 @@ L.Draw = {}; -L.Draw.Feature = L.ToolbarHandler.extend({ +L.Draw.Feature = L.ToolbarAction.extend({ includes: L.Mixin.Events, initialize: function (map, options) { @@ -13,13 +13,14 @@ L.Draw.Feature = L.ToolbarHandler.extend({ if (options && options.shapeOptions) { options.shapeOptions = L.Util.extend({}, this.options.shapeOptions, options.shapeOptions); } - L.setOptions(this, options); + + L.ToolbarAction.prototype.initialize.call(this, options); }, enable: function () { if (this._enabled) { return; } - L.ToolbarHandler.prototype.enable.call(this); + L.ToolbarAction.prototype.enable.call(this); this.fire('enabled', { handler: this.type }); @@ -29,7 +30,7 @@ L.Draw.Feature = L.ToolbarHandler.extend({ disable: function () { if (!this._enabled) { return; } - L.ToolbarHandler.prototype.disable.call(this); + L.ToolbarAction.prototype.disable.call(this); this._map.fire('draw:drawstop', { layerType: this.type }); diff --git a/src/draw/handler/Draw.Marker.js b/src/draw/handler/Draw.Marker.js index 7f89de2d8..5d0910d40 100644 --- a/src/draw/handler/Draw.Marker.js +++ b/src/draw/handler/Draw.Marker.js @@ -6,7 +6,8 @@ L.Draw.Marker = L.Draw.Feature.extend({ options: { icon: new L.Icon.Default(), repeatMode: false, - zIndexOffset: 2000 // This should be > than the highest z-index any markers + zIndexOffset: 2000, // This should be > than the highest z-index any markers + toolbarIcon: { className: 'leaflet-draw-draw-marker', tooltip: 'Draw a marker.' } }, initialize: function (map, options) { diff --git a/src/draw/handler/Draw.Polygon.js b/src/draw/handler/Draw.Polygon.js index b753662f5..796063fc1 100644 --- a/src/draw/handler/Draw.Polygon.js +++ b/src/draw/handler/Draw.Polygon.js @@ -16,7 +16,8 @@ L.Draw.Polygon = L.Draw.Polyline.extend({ fillColor: null, //same as color by default fillOpacity: 0.2, clickable: true - } + }, + toolbarIcon: { className: 'leaflet-draw-draw-polygon', tooltip: 'Draw a polygon.' } }, initialize: function (map, options) { diff --git a/src/draw/handler/Draw.Polyline.js b/src/draw/handler/Draw.Polyline.js index cc556d922..fb2a68192 100644 --- a/src/draw/handler/Draw.Polyline.js +++ b/src/draw/handler/Draw.Polyline.js @@ -28,7 +28,8 @@ L.Draw.Polyline = L.Draw.Feature.extend({ }, metric: true, // Whether to use the metric meaurement system or imperial showLength: true, // Whether to display distance in the tooltip - zIndexOffset: 2000 // This should be > than the highest z-index any map layers + zIndexOffset: 2000, // This should be > than the highest z-index any map layers + toolbarIcon: { className: 'leaflet-draw-draw-polyline', tooltip: 'Draw a polyline.' } }, initialize: function (map, options) { diff --git a/src/draw/handler/Draw.Rectangle.js b/src/draw/handler/Draw.Rectangle.js index d83120f27..432b6ef32 100644 --- a/src/draw/handler/Draw.Rectangle.js +++ b/src/draw/handler/Draw.Rectangle.js @@ -14,7 +14,8 @@ 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, + toolbarIcon: { className: 'leaflet-draw-draw-rectangle', tooltip: 'Draw a rectangle.' } }, initialize: function (map, options) { From d755267008c9271222f6717f30f697f64b25d949 Mon Sep 17 00:00:00 2001 From: Justin Manley Date: Sat, 3 Jan 2015 12:15:15 -0500 Subject: [PATCH 07/32] Move EditToolbar handlers into src/edit/control. Revert each edit handler to extend L.Handler (edit handlers as implemented don't actually correspond to toolbar icons/actions. --- src/edit/handler/Edit.Marker.js | 2 +- src/edit/handler/Edit.Poly.js | 4 +- src/edit/handler/Edit.SimpleShape.js | 2 +- src/edit/handler/EditToolbar.Delete.js | 125 ----------------- src/edit/handler/EditToolbar.Edit.js | 187 ------------------------- 5 files changed, 4 insertions(+), 316 deletions(-) delete mode 100644 src/edit/handler/EditToolbar.Delete.js delete mode 100644 src/edit/handler/EditToolbar.Edit.js diff --git a/src/edit/handler/Edit.Marker.js b/src/edit/handler/Edit.Marker.js index 9732ce132..252fa8605 100644 --- a/src/edit/handler/Edit.Marker.js +++ b/src/edit/handler/Edit.Marker.js @@ -1,6 +1,6 @@ L.Edit = L.Edit || {}; -L.Edit.Marker = L.ToolbarHandler.extend({ +L.Edit.Marker = L.Handler.extend({ initialize: function (marker, options) { this._marker = marker; L.setOptions(this, options); diff --git a/src/edit/handler/Edit.Poly.js b/src/edit/handler/Edit.Poly.js index 4fce72c2c..ac91718cf 100644 --- a/src/edit/handler/Edit.Poly.js +++ b/src/edit/handler/Edit.Poly.js @@ -4,7 +4,7 @@ L.Edit = L.Edit || {}; * L.Edit.Poly is an editing handler for polylines and polygons. */ -L.Edit.Poly = L.ToolbarHandler.extend({ +L.Edit.Poly = L.Handler.extend({ options: { icon: new L.DivIcon({ iconSize: new L.Point(8, 8), @@ -257,7 +257,7 @@ L.Edit.Poly = L.ToolbarHandler.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.ToolbarHandler.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/handler/Edit.SimpleShape.js b/src/edit/handler/Edit.SimpleShape.js index 562bfbed2..f00ce3142 100644 --- a/src/edit/handler/Edit.SimpleShape.js +++ b/src/edit/handler/Edit.SimpleShape.js @@ -1,6 +1,6 @@ L.Edit = L.Edit || {}; -L.Edit.SimpleShape = L.ToolbarHandler.extend({ +L.Edit.SimpleShape = L.Handler.extend({ options: { moveIcon: new L.DivIcon({ iconSize: new L.Point(8, 8), diff --git a/src/edit/handler/EditToolbar.Delete.js b/src/edit/handler/EditToolbar.Delete.js deleted file mode 100644 index 2bc6f3904..000000000 --- a/src/edit/handler/EditToolbar.Delete.js +++ /dev/null @@ -1,125 +0,0 @@ -L.EditToolbar.Delete = L.ToolbarHandler.extend({ - statics: { - TYPE: 'remove' // not delete as delete is reserved in js - }, - - includes: L.Mixin.Events, - - initialize: function (map, options) { - L.ToolbarHandler.prototype.initialize.call(this, map); - - L.Util.setOptions(this, options); - - // Store the selectable layer group for ease of access - this._deletableLayers = this.options.featureGroup; - - 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; - }, - - enable: function () { - if (this._enabled || !this._hasAvailableLayers()) { - return; - } - this.fire('enabled', { handler: this.type}); - - this._map.fire('draw:deletestart', { handler: this.type }); - - L.ToolbarHandler.prototype.enable.call(this); - - this._deletableLayers - .on('layeradd', this._enableLayerDelete, this) - .on('layerremove', this._disableLayerDelete, this); - }, - - disable: function () { - if (!this._enabled) { return; } - - this._deletableLayers - .off('layeradd', this._enableLayerDelete, this) - .off('layerremove', this._disableLayerDelete, this); - - L.ToolbarHandler.prototype.disable.call(this); - - this._map.fire('draw:deletestop', { handler: this.type }); - - this.fire('disabled', { handler: this.type}); - }, - - addHooks: function () { - var map = this._map; - - if (map) { - map.getContainer().focus(); - - this._deletableLayers.eachLayer(this._enableLayerDelete, this); - this._deletedLayers = new L.LayerGroup(); - - this._tooltip = new L.Tooltip(this._map); - this._tooltip.updateContent({ text: L.drawLocal.edit.handlers.remove.tooltip.text }); - - this._map.on('mousemove', this._onMouseMove, this); - } - }, - - removeHooks: function () { - if (this._map) { - this._deletableLayers.eachLayer(this._disableLayerDelete, this); - this._deletedLayers = null; - - this._tooltip.dispose(); - this._tooltip = null; - - this._map.off('mousemove', this._onMouseMove, this); - } - }, - - revertLayers: function () { - // Iterate of the deleted layers and add them back into the featureGroup - this._deletedLayers.eachLayer(function (layer) { - this._deletableLayers.addLayer(layer); - layer.fire('revert-deleted', { layer: layer }); - }, this); - }, - - save: function () { - this._map.fire('draw:deleted', { layers: this._deletedLayers }); - }, - - _enableLayerDelete: function (e) { - var layer = e.layer || e.target || e; - - layer.on('click', this._removeLayer, this); - }, - - _disableLayerDelete: function (e) { - var layer = e.layer || e.target || e; - - layer.off('click', this._removeLayer, this); - - // Remove from the deleted layers so we can't accidently revert if the user presses cancel - this._deletedLayers.removeLayer(layer); - }, - - _removeLayer: function (e) { - var layer = e.layer || e.target || e; - - this._deletableLayers.removeLayer(layer); - - this._deletedLayers.addLayer(layer); - - layer.fire('deleted'); - }, - - _onMouseMove: function (e) { - this._tooltip.updatePosition(e.latlng); - }, - - _hasAvailableLayers: function () { - return this._deletableLayers.getLayers().length !== 0; - } -}); diff --git a/src/edit/handler/EditToolbar.Edit.js b/src/edit/handler/EditToolbar.Edit.js deleted file mode 100644 index 8269c985b..000000000 --- a/src/edit/handler/EditToolbar.Edit.js +++ /dev/null @@ -1,187 +0,0 @@ -L.EditToolbar.Edit = L.ToolbarHandler.extend({ - statics: { - TYPE: 'edit' - }, - - options: { - selectedPathOptions: true - }, - - includes: L.Mixin.Events, - - initialize: function (map, options) { - L.ToolbarHandler.prototype.initialize.call(this, map); - - L.setOptions(this, options); - - // Store the selectable layer group for ease of access - this._featureGroup = options.featureGroup; - - if (!(this._featureGroup instanceof L.FeatureGroup)) { - throw new Error('options.featureGroup must be a L.FeatureGroup'); - } - - this._uneditedLayerProps = {}; - - // Save the type so super can fire, need to do this as cannot do this.TYPE :( - this.type = L.EditToolbar.Edit.TYPE; - }, - - enable: function () { - if (this._enabled || !this._hasAvailableLayers()) { - return; - } - this.fire('enabled', {handler: this.type}); - //this disable other handlers - - this._map.fire('draw:editstart', { handler: this.type }); - //allow drawLayer to be updated before beginning edition. - - L.ToolbarHandler.prototype.enable.call(this); - this._featureGroup - .on('layeradd', this._enableLayerEdit, this) - .on('layerremove', this._disableLayerEdit, this); - }, - - disable: function () { - if (!this._enabled) { return; } - this._featureGroup - .off('layeradd', this._enableLayerEdit, this) - .off('layerremove', this._disableLayerEdit, this); - L.ToolbarHandler.prototype.disable.call(this); - this._map.fire('draw:editstop', { handler: this.type }); - this.fire('disabled', {handler: this.type}); - }, - - addHooks: function () { - var map = this._map; - - if (map) { - map.getContainer().focus(); - - this._featureGroup.eachLayer(this._enableLayerEdit, this); - - this._tooltip = new L.Tooltip(this._map); - this._tooltip.updateContent({ - text: L.drawLocal.edit.handlers.edit.tooltip.text, - subtext: L.drawLocal.edit.handlers.edit.tooltip.subtext - }); - - this._map.on('mousemove', this._onMouseMove, this); - } - }, - - removeHooks: function () { - if (this._map) { - // Clean up selected layers. - this._featureGroup.eachLayer(this._disableLayerEdit, this); - - // Clear the backups of the original layers - this._uneditedLayerProps = {}; - - this._tooltip.dispose(); - this._tooltip = null; - - this._map.off('mousemove', this._onMouseMove, this); - } - }, - - revertLayers: function () { - this._featureGroup.eachLayer(function (layer) { - this._revertLayer(layer); - }, this); - }, - - save: function () { - var editedLayers = new L.LayerGroup(); - this._featureGroup.eachLayer(function (layer) { - if (layer.edited) { - editedLayers.addLayer(layer); - layer.edited = false; - } - }); - this._map.fire('draw:edited', {layers: editedLayers}); - }, - - _backupLayer: function (layer) { - var id = L.Util.stamp(layer); - - if (!this._uneditedLayerProps[id]) { - // Polyline, Polygon or Rectangle - if (layer instanceof L.Polyline || layer instanceof L.Polygon || layer instanceof L.Rectangle) { - this._uneditedLayerProps[id] = { - latlngs: L.LatLngUtil.cloneLatLngs(layer.getLatLngs()) - }; - } else if (layer instanceof L.Circle) { - this._uneditedLayerProps[id] = { - latlng: L.LatLngUtil.cloneLatLng(layer.getLatLng()), - radius: layer.getRadius() - }; - } else if (layer instanceof L.Marker) { // Marker - this._uneditedLayerProps[id] = { - latlng: L.LatLngUtil.cloneLatLng(layer.getLatLng()) - }; - } - } - }, - - _revertLayer: function (layer) { - var id = L.Util.stamp(layer); - layer.edited = false; - if (this._uneditedLayerProps.hasOwnProperty(id)) { - // Polyline, Polygon or Rectangle - if (layer instanceof L.Polyline || layer instanceof L.Polygon || layer instanceof L.Rectangle) { - layer.setLatLngs(this._uneditedLayerProps[id].latlngs); - } else if (layer instanceof L.Circle) { - layer.setLatLng(this._uneditedLayerProps[id].latlng); - layer.setRadius(this._uneditedLayerProps[id].radius); - } else if (layer instanceof L.Marker) { // Marker - layer.setLatLng(this._uneditedLayerProps[id].latlng); - } - - layer.fire('revert-edited', { layer: layer }); - } - }, - - _enableLayerEdit: function (e) { - var layer = e.layer || e.target || e, - pathOptions; - - // Back up this layer (if haven't before) - this._backupLayer(layer); - - // Set different style for editing mode - if (this.options.selectedPathOptions) { - pathOptions = L.Util.extend({}, this.options.selectedPathOptions); - - // Use the existing color of the layer - if (pathOptions.maintainColor) { - pathOptions.color = layer.options.color; - pathOptions.fillColor = layer.options.fillColor; - } - - layer.options.original = L.extend({}, layer.options); - layer.options.editing = pathOptions; - } - - layer.editing.enable(); - }, - - _disableLayerEdit: function (e) { - var layer = e.layer || e.target || e; - - layer.edited = false; - layer.editing.disable(); - - delete layer.options.editing; - delete layer.options.original; - }, - - _onMouseMove: function (e) { - this._tooltip.updatePosition(e.latlng); - }, - - _hasAvailableLayers: function () { - return this._featureGroup.getLayers().length !== 0; - } -}); From 0bb655546fe24861a410a67e64962030139a9430 Mon Sep 17 00:00:00 2001 From: Justin Manley Date: Sat, 3 Jan 2015 12:17:05 -0500 Subject: [PATCH 08/32] Delete src/Toolbar.js (it's completely replaced by Leaflet.Toolbar). --- src/Toolbar.js | 244 ------------------------------------------------- 1 file changed, 244 deletions(-) delete mode 100644 src/Toolbar.js 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'); - } -}); From 649f267f50cece7ccc0de4bc31971369bb537de8 Mon Sep 17 00:00:00 2001 From: Justin Manley Date: Sat, 3 Jan 2015 12:20:16 -0500 Subject: [PATCH 09/32] Remove old Control.Draw and DrawToolbar code. --- src/Control.Draw.js | 104 ---------------------------------------- src/draw/DrawToolbar.js | 88 +--------------------------------- 2 files changed, 1 insertion(+), 191 deletions(-) delete mode 100644 src/Control.Draw.js diff --git a/src/Control.Draw.js b/src/Control.Draw.js deleted file mode 100644 index 909d0aa8a..000000000 --- a/src/Control.Draw.js +++ /dev/null @@ -1,104 +0,0 @@ -L.Control.Draw = L.Control.extend({ - - options: { - position: 'topleft', - draw: {}, - edit: false - }, - - initialize: function (options) { - if (L.version < '0.7') { - throw new Error('Leaflet.draw 0.2.3+ requires Leaflet 0.7.0+. Download latest from https://github.com/Leaflet/Leaflet/'); - } - - L.Control.prototype.initialize.call(this, options); - - var 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.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); - } - }, - - onAdd: function (map) { - var container = L.DomUtil.create('div', 'leaflet-draw'), - addedTopClass = false, - topClassName = 'leaflet-draw-toolbar-top', - toolbarContainer; - - 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); - } - } - } - - return container; - }, - - onRemove: function () { - for (var toolbarId in this._toolbars) { - if (this._toolbars.hasOwnProperty(toolbarId)) { - this._toolbars[toolbarId].removeToolbar(); - } - } - }, - - setDrawingOptions: function (options) { - for (var toolbarId in this._toolbars) { - if (this._toolbars[toolbarId] instanceof L.DrawToolbar) { - 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(); - } - } - } -}); - -L.Map.mergeOptions({ - drawControlTooltips: true, - drawControl: false -}); - -L.Map.addInitHook(function () { - if (this.options.drawControl) { - this.drawControl = new L.Control.Draw(); - this.addControl(this.drawControl); - } -}); 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 From 84ef746fad0722e5fdb124bb4a347c79440522a0 Mon Sep 17 00:00:00 2001 From: Justin Manley Date: Sat, 3 Jan 2015 12:21:34 -0500 Subject: [PATCH 10/32] Add new control-style draw toolbar extending Leaflet.Toolbar. --- src/draw/control/Draw.Cancel.js | 15 +++++++++++ src/draw/control/Draw.RemoveLastPoint.js | 15 +++++++++++ src/draw/control/DrawToolbar.Control.js | 33 ++++++++++++++++++++++++ 3 files changed, 63 insertions(+) create mode 100644 src/draw/control/Draw.Cancel.js create mode 100644 src/draw/control/Draw.RemoveLastPoint.js create mode 100644 src/draw/control/DrawToolbar.Control.js diff --git a/src/draw/control/Draw.Cancel.js b/src/draw/control/Draw.Cancel.js new file mode 100644 index 000000000..fd4179f39 --- /dev/null +++ b/src/draw/control/Draw.Cancel.js @@ -0,0 +1,15 @@ +L.Draw.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.RemoveLastPoint.js b/src/draw/control/Draw.RemoveLastPoint.js new file mode 100644 index 000000000..f65e463fd --- /dev/null +++ b/src/draw/control/Draw.RemoveLastPoint.js @@ -0,0 +1,15 @@ +L.Draw.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/DrawToolbar.Control.js b/src/draw/control/DrawToolbar.Control.js new file mode 100644 index 000000000..64413dfa6 --- /dev/null +++ b/src/draw/control/DrawToolbar.Control.js @@ -0,0 +1,33 @@ +L.DrawToolbar.Control = L.Toolbar.Control.extend({ + options: { + actions: [ + L.Draw.Polygon, + L.Draw.Polyline, + L.Draw.Marker, + L.Draw.Rectangle, + L.Draw.Circle + ], + className: 'leaflet-draw-toolbar' + } +}); + +/* Include sub-toolbars. */ +L.setOptions(L.Draw.Polygon.prototype, { + subToolbar: new L.Toolbar({ actions: [L.Draw.Cancel, L.Draw.RemoveLastPoint] }) +}); + +L.setOptions(L.Draw.Polyline.prototype, { + subToolbar: new L.Toolbar({ actions: [L.Draw.Cancel, L.Draw.RemoveLastPoint] }) +}); + +L.setOptions(L.Draw.Marker.prototype, { + subToolbar: new L.Toolbar({ actions: [L.Draw.Cancel] }) +}); + +L.setOptions(L.Draw.Rectangle.prototype, { + subToolbar: new L.Toolbar({ actions: [L.Draw.Cancel] }) +}); + +L.setOptions(L.Draw.Circle.prototype, { + subToolbar: new L.Toolbar({ actions: [L.Draw.Cancel] }) +}); \ No newline at end of file From 89335a598c4a03f27be5b3ecd14960a99e49f2f7 Mon Sep 17 00:00:00 2001 From: Justin Manley Date: Sat, 3 Jan 2015 12:21:53 -0500 Subject: [PATCH 11/32] Add new control-style edit toolbar extending Leaflet.Toolbar (L.Edit.Control.Edit and L.Edit.Control.Delete are copied from the old src/edit/handlers/EditToolbar.Edit and EditToolbar.Delete, respectively)." --- src/edit/control/Edit.Control.Delete.js | 133 ++++++++++++++++ src/edit/control/Edit.Control.Edit.js | 192 ++++++++++++++++++++++++ src/edit/control/EditToolbar.Control.js | 60 ++++++++ 3 files changed, 385 insertions(+) create mode 100644 src/edit/control/Edit.Control.Delete.js create mode 100644 src/edit/control/Edit.Control.Edit.js create mode 100644 src/edit/control/EditToolbar.Control.js diff --git a/src/edit/control/Edit.Control.Delete.js b/src/edit/control/Edit.Control.Delete.js new file mode 100644 index 000000000..4c1b48c92 --- /dev/null +++ b/src/edit/control/Edit.Control.Delete.js @@ -0,0 +1,133 @@ +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.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 = this.constructor.TYPE; + }, + + enable: function () { + if (this._enabled || !this._hasAvailableLayers()) { + return; + } + this.fire('enabled', { handler: this.type}); + + this._map.fire('draw:deletestart', { handler: this.type }); + + L.ToolbarAction.prototype.enable.call(this); + + this._deletableLayers + .on('layeradd', this._enableLayerDelete, this) + .on('layerremove', this._disableLayerDelete, this); + }, + + disable: function () { + if (!this._enabled) { return; } + + this._deletableLayers + .off('layeradd', this._enableLayerDelete, this) + .off('layerremove', this._disableLayerDelete, this); + + L.ToolbarAction.prototype.disable.call(this); + + this._map.fire('draw:deletestop', { handler: this.type }); + + this.fire('disabled', { handler: this.type}); + }, + + addHooks: function () { + var map = this._map; + + if (map) { + map.getContainer().focus(); + + this._deletableLayers.eachLayer(this._enableLayerDelete, this); + this._deletedLayers = new L.layerGroup(); + + this._tooltip = new L.Tooltip(this._map); + this._tooltip.updateContent({ text: L.drawLocal.edit.handlers.remove.tooltip.text }); + + this._map.on('mousemove', this._onMouseMove, this); + } + }, + + removeHooks: function () { + if (this._map) { + this._deletableLayers.eachLayer(this._disableLayerDelete, this); + this._deletedLayers = null; + + this._tooltip.dispose(); + this._tooltip = null; + + this._map.off('mousemove', this._onMouseMove, this); + } + }, + + revertLayers: function () { + // Iterate of the deleted layers and add them back into the featureGroup + this._deletedLayers.eachLayer(function (layer) { + this._deletableLayers.addLayer(layer); + layer.fire('revert-deleted', { layer: layer }); + }, this); + }, + + save: function () { + this._map.fire('draw:deleted', { layers: this._deletedLayers }); + }, + + _enableLayerDelete: function (e) { + var layer = e.layer || e.target || e; + + layer.on('click', this._removeLayer, this); + }, + + _disableLayerDelete: function (e) { + var layer = e.layer || e.target || e; + + layer.off('click', this._removeLayer, this); + + // Remove from the deleted layers so we can't accidently revert if the user presses cancel + this._deletedLayers.removeLayer(layer); + }, + + _removeLayer: function (e) { + var layer = e.layer || e.target || e; + + this._deletableLayers.removeLayer(layer); + + this._deletedLayers.addLayer(layer); + + layer.fire('deleted'); + }, + + _onMouseMove: function (e) { + this._tooltip.updatePosition(e.latlng); + }, + + _hasAvailableLayers: function () { + return this._deletableLayers.getLayers().length !== 0; + } +}); diff --git a/src/edit/control/Edit.Control.Edit.js b/src/edit/control/Edit.Control.Edit.js new file mode 100644 index 000000000..813d33b3e --- /dev/null +++ b/src/edit/control/Edit.Control.Edit.js @@ -0,0 +1,192 @@ +L.Edit = L.Edit || {}; +L.Edit.Control = L.Edit.Control || {}; + +L.Edit.Control.Edit = L.ToolbarAction.extend({ + statics: { + TYPE: 'edit' + }, + + options: { + selectedPathOptions: true, + toolbarIcon: { className: 'leaflet-draw-edit-edit' } + }, + + includes: L.Mixin.Events, + + initialize: function (map, options) { + L.ToolbarAction.prototype.initialize.call(this, map); + + L.setOptions(this, options); + + // Store the selectable layer group for ease of access + this._featureGroup = this.options.featureGroup; + this._map = map; + + if (!(this._featureGroup instanceof L.FeatureGroup)) { + throw new Error('options.featureGroup must be a L.FeatureGroup'); + } + + this._uneditedLayerProps = {}; + + // Save the type so super can fire, need to do this as cannot do this.TYPE :( + this.type = this.constructor.TYPE; + }, + + enable: function () { + if (this._enabled || !this._hasAvailableLayers()) { + return; + } + this.fire('enabled', {handler: this.type}); + //this disable other handlers + + this._map.fire('draw:editstart', { handler: this.type }); + //allow drawLayer to be updated before beginning edition. + + L.ToolbarAction.prototype.enable.call(this); + this._featureGroup + .on('layeradd', this._enableLayerEdit, this) + .on('layerremove', this._disableLayerEdit, this); + }, + + disable: function () { + if (!this._enabled) { return; } + this._featureGroup + .off('layeradd', this._enableLayerEdit, this) + .off('layerremove', this._disableLayerEdit, this); + L.ToolbarAction.prototype.disable.call(this); + this._map.fire('draw:editstop', { handler: this.type }); + this.fire('disabled', {handler: this.type}); + }, + + addHooks: function () { + var map = this._map; + + if (map) { + map.getContainer().focus(); + + this._featureGroup.eachLayer(this._enableLayerEdit, this); + + this._tooltip = new L.Tooltip(this._map); + this._tooltip.updateContent({ + text: L.drawLocal.edit.handlers.edit.tooltip.text, + subtext: L.drawLocal.edit.handlers.edit.tooltip.subtext + }); + + this._map.on('mousemove', this._onMouseMove, this); + } + }, + + removeHooks: function () { + if (this._map) { + // Clean up selected layers. + this._featureGroup.eachLayer(this._disableLayerEdit, this); + + // Clear the backups of the original layers + this._uneditedLayerProps = {}; + + this._tooltip.dispose(); + this._tooltip = null; + + this._map.off('mousemove', this._onMouseMove, this); + } + }, + + revertLayers: function () { + this._featureGroup.eachLayer(function (layer) { + this._revertLayer(layer); + }, this); + }, + + save: function () { + var editedLayers = new L.LayerGroup(); + this._featureGroup.eachLayer(function (layer) { + if (layer.edited) { + editedLayers.addLayer(layer); + layer.edited = false; + } + }); + this._map.fire('draw:edited', {layers: editedLayers}); + }, + + _backupLayer: function (layer) { + var id = L.Util.stamp(layer); + + if (!this._uneditedLayerProps[id]) { + // Polyline, Polygon or Rectangle + if (layer instanceof L.Polyline || layer instanceof L.Polygon || layer instanceof L.Rectangle) { + this._uneditedLayerProps[id] = { + latlngs: L.LatLngUtil.cloneLatLngs(layer.getLatLngs()) + }; + } else if (layer instanceof L.Circle) { + this._uneditedLayerProps[id] = { + latlng: L.LatLngUtil.cloneLatLng(layer.getLatLng()), + radius: layer.getRadius() + }; + } else if (layer instanceof L.Marker) { // Marker + this._uneditedLayerProps[id] = { + latlng: L.LatLngUtil.cloneLatLng(layer.getLatLng()) + }; + } + } + }, + + _revertLayer: function (layer) { + var id = L.Util.stamp(layer); + layer.edited = false; + if (this._uneditedLayerProps.hasOwnProperty(id)) { + // Polyline, Polygon or Rectangle + if (layer instanceof L.Polyline || layer instanceof L.Polygon || layer instanceof L.Rectangle) { + layer.setLatLngs(this._uneditedLayerProps[id].latlngs); + } else if (layer instanceof L.Circle) { + layer.setLatLng(this._uneditedLayerProps[id].latlng); + layer.setRadius(this._uneditedLayerProps[id].radius); + } else if (layer instanceof L.Marker) { // Marker + layer.setLatLng(this._uneditedLayerProps[id].latlng); + } + + layer.fire('revert-edited', { layer: layer }); + } + }, + + _enableLayerEdit: function (e) { + var layer = e.layer || e.target || e, + pathOptions; + + // Back up this layer (if haven't before) + this._backupLayer(layer); + + // Set different style for editing mode + if (this.options.selectedPathOptions) { + pathOptions = L.Util.extend({}, this.options.selectedPathOptions); + + // Use the existing color of the layer + if (pathOptions.maintainColor) { + pathOptions.color = layer.options.color; + pathOptions.fillColor = layer.options.fillColor; + } + + layer.options.original = L.extend({}, layer.options); + layer.options.editing = pathOptions; + } + + layer.editing.enable(); + }, + + _disableLayerEdit: function (e) { + var layer = e.layer || e.target || e; + + layer.edited = false; + layer.editing.disable(); + + delete layer.options.editing; + delete layer.options.original; + }, + + _onMouseMove: function (e) { + this._tooltip.updatePosition(e.latlng); + }, + + _hasAvailableLayers: function () { + return this._featureGroup.getLayers().length !== 0; + } +}); diff --git a/src/edit/control/EditToolbar.Control.js b/src/edit/control/EditToolbar.Control.js new file mode 100644 index 000000000..41f6776af --- /dev/null +++ b/src/edit/control/EditToolbar.Control.js @@ -0,0 +1,60 @@ +L.EditToolbar.Control = L.Toolbar.Control.extend({ + options: { + actions: [ + L.Edit.Control.Edit, + L.Edit.Control.Delete + ], + className: 'leaflet-draw-toolbar' + }, + + /* Accomodate Leaflet.draw design decision to pass featureGroup as an option rather than a parameter. */ + _getActionConstructor: function (Action) { + var map = this._arguments[0], + featureGroup = this._arguments[1], + A = L.Toolbar.prototype._getActionConstructor.call(this, Action); + + return A.extend({ + options: { featureGroup: featureGroup }, + initialize: function() { + Action.prototype.initialize.call(this, map); + } + }); + } +}); + +L.EditToolbar.Save = L.ToolbarAction.extend({ + options: { + toolbarIcon: { html: 'Save' } + }, + initialize: function(map, featureGroup, 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, featureGroup, 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 From 05418a465c2d27ada9b4b15b9cf97aac2cbbcbed Mon Sep 17 00:00:00 2001 From: Justin Manley Date: Sat, 3 Jan 2015 12:24:26 -0500 Subject: [PATCH 12/32] Add popup-style toolbar for editing features on the map. Uses Leaflet.Toolbar. --- src/edit/popup/Edit.Popup.Delete.js | 20 ++++++++++++++++++++ src/edit/popup/Edit.Popup.Edit.js | 29 +++++++++++++++++++++++++++++ src/edit/popup/EditToolbar.Popup.js | 8 ++++++++ 3 files changed, 57 insertions(+) create mode 100644 src/edit/popup/Edit.Popup.Delete.js create mode 100644 src/edit/popup/Edit.Popup.Edit.js create mode 100644 src/edit/popup/EditToolbar.Popup.js 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..8b3ee96dc --- /dev/null +++ b/src/edit/popup/EditToolbar.Popup.js @@ -0,0 +1,8 @@ +L.EditToolbar.Popup = L.Toolbar.Popup.extend({ + options: { + actions: [ + L.Edit.Popup.Edit, + L.Edit.Popup.Delete + ] + } +}); \ No newline at end of file From 747c4cfe90d8394dcb3071f008eda925f86e6bcb Mon Sep 17 00:00:00 2001 From: Justin Manley Date: Thu, 15 Jan 2015 01:26:07 -0600 Subject: [PATCH 13/32] Take advantage of localization for the tooltips of each Leaflet.draw toolbar icon. --- src/draw/handler/Draw.Circle.js | 5 ++++- src/draw/handler/Draw.Marker.js | 5 ++++- src/draw/handler/Draw.Polygon.js | 5 ++++- src/draw/handler/Draw.Polyline.js | 5 ++++- src/draw/handler/Draw.Rectangle.js | 5 ++++- 5 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/draw/handler/Draw.Circle.js b/src/draw/handler/Draw.Circle.js index f4b003f06..4a3d0e32b 100644 --- a/src/draw/handler/Draw.Circle.js +++ b/src/draw/handler/Draw.Circle.js @@ -16,7 +16,10 @@ L.Draw.Circle = L.Draw.SimpleShape.extend({ }, showRadius: true, metric: true, // Whether to use the metric meaurement system or imperial - toolbarIcon: { className: 'leaflet-draw-draw-circle', tooltip: 'Draw a circle.' } + toolbarIcon: { + className: 'leaflet-draw-draw-circle', + tooltip: 'Hi' + } }, initialize: function (map, options) { diff --git a/src/draw/handler/Draw.Marker.js b/src/draw/handler/Draw.Marker.js index 5d0910d40..4f634ad66 100644 --- a/src/draw/handler/Draw.Marker.js +++ b/src/draw/handler/Draw.Marker.js @@ -7,7 +7,10 @@ L.Draw.Marker = L.Draw.Feature.extend({ icon: new L.Icon.Default(), repeatMode: false, zIndexOffset: 2000, // This should be > than the highest z-index any markers - toolbarIcon: { className: 'leaflet-draw-draw-marker', tooltip: 'Draw a marker.' } + toolbarIcon: { + className: 'leaflet-draw-draw-marker', + tooltip: L.drawLocal.draw.toolbar.buttons.marker + } }, initialize: function (map, options) { diff --git a/src/draw/handler/Draw.Polygon.js b/src/draw/handler/Draw.Polygon.js index 796063fc1..52d66578c 100644 --- a/src/draw/handler/Draw.Polygon.js +++ b/src/draw/handler/Draw.Polygon.js @@ -17,7 +17,10 @@ L.Draw.Polygon = L.Draw.Polyline.extend({ fillOpacity: 0.2, clickable: true }, - toolbarIcon: { className: 'leaflet-draw-draw-polygon', tooltip: 'Draw a polygon.' } + toolbarIcon: { + className: 'leaflet-draw-draw-polygon', + tooltip: L.drawLocal.draw.toolbar.buttons.polygon + } }, initialize: function (map, options) { diff --git a/src/draw/handler/Draw.Polyline.js b/src/draw/handler/Draw.Polyline.js index fb2a68192..a0fd58bee 100644 --- a/src/draw/handler/Draw.Polyline.js +++ b/src/draw/handler/Draw.Polyline.js @@ -29,7 +29,10 @@ L.Draw.Polyline = L.Draw.Feature.extend({ metric: true, // Whether to use the metric meaurement system or imperial showLength: true, // Whether to display distance in the tooltip zIndexOffset: 2000, // This should be > than the highest z-index any map layers - toolbarIcon: { className: 'leaflet-draw-draw-polyline', tooltip: 'Draw a polyline.' } + toolbarIcon: { + className: 'leaflet-draw-draw-polyline', + tooltip: L.drawLocal.draw.toolbar.buttons.polyline + } }, initialize: function (map, options) { diff --git a/src/draw/handler/Draw.Rectangle.js b/src/draw/handler/Draw.Rectangle.js index 432b6ef32..40aa9474e 100644 --- a/src/draw/handler/Draw.Rectangle.js +++ b/src/draw/handler/Draw.Rectangle.js @@ -15,7 +15,10 @@ L.Draw.Rectangle = L.Draw.SimpleShape.extend({ clickable: true }, metric: true, // Whether to use the metric meaurement system or imperial, - toolbarIcon: { className: 'leaflet-draw-draw-rectangle', tooltip: 'Draw a rectangle.' } + toolbarIcon: { + className: 'leaflet-draw-draw-rectangle', + tooltip: L.drawLocal.draw.toolbar.buttons.rectangle + } }, initialize: function (map, options) { From 2b6d0ab7df9b0d76d1193d38181bdc460befc68b Mon Sep 17 00:00:00 2001 From: Justin Manley Date: Thu, 15 Jan 2015 18:13:38 -0600 Subject: [PATCH 14/32] Add selectedPathOptions to L.Control.Edit to give polylines and polygons a distinctive style during editing mode. --- spec/suites/EditSpec.js | 5 ++--- src/edit/control/Edit.Control.Edit.js | 13 ++++++++++++- src/edit/control/EditToolbar.Control.js | 14 +++++++------- 3 files changed, 21 insertions(+), 11 deletions(-) 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/edit/control/Edit.Control.Edit.js b/src/edit/control/Edit.Control.Edit.js index 813d33b3e..b29259279 100644 --- a/src/edit/control/Edit.Control.Edit.js +++ b/src/edit/control/Edit.Control.Edit.js @@ -7,7 +7,18 @@ L.Edit.Control.Edit = L.ToolbarAction.extend({ }, options: { - selectedPathOptions: true, + 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' } }, diff --git a/src/edit/control/EditToolbar.Control.js b/src/edit/control/EditToolbar.Control.js index 41f6776af..9fd5413c6 100644 --- a/src/edit/control/EditToolbar.Control.js +++ b/src/edit/control/EditToolbar.Control.js @@ -13,9 +13,9 @@ L.EditToolbar.Control = L.Toolbar.Control.extend({ featureGroup = this._arguments[1], A = L.Toolbar.prototype._getActionConstructor.call(this, Action); - return A.extend({ + return A.extend({ options: { featureGroup: featureGroup }, - initialize: function() { + initialize: function () { Action.prototype.initialize.call(this, map); } }); @@ -26,11 +26,11 @@ L.EditToolbar.Save = L.ToolbarAction.extend({ options: { toolbarIcon: { html: 'Save' } }, - initialize: function(map, featureGroup, editing) { + initialize: function (map, featureGroup, editing) { this.editing = editing; L.ToolbarAction.prototype.initialize.call(this); }, - addHooks: function() { + addHooks: function () { this.editing.save(); this.editing.disable(); } @@ -40,12 +40,12 @@ L.EditToolbar.Undo = L.ToolbarAction.extend({ options: { toolbarIcon: { html: 'Undo' } }, - initialize: function(map, featureGroup, editing) { + initialize: function (map, featureGroup, editing) { this.editing = editing; L.ToolbarAction.prototype.initialize.call(this); }, - addHooks: function() { - this.editing.revertLayers(); + addHooks: function () { + this.editing.revertLayers(); this.editing.disable(); } }); From 1affa54d6dc9b6ff0b42b752eb684a87534702ce Mon Sep 17 00:00:00 2001 From: Justin Manley Date: Thu, 15 Jan 2015 18:14:25 -0600 Subject: [PATCH 15/32] Fix tests by adding Leaflet.toolbar as a dependency in karma.conf.js. --- spec/karma.conf.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/spec/karma.conf.js b/spec/karma.conf.js index 903ade0a9..645743f98 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.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", From 3875ca85dfd01d30f7488c62ab2a1fe908f47aac Mon Sep 17 00:00:00 2001 From: Justin Manley Date: Thu, 15 Jan 2015 18:20:27 -0600 Subject: [PATCH 16/32] Fix circle drawing handler tooltip. --- src/draw/handler/Draw.Circle.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/draw/handler/Draw.Circle.js b/src/draw/handler/Draw.Circle.js index 4a3d0e32b..a6c757170 100644 --- a/src/draw/handler/Draw.Circle.js +++ b/src/draw/handler/Draw.Circle.js @@ -18,7 +18,7 @@ L.Draw.Circle = L.Draw.SimpleShape.extend({ metric: true, // Whether to use the metric meaurement system or imperial toolbarIcon: { className: 'leaflet-draw-draw-circle', - tooltip: 'Hi' + tooltip: L.drawLocal.draw.toolbar.buttons.circle } }, From 1f1670d6c95798ba49680299e3ccf106b099a043 Mon Sep 17 00:00:00 2001 From: Justin Manley Date: Sat, 31 Jan 2015 21:22:56 -0600 Subject: [PATCH 17/32] Add drawControl and drawControlTooltips options to L.Map. Fixes Leaflet.toolbar#17 and ensures that helpful tooltips are shown by default when using Leaflet.draw. --- src/draw/DrawToolbar.js | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/src/draw/DrawToolbar.js b/src/draw/DrawToolbar.js index 63cb4abd8..7c3259d68 100644 --- a/src/draw/DrawToolbar.js +++ b/src/draw/DrawToolbar.js @@ -1 +1,16 @@ -L.DrawToolbar = {}; \ No newline at end of file +L.DrawToolbar = {}; + +/* + * Defaults added to map for convenience. + */ +L.Map.mergeOptions({ + drawControlTooltips: true, + drawControl: false +}); + +L.Map.addInitHook(function () { + if (this.options.drawControl) { + this.drawControl = new L.DrawToolbar.Control(); + this.addLayer(this.drawControl); + } +}); From 98229854d7d0d02d648e281fa9d140d3c6fc149f Mon Sep 17 00:00:00 2001 From: Justin Manley Date: Sun, 8 Feb 2015 21:23:43 -0600 Subject: [PATCH 18/32] Tweak EditToolbar.Popup to offset the popup toolbar if it is opened on a marker (fixes #18 and #9). --- src/edit/popup/EditToolbar.Popup.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/edit/popup/EditToolbar.Popup.js b/src/edit/popup/EditToolbar.Popup.js index 8b3ee96dc..8dd6ed123 100644 --- a/src/edit/popup/EditToolbar.Popup.js +++ b/src/edit/popup/EditToolbar.Popup.js @@ -4,5 +4,16 @@ L.EditToolbar.Popup = L.Toolbar.Popup.extend({ 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 From c0d92038d6bfc0663fc92cc186114535f8aaa01a Mon Sep 17 00:00:00 2001 From: Justin Manley Date: Sun, 8 Feb 2015 22:12:24 -0600 Subject: [PATCH 19/32] Tweak stylesheet to remove spritesheet images from toolbar background and restrict scope of toolbar margin. --- dist/leaflet.draw.css | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/dist/leaflet.draw.css b/dist/leaflet.draw.css index 7bc9978d1..459c94bc2 100644 --- a/dist/leaflet.draw.css +++ b/dist/leaflet.draw.css @@ -6,7 +6,7 @@ position: relative; } -.leaflet-draw-toolbar { +.leaflet-draw-toolbar.leaflet-control-toolbar { margin-top: 12px; } @@ -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; } From 737fea410befb8307b0cc4ce16bbd195de4e6bf2 Mon Sep 17 00:00:00 2001 From: Justin Manley Date: Sun, 8 Feb 2015 22:12:50 -0600 Subject: [PATCH 20/32] Update karma configuration to point to leaflet.toolbar-src.js (from Leaflet.Toolbar.js). --- package.json | 6 ++---- spec/karma.conf.js | 2 +- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 5f1b60ba6..a4ff0d2e9 100644 --- a/package.json +++ b/package.json @@ -2,9 +2,6 @@ "name": "leaflet-draw", "version": "0.2.3", "description": "Vector drawing plugin for Leaflet", - "dependencies": { - "leaflet-toolbar": "manleyjster/Leaflet.Toolbar" - }, "devDependencies": { "leaflet": "~0.7.0", "jshint": "~2.3.0", @@ -14,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 645743f98..7284f52a5 100644 --- a/spec/karma.conf.js +++ b/spec/karma.conf.js @@ -3,7 +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.js'; + 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]; From 3e5176920e8aadcf584fcc53a9e4b96a8fb05753 Mon Sep 17 00:00:00 2001 From: jacobtoye Date: Mon, 18 May 2015 14:43:35 +1200 Subject: [PATCH 21/32] Adding Leaflet.toolbar to be used in the examples. --- examples/libs/leaflet.toolbar-src.js | 363 +++++++++++++++++++++++++++ examples/libs/leaflet.toolbar.css | 117 +++++++++ 2 files changed, 480 insertions(+) create mode 100644 examples/libs/leaflet.toolbar-src.js create mode 100644 examples/libs/leaflet.toolbar.css 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; +} From 186f6d3cf9bce174c561adb88a3587d8d58677e4 Mon Sep 17 00:00:00 2001 From: jacobtoye Date: Mon, 18 May 2015 14:44:38 +1200 Subject: [PATCH 22/32] Getting Leaflet.draw to work with Leaflet.toolbar. Sorry single commit :( --- examples/basic.html | 22 ++- examples/full.html | 54 ++++--- src/Control.Draw.js | 97 +++++++++++++ src/Leaflet.draw.js | 2 +- src/draw/DrawToolbar.js | 17 +-- src/draw/control/DrawToolbar.Control.js | 180 ++++++++++++++++++++++-- src/draw/handler/Draw.Circle.js | 6 +- src/draw/handler/Draw.Marker.js | 6 +- src/draw/handler/Draw.Polygon.js | 4 - src/draw/handler/Draw.Polyline.js | 6 +- src/draw/handler/Draw.Rectangle.js | 6 +- src/edit/control/EditToolbar.Control.js | 46 +++--- 12 files changed, 345 insertions(+), 101 deletions(-) create mode 100644 src/Control.Draw.js diff --git a/examples/basic.html b/examples/basic.html index 52b71a456..92c14cdab 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,20 @@ - + + + + + + - - + + + + +
@@ -55,7 +65,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 +93,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..103249d83 100644 --- a/examples/full.html +++ b/examples/full.html @@ -3,43 +3,51 @@ Leaflet.draw vector editing handlers - - - + - - + + - - - - - + + + + + + - - - - + + + - - - - + + + + + + - - - - - + + + + + + + + + + + + +
diff --git a/src/Control.Draw.js b/src/Control.Draw.js new file mode 100644 index 000000000..678218a12 --- /dev/null +++ b/src/Control.Draw.js @@ -0,0 +1,97 @@ +L.Control.Draw = L.Control.extend({ + + options: { + position: 'topleft', + draw: {}, + edit: false + }, + + initialize: function (options) { + if (L.version < '0.7') { + 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 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.Control && this.options.draw) { + toolbar = new L.DrawToolbar.Control(drawOptions); + id = L.stamp(toolbar); + this._toolbars[id] = toolbar; + + // Listen for when toolbar is enabled + this._toolbars[id].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; + + // Listen for when toolbar is enabled + this._toolbars[id].on('enable', this._toolbarEnabled, this); + } + }, + + onAdd: function (map) { + var container = L.DomUtil.create('div', 'leaflet-draw'), + addedTopClass = false, + topClassName = 'leaflet-draw-toolbar-top', + toolbarContainer; + + for (var toolbarId in this._toolbars) { + if (this._toolbars.hasOwnProperty(toolbarId)) { + this._toolbars[toolbarId].addTo(map); + } + } + + return container; + }, + + onRemove: function () { + for (var toolbarId in this._toolbars) { + if (this._toolbars.hasOwnProperty(toolbarId)) { + this._toolbars[toolbarId].removeToolbar(); + } + } + }, + + setDrawingOptions: function (options) { + for (var toolbarId in this._toolbars) { + 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(); + } + } + } +}); + +L.Map.mergeOptions({ + drawControlTooltips: true, + drawControl: false +}); + +L.Map.addInitHook(function () { + if (this.options.drawControl) { + 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/draw/DrawToolbar.js b/src/draw/DrawToolbar.js index 7c3259d68..63cb4abd8 100644 --- a/src/draw/DrawToolbar.js +++ b/src/draw/DrawToolbar.js @@ -1,16 +1 @@ -L.DrawToolbar = {}; - -/* - * Defaults added to map for convenience. - */ -L.Map.mergeOptions({ - drawControlTooltips: true, - drawControl: false -}); - -L.Map.addInitHook(function () { - if (this.options.drawControl) { - this.drawControl = new L.DrawToolbar.Control(); - this.addLayer(this.drawControl); - } -}); +L.DrawToolbar = {}; \ No newline at end of file diff --git a/src/draw/control/DrawToolbar.Control.js b/src/draw/control/DrawToolbar.Control.js index 64413dfa6..8af698148 100644 --- a/src/draw/control/DrawToolbar.Control.js +++ b/src/draw/control/DrawToolbar.Control.js @@ -1,33 +1,185 @@ L.DrawToolbar.Control = L.Toolbar.Control.extend({ options: { - actions: [ - L.Draw.Polygon, - L.Draw.Polyline, - L.Draw.Marker, - L.Draw.Rectangle, - L.Draw.Circle - ], - className: 'leaflet-draw-toolbar' + 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.Polygon, + options: this.options.polygon + } + } + + if (this.options.polyline) { + this.options.actions.polyline = { + action: L.Draw.Polyline, + options: this.options.polyline + } + } + + if (this.options.circle) { + this.options.actions.circle = { + action: L.Draw.Circle, + options: this.options.circle + } + } + + if (this.options.rectangle) { + this.options.actions.rectangle = { + action: L.Draw.Rectangle, + options: this.options.rectangle + } + } + + if (this.options.marker) { + this.options.actions.marker = { + action: L.Draw.Marker, + options: this.options.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].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() { + /* 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); + } + }); +}; + + +/*L.Draw.Polygon.ToolbarAction = L.ToolbarAction.extend({ + options: { + + }, + + initialize: function (options) { + L.ToolbarAction.prototype.initialize.call(this, options); + + this._drawHandler = new L.draw.Polygon(); + }, + + 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(); + } +});*/ + /* Include sub-toolbars. */ L.setOptions(L.Draw.Polygon.prototype, { - subToolbar: new L.Toolbar({ actions: [L.Draw.Cancel, L.Draw.RemoveLastPoint] }) + subToolbar: new L.Toolbar({ actions: [L.Draw.Cancel, L.Draw.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.Cancel, L.Draw.RemoveLastPoint] }) + subToolbar: new L.Toolbar({ actions: [L.Draw.Cancel, L.Draw.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.Cancel] }) + subToolbar: new L.Toolbar({ actions: [L.Draw.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.Cancel] }) + subToolbar: new L.Toolbar({ actions: [L.Draw.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.Cancel] }) -}); \ No newline at end of file + subToolbar: new L.Toolbar({ actions: [L.Draw.Cancel] }), + + toolbarIcon: { + className: 'leaflet-draw-draw-circle', + tooltip: L.drawLocal.draw.toolbar.buttons.circle + } +}); + diff --git a/src/draw/handler/Draw.Circle.js b/src/draw/handler/Draw.Circle.js index a6c757170..5b3ca29fc 100644 --- a/src/draw/handler/Draw.Circle.js +++ b/src/draw/handler/Draw.Circle.js @@ -15,11 +15,7 @@ L.Draw.Circle = L.Draw.SimpleShape.extend({ clickable: true }, showRadius: true, - metric: true, // Whether to use the metric meaurement system or imperial - toolbarIcon: { - className: 'leaflet-draw-draw-circle', - tooltip: L.drawLocal.draw.toolbar.buttons.circle - } + metric: true // Whether to use the metric meaurement system or imperial }, initialize: function (map, options) { diff --git a/src/draw/handler/Draw.Marker.js b/src/draw/handler/Draw.Marker.js index 4f634ad66..7f89de2d8 100644 --- a/src/draw/handler/Draw.Marker.js +++ b/src/draw/handler/Draw.Marker.js @@ -6,11 +6,7 @@ L.Draw.Marker = L.Draw.Feature.extend({ options: { icon: new L.Icon.Default(), repeatMode: false, - zIndexOffset: 2000, // This should be > than the highest z-index any markers - toolbarIcon: { - className: 'leaflet-draw-draw-marker', - tooltip: L.drawLocal.draw.toolbar.buttons.marker - } + zIndexOffset: 2000 // This should be > than the highest z-index any markers }, initialize: function (map, options) { diff --git a/src/draw/handler/Draw.Polygon.js b/src/draw/handler/Draw.Polygon.js index 52d66578c..b753662f5 100644 --- a/src/draw/handler/Draw.Polygon.js +++ b/src/draw/handler/Draw.Polygon.js @@ -16,10 +16,6 @@ L.Draw.Polygon = L.Draw.Polyline.extend({ fillColor: null, //same as color by default fillOpacity: 0.2, clickable: true - }, - toolbarIcon: { - className: 'leaflet-draw-draw-polygon', - tooltip: L.drawLocal.draw.toolbar.buttons.polygon } }, diff --git a/src/draw/handler/Draw.Polyline.js b/src/draw/handler/Draw.Polyline.js index a0fd58bee..cc556d922 100644 --- a/src/draw/handler/Draw.Polyline.js +++ b/src/draw/handler/Draw.Polyline.js @@ -28,11 +28,7 @@ L.Draw.Polyline = L.Draw.Feature.extend({ }, metric: true, // Whether to use the metric meaurement system or imperial showLength: true, // Whether to display distance in the tooltip - zIndexOffset: 2000, // This should be > than the highest z-index any map layers - toolbarIcon: { - className: 'leaflet-draw-draw-polyline', - tooltip: L.drawLocal.draw.toolbar.buttons.polyline - } + zIndexOffset: 2000 // This should be > than the highest z-index any map layers }, initialize: function (map, options) { diff --git a/src/draw/handler/Draw.Rectangle.js b/src/draw/handler/Draw.Rectangle.js index 40aa9474e..cae8b7531 100644 --- a/src/draw/handler/Draw.Rectangle.js +++ b/src/draw/handler/Draw.Rectangle.js @@ -14,11 +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, - toolbarIcon: { - className: 'leaflet-draw-draw-rectangle', - tooltip: L.drawLocal.draw.toolbar.buttons.rectangle - } + metric: true // Whether to use the metric meaurement system or imperial, }, initialize: function (map, options) { diff --git a/src/edit/control/EditToolbar.Control.js b/src/edit/control/EditToolbar.Control.js index 9fd5413c6..1e32d0080 100644 --- a/src/edit/control/EditToolbar.Control.js +++ b/src/edit/control/EditToolbar.Control.js @@ -1,24 +1,32 @@ L.EditToolbar.Control = L.Toolbar.Control.extend({ options: { - actions: [ - L.Edit.Control.Edit, - L.Edit.Control.Delete - ], - className: 'leaflet-draw-toolbar' + className: 'leaflet-draw-toolbar', + edit: {}, + remove: {}, + featureGroup: null /* REQUIRED! TODO: perhaps if not set then all layers on the map are selectable? */ }, - /* Accomodate Leaflet.draw design decision to pass featureGroup as an option rather than a parameter. */ - _getActionConstructor: function (Action) { - var map = this._arguments[0], - featureGroup = this._arguments[1], - A = L.Toolbar.prototype._getActionConstructor.call(this, Action); + initialize: function (options) { + L.setOptions(this, options); - return A.extend({ - options: { featureGroup: featureGroup }, - initialize: function () { - Action.prototype.initialize.call(this, map); + 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); } }); @@ -26,10 +34,12 @@ L.EditToolbar.Save = L.ToolbarAction.extend({ options: { toolbarIcon: { html: 'Save' } }, - initialize: function (map, featureGroup, editing) { + + initialize: function (map, editing) { this.editing = editing; L.ToolbarAction.prototype.initialize.call(this); }, + addHooks: function () { this.editing.save(); this.editing.disable(); @@ -40,10 +50,12 @@ L.EditToolbar.Undo = L.ToolbarAction.extend({ options: { toolbarIcon: { html: 'Undo' } }, - initialize: function (map, featureGroup, editing) { + + initialize: function (map, editing) { this.editing = editing; L.ToolbarAction.prototype.initialize.call(this); }, + addHooks: function () { this.editing.revertLayers(); this.editing.disable(); From 1e9df5a18aefb6b1cc0d1b85493da2453faa7590 Mon Sep 17 00:00:00 2001 From: jacobtoye Date: Mon, 18 May 2015 14:45:08 +1200 Subject: [PATCH 23/32] Make sure the toolbar have no marking as the container now has. --- dist/leaflet.draw.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dist/leaflet.draw.css b/dist/leaflet.draw.css index 459c94bc2..e760d50ec 100644 --- a/dist/leaflet.draw.css +++ b/dist/leaflet.draw.css @@ -7,7 +7,7 @@ } .leaflet-draw-toolbar.leaflet-control-toolbar { - margin-top: 12px; + margin: 0; } .leaflet-draw-toolbar-top { From 60d8c13dd2d17bda14c822a5c9ad06a729ee6d29 Mon Sep 17 00:00:00 2001 From: jacobtoye Date: Mon, 18 May 2015 14:54:45 +1200 Subject: [PATCH 24/32] Rename the Cancel and RemoveLastPoint Toolbar actions to be Draw.Control.Handler. --- build/deps.js | 4 ++-- examples/basic.html | 4 ++-- examples/full.html | 4 ++-- .../control/{Draw.Cancel.js => Draw.Control.Cancel.js} | 5 ++++- ...oveLastPoint.js => Draw.Control.RemoveLastPoint.js} | 5 ++++- src/draw/control/DrawToolbar.Control.js | 10 +++++----- 6 files changed, 19 insertions(+), 13 deletions(-) rename src/draw/control/{Draw.Cancel.js => Draw.Control.Cancel.js} (68%) rename src/draw/control/{Draw.RemoveLastPoint.js => Draw.Control.RemoveLastPoint.js} (68%) diff --git a/build/deps.js b/build/deps.js index af30f233e..df71f6a33 100644 --- a/build/deps.js +++ b/build/deps.js @@ -54,8 +54,8 @@ var deps = { DrawUI: { src: [ 'draw/DrawToolbar.js', - 'draw/control/Draw.Cancel.js', - 'draw/control/Draw.RemoveLastPoint.js', + 'draw/control/Draw.Control.Cancel.js', + 'draw/control/Draw.Control.RemoveLastPoint.js', 'draw/control/DrawToolbar.Control.js' ], desc: 'Draw toolbar.', diff --git a/examples/basic.html b/examples/basic.html index 92c14cdab..7c1041a90 100644 --- a/examples/basic.html +++ b/examples/basic.html @@ -35,8 +35,8 @@ - - + + diff --git a/examples/full.html b/examples/full.html index 103249d83..bec83b606 100644 --- a/examples/full.html +++ b/examples/full.html @@ -35,8 +35,8 @@ - - + + diff --git a/src/draw/control/Draw.Cancel.js b/src/draw/control/Draw.Control.Cancel.js similarity index 68% rename from src/draw/control/Draw.Cancel.js rename to src/draw/control/Draw.Control.Cancel.js index fd4179f39..91667e7cf 100644 --- a/src/draw/control/Draw.Cancel.js +++ b/src/draw/control/Draw.Control.Cancel.js @@ -1,4 +1,7 @@ -L.Draw.Cancel = L.ToolbarAction.extend({ +L.Draw = L.Draw || {}; +L.Draw.Control = L.Draw.Control || {}; + +L.Draw.Control.Cancel = L.ToolbarAction.extend({ options: { toolbarIcon: { html: 'Cancel' } }, diff --git a/src/draw/control/Draw.RemoveLastPoint.js b/src/draw/control/Draw.Control.RemoveLastPoint.js similarity index 68% rename from src/draw/control/Draw.RemoveLastPoint.js rename to src/draw/control/Draw.Control.RemoveLastPoint.js index f65e463fd..291d8179c 100644 --- a/src/draw/control/Draw.RemoveLastPoint.js +++ b/src/draw/control/Draw.Control.RemoveLastPoint.js @@ -1,4 +1,7 @@ -L.Draw.RemoveLastPoint = L.ToolbarAction.extend({ +L.Draw = L.Draw || {}; +L.Draw.Control = L.Draw.Control || {}; + +L.Draw.Control.RemoveLastPoint = L.ToolbarAction.extend({ options: { toolbarIcon: { html: 'Delete last point' } }, diff --git a/src/draw/control/DrawToolbar.Control.js b/src/draw/control/DrawToolbar.Control.js index 8af698148..4c04fee2a 100644 --- a/src/draw/control/DrawToolbar.Control.js +++ b/src/draw/control/DrawToolbar.Control.js @@ -139,7 +139,7 @@ L.Toolbar.Control.prototype._getActionConstructor = function (Action, actionOpti /* Include sub-toolbars. */ L.setOptions(L.Draw.Polygon.prototype, { - subToolbar: new L.Toolbar({ actions: [L.Draw.Cancel, L.Draw.RemoveLastPoint] }), + subToolbar: new L.Toolbar({ actions: [L.Draw.Control.Cancel, L.Draw.Control.RemoveLastPoint] }), toolbarIcon: { className: 'leaflet-draw-draw-polygon', @@ -148,7 +148,7 @@ L.setOptions(L.Draw.Polygon.prototype, { }); L.setOptions(L.Draw.Polyline.prototype, { - subToolbar: new L.Toolbar({ actions: [L.Draw.Cancel, L.Draw.RemoveLastPoint] }), + subToolbar: new L.Toolbar({ actions: [L.Draw.Control.Cancel, L.Draw.Control.RemoveLastPoint] }), toolbarIcon: { className: 'leaflet-draw-draw-polyline', @@ -157,7 +157,7 @@ L.setOptions(L.Draw.Polyline.prototype, { }); L.setOptions(L.Draw.Marker.prototype, { - subToolbar: new L.Toolbar({ actions: [L.Draw.Cancel] }), + subToolbar: new L.Toolbar({ actions: [L.Draw.Control.Cancel] }), toolbarIcon: { className: 'leaflet-draw-draw-marker', @@ -166,7 +166,7 @@ L.setOptions(L.Draw.Marker.prototype, { }); L.setOptions(L.Draw.Rectangle.prototype, { - subToolbar: new L.Toolbar({ actions: [L.Draw.Cancel] }), + subToolbar: new L.Toolbar({ actions: [L.Draw.Control.Cancel] }), toolbarIcon: { className: 'leaflet-draw-draw-rectangle', @@ -175,7 +175,7 @@ L.setOptions(L.Draw.Rectangle.prototype, { }); L.setOptions(L.Draw.Circle.prototype, { - subToolbar: new L.Toolbar({ actions: [L.Draw.Cancel] }), + subToolbar: new L.Toolbar({ actions: [L.Draw.Control.Cancel] }), toolbarIcon: { className: 'leaflet-draw-draw-circle', From c4f0f9bd215c61f157f0689f89a8bf30ec55d73e Mon Sep 17 00:00:00 2001 From: jacobtoye Date: Mon, 18 May 2015 14:58:01 +1200 Subject: [PATCH 25/32] Remove commented out code. --- src/draw/control/DrawToolbar.Control.js | 29 ------------------------- 1 file changed, 29 deletions(-) diff --git a/src/draw/control/DrawToolbar.Control.js b/src/draw/control/DrawToolbar.Control.js index 4c04fee2a..6e3c901c8 100644 --- a/src/draw/control/DrawToolbar.Control.js +++ b/src/draw/control/DrawToolbar.Control.js @@ -108,35 +108,6 @@ L.Toolbar.Control.prototype._getActionConstructor = function (Action, actionOpti }); }; - -/*L.Draw.Polygon.ToolbarAction = L.ToolbarAction.extend({ - options: { - - }, - - initialize: function (options) { - L.ToolbarAction.prototype.initialize.call(this, options); - - this._drawHandler = new L.draw.Polygon(); - }, - - 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(); - } -});*/ - /* Include sub-toolbars. */ L.setOptions(L.Draw.Polygon.prototype, { subToolbar: new L.Toolbar({ actions: [L.Draw.Control.Cancel, L.Draw.Control.RemoveLastPoint] }), From b93cf2288aacf165b1d8575d34e833f45b8cd0f5 Mon Sep 17 00:00:00 2001 From: jacobtoye Date: Wed, 20 May 2015 18:20:29 +1200 Subject: [PATCH 26/32] Begin adding intermediate toolbar actions. --- examples/basic.html | 1 + .../control/Draw.Control.ToolbarAction.js | 87 +++++++++++++++++++ src/draw/control/DrawToolbar.Control.js | 24 ++--- src/draw/handler/Draw.Feature.js | 16 ++-- 4 files changed, 108 insertions(+), 20 deletions(-) create mode 100644 src/draw/control/Draw.Control.ToolbarAction.js diff --git a/examples/basic.html b/examples/basic.html index 7c1041a90..1a84b48bd 100644 --- a/examples/basic.html +++ b/examples/basic.html @@ -37,6 +37,7 @@ + diff --git a/src/draw/control/Draw.Control.ToolbarAction.js b/src/draw/control/Draw.Control.ToolbarAction.js new file mode 100644 index 000000000..697d063d9 --- /dev/null +++ b/src/draw/control/Draw.Control.ToolbarAction.js @@ -0,0 +1,87 @@ +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); + + 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 index 6e3c901c8..fa3231946 100644 --- a/src/draw/control/DrawToolbar.Control.js +++ b/src/draw/control/DrawToolbar.Control.js @@ -16,36 +16,36 @@ L.DrawToolbar.Control = L.Toolbar.Control.extend({ if (this.options.polygon) { this.options.actions.polygon = { - action: L.Draw.Polygon, - options: this.options.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.Polyline, - options: this.options.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.Circle, - options: this.options.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.Rectangle, - options: this.options.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.Marker, - options: this.options.marker + action: L.Draw.Control.Marker, + options: L.Util.extend(this.options.marker, { DrawAction: L.Draw.Marker }) } } @@ -109,7 +109,7 @@ L.Toolbar.Control.prototype._getActionConstructor = function (Action, actionOpti }; /* Include sub-toolbars. */ -L.setOptions(L.Draw.Polygon.prototype, { +/*L.setOptions(L.Draw.Polygon.prototype, { subToolbar: new L.Toolbar({ actions: [L.Draw.Control.Cancel, L.Draw.Control.RemoveLastPoint] }), toolbarIcon: { @@ -152,5 +152,5 @@ L.setOptions(L.Draw.Circle.prototype, { 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 49574c9c0..4d497df94 100644 --- a/src/draw/handler/Draw.Feature.js +++ b/src/draw/handler/Draw.Feature.js @@ -1,26 +1,26 @@ L.Draw = {}; -L.Draw.Feature = L.ToolbarAction.extend({ +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.ToolbarAction.prototype.initialize.call(this, options); + }*/ + L.setOptions(this, options); }, enable: function () { if (this._enabled) { return; } - L.ToolbarAction.prototype.enable.call(this); + L.Handler.prototype.enable.call(this); this.fire('enabled', { handler: this.type }); @@ -30,7 +30,7 @@ L.Draw.Feature = L.ToolbarAction.extend({ disable: function () { if (!this._enabled) { return; } - L.ToolbarAction.prototype.disable.call(this); + L.Handler.prototype.disable.call(this); this._map.fire('draw:drawstop', { layerType: this.type }); From 69c514750c6a0290d8942618bd7ffad5d54c3ebd Mon Sep 17 00:00:00 2001 From: jacobtoye Date: Thu, 21 May 2015 09:58:05 +1200 Subject: [PATCH 27/32] No longer need to take care of handling disabling other handlers when another is enabled in the main Control class. --- src/Control.Draw.js | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/Control.Draw.js b/src/Control.Draw.js index 678218a12..32bba2d48 100644 --- a/src/Control.Draw.js +++ b/src/Control.Draw.js @@ -27,18 +27,12 @@ L.Control.Draw = L.Control.extend({ toolbar = new L.DrawToolbar.Control(drawOptions); id = L.stamp(toolbar); this._toolbars[id] = toolbar; - - // Listen for when toolbar is enabled - this._toolbars[id].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; - - // Listen for when toolbar is enabled - this._toolbars[id].on('enable', this._toolbarEnabled, this); } }, @@ -71,16 +65,6 @@ L.Control.Draw = L.Control.extend({ 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(); - } - } } }); From 27f6475764c1ed7fc66f6a09257e575e8e898de6 Mon Sep 17 00:00:00 2001 From: jacobtoye Date: Thu, 21 May 2015 10:17:42 +1200 Subject: [PATCH 28/32] Make it do we don't try to enable a toolbar action twice in a row. When a toolbar action is disabled we remove the reference to the active toolbar action. --- src/draw/control/DrawToolbar.Control.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/draw/control/DrawToolbar.Control.js b/src/draw/control/DrawToolbar.Control.js index fa3231946..c2ce84091 100644 --- a/src/draw/control/DrawToolbar.Control.js +++ b/src/draw/control/DrawToolbar.Control.js @@ -99,11 +99,22 @@ L.Toolbar.Control.prototype._getActionConstructor = function (Action, actionOpti 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(); } + if (toolbar._active) { + toolbar._active.disable(); + } toolbar._active = this; Action.prototype.enable.call(this); + }, + disable: function () { + toolbar._active = null; + + Action.prototype.disable.call(this); } }); }; From a8f0c1f6a9497a41d997ee2a3c2320f23220586d Mon Sep 17 00:00:00 2001 From: jacobtoye Date: Thu, 21 May 2015 10:18:30 +1200 Subject: [PATCH 29/32] Listen for disabled and enabled events from the draw handlers. This ensure that when a shape is created we disable to toolbar action. --- src/draw/control/Draw.Control.ToolbarAction.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/draw/control/Draw.Control.ToolbarAction.js b/src/draw/control/Draw.Control.ToolbarAction.js index 697d063d9..98ff63928 100644 --- a/src/draw/control/Draw.Control.ToolbarAction.js +++ b/src/draw/control/Draw.Control.ToolbarAction.js @@ -7,6 +7,10 @@ L.Draw.Control.ToolbarAction = L.ToolbarAction.extend({ 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); }, From 52f3102bc3a7c8cf65c7c90195af989badd25952 Mon Sep 17 00:00:00 2001 From: jacobtoye Date: Thu, 21 May 2015 10:27:11 +1200 Subject: [PATCH 30/32] Adding support for changing the draw handler options after initialization. --- src/draw/control/Draw.Control.ToolbarAction.js | 8 ++++---- src/draw/control/DrawToolbar.Control.js | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/draw/control/Draw.Control.ToolbarAction.js b/src/draw/control/Draw.Control.ToolbarAction.js index 98ff63928..639c889c5 100644 --- a/src/draw/control/Draw.Control.ToolbarAction.js +++ b/src/draw/control/Draw.Control.ToolbarAction.js @@ -5,9 +5,9 @@ L.Draw.Control.ToolbarAction = L.ToolbarAction.extend({ options: {}, initialize: function (map, options) { - this._drawHandler = new options.DrawAction(map, options); + this.drawHandler = new options.DrawAction(map, options); - this._drawHandler + this.drawHandler .on('enabled', this.enable, this) .on('disabled', this.disable, this); @@ -19,7 +19,7 @@ L.Draw.Control.ToolbarAction = L.ToolbarAction.extend({ L.ToolbarAction.prototype.enable.call(this); - this._drawHandler.enable(); + this.drawHandler.enable(); }, disable: function () { @@ -27,7 +27,7 @@ L.Draw.Control.ToolbarAction = L.ToolbarAction.extend({ L.ToolbarAction.prototype.disable.call(this); - this._drawHandler.disable(); + this.drawHandler.disable(); } }); diff --git a/src/draw/control/DrawToolbar.Control.js b/src/draw/control/DrawToolbar.Control.js index c2ce84091..6a9de1390 100644 --- a/src/draw/control/DrawToolbar.Control.js +++ b/src/draw/control/DrawToolbar.Control.js @@ -58,7 +58,7 @@ L.DrawToolbar.Control = L.Toolbar.Control.extend({ for (var type in this._actions) { if (this._actions.hasOwnProperty(type) && options.hasOwnProperty(type)) { - this._actions[type].setOptions(options[type]); + this._actions[type].drawHandler.setOptions(options[type]); } } } From dc7eb5388469deb278f5b57ca609ac1c2aaac94b Mon Sep 17 00:00:00 2001 From: jacobtoye Date: Thu, 21 May 2015 11:41:35 +1200 Subject: [PATCH 31/32] Updating include files for full example. --- examples/full.html | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/full.html b/examples/full.html index bec83b606..d09f22c7d 100644 --- a/examples/full.html +++ b/examples/full.html @@ -37,6 +37,7 @@ + From 635e02b696025d868a37d0018a014ed2b7b2212a Mon Sep 17 00:00:00 2001 From: nateemerson Date: Thu, 3 Sep 2015 14:10:19 -0700 Subject: [PATCH 32/32] Fixed toolbar removal --- src/Control.Draw.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Control.Draw.js b/src/Control.Draw.js index 32bba2d48..4ae2c6d14 100644 --- a/src/Control.Draw.js +++ b/src/Control.Draw.js @@ -51,10 +51,10 @@ L.Control.Draw = L.Control.extend({ 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]); } } },