Project

General

Profile

Download (7.54 KB) Statistics
| Branch: | Tag: | Revision:
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
});
(1-1/12)