]> dev.renevier.net Git - syp.git/blob - openlayers/lib/OpenLayers/Control/Panel.js
initial commit
[syp.git] / openlayers / lib / OpenLayers / Control / Panel.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/Control.js
7  */
8
9 /**
10  * Class: OpenLayers.Control.Panel
11  * The Panel control is a container for other controls. With it toolbars
12  * may be composed.
13  *
14  * Inherits from:
15  *  - <OpenLayers.Control>
16  */
17 OpenLayers.Control.Panel = OpenLayers.Class(OpenLayers.Control, {
18     /**
19      * Property: controls
20      * {Array(<OpenLayers.Control>)}
21      */
22     controls: null,    
23     
24     /** 
25      * APIProperty: defaultControl
26      * {<OpenLayers.Control>} The control which is activated when the control is
27      * activated (turned on), which also happens at instantiation.
28      */
29     defaultControl: null, 
30
31     /**
32      * Constructor: OpenLayers.Control.Panel
33      * Create a new control panel.
34      * 
35      * Parameters:
36      * options - {Object} An optional object whose properties will be used
37      *     to extend the control.
38      */
39     initialize: function(options) {
40         OpenLayers.Control.prototype.initialize.apply(this, [options]);
41         this.controls = [];
42     },
43
44     /**
45      * APIMethod: destroy
46      */
47     destroy: function() {
48         OpenLayers.Control.prototype.destroy.apply(this, arguments);
49         for(var i = this.controls.length - 1 ; i >= 0; i--) {
50             if(this.controls[i].events) {
51                 this.controls[i].events.un({
52                     "activate": this.redraw,
53                     "deactivate": this.redraw,
54                     scope: this
55                 });
56             }
57             OpenLayers.Event.stopObservingElement(this.controls[i].panel_div);
58             this.controls[i].panel_div = null;
59         }    
60     },
61
62     /**
63      * APIMethod: activate
64      */
65     activate: function() {
66         if (OpenLayers.Control.prototype.activate.apply(this, arguments)) {
67             for(var i=0, len=this.controls.length; i<len; i++) {
68                 if (this.controls[i] == this.defaultControl) {
69                     this.controls[i].activate();
70                 }
71             }    
72             this.redraw();
73             return true;
74         } else {
75             return false;
76         }
77     },
78     
79     /**
80      * APIMethod: deactivate
81      */
82     deactivate: function() {
83         if (OpenLayers.Control.prototype.deactivate.apply(this, arguments)) {
84             for(var i=0, len=this.controls.length; i<len; i++) {
85                 this.controls[i].deactivate();
86             }    
87             return true;
88         } else {
89             return false;
90         }
91     },
92     
93     /**
94      * Method: draw
95      *
96      * Returns:
97      * {DOMElement}
98      */    
99     draw: function() {
100         OpenLayers.Control.prototype.draw.apply(this, arguments);
101         for (var i=0, len=this.controls.length; i<len; i++) {
102             this.map.addControl(this.controls[i]);
103             this.controls[i].deactivate();
104             this.controls[i].events.on({
105                 "activate": this.redraw,
106                 "deactivate": this.redraw,
107                 scope: this
108             });
109         }
110         this.activate();
111         return this.div;
112     },
113
114     /**
115      * Method: redraw
116      */
117     redraw: function() {
118         this.div.innerHTML = "";
119         if (this.active) {
120             for (var i=0, len=this.controls.length; i<len; i++) {
121                 var element = this.controls[i].panel_div;
122                 if (this.controls[i].active) {
123                     element.className = this.controls[i].displayClass + "ItemActive";
124                 } else {    
125                     element.className = this.controls[i].displayClass + "ItemInactive";
126                 }    
127                 this.div.appendChild(element);
128             }
129         }
130     },
131
132     /**
133      * APIMethod: activateControl
134      * 
135      * Parameters:
136      * control - {<OpenLayers.Control>}
137      */
138     activateControl: function (control) {
139         if (!this.active) { return false; }
140         if (control.type == OpenLayers.Control.TYPE_BUTTON) {
141             control.trigger();
142             this.redraw();
143             return;
144         }
145         if (control.type == OpenLayers.Control.TYPE_TOGGLE) {
146             if (control.active) {
147                 control.deactivate();
148             } else {
149                 control.activate();
150             }
151             this.redraw();
152             return;
153         }
154         for (var i=0, len=this.controls.length; i<len; i++) {
155             if (this.controls[i] != control) {
156                 if (this.controls[i].type != OpenLayers.Control.TYPE_TOGGLE) {
157                     this.controls[i].deactivate();
158                 }
159             }
160         }
161         control.activate();
162     },
163
164     /**
165      * APIMethod: addControls
166      * To build a toolbar, you add a set of controls to it. addControls
167      * lets you add a single control or a list of controls to the 
168      * Control Panel.
169      *
170      * Parameters:
171      * controls - {<OpenLayers.Control>} 
172      */    
173     addControls: function(controls) {
174         if (!(controls instanceof Array)) {
175             controls = [controls];
176         }
177         this.controls = this.controls.concat(controls);
178         
179         // Give each control a panel_div which will be used later.
180         // Access to this div is via the panel_div attribute of the 
181         // control added to the panel.
182         // Also, stop mousedowns and clicks, but don't stop mouseup,
183         // since they need to pass through.
184         for (var i=0, len=controls.length; i<len; i++) {
185             var element = document.createElement("div");
186             var textNode = document.createTextNode(" ");
187             controls[i].panel_div = element;
188             if (controls[i].title != "") {
189                 controls[i].panel_div.title = controls[i].title;
190             }
191             OpenLayers.Event.observe(controls[i].panel_div, "click", 
192                 OpenLayers.Function.bind(this.onClick, this, controls[i]));
193             OpenLayers.Event.observe(controls[i].panel_div, "mousedown", 
194                 OpenLayers.Function.bindAsEventListener(OpenLayers.Event.stop));
195         }    
196
197         if (this.map) { // map.addControl() has already been called on the panel
198             for (var i=0, len=controls.length; i<len; i++) {
199                 this.map.addControl(controls[i]);
200                 controls[i].deactivate();
201                 controls[i].events.on({
202                     "activate": this.redraw,
203                     "deactivate": this.redraw,
204                     scope: this
205                 });
206             }
207             this.redraw();
208         }
209     },
210    
211     /**
212      * Method: onClick
213      */
214     onClick: function (ctrl, evt) {
215         OpenLayers.Event.stop(evt ? evt : window.event);
216         this.activateControl(ctrl);
217     },
218
219     /**
220      * APIMethod: getControlsBy
221      * Get a list of controls with properties matching the given criteria.
222      *
223      * Parameter:
224      * property - {String} A control property to be matched.
225      * match - {String | Object} A string to match.  Can also be a regular
226      *     expression literal or object.  In addition, it can be any object
227      *     with a method named test.  For reqular expressions or other, if
228      *     match.test(control[property]) evaluates to true, the control will be
229      *     included in the array returned.  If no controls are found, an empty
230      *     array is returned.
231      *
232      * Returns:
233      * {Array(<OpenLayers.Control>)} A list of controls matching the given criteria.
234      *     An empty array is returned if no matches are found.
235      */
236     getControlsBy: function(property, match) {
237         var test = (typeof match.test == "function");
238         var found = OpenLayers.Array.filter(this.controls, function(item) {
239             return item[property] == match || (test && match.test(item[property]));
240         });
241         return found;
242     },
243
244     /**
245      * APIMethod: getControlsByName
246      * Get a list of contorls with names matching the given name.
247      *
248      * Parameter:
249      * match - {String | Object} A control name.  The name can also be a regular
250      *     expression literal or object.  In addition, it can be any object
251      *     with a method named test.  For reqular expressions or other, if
252      *     name.test(control.name) evaluates to true, the control will be included
253      *     in the list of controls returned.  If no controls are found, an empty
254      *     array is returned.
255      *
256      * Returns:
257      * {Array(<OpenLayers.Control>)} A list of controls matching the given name.
258      *     An empty array is returned if no matches are found.
259      */
260     getControlsByName: function(match) {
261         return this.getControlsBy("name", match);
262     },
263
264     /**
265      * APIMethod: getControlsByClass
266      * Get a list of controls of a given type (CLASS_NAME).
267      *
268      * Parameter:
269      * match - {String | Object} A control class name.  The type can also be a
270      *     regular expression literal or object.  In addition, it can be any
271      *     object with a method named test.  For reqular expressions or other,
272      *     if type.test(control.CLASS_NAME) evaluates to true, the control will
273      *     be included in the list of controls returned.  If no controls are
274      *     found, an empty array is returned.
275      *
276      * Returns:
277      * {Array(<OpenLayers.Control>)} A list of controls matching the given type.
278      *     An empty array is returned if no matches are found.
279      */
280     getControlsByClass: function(match) {
281         return this.getControlsBy("CLASS_NAME", match);
282     },
283
284     CLASS_NAME: "OpenLayers.Control.Panel"
285 });
286