[OpenLayers-Commits] r9791 - in trunk/openlayers: examples lib/OpenLayers/Control lib/OpenLayers/Handler tests/Control

commits-20090109 at openlayers.org commits-20090109 at openlayers.org
Tue Nov 10 06:14:28 EST 2009


Author: ahocevar
Date: 2009-11-10 06:14:28 -0500 (Tue, 10 Nov 2009)
New Revision: 9791
URL: http://trac.openlayers.org/changeset/9791

Added:
   trunk/openlayers/examples/document-drag.html
Modified:
   trunk/openlayers/lib/OpenLayers/Control/DragPan.js
   trunk/openlayers/lib/OpenLayers/Handler/Drag.js
   trunk/openlayers/tests/Control/DragPan.html
Log:
Added documentDrag option to the DragPan control and Drag handler. 
When set to true, this allow pan-dragging while outside the map. 
Thanks vmx for the initial patches. r=vmx, bartvde (closes #39)


Added: trunk/openlayers/examples/document-drag.html
===================================================================
--- trunk/openlayers/examples/document-drag.html	                        (rev 0)
+++ trunk/openlayers/examples/document-drag.html	2009-11-10 11:14:28 UTC (rev 9791)
@@ -0,0 +1,39 @@
+<html xmlns="http://www.w3.org/1999/xhtml">
+  <head>
+    <title>OpenLayers Document Drag Example</title>
+    <link rel="stylesheet" href="../theme/default/style.css" type="text/css" />
+    <link rel="stylesheet" href="style.css" type="text/css" />
+    <script src="../lib/OpenLayers.js"></script>
+    <script type="text/javascript">
+        var map, layer;
+        function init(){
+            map = new OpenLayers.Map( 'map', {controls: [
+                new OpenLayers.Control.Navigation(
+                    {dragPanOptions: {documentDrag: true}}
+                ),
+                new OpenLayers.Control.PanZoom(),
+                new OpenLayers.Control.ArgParser(),
+                new OpenLayers.Control.Attribution()
+            ]} );
+            layer = new OpenLayers.Layer.WMS( "OpenLayers WMS",
+                    "http://labs.metacarta.com/wms/vmap0",
+                    {layers: 'basic'} );
+            map.addLayer(layer);
+            map.zoomToMaxExtent();
+        }
+    </script>
+  </head>
+  <body onload="init()">
+    <h1 id="title">OpenLayers Document Drag Example</h1>
+
+    <div id="tags"></div>
+
+    <div id="shortdesc">Keep on dragging even when the mouse cursor moves outside of the map</div>
+
+    <div id="map" class="smallmap"></div>
+
+    <div id="docs">
+        This example shows how to make a map draggable outside of the map itself.
+    </div>
+  </body>
+</html>
\ No newline at end of file


Property changes on: trunk/openlayers/examples/document-drag.html
___________________________________________________________________
Added: svn:keywords
   + Id Author Date Revision
Added: svn:eol-style
   + native

Modified: trunk/openlayers/lib/OpenLayers/Control/DragPan.js
===================================================================
--- trunk/openlayers/lib/OpenLayers/Control/DragPan.js	2009-11-09 14:43:58 UTC (rev 9790)
+++ trunk/openlayers/lib/OpenLayers/Control/DragPan.js	2009-11-10 11:14:28 UTC (rev 9791)
@@ -34,9 +34,16 @@
      *     panning the map again. Set this to increase dragging performance.
      *     Defaults to 25 milliseconds.
      */
-    interval: 25, 
+    interval: 25,
     
     /**
+     * APIProperty: documentDrag
+     * {Boolean} If set to true, mouse dragging will continue even if the
+     *     mouse cursor leaves the map viewport. Default is false.
+     */
+    documentDrag: false,
+    
+    /**
      * Method: draw
      * Creates a Drag handler, using <panMap> and
      * <panMapDone> as callbacks.
@@ -46,7 +53,8 @@
                 "move": this.panMap,
                 "done": this.panMapDone
             }, {
-                interval: this.interval
+                interval: this.interval,
+                documentDrag: this.documentDrag
             }
         );
     },

Modified: trunk/openlayers/lib/OpenLayers/Handler/Drag.js
===================================================================
--- trunk/openlayers/lib/OpenLayers/Handler/Drag.js	2009-11-09 14:43:58 UTC (rev 9790)
+++ trunk/openlayers/lib/OpenLayers/Handler/Drag.js	2009-11-10 11:14:28 UTC (rev 9791)
@@ -83,6 +83,20 @@
      *     This is "private", and should be left alone.
      */
     timeoutId: null,
+    
+    /**
+     * APIProperty: documentDrag
+     * {Boolean} If set to true, the handler will also handle mouse moves when
+     *     the cursor has moved out of the map viewport. Default is false.
+     */
+    documentDrag: false,
+    
+    /**
+     * Property: documentEvents
+     * {<OpenLayers.Events>} Event instance for observing document events. Will
+     *     be set on mouseout if documentDrag is set to true.
+     */
+    documentEvents: null,
 
     /**
      * Constructor: OpenLayers.Handler.Drag
@@ -210,6 +224,16 @@
      */
     mousemove: function (evt) {
         if (this.started && !this.timeoutId && (evt.xy.x != this.last.x || evt.xy.y != this.last.y)) {
+            if(this.documentDrag === true && this.documentEvents) {
+                if(evt.element === document) {
+                    this.adjustXY(evt);
+                    // do setEvent manually because the documentEvents are not
+                    // registered with the map
+                    this.setEvent(evt);
+                } else {
+                    this.destroyDocumentEvents();
+                }
+            }
             if (this.interval > 0) {
                 this.timeoutId = setTimeout(OpenLayers.Function.bind(this.removeTimeout, this), this.interval);
             }
@@ -245,6 +269,10 @@
      */
     mouseup: function (evt) {
         if (this.started) {
+            if(this.documentDrag === true && this.documentEvents) {
+                this.adjustXY(evt);
+                this.destroyDocumentEvents();
+            }
             var dragged = (this.start != this.last);
             this.started = false;
             this.dragging = false;
@@ -273,20 +301,32 @@
      */
     mouseout: function (evt) {
         if (this.started && OpenLayers.Util.mouseLeft(evt, this.map.div)) {
-            var dragged = (this.start != this.last);
-            this.started = false; 
-            this.dragging = false;
-            OpenLayers.Element.removeClass(
-                this.map.viewPortDiv, "olDragDown"
-            );
-            this.out(evt);
-            this.callback("out", []);
-            if(dragged) {
-                this.callback("done", [evt.xy]);
+            if(this.documentDrag === true) {
+                this.documentEvents = new OpenLayers.Events(this, document,
+                                            null, null, {includeXY: true});
+                this.documentEvents.on({
+                    mousemove: this.mousemove,
+                    mouseup: this.mouseup
+                });
+                OpenLayers.Element.addClass(
+                    document.body, "olDragDown"
+                );
+            } else {
+                var dragged = (this.start != this.last);
+                this.started = false; 
+                this.dragging = false;
+                OpenLayers.Element.removeClass(
+                    this.map.viewPortDiv, "olDragDown"
+                );
+                this.out(evt);
+                this.callback("out", []);
+                if(dragged) {
+                    this.callback("done", [evt.xy]);
+                }
+                if(document.onselectstart) {
+                    document.onselectstart = this.oldOnselectstart;
+                }
             }
-            if(document.onselectstart) {
-                document.onselectstart = this.oldOnselectstart;
-            }
         }
         return true;
     },
@@ -345,6 +385,35 @@
         }
         return deactivated;
     },
+    
+    /**
+     * Method: adjustXY
+     * Converts event coordinates that are relative to the document body to
+     * ones that are relative to the map viewport. The latter is the default in
+     * OpenLayers.
+     * 
+     * Parameters:
+     * evt - {Object}
+     */
+    adjustXY: function(evt) {
+        var pos = OpenLayers.Util.pagePosition(this.map.div);
+        evt.xy.x -= pos[0];
+        evt.xy.y -= pos[1];
+    },
+    
+    /**
+     * Method: destroyDocumentEvents
+     * Destroys the events instance that gets added to the document body when
+     * documentDrag is true and the mouse cursor leaves the map viewport while
+     * dragging.
+     */
+    destroyDocumentEvents: function() {
+        OpenLayers.Element.removeClass(
+            document.body, "olDragDown"
+        );
+        this.documentEvents.destroy();
+        this.documentEvents = null;
+    },
 
     CLASS_NAME: "OpenLayers.Handler.Drag"
 });

Modified: trunk/openlayers/tests/Control/DragPan.html
===================================================================
--- trunk/openlayers/tests/Control/DragPan.html	2009-11-09 14:43:58 UTC (rev 9790)
+++ trunk/openlayers/tests/Control/DragPan.html	2009-11-10 11:14:28 UTC (rev 9791)
@@ -36,6 +36,28 @@
         t.eq(map.getCenter().lat, res * 5, "Lat is " + (res * 5) + " after drag");
         t.eq(map.getCenter().lon, res * -5, "Lon is " + (res * -5) + " after drag");
     }
+    function test_Control_DragPan_drag_documentDrag (t) {
+        t.plan(4);
+        control = new OpenLayers.Control.DragPan({documentDrag: true});
+        map = new OpenLayers.Map("map", {controls:[control]});
+        layer = new OpenLayers.Layer.WMS( "OpenLayers WMS",
+                    "http://labs.metacarta.com/wms/vmap0",
+                    {layers: 'basic'} );
+        map.addLayer(layer);
+        map.zoomToMaxExtent();
+        map.zoomIn();
+        control.activate();
+
+        res = map.baseLayer.resolutions[map.getZoom()];
+        t.eq(map.center.lat, 0, "Lat is 0 before drag");
+        t.eq(map.center.lon, 0, "Lon is 0 before drag");
+        map.events.triggerEvent('mousedown', {'type':'mousedown', 'xy':new OpenLayers.Pixel(0,0), 'which':1});
+        map.events.triggerEvent('mousemove', {'type':'mousemove', 'xy':new OpenLayers.Pixel(5,5), 'which':1});
+        map.events.triggerEvent('mouseup', {'type':'mouseup', 'xy':new OpenLayers.Pixel(5,5), 'which':1});
+        
+        t.eq(map.getCenter().lat, res * 5, "Lat is " + (res * 5) + " after drag");
+        t.eq(map.getCenter().lon, res * -5, "Lon is " + (res * -5) + " after drag");
+    }
     function test_Control_DragPan_click(t) {
         t.plan(1);
         var control = new OpenLayers.Control.DragPan();



More information about the Commits mailing list