/* Copyright (c) 2004-2012, 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: "" }); } } ); }