From 805f3b39b9bb5b57f0fdd01b8154db40818f78b3 Mon Sep 17 00:00:00 2001 From: Matt Spence Date: Mon, 11 Apr 2011 16:26:41 +0100 Subject: [PATCH 1/4] Added draggability to markers --- src/dom/DomEvent.js | 17 +++++++++++++-- src/layer/marker/Marker.js | 42 +++++++++++++++++++++++++++++++++++--- src/map/Map.js | 1 + 3 files changed, 55 insertions(+), 5 deletions(-) diff --git a/src/dom/DomEvent.js b/src/dom/DomEvent.js index d259a694..c1f63575 100644 --- a/src/dom/DomEvent.js +++ b/src/dom/DomEvent.js @@ -35,6 +35,19 @@ L.DomEvent = { obj[key] = null; }, + fireEvent: function (/*HTMLElement*/ obj, /*String*/ type) { + if (document.createEventObject){ + // dispatch for IE + var evt = document.createEventObject(); + return obj.fireEvent('on'+type,evt) + } else{ + // dispatch for firefox + others + var evt = document.createEvent("HTMLEvents"); + evt.initEvent(type, true, true ); // event type,bubbling,cancelable + return !obj.dispatchEvent(evt); + } + }, + _getEvent: function()/*->Event*/ { var e = window.event; if (!e) { @@ -84,8 +97,8 @@ L.DomEvent = { getWheelDelta: function(e) { var delta = 0; if (e.wheelDelta) { delta = e.wheelDelta/120; } - if (e.detail) { delta = -e.detail/3; } - return delta; + if (e.detail) { delta = -e.detail/3; } + return delta; } }; diff --git a/src/layer/marker/Marker.js b/src/layer/marker/Marker.js index 074a8392..46e3fdce 100644 --- a/src/layer/marker/Marker.js +++ b/src/layer/marker/Marker.js @@ -8,12 +8,13 @@ L.Marker = L.Class.extend({ options: { icon: new L.Icon(), - clickable: true + clickable: true, + draggable: false }, initialize: function(latlng, options) { L.Util.setOptions(this, options); - this._latlng = latlng; + this._latlng = latlng; }, onAdd: function(map) { @@ -44,7 +45,8 @@ L.Marker = L.Class.extend({ }, getLatLng: function() { - return this._latlng; + var pos = L.DomUtil.getPosition(this._icon); + return this._map.layerPointToLatLng(pos); }, _reset: function() { @@ -57,16 +59,50 @@ L.Marker = L.Class.extend({ }, _initInteraction: function() { + if (this.options.clickable) { this._icon.className += ' leaflet-clickable'; L.DomEvent.addListener(this._icon, 'mousedown', this._fireMouseEvent, this); L.DomEvent.addListener(this._icon, 'click', this._fireMouseEvent, this); L.DomEvent.addListener(this._icon, 'dblclick', this._fireMouseEvent, this); } + + if (this.options.draggable) { + this._draggable = new L.Draggable(this._icon, this._icon); + this._draggable.on('dragstart', this._onDragStart, this); + this._draggable.on('drag', this._onDrag, this); + this._draggable.on('dragend', this._onDragEnd, this); + this._draggable.enable(); + } + }, _fireMouseEvent: function(e) { this.fire(e.type); + if (e.type == 'mouseup') { + // Draggable stops listening on document mouseup so because we are stopping propagation we will explicitaly fire it + L.DomEvent.fireEvent(document,'mouseup'); + } L.DomEvent.stopPropagation(e); + }, + + moved: function() { + return this._draggable._moved; + }, + + _onDragStart: function(e) { + this.fire('movestart',this); + this.fire('dragstart',"hello"); + }, + + _onDrag: function() { + this.fire('move',this); + this.fire('drag',this); + }, + + _onDragEnd: function() { + this.fire('moveend',this); + this.fire('dragend',this); } + }); \ No newline at end of file diff --git a/src/map/Map.js b/src/map/Map.js index abeb8287..286ec560 100644 --- a/src/map/Map.js +++ b/src/map/Map.js @@ -129,6 +129,7 @@ L.Map = L.Class.extend({ this.on('load', onMapLoad, this); } } + return this; }, From ee93d73b69f07eac7ee550074d06e5d026c6f306 Mon Sep 17 00:00:00 2001 From: Matt Spence Date: Mon, 11 Apr 2011 19:15:35 +0100 Subject: [PATCH 2/4] Refactored marker dragging into MarkerDrag and support for shadows --- src/core/Class.js | 3 +++ src/handler/Handler.js | 9 +++++-- src/handler/MapDrag.js | 1 + src/handler/MarkerDrag.js | 51 ++++++++++++++++++++++++++++++++++++++ src/layer/marker/Marker.js | 34 ++++++++----------------- src/map/Map.js | 1 + 6 files changed, 73 insertions(+), 26 deletions(-) create mode 100644 src/handler/MarkerDrag.js diff --git a/src/core/Class.js b/src/core/Class.js index 5ae58a3a..09a9e539 100644 --- a/src/core/Class.js +++ b/src/core/Class.js @@ -24,6 +24,9 @@ L.Class.extend = function(/*Object*/ props) /*-> Class*/ { // add superclass access proto.superclass = this.prototype; + // add class name + //proto.className = props; + // mix static properties into the class if (props.statics) { L.Util.extend(NewClass, props.statics); diff --git a/src/handler/Handler.js b/src/handler/Handler.js index 195986b8..4e6f207d 100644 --- a/src/handler/Handler.js +++ b/src/handler/Handler.js @@ -3,8 +3,13 @@ */ L.Handler = L.Class.extend({ - initialize: function(map) { - this._map = map; + initialize: function(handlee) { + // not sure this is the best name for this property + this._handlee = handlee; + // this ensures map handles looking for ._map can still find it + // I would remove this and change them but with out full test coverage + // am worried I will break something + this._map = handlee; }, enabled: function() { diff --git a/src/handler/MapDrag.js b/src/handler/MapDrag.js index 997a66ad..49c47af6 100644 --- a/src/handler/MapDrag.js +++ b/src/handler/MapDrag.js @@ -3,6 +3,7 @@ */ L.Handler.MapDrag = L.Handler.extend({ + enable: function() { if (this._enabled) { return; } if (!this._draggable) { diff --git a/src/handler/MarkerDrag.js b/src/handler/MarkerDrag.js new file mode 100644 index 00000000..960489af --- /dev/null +++ b/src/handler/MarkerDrag.js @@ -0,0 +1,51 @@ +/* + * L.Handler.MarkerDrag is used internally by L.Marker to make the markers draggable. + */ + +L.Handler.MarkerDrag = L.Handler.extend({ + + enable: function() { + if (this._enabled) { return; } + if (!this._draggable) { + this._draggable = new L.Draggable(this._handlee._icon, this._handlee._icon); + this._draggable.on('dragstart', this._onDragStart, this); + this._draggable.on('drag', this._onDrag, this); + this._draggable.on('dragend', this._onDragEnd, this); + } + this._draggable.enable(); + this._enabled = true; + }, + + disable: function() { + if (!this._enabled) { return; } + this._draggable.disable(); + this._enabled = false; + }, + + moved: function() { + return this._draggable._moved; + }, + + _onDragStart: function(e) { + this._handlee.fire('movestart',this); + this._handlee.fire('dragstart',"hello"); + this._dragStartShadowPos = L.DomUtil.getPosition(this._handlee._shadow); + }, + + _onDrag: function(e) { + + // update shadow position + var newShadowPos = this._dragStartShadowPos.add(e.target._offset); + L.DomUtil.setPosition(this._handlee._shadow, newShadowPos); + + this._handlee.fire('move',this); + this._handlee.fire('drag',this); + + }, + + _onDragEnd: function() { + this._handlee.fire('moveend',this); + this._handlee.fire('dragend',this); + } + +}); diff --git a/src/layer/marker/Marker.js b/src/layer/marker/Marker.js index 46e3fdce..64655fb8 100644 --- a/src/layer/marker/Marker.js +++ b/src/layer/marker/Marker.js @@ -4,6 +4,7 @@ L.Marker = L.Class.extend({ + includes: L.Mixin.Events, options: { @@ -67,22 +68,21 @@ L.Marker = L.Class.extend({ L.DomEvent.addListener(this._icon, 'dblclick', this._fireMouseEvent, this); } - if (this.options.draggable) { - this._draggable = new L.Draggable(this._icon, this._icon); - this._draggable.on('dragstart', this._onDragStart, this); - this._draggable.on('drag', this._onDrag, this); - this._draggable.on('dragend', this._onDragEnd, this); - this._draggable.enable(); + var handlers = { + draggable: L.Handler.MarkerDrag + } + + for (var i in handlers) { + if (handlers.hasOwnProperty(i) && handlers[i]) { + this[i] = new handlers[i](this); + if (this.options[i]) this[i].enable(); + } } }, _fireMouseEvent: function(e) { this.fire(e.type); - if (e.type == 'mouseup') { - // Draggable stops listening on document mouseup so because we are stopping propagation we will explicitaly fire it - L.DomEvent.fireEvent(document,'mouseup'); - } L.DomEvent.stopPropagation(e); }, @@ -90,19 +90,5 @@ L.Marker = L.Class.extend({ return this._draggable._moved; }, - _onDragStart: function(e) { - this.fire('movestart',this); - this.fire('dragstart',"hello"); - }, - - _onDrag: function() { - this.fire('move',this); - this.fire('drag',this); - }, - - _onDragEnd: function() { - this.fire('moveend',this); - this.fire('dragend',this); - } }); \ No newline at end of file diff --git a/src/map/Map.js b/src/map/Map.js index 286ec560..49b14e71 100644 --- a/src/map/Map.js +++ b/src/map/Map.js @@ -3,6 +3,7 @@ */ L.Map = L.Class.extend({ + includes: L.Mixin.Events, options: { From 7162bd493062215c0fd88a98dce34b32ca17006c Mon Sep 17 00:00:00 2001 From: mourner Date: Mon, 11 Apr 2011 23:43:23 +0300 Subject: [PATCH 3/4] refactor popup code, merge marker dragging from msaspence --- build/build.bat | 1 + build/deps.js | 8 +++++++- debug/include.js | 1 + src/dom/DomEvent.js | 13 ------------ src/handler/Handler.js | 11 +++-------- src/handler/MarkerDrag.js | 31 ++++++++++++++++------------- src/layer/Popup.js | 26 ++++++++++++++++++++---- src/layer/marker/Marker.Popup.js | 16 ++++++++++----- src/layer/marker/Marker.js | 34 +++++++++++--------------------- src/layer/vector/Path.Popup.js | 10 +++------- src/map/Map.js | 2 +- 11 files changed, 78 insertions(+), 75 deletions(-) diff --git a/build/build.bat b/build/build.bat index 55c6a25e..15c70e3f 100644 --- a/build/build.bat +++ b/build/build.bat @@ -37,6 +37,7 @@ java -jar ../lib/closure-compiler/compiler.jar ^ --js ../src/handler/ScrollWheelZoom.js ^ --js ../src/handler/DoubleClickZoom.js ^ --js ../src/handler/ShiftDragZoom.js ^ +--js ../src/handler/MarkerDrag.js ^ --js ../src/control/Control.js ^ --js ../src/control/Control.Zoom.js ^ --js ../src/map/Map.js ^ diff --git a/build/deps.js b/build/deps.js index 0fd6496e..9a36a775 100644 --- a/build/deps.js +++ b/build/deps.js @@ -75,7 +75,7 @@ var deps = { 'dom/Draggable.js', 'handler/Handler.js', 'handler/MapDrag.js'], - desc: 'Makes the map draggable (on both desktop and mobile webkit browsers).', + desc: 'Makes the map draggable (by mouse or touch).', heading: 'Interaction' }, @@ -100,6 +100,12 @@ var deps = { desc: 'Enables zooming to bounding box by shift-dragging the map.' }, + MarkerDrag: { + src: ['handler/MarkerDrag.js'], + desc: 'Makes markers draggable (by mouse or touch).' + }, + + ControlZoom: { src: ['control/Control.js', 'map/ext/Map.Control.js', diff --git a/debug/include.js b/debug/include.js index c8d23faa..f9f729b3 100644 --- a/debug/include.js +++ b/debug/include.js @@ -47,6 +47,7 @@ 'handler/DoubleClickZoom.js', 'handler/ScrollWheelZoom.js', 'handler/ShiftDragZoom.js', + 'handler/MarkerDrag.js', 'control/Control.js', 'control/Control.Zoom.js', diff --git a/src/dom/DomEvent.js b/src/dom/DomEvent.js index c1f63575..08d7fa93 100644 --- a/src/dom/DomEvent.js +++ b/src/dom/DomEvent.js @@ -35,19 +35,6 @@ L.DomEvent = { obj[key] = null; }, - fireEvent: function (/*HTMLElement*/ obj, /*String*/ type) { - if (document.createEventObject){ - // dispatch for IE - var evt = document.createEventObject(); - return obj.fireEvent('on'+type,evt) - } else{ - // dispatch for firefox + others - var evt = document.createEvent("HTMLEvents"); - evt.initEvent(type, true, true ); // event type,bubbling,cancelable - return !obj.dispatchEvent(evt); - } - }, - _getEvent: function()/*->Event*/ { var e = window.event; if (!e) { diff --git a/src/handler/Handler.js b/src/handler/Handler.js index 4e6f207d..c38a6b6a 100644 --- a/src/handler/Handler.js +++ b/src/handler/Handler.js @@ -1,15 +1,10 @@ /* - * L.Handler classes are used internally to inject interaction features to the Map class. + * L.Handler classes are used internally to inject interaction features to classes like Map and Marker. */ L.Handler = L.Class.extend({ - initialize: function(handlee) { - // not sure this is the best name for this property - this._handlee = handlee; - // this ensures map handles looking for ._map can still find it - // I would remove this and change them but with out full test coverage - // am worried I will break something - this._map = handlee; + initialize: function(map) { + this._map = map; }, enabled: function() { diff --git a/src/handler/MarkerDrag.js b/src/handler/MarkerDrag.js index 960489af..a19922b5 100644 --- a/src/handler/MarkerDrag.js +++ b/src/handler/MarkerDrag.js @@ -3,11 +3,14 @@ */ L.Handler.MarkerDrag = L.Handler.extend({ - + initialize: function(marker) { + this._marker = marker; + }, + enable: function() { if (this._enabled) { return; } if (!this._draggable) { - this._draggable = new L.Draggable(this._handlee._icon, this._handlee._icon); + this._draggable = new L.Draggable(this._marker._icon, this._marker._icon); this._draggable.on('dragstart', this._onDragStart, this); this._draggable.on('drag', this._onDrag, this); this._draggable.on('dragend', this._onDragEnd, this); @@ -27,25 +30,25 @@ L.Handler.MarkerDrag = L.Handler.extend({ }, _onDragStart: function(e) { - this._handlee.fire('movestart',this); - this._handlee.fire('dragstart',"hello"); - this._dragStartShadowPos = L.DomUtil.getPosition(this._handlee._shadow); + this._marker.closePopup(); + + this._marker.fire('movestart'); + this._marker.fire('dragstart'); }, _onDrag: function(e) { - // update shadow position - var newShadowPos = this._dragStartShadowPos.add(e.target._offset); - L.DomUtil.setPosition(this._handlee._shadow, newShadowPos); - - this._handlee.fire('move',this); - this._handlee.fire('drag',this); + var iconPos = L.DomUtil.getPosition(this._marker._icon); + L.DomUtil.setPosition(this._marker._shadow, iconPos); + this._marker._latlng = this._marker._map.layerPointToLatLng(iconPos); + + this._marker.fire('move'); + this._marker.fire('drag'); }, _onDragEnd: function() { - this._handlee.fire('moveend',this); - this._handlee.fire('dragend',this); + this._marker.fire('moveend'); + this._marker.fire('dragend'); } - }); diff --git a/src/layer/Popup.js b/src/layer/Popup.js index 8d3a970a..bf67d611 100644 --- a/src/layer/Popup.js +++ b/src/layer/Popup.js @@ -12,10 +12,8 @@ L.Popup = L.Class.extend({ autoPanPadding: new L.Point(5, 5) }, - initialize: function(latlng, content, options) { + initialize: function(options) { L.Util.setOptions(this, options); - this._latlng = latlng; - this._content = content; }, onAdd: function(map) { @@ -33,6 +31,8 @@ L.Popup = L.Class.extend({ this._update(); this._container.style.opacity = '1'; //TODO fix ugly opacity hack + + this._opened = true; }, onRemove: function(map) { @@ -41,10 +41,28 @@ L.Popup = L.Class.extend({ map.off('click', this._close, this); this._container.style.opacity = '0'; + + this._opened = false; + }, + + setLatLng: function(latlng) { + this._latlng = latlng; + if (this._opened) { + this._update(); + } + }, + + setContent: function(content) { + this._content = content; + if (this._opened) { + this._update(); + } }, _close: function() { - this._map.removeLayer(this); + if (this._opened) { + this._map.removeLayer(this); + } }, _initLayout: function() { diff --git a/src/layer/marker/Marker.Popup.js b/src/layer/marker/Marker.Popup.js index b63542ac..4c5cad04 100644 --- a/src/layer/marker/Marker.Popup.js +++ b/src/layer/marker/Marker.Popup.js @@ -4,17 +4,23 @@ L.Marker.include({ openPopup: function() { - this._map.closePopup(); - if (this._popup) { - this._map.openPopup(this._popup); - } + this._popup.setLatLng(this._latlng); + this._map.openPopup(this._popup); + return this; }, + closePopup: function() { + if (this._popup) { + this._popup._close(); + } + }, + bindPopup: function(content, options) { options = L.Util.extend({offset: this.options.icon.popupAnchor}, options); - this._popup = new L.Popup(this._latlng, content, options); + this._popup = new L.Popup(options); + this._popup.setContent(content); this.on('click', this.openPopup, this); return this; diff --git a/src/layer/marker/Marker.js b/src/layer/marker/Marker.js index 64655fb8..9367ce00 100644 --- a/src/layer/marker/Marker.js +++ b/src/layer/marker/Marker.js @@ -2,7 +2,6 @@ * L.Marker is used to display clickable/draggable icons on the map. */ - L.Marker = L.Class.extend({ includes: L.Mixin.Events, @@ -46,8 +45,7 @@ L.Marker = L.Class.extend({ }, getLatLng: function() { - var pos = L.DomUtil.getPosition(this._icon); - return this._map.layerPointToLatLng(pos); + return this._latlng; }, _reset: function() { @@ -60,35 +58,27 @@ L.Marker = L.Class.extend({ }, _initInteraction: function() { - if (this.options.clickable) { this._icon.className += ' leaflet-clickable'; L.DomEvent.addListener(this._icon, 'mousedown', this._fireMouseEvent, this); - L.DomEvent.addListener(this._icon, 'click', this._fireMouseEvent, this); + L.DomEvent.addListener(this._icon, 'click', this._onMouseClick, this); L.DomEvent.addListener(this._icon, 'dblclick', this._fireMouseEvent, this); } - var handlers = { - draggable: L.Handler.MarkerDrag + if (this.options.draggable) { + this.dragging = new L.Handler.MarkerDrag(this); + this.dragging.enable(); } - - for (var i in handlers) { - if (handlers.hasOwnProperty(i) && handlers[i]) { - this[i] = new handlers[i](this); - if (this.options[i]) this[i].enable(); - } - } - + }, + + _onMouseClick: function(e) { + L.DomEvent.stopPropagation(e); + if (this.dragging && this.dragging.moved()) { return; } + this.fire(e.type); }, _fireMouseEvent: function(e) { this.fire(e.type); L.DomEvent.stopPropagation(e); - }, - - moved: function() { - return this._draggable._moved; - }, - - + } }); \ No newline at end of file diff --git a/src/layer/vector/Path.Popup.js b/src/layer/vector/Path.Popup.js index b1f1eeb1..1934fc32 100644 --- a/src/layer/vector/Path.Popup.js +++ b/src/layer/vector/Path.Popup.js @@ -4,18 +4,14 @@ L.Path.include({ bindPopup: function(content, options) { - this._popup = new L.Popup(null, content, options); + this._popup = new L.Popup(options); + this._popup.setContent(content); this.on('click', this._openPopup, this); return this; }, _openPopup: function(e) { - this._popup._latlng = e.position; - if (this._popup._map) { - this._popup._updatePosition(); - } - - this._map.closePopup(); + this._popup.setLatLng(e.position); this._map.openPopup(this._popup); } }); \ No newline at end of file diff --git a/src/map/Map.js b/src/map/Map.js index 49b14e71..16ad44ca 100644 --- a/src/map/Map.js +++ b/src/map/Map.js @@ -3,7 +3,6 @@ */ L.Map = L.Class.extend({ - includes: L.Mixin.Events, options: { @@ -353,6 +352,7 @@ L.Map = L.Class.extend({ }, _onMouseClick: function(e) { + console.log(e); if (this.dragging && this.dragging.moved()) { return; } this._fireMouseEvent(e); }, From ef8b0c9a9b81af0ae529497e63f6ecdb71199a01 Mon Sep 17 00:00:00 2001 From: mourner Date: Mon, 11 Apr 2011 23:51:56 +0300 Subject: [PATCH 4/4] oops, remove console.log --- src/map/Map.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/map/Map.js b/src/map/Map.js index 16ad44ca..286ec560 100644 --- a/src/map/Map.js +++ b/src/map/Map.js @@ -352,7 +352,6 @@ L.Map = L.Class.extend({ }, _onMouseClick: function(e) { - console.log(e); if (this.dragging && this.dragging.moved()) { return; } this._fireMouseEvent(e); },