]> dev.renevier.net Git - syp.git/blob - openlayers/lib/OpenLayers/Handler/Box.js
initial commit
[syp.git] / openlayers / lib / OpenLayers / Handler / Box.js
1 /* Copyright (c) 2006-2008 MetaCarta, Inc., published under the Clear BSD
2  * license.  See http://svn.openlayers.org/trunk/openlayers/license.txt for the
3  * full text of the license. */
4
5 /**
6  * @requires OpenLayers/Handler.js
7  * @requires OpenLayers/Handler/Drag.js
8  */
9
10 /**
11  * Class: OpenLayers.Handler.Box
12  * Handler for dragging a rectangle across the map.  Box is displayed 
13  * on mouse down, moves on mouse move, and is finished on mouse up.
14  *
15  * Inherits from:
16  *  - <OpenLayers.Handler> 
17  */
18 OpenLayers.Handler.Box = OpenLayers.Class(OpenLayers.Handler, {
19
20     /** 
21      * Property: dragHandler 
22      * {<OpenLayers.Handler.Drag>} 
23      */
24     dragHandler: null,
25
26     /**
27      * APIProperty: boxDivClassName
28      * {String} The CSS class to use for drawing the box. Default is
29      *     olHandlerBoxZoomBox
30      */
31     boxDivClassName: 'olHandlerBoxZoomBox',
32     
33     /**
34      * Property: boxCharacteristics
35      * {Object} Caches some box characteristics from css. This is used
36      *     by the getBoxCharacteristics method.
37      */
38     boxCharacteristics: null,
39
40     /**
41      * Constructor: OpenLayers.Handler.Box
42      *
43      * Parameters:
44      * control - {<OpenLayers.Control>} 
45      * callbacks - {Object} An object containing a single function to be
46      *                          called when the drag operation is finished.
47      *                          The callback should expect to recieve a single
48      *                          argument, the point geometry.
49      * options - {Object} 
50      */
51     initialize: function(control, callbacks, options) {
52         OpenLayers.Handler.prototype.initialize.apply(this, arguments);
53         var callbacks = {
54             "down": this.startBox, 
55             "move": this.moveBox, 
56             "out":  this.removeBox,
57             "up":   this.endBox
58         };
59         this.dragHandler = new OpenLayers.Handler.Drag(
60                                 this, callbacks, {keyMask: this.keyMask});
61     },
62
63     /**
64      * Method: setMap
65      */
66     setMap: function (map) {
67         OpenLayers.Handler.prototype.setMap.apply(this, arguments);
68         if (this.dragHandler) {
69             this.dragHandler.setMap(map);
70         }
71     },
72
73     /**
74     * Method: startBox
75     *
76     * Parameters:
77     * evt - {Event} 
78     */
79     startBox: function (xy) {
80         this.zoomBox = OpenLayers.Util.createDiv('zoomBox',
81                                                  this.dragHandler.start);
82         this.zoomBox.className = this.boxDivClassName;                                         
83         this.zoomBox.style.zIndex = this.map.Z_INDEX_BASE["Popup"] - 1;
84         this.map.viewPortDiv.appendChild(this.zoomBox);
85
86         OpenLayers.Element.addClass(
87             this.map.viewPortDiv, "olDrawBox"
88         );
89     },
90
91     /**
92     * Method: moveBox
93     */
94     moveBox: function (xy) {
95         var startX = this.dragHandler.start.x;
96         var startY = this.dragHandler.start.y;
97         var deltaX = Math.abs(startX - xy.x);
98         var deltaY = Math.abs(startY - xy.y);
99         this.zoomBox.style.width = Math.max(1, deltaX) + "px";
100         this.zoomBox.style.height = Math.max(1, deltaY) + "px";
101         this.zoomBox.style.left = xy.x < startX ? xy.x+"px" : startX+"px";
102         this.zoomBox.style.top = xy.y < startY ? xy.y+"px" : startY+"px";
103
104         // depending on the box model, modify width and height to take borders
105         // of the box into account
106         var box = this.getBoxCharacteristics();
107         if (box.newBoxModel) {
108             if (xy.x > startX) {
109                 this.zoomBox.style.width =
110                     Math.max(1, deltaX - box.xOffset) + "px";
111             }
112             if (xy.y > startY) {
113                 this.zoomBox.style.height =
114                     Math.max(1, deltaY - box.yOffset) + "px";
115             }
116         }
117     },
118
119     /**
120     * Method: endBox
121     */
122     endBox: function(end) {
123         var result;
124         if (Math.abs(this.dragHandler.start.x - end.x) > 5 ||    
125             Math.abs(this.dragHandler.start.y - end.y) > 5) {   
126             var start = this.dragHandler.start;
127             var top = Math.min(start.y, end.y);
128             var bottom = Math.max(start.y, end.y);
129             var left = Math.min(start.x, end.x);
130             var right = Math.max(start.x, end.x);
131             result = new OpenLayers.Bounds(left, bottom, right, top);
132         } else {
133             result = this.dragHandler.start.clone(); // i.e. OL.Pixel
134         } 
135         this.removeBox();
136
137         this.callback("done", [result]);
138     },
139
140     /**
141      * Method: removeBox
142      * Remove the zoombox from the screen and nullify our reference to it.
143      */
144     removeBox: function() {
145         this.map.viewPortDiv.removeChild(this.zoomBox);
146         this.zoomBox = null;
147         this.boxCharacteristics = null;
148         OpenLayers.Element.removeClass(
149             this.map.viewPortDiv, "olDrawBox"
150         );
151
152     },
153
154     /**
155      * Method: activate
156      */
157     activate: function () {
158         if (OpenLayers.Handler.prototype.activate.apply(this, arguments)) {
159             this.dragHandler.activate();
160             return true;
161         } else {
162             return false;
163         }
164     },
165
166     /**
167      * Method: deactivate
168      */
169     deactivate: function () {
170         if (OpenLayers.Handler.prototype.deactivate.apply(this, arguments)) {
171             this.dragHandler.deactivate();
172             return true;
173         } else {
174             return false;
175         }
176     },
177     
178     /**
179      * Method: getCharacteristics
180      * Determines offset and box model for a box.
181      * 
182      * Returns:
183      * {Object} a hash with the following properties:
184      *     - xOffset - Corner offset in x-direction
185      *     - yOffset - Corner offset in y-direction
186      *     - newBoxModel - true for all browsers except IE in quirks mode
187      */
188     getBoxCharacteristics: function() {
189         if (!this.boxCharacteristics) {
190             var xOffset = parseInt(OpenLayers.Element.getStyle(this.zoomBox,
191                 "border-left-width")) + parseInt(OpenLayers.Element.getStyle(
192                 this.zoomBox, "border-right-width")) + 1;
193             var yOffset = parseInt(OpenLayers.Element.getStyle(this.zoomBox,
194                 "border-top-width")) + parseInt(OpenLayers.Element.getStyle(
195                 this.zoomBox, "border-bottom-width")) + 1;
196             // all browsers use the new box model, except IE in quirks mode
197             var newBoxModel = OpenLayers.Util.getBrowserName() == "msie" ?
198                 document.compatMode != "BackCompat" : true;
199             this.boxCharacteristics = {
200                 xOffset: xOffset,
201                 yOffset: yOffset,
202                 newBoxModel: newBoxModel
203             };
204         }
205         return this.boxCharacteristics;
206     },
207
208     CLASS_NAME: "OpenLayers.Handler.Box"
209 });