Files
openlayers/lib/OpenLayers/Handler/Drag.js
crschmidt d597e4f9a9 Because onselectstart is null by default, our logic to set it and
replace it was somewhat lacking. This changes the behavior such that 
using hte drag handler does not totally disable text selection in IE. 
Patch from Bart, r=me (Closes #906)


git-svn-id: http://svn.openlayers.org/trunk/openlayers@5911 dc9f47b5-9b13-0410-9fdd-eb0c1a62fdaf
2008-01-27 14:48:02 +00:00

319 lines
9.0 KiB
JavaScript

/* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
* license. See http://svn.openlayers.org/trunk/openlayers/license.txt for the
* full text of the license. */
/**
* @requires OpenLayers/Handler.js
*/
/**
* Class: OpenLayers.Handler.Drag
* The drag handler is used to deal with sequences of browser events related
* to dragging. The handler is used by controls that want to know when
* a drag sequence begins, when a drag is happening, and when it has
* finished.
*
* Controls that use the drag handler typically construct it with callbacks
* for 'down', 'move', and 'done'. Callbacks for these keys are called
* when the drag begins, with each move, and when the drag is done. In
* addition, controls can have callbacks keyed to 'up' and 'out' if they
* care to differentiate between the types of events that correspond with
* the end of a drag sequence. If no drag actually occurs (no mouse move)
* the 'down' and 'up' callbacks will be called, but not the 'done'
* callback.
*
* Create a new drag handler with the <OpenLayers.Handler.Drag> constructor.
*
* Inherits from:
* - <OpenLayers.Handler>
*/
OpenLayers.Handler.Drag = OpenLayers.Class(OpenLayers.Handler, {
/**
* Property: started
* {Boolean} When a mousedown event is received, we want to record it, but
* not set 'dragging' until the mouse moves after starting.
*/
started: false,
/**
* Property: stopDown
* {Boolean} Stop propagation of mousedown events from getting to listeners
* on the same element. Default is true.
*/
stopDown: true,
/**
* Property: dragging
* {Boolean}
*/
dragging: false,
/**
* Property: last
* {<OpenLayers.Pixel>} The last pixel location of the drag.
*/
last: null,
/**
* Property: start
* {<OpenLayers.Pixel>} The first pixel location of the drag.
*/
start: null,
/**
* Property: oldOnselectstart
* {Function}
*/
oldOnselectstart: null,
/**
* Constructor: OpenLayers.Handler.Drag
* Returns OpenLayers.Handler.Drag
*
* Parameters:
* control - {<OpenLayers.Control>} The control that is making use of
* this handler. If a handler is being used without a control, the
* handlers setMap method must be overridden to deal properly with
* the map.
* callbacks - {Object} An object containing a single function to be
* called when the drag operation is finished. The callback should
* expect to recieve a single argument, the pixel location of the event.
* Callbacks for 'move' and 'done' are supported. You can also speficy
* callbacks for 'down', 'up', and 'out' to respond to those events.
* options - {Object}
*/
initialize: function(control, callbacks, options) {
OpenLayers.Handler.prototype.initialize.apply(this, arguments);
},
/**
* The four methods below (down, move, up, and out) are used by subclasses
* to do their own processing related to these mouse events.
*/
/**
* Method: down
* This method is called during the handling of the mouse down event.
* Subclasses can do their own processing here.
*
* Parameters:
* evt - {Event} The mouse down event
*/
down: function(evt) {
},
/**
* Method: move
* This method is called during the handling of the mouse move event.
* Subclasses can do their own processing here.
*
* Parameters:
* evt - {Event} The mouse move event
*
*/
move: function(evt) {
},
/**
* Method: up
* This method is called during the handling of the mouse up event.
* Subclasses can do their own processing here.
*
* Parameters:
* evt - {Event} The mouse up event
*/
up: function(evt) {
},
/**
* Method: out
* This method is called during the handling of the mouse out event.
* Subclasses can do their own processing here.
*
* Parameters:
* evt - {Event} The mouse out event
*/
out: function(evt) {
},
/**
* The methods below are part of the magic of event handling. Because
* they are named like browser events, they are registered as listeners
* for the events they represent.
*/
/**
* Method: mousedown
* Handle mousedown events
*
* Parameters:
* evt - {Event}
*
* Returns:
* {Boolean} Let the event propagate.
*/
mousedown: function (evt) {
var propagate = true;
this.dragging = false;
if (this.checkModifiers(evt) && OpenLayers.Event.isLeftClick(evt)) {
this.started = true;
this.start = evt.xy;
this.last = evt.xy;
// TBD replace with CSS classes
this.map.div.style.cursor = "move";
this.down(evt);
this.callback("down", [evt.xy]);
OpenLayers.Event.stop(evt);
if(!this.oldOnselectstart) {
this.oldOnselectstart = (document.onselectstart) ? document.onselectstart : function() { return true; };
document.onselectstart = function() {return false;};
}
propagate = !this.stopDown;
} else {
this.started = false;
this.start = null;
this.last = null;
}
return propagate;
},
/**
* Method: mousemove
* Handle mousemove events
*
* Parameters:
* evt - {Event}
*
* Returns:
* {Boolean} Let the event propagate.
*/
mousemove: function (evt) {
if (this.started) {
if(evt.xy.x != this.last.x || evt.xy.y != this.last.y) {
this.dragging = true;
this.move(evt);
this.callback("move", [evt.xy]);
if(!this.oldOnselectstart) {
this.oldOnselectstart = document.onselectstart;
document.onselectstart = function() {return false;};
}
this.last = evt.xy;
}
}
return true;
},
/**
* Method: mouseup
* Handle mouseup events
*
* Parameters:
* evt - {Event}
*
* Returns:
* {Boolean} Let the event propagate.
*/
mouseup: function (evt) {
if (this.started) {
var dragged = (this.start != this.last);
this.started = false;
this.dragging = false;
// TBD replace with CSS classes
this.map.div.style.cursor = "";
this.up(evt);
this.callback("up", [evt.xy]);
if(dragged) {
this.callback("done", [evt.xy]);
}
document.onselectstart = this.oldOnselectstart;
}
return true;
},
/**
* Method: mouseout
* Handle mouseout events
*
* Parameters:
* evt - {Event}
*
* Returns:
* {Boolean} Let the event propagate.
*/
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;
// TBD replace with CSS classes
this.map.div.style.cursor = "";
this.out(evt);
this.callback("out", []);
if(dragged) {
this.callback("done", [evt.xy]);
}
if(document.onselectstart) {
document.onselectstart = this.oldOnselectstart;
}
}
return true;
},
/**
* Method: click
* The drag handler captures the click event. If something else registers
* for clicks on the same element, its listener will not be called
* after a drag.
*
* Parameters:
* evt - {Event}
*
* Returns:
* {Boolean} Let the event propagate.
*/
click: function (evt) {
// let the click event propagate only if the mouse moved
return (this.start == this.last);
},
/**
* Method: activate
* Activate the handler.
*
* Returns:
* {Boolean} The handler was successfully activated.
*/
activate: function() {
var activated = false;
if(OpenLayers.Handler.prototype.activate.apply(this, arguments)) {
this.dragging = false;
activated = true;
}
return activated;
},
/**
* Method: deactivate
* Deactivate the handler.
*
* Returns:
* {Boolean} The handler was successfully deactivated.
*/
deactivate: function() {
var deactivated = false;
if(OpenLayers.Handler.prototype.deactivate.apply(this, arguments)) {
this.started = false;
this.dragging = false;
this.start = null;
this.last = null;
deactivated = true;
}
return deactivated;
},
CLASS_NAME: "OpenLayers.Handler.Drag"
});