summaryrefslogtreecommitdiff
path: root/js/dojo-1.7.2/dojox/dnd/BoundingBoxController.js
blob: fb7b68866e754fe1e6740fa23d001337abd8d677 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
//>>built
define("dojox/dnd/BoundingBoxController", ["dojo", "dojox"], function(dojo, dojox) {

	return 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;
			},

			shouldStartDrawingBox: function(evt) {
				// summary: Override-able by the client as an extra check to ensure that a bounding
				// box should begin to be drawn. If the client has any preconditions to when a
				// bounding box should be drawn, they should be included in this method.
				// evt: Object: the mouse event which caused this callback to fire.
				return true;
			},

			boundingBoxIsViable: function(evt) {
				// 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.
				// evt: Object: the mouse event which caused this callback to fire.
				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 (this.shouldStartDrawingBox(evt) && 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(evt)) {
					// 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 = null;
					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: ''
				});
			}
		}
	);
});