1
|
/* Copyright (c) 2006-2013 by OpenLayers Contributors (see authors.txt for
|
2
|
* full list of contributors). Published under the 2-clause BSD license.
|
3
|
* See license.txt in the OpenLayers distribution or repository for the
|
4
|
* full text of the license. */
|
5
|
|
6
|
/**
|
7
|
* @requires OpenLayers/Handler.js
|
8
|
* @requires OpenLayers/Handler/Drag.js
|
9
|
*/
|
10
|
|
11
|
/**
|
12
|
* Class: OpenLayers.Handler.Box
|
13
|
* Handler for dragging a rectangle across the map. Box is displayed
|
14
|
* on mouse down, moves on mouse move, and is finished on mouse up.
|
15
|
*
|
16
|
* Inherits from:
|
17
|
* - <OpenLayers.Handler>
|
18
|
*/
|
19
|
OpenLayers.Handler.Box = OpenLayers.Class(OpenLayers.Handler, {
|
20
|
|
21
|
/**
|
22
|
* Property: dragHandler
|
23
|
* {<OpenLayers.Handler.Drag>}
|
24
|
*/
|
25
|
dragHandler: null,
|
26
|
|
27
|
/**
|
28
|
* APIProperty: boxDivClassName
|
29
|
* {String} The CSS class to use for drawing the box. Default is
|
30
|
* olHandlerBoxZoomBox
|
31
|
*/
|
32
|
boxDivClassName: 'olHandlerBoxZoomBox',
|
33
|
|
34
|
/**
|
35
|
* Property: boxOffsets
|
36
|
* {Object} Caches box offsets from css. This is used by the getBoxOffsets
|
37
|
* method.
|
38
|
*/
|
39
|
boxOffsets: null,
|
40
|
|
41
|
/**
|
42
|
* Constructor: OpenLayers.Handler.Box
|
43
|
*
|
44
|
* Parameters:
|
45
|
* control - {<OpenLayers.Control>}
|
46
|
* callbacks - {Object} An object with a properties whose values are
|
47
|
* functions. Various callbacks described below.
|
48
|
* options - {Object}
|
49
|
*
|
50
|
* Named callbacks:
|
51
|
* start - Called when the box drag operation starts.
|
52
|
* done - Called when the box drag operation is finished.
|
53
|
* The callback should expect to receive a single argument, the box
|
54
|
* bounds or a pixel. If the box dragging didn't span more than a 5
|
55
|
* pixel distance, a pixel will be returned instead of a bounds object.
|
56
|
*/
|
57
|
initialize: function(control, callbacks, options) {
|
58
|
OpenLayers.Handler.prototype.initialize.apply(this, arguments);
|
59
|
this.dragHandler = new OpenLayers.Handler.Drag(
|
60
|
this,
|
61
|
{
|
62
|
down: this.startBox,
|
63
|
move: this.moveBox,
|
64
|
out: this.removeBox,
|
65
|
up: this.endBox
|
66
|
},
|
67
|
{keyMask: this.keyMask}
|
68
|
);
|
69
|
},
|
70
|
|
71
|
/**
|
72
|
* Method: destroy
|
73
|
*/
|
74
|
destroy: function() {
|
75
|
OpenLayers.Handler.prototype.destroy.apply(this, arguments);
|
76
|
if (this.dragHandler) {
|
77
|
this.dragHandler.destroy();
|
78
|
this.dragHandler = null;
|
79
|
}
|
80
|
},
|
81
|
|
82
|
/**
|
83
|
* Method: setMap
|
84
|
*/
|
85
|
setMap: function (map) {
|
86
|
OpenLayers.Handler.prototype.setMap.apply(this, arguments);
|
87
|
if (this.dragHandler) {
|
88
|
this.dragHandler.setMap(map);
|
89
|
}
|
90
|
},
|
91
|
|
92
|
/**
|
93
|
* Method: startBox
|
94
|
*
|
95
|
* Parameters:
|
96
|
* xy - {<OpenLayers.Pixel>}
|
97
|
*/
|
98
|
startBox: function (xy) {
|
99
|
this.callback("start", []);
|
100
|
this.zoomBox = OpenLayers.Util.createDiv('zoomBox', {
|
101
|
x: -9999, y: -9999
|
102
|
});
|
103
|
this.zoomBox.className = this.boxDivClassName;
|
104
|
this.zoomBox.style.zIndex = this.map.Z_INDEX_BASE["Popup"] - 1;
|
105
|
|
106
|
this.map.viewPortDiv.appendChild(this.zoomBox);
|
107
|
|
108
|
OpenLayers.Element.addClass(
|
109
|
this.map.viewPortDiv, "olDrawBox"
|
110
|
);
|
111
|
},
|
112
|
|
113
|
/**
|
114
|
* Method: moveBox
|
115
|
*/
|
116
|
moveBox: function (xy) {
|
117
|
var startX = this.dragHandler.start.x;
|
118
|
var startY = this.dragHandler.start.y;
|
119
|
var deltaX = Math.abs(startX - xy.x);
|
120
|
var deltaY = Math.abs(startY - xy.y);
|
121
|
|
122
|
var offset = this.getBoxOffsets();
|
123
|
this.zoomBox.style.width = (deltaX + offset.width + 1) + "px";
|
124
|
this.zoomBox.style.height = (deltaY + offset.height + 1) + "px";
|
125
|
this.zoomBox.style.left = (xy.x < startX ?
|
126
|
startX - deltaX - offset.left : startX - offset.left) + "px";
|
127
|
this.zoomBox.style.top = (xy.y < startY ?
|
128
|
startY - deltaY - offset.top : startY - offset.top) + "px";
|
129
|
},
|
130
|
|
131
|
/**
|
132
|
* Method: endBox
|
133
|
*/
|
134
|
endBox: function(end) {
|
135
|
var result;
|
136
|
if (Math.abs(this.dragHandler.start.x - end.x) > 5 ||
|
137
|
Math.abs(this.dragHandler.start.y - end.y) > 5) {
|
138
|
var start = this.dragHandler.start;
|
139
|
var top = Math.min(start.y, end.y);
|
140
|
var bottom = Math.max(start.y, end.y);
|
141
|
var left = Math.min(start.x, end.x);
|
142
|
var right = Math.max(start.x, end.x);
|
143
|
result = new OpenLayers.Bounds(left, bottom, right, top);
|
144
|
} else {
|
145
|
result = this.dragHandler.start.clone(); // i.e. OL.Pixel
|
146
|
}
|
147
|
this.removeBox();
|
148
|
|
149
|
this.callback("done", [result]);
|
150
|
},
|
151
|
|
152
|
/**
|
153
|
* Method: removeBox
|
154
|
* Remove the zoombox from the screen and nullify our reference to it.
|
155
|
*/
|
156
|
removeBox: function() {
|
157
|
this.map.viewPortDiv.removeChild(this.zoomBox);
|
158
|
this.zoomBox = null;
|
159
|
this.boxOffsets = null;
|
160
|
OpenLayers.Element.removeClass(
|
161
|
this.map.viewPortDiv, "olDrawBox"
|
162
|
);
|
163
|
|
164
|
},
|
165
|
|
166
|
/**
|
167
|
* Method: activate
|
168
|
*/
|
169
|
activate: function () {
|
170
|
if (OpenLayers.Handler.prototype.activate.apply(this, arguments)) {
|
171
|
this.dragHandler.activate();
|
172
|
return true;
|
173
|
} else {
|
174
|
return false;
|
175
|
}
|
176
|
},
|
177
|
|
178
|
/**
|
179
|
* Method: deactivate
|
180
|
*/
|
181
|
deactivate: function () {
|
182
|
if (OpenLayers.Handler.prototype.deactivate.apply(this, arguments)) {
|
183
|
if (this.dragHandler.deactivate()) {
|
184
|
if (this.zoomBox) {
|
185
|
this.removeBox();
|
186
|
}
|
187
|
}
|
188
|
return true;
|
189
|
} else {
|
190
|
return false;
|
191
|
}
|
192
|
},
|
193
|
|
194
|
/**
|
195
|
* Method: getBoxOffsets
|
196
|
* Determines border offsets for a box, according to the box model.
|
197
|
*
|
198
|
* Returns:
|
199
|
* {Object} an object with the following offsets:
|
200
|
* - left
|
201
|
* - right
|
202
|
* - top
|
203
|
* - bottom
|
204
|
* - width
|
205
|
* - height
|
206
|
*/
|
207
|
getBoxOffsets: function() {
|
208
|
if (!this.boxOffsets) {
|
209
|
// Determine the box model. If the testDiv's clientWidth is 3, then
|
210
|
// the borders are outside and we are dealing with the w3c box
|
211
|
// model. Otherwise, the browser uses the traditional box model and
|
212
|
// the borders are inside the box bounds, leaving us with a
|
213
|
// clientWidth of 1.
|
214
|
var testDiv = document.createElement("div");
|
215
|
//testDiv.style.visibility = "hidden";
|
216
|
testDiv.style.position = "absolute";
|
217
|
testDiv.style.border = "1px solid black";
|
218
|
testDiv.style.width = "3px";
|
219
|
document.body.appendChild(testDiv);
|
220
|
var w3cBoxModel = testDiv.clientWidth == 3;
|
221
|
document.body.removeChild(testDiv);
|
222
|
|
223
|
var left = parseInt(OpenLayers.Element.getStyle(this.zoomBox,
|
224
|
"border-left-width"));
|
225
|
var right = parseInt(OpenLayers.Element.getStyle(
|
226
|
this.zoomBox, "border-right-width"));
|
227
|
var top = parseInt(OpenLayers.Element.getStyle(this.zoomBox,
|
228
|
"border-top-width"));
|
229
|
var bottom = parseInt(OpenLayers.Element.getStyle(
|
230
|
this.zoomBox, "border-bottom-width"));
|
231
|
this.boxOffsets = {
|
232
|
left: left,
|
233
|
right: right,
|
234
|
top: top,
|
235
|
bottom: bottom,
|
236
|
width: w3cBoxModel === false ? left + right : 0,
|
237
|
height: w3cBoxModel === false ? top + bottom : 0
|
238
|
};
|
239
|
}
|
240
|
return this.boxOffsets;
|
241
|
},
|
242
|
|
243
|
CLASS_NAME: "OpenLayers.Handler.Box"
|
244
|
});
|