/*
Copyright (c) 2004-2011, The Dojo Foundation All Rights Reserved.
Available via Academic Free License >= 2.1 OR the modified BSD license.
see: http://dojotoolkit.org/license for details
*/
if(!dojo._hasResource["dojox.dnd.BoundingBoxController"]){ //_hasResource checks added by build. Do not use _hasResource directly in your code.
dojo._hasResource["dojox.dnd.BoundingBoxController"] = true;
dojo.provide("dojox.dnd.BoundingBoxController");
dojo.declare(
"dojox.dnd.BoundingBoxController",
null,
{
// summary: Allows the user draw bounding boxes around nodes on the page.
// Publishes to the "/dojox/dnd/bounding" topic to tell the selector to check
// to see whether any dnd items fall within the coordinates of the bounding box
// x,y start and end coordinates for the bounding box
_startX: null,
_startY: null,
_endX: null,
_endY: null,
constructor: function(sources, domNode){
// summary:
// Sets mouse handlers for the document to capture when a user
// is trying to draw a bounding box.
// sources: Array:
// an array of dojox.dnd.Selectors which need to be aware of
// the positioning of the bounding box.
// domNode: String|DomNode:
// the DOM node or id which represents the bounding box on the page.
this.events = [
dojo.connect(dojo.doc, "onmousedown", this, "_onMouseDown"),
dojo.connect(dojo.doc, "onmouseup", this, "_onMouseUp"),
// cancel text selection and text dragging
//dojo.connect(dojo.doc, "ondragstart", dojo.stopEvent),
//dojo.connect(dojo.doc, "onselectstart", dojo.stopEvent),
// when a user is scrolling using a scrollbar, don't draw the bounding box.
dojo.connect(dojo.doc, "onscroll", this, "_finishSelecting")
];
// set up a subscription so the client can easily cancel a user drawing a bounding box.
this.subscriptions = [
dojo.subscribe("/dojox/bounding/cancel", this, "_finishSelecting")
];
dojo.forEach(sources, function(item){
// listen for "/dojox/dnd/bounding" events eminating from the bounding box.
// for each of the dojox.dnd.selectors passed in args.
if(item.selectByBBox){
this.subscriptions.push(dojo.subscribe("/dojox/dnd/bounding", item, "selectByBBox"));
}
}, this)
this.domNode = dojo.byId(domNode);
dojo.style(this.domNode, {
position: "absolute",
display: "none"
});
},
destroy: function(){
// summary:
// prepares this object to be garbage-collected
dojo.forEach(this.events, dojo.disconnect);
dojo.forEach(this.subscriptions, dojo.unsubscribe);
this.domNode = null;
},
boundingBoxIsViable: function(){
// summary: Override-able by the client as an extra check to ensure that a bounding
// box is viable. In some instances, it might not make sense that
// a mouse down -> mouse move -> mouse up interaction represents a bounding box.
// For example, if a dialog is open the client might want to suppress a bounding
// box. This function could be used by the client to ensure that a bounding box is only
// drawn on the document when certain conditions are met.
return true;
},
_onMouseDown: function(evt){
// summary: Executed when the user mouses down on the document. Resets the
// this._startX and this._startY member variables.
// evt: Object: the mouse event which caused this callback to fire.
if(dojo.mouseButtons.isLeft(evt)){
if(this._startX === null){
this._startX = evt.clientX;
this._startY = evt.clientY;
}
this.events.push(
dojo.connect(dojo.doc, "onmousemove", this, "_onMouseMove")
);
}
},
_onMouseMove: function(evt){
// summary: Executed when the user moves the mouse over the document. Delegates to
// this._drawBoundingBox if the user is trying to draw a bounding box.
// whether the user was drawing a bounding box and publishes to the
// "/dojox/dnd/bounding" topic if the user is finished drawing their bounding box.
// evt: Object: the mouse event which caused this callback to fire.
this._endX = evt.clientX;
this._endY = evt.clientY;
this._drawBoundingBox();
},
_onMouseUp: function(evt){
// summary: Executed when the users mouses up on the document. Checks to see
// whether the user was drawing a bounding box and publishes to the
// "/dojox/dnd/bounding" topic if the user is finished drawing their bounding box.
// evt: Object: the mouse event which caused this callback to fire.
if(this._endX !== null && this.boundingBoxIsViable()){
// the user has moused up ... tell the selector to check to see whether
// any nodes within the bounding box need to be selected.
dojo.publish("/dojox/dnd/bounding", [this._startX, this._startY, this._endX, this._endY]);
}
this._finishSelecting();
},
_finishSelecting: function(){
// summary: hide the bounding box and reset for the next time around
if(this._startX !== null){
dojo.disconnect(this.events.pop());
dojo.style(this.domNode, "display", "none");
this._startX = this._endX = null;
}
},
_drawBoundingBox: function(){
// summary: draws the bounding box over the document.
dojo.style(this.domNode, {
left: Math.min(this._startX, this._endX) + "px",
top: Math.min(this._startY, this._endY) + "px",
width: Math.abs(this._startX - this._endX) + "px",
height: Math.abs(this._startY - this._endY) + "px",
display: ""
});
}
}
);
}