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

commits-20090109 at openlayers.org commits-20090109 at openlayers.org
Sun Feb 27 10:00:43 EST 2011


Author: ahocevar
Date: 2011-02-27 07:00:38 -0800 (Sun, 27 Feb 2011)
New Revision: 11563

Modified:
   trunk/openlayers/lib/OpenLayers/Handler/Path.js
   trunk/openlayers/lib/OpenLayers/Handler/Point.js
   trunk/openlayers/lib/OpenLayers/Handler/Polygon.js
   trunk/openlayers/tests/Control/Measure.html
   trunk/openlayers/tests/Handler/Path.html
   trunk/openlayers/tests/Handler/Point.html
   trunk/openlayers/tests/Handler/Polygon.html
Log:
making drawing handler work on touch devices. p=sbrunner, r=me (closes #3072)

Modified: trunk/openlayers/lib/OpenLayers/Handler/Path.js
===================================================================
--- trunk/openlayers/lib/OpenLayers/Handler/Path.js	2011-02-27 14:54:33 UTC (rev 11562)
+++ trunk/openlayers/lib/OpenLayers/Handler/Path.js	2011-02-27 15:00:38 UTC (rev 11563)
@@ -223,12 +223,12 @@
      * Returns: 
      * {Boolean} Allow event propagation
      */
-    mousedown: function(evt) {
+    down: function(evt) {
         var stopDown = this.stopDown;
         if(this.freehandMode(evt)) {
             stopDown = true;
         }
-        if(!this.lastDown || !this.lastDown.equals(evt.xy)) {
+        if (!this.touch && (!this.lastDown || !this.passesTolerance(this.lastDown, evt.xy, this.pixelTolerance))) {
             this.modifyFeature(evt.xy, !!this.lastUp);
         }
         this.mouseDown = true;
@@ -248,7 +248,7 @@
      * Returns: 
      * {Boolean} Allow event propagation
      */
-    mousemove: function (evt) {
+    move: function (evt) {
         if(this.stoppedDown && this.freehandMode(evt)) {
             if(this.persist) {
                 this.destroyPersistedFeature();
@@ -256,7 +256,7 @@
             this.addPoint(evt.xy);
             return false;
         }
-        if(!this.mouseDown || this.stoppedDown) {
+        if (!this.touch && (!this.mouseDown || this.stoppedDown)) {
             this.modifyFeature(evt.xy, !!this.lastUp);
         }
         return true;
@@ -273,13 +273,17 @@
      * Returns: 
      * {Boolean} Allow event propagation
      */
-    mouseup: function (evt) {
-        if(this.mouseDown && (!this.lastUp || !this.lastUp.equals(evt.xy))) {
+    up: function (evt) {
+        if (this.mouseDown && (!this.lastUp || !this.passesTolerance(
+                this.lastUp, evt.xy, this.dblclickTolerance))) {
             if(this.stoppedDown && this.freehandMode(evt)) {
                 this.removePoint();
                 this.finalize();
             } else {
-                if(this.lastDown.equals(evt.xy)) {
+                if (this.passesTolerance(this.lastDown, evt.xy, this.pixelTolerance)) {
+                    if (this.touch) {
+                        this.modifyFeature(evt.xy);
+                    }
                     if(this.lastUp == null && this.persist) {
                         this.destroyPersistedFeature();
                     }
@@ -290,10 +294,18 @@
         }
         this.stoppedDown = this.stopDown;
         this.mouseDown = false;
-        return !this.stopUp;
+        return !this.stopUp && !this.isDblclick;
     },
 
     /**
+     * Method: finishTouchGeometry
+     * Finish the geometry and send it back to the control.
+     */
+    finishTouchGeometry: function() {
+        this.finishGeometry();
+    },
+
+    /**
      * APIMethod: finishGeometry
      * Finish the geometry and send it back to the control.
      */

Modified: trunk/openlayers/lib/OpenLayers/Handler/Point.js
===================================================================
--- trunk/openlayers/lib/OpenLayers/Handler/Point.js	2011-02-27 14:54:33 UTC (rev 11562)
+++ trunk/openlayers/lib/OpenLayers/Handler/Point.js	2011-02-27 15:00:38 UTC (rev 11563)
@@ -95,8 +95,51 @@
      * {Object} Any optional properties to be set on the sketch layer.
      */
     layerOptions: null,
+    
+    /**
+     * APIProperty: pixelTolerance
+     * {Number} Maximum number of pixels between mouseup and mousedown for an
+     *     event to be considered a click.  Default is 5.  If set to an
+     *     integer value, clicks with a drag greater than the value will be
+     *     ignored.  This property can only be set when the handler is
+     *     constructed.
+     */
+    pixelTolerance: 5,
 
     /**
+     * APIProperty: dblclickTolerance
+     * {Number} Maximum number of pixels between two touchend for an
+     *     event to be considered a dblclick.  Default is 20.
+     */
+    dblclickTolerance: 20,
+
+    /**
+     * Property: touch
+     * {Boolean} Indcates the support of touch events.
+     */
+    touch: false,
+
+    /**
+     * Property: timerId
+     * {Integer} The timer used to test the double touch.
+     */
+    timerId: null,
+
+    /**
+     * Property: last
+     * {<OpenLayers.Pixel>} The last pixel used to know the distance between
+     * two touches (for double touch).
+     */
+    last: null,
+
+    /**
+     * Property: dblclick
+     * {Boolean} The current event is a dblclick.
+     */
+    isDblclick: false,
+    
+    
+    /**
      * Constructor: OpenLayers.Handler.Point
      * Create a new point handler.
      *
@@ -214,6 +257,14 @@
     },
 
     /**
+     * Method: finishTouchGeometry
+     * Finish the geometry and send it back to the control.
+     */
+    finishTouchGeometry: function() {
+        this.finalize();
+    },
+    
+    /**
      * Method: finalize
      * Finish the geometry and call the "done" callback.
      *
@@ -333,6 +384,127 @@
         var geom = this.getGeometry();
         return geom && geom.clone();
     },
+
+    /**
+     * Method: mousedown
+     * Handle mousedown.
+     * 
+     * Parameters:
+     * evt - {Event} The browser event
+     *
+     * Returns: 
+     * {Boolean} Allow event propagation
+     */
+    mousedown: function(evt) {
+        if (this.touch) {
+            return;
+        }
+        return this.down(evt);
+    },
+
+    /**
+     * Method: touchstart
+     * Handle touchstart.
+     * 
+     * Parameters:
+     * evt - {Event} The browser event
+     *
+     * Returns: 
+     * {Boolean} Allow event propagation
+     */
+    touchstart: function(evt) {
+        this.touch = true;
+
+        var last = this.last;
+        this.last = evt.xy;
+
+        if (this.timerId &&
+                this.passesTolerance(last, evt.xy, this.dblclickTolerance)) {
+            this.isDblclick = true;
+            // a valid touch immediately adds a component and leaves us with a
+            // complete geometry
+            this.finishTouchGeometry();
+            window.clearTimeout(this.timerId);
+            this.timerId = null;
+            return false;
+        }
+        else {
+            if (this.timerId) {
+                window.clearTimeout(this.timerId);
+                this.timerId = null;
+            }
+            this.isDblclick = false;
+            this.timerId = window.setTimeout(
+                OpenLayers.Function.bind(function() {
+                    this.timerId = null;
+                }, this), 300);
+            return this.down(evt);
+        }
+    },
+
+    /**
+     * Method: mousemove
+     * Handle mousemove.
+     * 
+     * Parameters:
+     * evt - {Event} The browser event
+     *
+     * Returns: 
+     * {Boolean} Allow event propagation
+     */
+    mousemove: function(evt) {
+        if (this.touch) {
+            return;
+        }
+        return this.move(evt);
+    },
+
+    /**
+     * Method: touchmove
+     * Handle touchmove.
+     * 
+     * Parameters:
+     * evt - {Event} The browser event
+     *
+     * Returns: 
+     * {Boolean} Allow event propagation
+     */
+    touchmove: function(evt) {
+        this.last = evt.xy;
+        return this.move(evt);
+    },
+
+    /**
+     * Method: mouseup
+     * Handle mouseup.
+     * 
+     * Parameters:
+     * evt - {Event} The browser event
+     *
+     * Returns: 
+     * {Boolean} Allow event propagation
+     */
+    mouseup: function(evt) {
+        if (this.touch) {
+            return;
+        }
+        return this.up(evt);
+    },
+
+    /**
+     * Method: touchend
+     * Handle touchend.
+     * 
+     * Parameters:
+     * evt - {Event} The browser event
+     *
+     * Returns: 
+     * {Boolean} Allow event propagation
+     */
+    touchend: function(evt) {
+        evt.xy = this.last;
+        return this.up(evt);
+    },
   
     /**
      * Method: mousedown
@@ -345,10 +517,12 @@
      * Returns: 
      * {Boolean} Allow event propagation
      */
-    mousedown: function(evt) {
+    down: function(evt) {
         this.mouseDown = true;
         this.lastDown = evt.xy;
-        this.modifyFeature(evt.xy);
+        if (!this.touch) {
+            this.modifyFeature(evt.xy);
+        }
         this.stoppedDown = this.stopDown;
         return !this.stopDown;
     },
@@ -364,8 +538,8 @@
      * Returns: 
      * {Boolean} Allow event propagation
      */
-    mousemove: function (evt) {
-        if(!this.mouseDown || this.stoppedDown) {
+    move: function (evt) {
+        if(!this.touch && (!this.mouseDown || this.stoppedDown)) {
             this.modifyFeature(evt.xy);
         }
         return true;
@@ -382,18 +556,24 @@
      * Returns: 
      * {Boolean} Allow event propagation
      */
-    mouseup: function (evt) {
+    up: function (evt) {
         this.mouseDown = false;
         this.stoppedDown = this.stopDown;
+
         // check keyboard modifiers
         if(!this.checkModifiers(evt)) {
             return true;
         }
         // ignore double-clicks
-        if(this.lastUp && this.lastUp.equals(evt.xy)) {
+        if (this.lastUp && this.passesTolerance(this.lastUp, evt.xy,
+                                                    this.dblclickTolerance)) {
             return true;
         }
-        if(this.lastDown && this.lastDown.equals(evt.xy)) {
+        if (this.lastDown && this.passesTolerance(this.lastDown, evt.xy,
+                                                    this.pixelTolerance)) {
+            if (this.touch) {
+                this.modifyFeature(evt.xy);
+            }
             if(this.persist) {
                 this.destroyPersistedFeature();
             }
@@ -420,5 +600,28 @@
         }
     },
 
+    /**
+     * Method: passesTolerance
+     * Determine whether the event is within the optional pixel tolerance.
+     * Note that the pixel tolerance check only works if mousedown events get
+     * to the listeners registered here.  If they are stopped by other
+     * elements, <pixelTolerance> and <dblclickTolerance> will have no effect
+     * here (this method will always return true).
+     *
+     * Returns:
+     * {Boolean} The click is within the pixel tolerance (if specified).
+     */
+    passesTolerance: function(pixel1, pixel2, tolerance) {
+        var passes = true;
+
+        if (tolerance != null && pixel1 && pixel2) {
+            var dist = pixel1.distanceTo(pixel2);
+            if (dist > tolerance) {
+                passes = false;
+            }
+        }
+        return passes;
+    },
+    
     CLASS_NAME: "OpenLayers.Handler.Point"
 });

Modified: trunk/openlayers/lib/OpenLayers/Handler/Polygon.js
===================================================================
--- trunk/openlayers/lib/OpenLayers/Handler/Polygon.js	2011-02-27 14:54:33 UTC (rev 11562)
+++ trunk/openlayers/lib/OpenLayers/Handler/Polygon.js	2011-02-27 15:00:38 UTC (rev 11563)
@@ -148,8 +148,19 @@
             point.y = last.y;
         }
     },
-    
+
     /**
+     * Method: finishTouchGeometry
+     * Finish the geometry and send it back to the control.
+     */
+    finishTouchGeometry: function() {
+        var index = this.line.geometry.components.length - 2;
+        this.line.geometry.removeComponent(this.line.geometry.components[index]);
+        this.removePoint();
+        this.finalize();
+    },
+
+    /**
      * Method: finalizeInteriorRing
      * Enforces that new ring has some area and doesn't contain vertices of any
      *     other rings.

Modified: trunk/openlayers/tests/Control/Measure.html
===================================================================
--- trunk/openlayers/tests/Control/Measure.html	2011-02-27 14:54:33 UTC (rev 11562)
+++ trunk/openlayers/tests/Control/Measure.html	2011-02-27 15:00:38 UTC (rev 11563)
@@ -96,6 +96,10 @@
                     measure: function(evt){
                         log.push(evt);
                     }
+                },
+                handlerOptions: {
+                    pixelTolerance: 0,
+                    dblclickTolerance: 0
                 }
             }
         );
@@ -131,8 +135,8 @@
             // wait for delay then confirm event was logged
             delay, function() {
                 t.eq(log.length, 1, "a) event logged")
-                t.ok(log[0] && log[0].type == "measurepartial", "a) event logged");
-                t.ok(log[0] && log[0].measure == 10, "a) correct measure");
+                t.eq(log[0] && log[0].type, "measurepartial", "a) event logged");
+                t.eq(log[0] && log[0].measure, 10, "a) correct measure");
                 
                 // b) move 10 pixels and click
                 trigger("mousemove", 0, 20);
@@ -145,8 +149,8 @@
             },
             delay, function() {
                 t.eq(log.length, 2, "b) event logged");
-                t.ok(log[1] && log[1].type == "measurepartial", "b) correct type");
-                t.ok(log[1] && log[1].measure == 20, "b) correct measure");
+                t.eq(log[1] && log[1].type, "measurepartial", "b) correct type");
+                t.eq(log[1] && log[1].measure, 20, "b) correct measure");
 
                 // c) move 10 pixels and click
                 trigger("mousemove", 0, 30);
@@ -161,8 +165,8 @@
             // wait for rest of delay and confirm event logged
             delay / 2, function() {
                 t.eq(log.length, 3, "c) event logged");
-                t.ok(log[2] && log[2].type == "measurepartial", "c) correct type");
-                t.ok(log[2] && log[2].measure == 30, "c) correct measure");
+                t.eq(log[2] && log[2].type, "measurepartial", "c) correct type");
+                t.eq(log[2] && log[2].measure, 30, "c) correct measure");
                 
                 // d) move 10 pixels and click
                 trigger("mousemove", 0, 40);
@@ -176,8 +180,8 @@
                 trigger("dblclick", 0, 40);
 
                 t.eq(log.length, 4, "e) event logged");
-                t.ok(log[3] && log[3].type == "measure", "e) correct type");
-                t.ok(log[3] && log[3].measure == 40, "e) correct measure");                
+                t.eq(log[3] && log[3].type, "measure", "e) correct type");
+                t.eq(log[3] && log[3].measure, 40, "e) correct measure");                
             },
             // wait for rest of delay and confirm no measurepartial logged
             delay, function() {
@@ -198,22 +202,22 @@
                 trigger("mousemove", 10, 0);
 
                 t.eq(log.length, 1, "g) event logged");
-                t.ok(log[0] && log[0].type == "measurepartial", "g) correct type");
-                t.ok(log[0] && log[0].measure == 10, "g) correct measure");
+                t.eq(log[0] && log[0].type, "measurepartial", "g) correct type");
+                t.eq(log[0] && log[0].measure, 10, "g) correct measure");
                 
                 // h) move 10 pixels
                 trigger("mousemove", 20, 0);
 
                 t.eq(log.length, 2, "h) event logged");
-                t.ok(log[1] && log[1].type == "measurepartial", "h) correct type");
-                t.ok(log[1] && log[1].measure == 20, "h) correct measure");
+                t.eq(log[1] && log[1].type, "measurepartial", "h) correct type");
+                t.eq(log[1] && log[1].measure, 20, "h) correct measure");
 
                 // i) mouse up to finish
                 trigger("mouseup", 20, 0);
 
                 t.eq(log.length, 3, "i) event logged");
-                t.ok(log[2] && log[2].type == "measure", "i) correct type");
-                t.ok(log[2] && log[2].measure == 20, "i) correct measure");
+                t.eq(log[2] && log[2].type, "measure", "i) correct type");
+                t.eq(log[2] && log[2].measure, 20, "i) correct measure");
 
                 // j) clean up
                 log = [];
@@ -254,6 +258,10 @@
                     measure: function(evt){
                         log.push(evt);
                     }
+                },
+                handlerOptions: {
+                    pixelTolerance: 0,
+                    dblclickTolerance: 0
                 }
             }
         );
@@ -296,10 +304,10 @@
 
                 // confirm measurepartial is fired 2 times
                 t.eq(log.length, 3, "b) event logged");
-                t.ok(log[1] && log[1].type == "measurepartial", "b) correct type");
-                t.ok(log[1] && log[1].measure == 20, "b) correct measure");
-                t.ok(log[2] && log[2].type == "measurepartial", "c) correct type");
-                t.ok(log[2] && log[2].measure == 30, "c) correct measure");
+                t.eq(log[1] && log[1].type, "measurepartial", "b) correct type");
+                t.eq(log[1] && log[1].measure, 20, "b) correct measure");
+                t.eq(log[2] && log[2].type, "measurepartial", "c) correct type");
+                t.eq(log[2] && log[2].measure, 30, "c) correct measure");
 
                 // d) switch immediate measurement off
                 control.setImmediate(false);
@@ -346,23 +354,23 @@
                 t.eq(log.length, 7, "i) no event fired yet");
             },
             delay, function() {
-                t.eq(log.length, 8, "i) event logged");
-                t.eq(log[7] && log[7].type, "measurepartial", "i) correct type");
-                t.eq(log[7] && log[7].measure, 60, "i) correct measure");
+                t.eq(log.length, 8, "j) event logged");
+                t.eq(log[7] && log[7].type, "measurepartial", "j) correct type");
+                t.eq(log[7] && log[7].measure, 60, "j) correct measure");
 
                 trigger("dblclick", 0, 60);
-                t.eq(log.length, 9, "i) event logged");
-                t.eq(log[8] && log[8].type, "measure", "i) correct type");
-                t.eq(log[8] && log[8].measure, 60, "i) correct measure");
+                t.eq(log.length, 9, "k) event logged");
+                t.eq(log[8] && log[8].type, "measure", "k) correct type");
+                t.eq(log[8] && log[8].measure, 60, "k) correct measure");
                 // clear log
                 log = [];
 
-                // j) clean up
+                // l) clean up
                 map.destroy();
                 // wait for delay and confirm event not logged
             },
             delay, function() {
-                t.eq(log.length, 0, "j) no event fired after destroy");
+                t.eq(log.length, 0, "l) no event fired after destroy");
             }
         );
     }

Modified: trunk/openlayers/tests/Handler/Path.html
===================================================================
--- trunk/openlayers/tests/Handler/Path.html	2011-02-27 14:54:33 UTC (rev 11562)
+++ trunk/openlayers/tests/Handler/Path.html	2011-02-27 15:00:38 UTC (rev 11563)
@@ -145,6 +145,10 @@
             cancel: function() {
                 logs.push({type: "cancel", args: arguments});
             }
+        },
+        {
+            pixelTolerance: 0,
+            dblclickTolerance: 0
         });
         control.handler = handler;
         map.addControl(control);
@@ -642,7 +646,11 @@
         });
         map.addLayer(layer);
         var control = new OpenLayers.Control({});
-        var handler = new OpenLayers.Handler.Path(control, {});
+        var handler = new OpenLayers.Handler.Path(control, {},
+        {
+            pixelTolerance: 0,
+            dblclickTolerance: 0
+        });
         control.handler = handler;
         map.addControl(control);
         map.setCenter(new OpenLayers.LonLat(0, 0), 0);
@@ -741,6 +749,97 @@
             ]), "geometry is correct after mousemove");
     }
 
+    function test_sequence_touch_1(t) {
+        t.plan(19);
+        
+        log = [];
+        var map = new OpenLayers.Map("map", { // 300 x 150
+            resolutions: [1]
+        });
+        var layer = new OpenLayers.Layer.Vector("foo", {
+            maxExtent: new OpenLayers.Bounds(-100, -100, 100, 100),
+            isBaseLayer: true
+        });
+        map.addLayer(layer);
+        var control = new OpenLayers.Control({});
+        var handler = new OpenLayers.Handler.Path(control, {
+            "done": function(g, f) {
+                log.push({geometry: g, feature: f});
+            }
+        });
+        control.handler = handler;
+        map.addControl(control);
+        map.setCenter(new OpenLayers.LonLat(0, 0), 5);
+        handler.activate();
+
+        handler.touchstart({type: "touchstart", xy: new OpenLayers.Pixel(49, 75)});
+        t.eq(log.length, 0, "touch start 1");
+
+        handler.touchmove({type: "touchmove", xy: new OpenLayers.Pixel(50, 75)});
+        t.eq(log.length, 0, "touch move");
+
+        handler.touchend({type: "touchend"});
+        t.eq(log.length, 0, "touch end");
+        t.geom_eq(handler.line.geometry,
+            new OpenLayers.Geometry.LineString([
+                new OpenLayers.Geometry.Point(-100, 0),
+                new OpenLayers.Geometry.Point(-100, 0)
+            ]), "geometry is correct");
+
+        handler.touchstart({type: "touchstart", xy: new OpenLayers.Pixel(100, 75)});
+        t.eq(log.length, 0, "touch start 2");
+
+        handler.touchmove({type: "touchmove", xy: new OpenLayers.Pixel(250, 75)});
+        t.eq(log.length, 0, "touch move");
+
+        handler.touchend({type: "touchend"});
+        t.eq(log.length, 0, "touch end");
+        t.geom_eq(handler.line.geometry,
+            new OpenLayers.Geometry.LineString([
+                new OpenLayers.Geometry.Point(-100, 0),
+                new OpenLayers.Geometry.Point(-100, 0)
+            ]), "geometry is correct");
+            
+        handler.touchstart({type: "touchstart", xy: new OpenLayers.Pixel(100, 75)});
+        t.eq(log.length, 0, "touch start 3");
+
+        handler.touchmove({type: "touchmove", xy: new OpenLayers.Pixel(100, 75)});
+        t.eq(log.length, 0, "touch move");
+
+        handler.touchend({type: "touchend"});
+        t.eq(log.length, 0, "touch end");
+        t.geom_eq(handler.line.geometry,
+            new OpenLayers.Geometry.LineString([
+                new OpenLayers.Geometry.Point(-100, 0),
+                new OpenLayers.Geometry.Point(-50, 0),
+                new OpenLayers.Geometry.Point(-50, 0)
+            ]), "geometry is correct");
+            
+        handler.touchstart({type: "touchstart", xy: new OpenLayers.Pixel(252, 100)});
+        t.eq(log.length, 0, "touch start 4");
+
+        handler.touchmove({type: "touchmove", xy: new OpenLayers.Pixel(252, 100)});
+        t.eq(log.length, 0, "touch move");
+
+        handler.touchend({type: "touchend"});
+        t.eq(log.length, 0, "touch end");
+            
+        handler.touchstart({type: "touchstart", xy: new OpenLayers.Pixel(250, 100)});
+        t.eq(log.length, 1, "touch start");
+
+        handler.touchmove({type: "touchmove", xy: new OpenLayers.Pixel(250, 100)});
+        t.eq(log.length, 1, "touch move");
+
+        handler.touchend({type: "touchend"});
+        t.eq(log.length, 1, "touch end");
+        t.geom_eq(log[0].geometry,
+            new OpenLayers.Geometry.LineString([
+                new OpenLayers.Geometry.Point(-100, 0),
+                new OpenLayers.Geometry.Point(-50, 0),
+                new OpenLayers.Geometry.Point(102, -25)
+            ]), "geometry is correct");
+    }
+
   </script>
 </head>
 <body>

Modified: trunk/openlayers/tests/Handler/Point.html
===================================================================
--- trunk/openlayers/tests/Handler/Point.html	2011-02-27 14:54:33 UTC (rev 11562)
+++ trunk/openlayers/tests/Handler/Point.html	2011-02-27 15:00:38 UTC (rev 11563)
@@ -75,7 +75,7 @@
     }
 
     function test_Handler_Point_events(t) {
-        t.plan(34);
+        t.plan(49);
         var log = [];
         var map = new OpenLayers.Map("map", {
             resolutions: [1]
@@ -97,7 +97,7 @@
 
         // list below events that should be handled (events) and those
         // that should not be handled (nonevents) by the handler
-        var events = ["click", "dblclick", "mousedown", "mouseup", "mousemove", "mouseout"];
+        var events = ["click", "dblclick", "mousedown", "mouseup", "mousemove", "mouseout", "touchstart", "touchmove", "touchend"];
         var nonevents = ["resize", "focus", "blur"];
         map.events.registerPriority = function(type, obj, func) {
             var r = func();
@@ -166,6 +166,10 @@
             cancel: function() {
                 logs.push({type: "cancel", args: arguments});
             }
+        },
+        {
+            pixelTolerance: 0,
+            dblclickTolerance: 0
         });
         control.handler = handler;
         map.addControl(control);
@@ -379,8 +383,49 @@
              "handler.point is null after destroy");
     }
     
+    function test_sequence_touch_1(t) {
+        t.plan(7);
 
+        log = [];
+        var map = new OpenLayers.Map("map", { // 300 x 150
+            resolutions: [1]
+        });
+        var layer = new OpenLayers.Layer.Vector("foo", {
+            maxExtent: new OpenLayers.Bounds(-100, -100, 100, 100),
+            isBaseLayer: true
+        });
+        map.addLayer(layer);
+        var control = new OpenLayers.Control();
+        var handler = new OpenLayers.Handler.Point(control, {
+            "done": function(g, f) {
+                log.push({geometry: g, feature: f});
+            }
+        });
+        control.handler = handler;
+        map.addControl(control);
+        map.setCenter(new OpenLayers.LonLat(0, 0), 5);
+        handler.activate();
+        
+        handler.touchstart({type: "touchstart", xy: new OpenLayers.Pixel(50, 75)});
+        t.eq(log.length, 0, "touch start 1");
+        
+        handler.touchmove({type: "touchmove", xy: new OpenLayers.Pixel(250, 75)});
+        t.eq(log.length, 0, "touch move");
 
+        handler.touchend({type: "touchend"});
+        t.eq(log.length, 0, "touch end");
+        
+        handler.touchstart({type: "touchstart", xy: new OpenLayers.Pixel(99, 75)});
+        t.eq(log.length, 0, "touch start 2");
+
+        handler.touchmove({type: "touchmove", xy: new OpenLayers.Pixel(100, 75)});
+        t.eq(log.length, 0, "touch move");
+
+        handler.touchend({type: "touchend"});
+        t.eq(log.length, 1, "touch end");
+        t.geom_eq(log[0].geometry, new OpenLayers.Geometry.Point(-50, 0), "geometry is correct");
+    }
+
   </script>
 </head>
 <body>

Modified: trunk/openlayers/tests/Handler/Polygon.html
===================================================================
--- trunk/openlayers/tests/Handler/Polygon.html	2011-02-27 14:54:33 UTC (rev 11562)
+++ trunk/openlayers/tests/Handler/Polygon.html	2011-02-27 15:00:38 UTC (rev 11563)
@@ -142,6 +142,10 @@
             cancel: function() {
                 logs.push({type: "cancel", args: arguments});
             }
+        },
+        {
+            pixelTolerance: 0,
+            dblclickTolerance: 0
         });
         control.handler = handler;
         map.addControl(control);
@@ -531,7 +535,11 @@
         var draw = new OpenLayers.Control.DrawFeature(
             map.layers[0],
             OpenLayers.Handler.Polygon,
-            {handlerOptions: {holeModifier: "altKey"}}
+            {handlerOptions: {
+                holeModifier: "altKey",
+                pixelTolerance: 0,
+                dblclickTolerance: 0
+            }}
         );
         map.addControl(draw);
         draw.activate();
@@ -745,7 +753,8 @@
         var control = new OpenLayers.Control({});
         var handler = new OpenLayers.Handler.Polygon(control,
             {done: function(g) { log.geometry = g; }},
-            {stopDown: true, stopUp: true}
+            {stopDown: true, stopUp: true,
+            pixelTolerance: 0, dblclickTolerance: 0}
         );
         control.handler = handler;
         map.addControl(control);
@@ -816,7 +825,8 @@
         var control = new OpenLayers.Control({});
         var handler = new OpenLayers.Handler.Polygon(control,
             {done: function(g) { log.geometry = g; }},
-            {stopDown: false, stopUp: false}
+            {stopDown: false, stopUp: false,
+            pixelTolerance: 0, dblclickTolerance: 0}
         );
         control.handler = handler;
         map.addControl(control);
@@ -868,6 +878,105 @@
             ]), "geometry is correct");
     }
 
+
+    function test_sequence_touch_1(t) {
+        t.plan(19);
+        
+        log = [];
+        var map = new OpenLayers.Map("map", { // 300 x 150
+            resolutions: [1]
+        });
+        var layer = new OpenLayers.Layer.Vector("foo", {
+            maxExtent: new OpenLayers.Bounds(-100, -100, 100, 100),
+            isBaseLayer: true
+        });
+        map.addLayer(layer);
+        var control = new OpenLayers.Control({});
+        var handler = new OpenLayers.Handler.Polygon(control, {
+            "done": function(g, f) {
+                log.push({geometry: g, feature: f});
+            }
+        });
+        control.handler = handler;
+        control.layer = layer;
+        map.addControl(control);
+        map.setCenter(new OpenLayers.LonLat(0, 0), 5);
+        handler.activate();
+        
+        handler.touchstart({type: "touchstart", xy: new OpenLayers.Pixel(49, 75)});
+        t.eq(log.length, 0, "touch start 1");
+        var expectedRing = new OpenLayers.Geometry.LinearRing([
+            new OpenLayers.Geometry.Point(-100, 0),
+            new OpenLayers.Geometry.Point(-100, 0)
+        ]);
+
+        handler.touchmove({type: "touchmove", xy: new OpenLayers.Pixel(50, 75)});
+        t.eq(log.length, 0, "touch move");
+        
+        handler.touchend({type: "touchend"});
+        t.eq(log.length, 0, "touch end");
+        expectedRing.addComponent(new OpenLayers.Geometry.Point(-100,0), 1);
+
+        t.geom_eq(handler.polygon.geometry.components[0], expectedRing, "geometry is correct");
+
+        handler.touchstart({type: "touchstart", xy: new OpenLayers.Pixel(100, 75)});
+        t.eq(log.length, 0, "touch start 2");
+        var expectedRing = new OpenLayers.Geometry.LinearRing([
+            new OpenLayers.Geometry.Point(-100, 0),
+            new OpenLayers.Geometry.Point(-100, 0)
+        ]);
+
+        handler.touchmove({type: "touchmove", xy: new OpenLayers.Pixel(250, 75)});
+        t.eq(log.length, 0, "touch move");
+
+        handler.touchend({type: "touchend"});
+        t.eq(log.length, 0, "touch end");
+        expectedRing.addComponent(new OpenLayers.Geometry.Point(-100,0), 1);
+        
+        t.geom_eq(handler.polygon.geometry.components[0], expectedRing, "geometry is correct");
+            
+        handler.touchstart({type: "touchstart", xy: new OpenLayers.Pixel(100, 75)});
+        t.eq(log.length, 0, "touch start 3");
+
+        handler.touchmove({type: "touchmove", xy: new OpenLayers.Pixel(100, 75)});
+        t.eq(log.length, 0, "touch move");
+
+        handler.touchend({type: "touchend"});
+        t.eq(log.length, 0, "touch end");
+        t.geom_eq(handler.polygon.geometry,
+            new OpenLayers.Geometry.Polygon([new OpenLayers.Geometry.LinearRing([
+                new OpenLayers.Geometry.Point(-100, 0),
+                new OpenLayers.Geometry.Point(-50, 0),
+                new OpenLayers.Geometry.Point(-50, 0),
+                new OpenLayers.Geometry.Point(-100, 0)
+            ])]), "geometry is correct");
+            
+        handler.touchstart({type: "touchstart", xy: new OpenLayers.Pixel(252, 100)});
+        t.eq(log.length, 0, "touch start 4");
+
+        handler.touchmove({type: "touchmove", xy: new OpenLayers.Pixel(252, 100)});
+        t.eq(log.length, 0, "touch move");
+
+        handler.touchend({type: "touchend"});
+        t.eq(log.length, 0, "touch end");
+            
+        handler.touchstart({type: "touchstart", xy: new OpenLayers.Pixel(250, 100)});
+        t.eq(log.length, 1, "touch start");
+
+        handler.touchmove({type: "touchmove", xy: new OpenLayers.Pixel(250, 100)});
+        t.eq(log.length, 1, "touch move");
+
+        handler.touchend({type: "touchend"});
+        t.eq(log.length, 1, "touch end");
+        t.geom_eq(log[0].geometry,
+            new OpenLayers.Geometry.Polygon([new OpenLayers.Geometry.LinearRing([
+                new OpenLayers.Geometry.Point(-100, 0),
+                new OpenLayers.Geometry.Point(-50, 0),
+                new OpenLayers.Geometry.Point(102, -25),
+                new OpenLayers.Geometry.Point(-100, 0)
+            ])]), "geometry is correct");
+    }
+
   </script>
 </head>
 <body>



More information about the Commits mailing list