]> dev.renevier.net Git - syp.git/blob - openlayers/lib/OpenLayers/Handler.js
initial commit
[syp.git] / openlayers / lib / OpenLayers / Handler.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/Events.js
7  */
8
9 /**
10  * Class: OpenLayers.Handler
11  * Base class to construct a higher-level handler for event sequences.  All
12  *     handlers have activate and deactivate methods.  In addition, they have
13  *     methods named like browser events.  When a handler is activated, any
14  *     additional methods named like a browser event is registered as a
15  *     listener for the corresponding event.  When a handler is deactivated,
16  *     those same methods are unregistered as event listeners.
17  *
18  * Handlers also typically have a callbacks object with keys named like
19  *     the abstracted events or event sequences that they are in charge of
20  *     handling.  The controls that wrap handlers define the methods that
21  *     correspond to these abstract events - so instead of listening for
22  *     individual browser events, they only listen for the abstract events
23  *     defined by the handler.
24  *     
25  * Handlers are created by controls, which ultimately have the responsibility
26  *     of making changes to the the state of the application.  Handlers
27  *     themselves may make temporary changes, but in general are expected to
28  *     return the application in the same state that they found it.
29  */
30 OpenLayers.Handler = OpenLayers.Class({
31
32     /**
33      * Property: id
34      * {String}
35      */
36     id: null,
37         
38     /**
39      * APIProperty: control
40      * {<OpenLayers.Control>}. The control that initialized this handler.  The
41      *     control is assumed to have a valid map property - that map is used
42      *     in the handler's own setMap method.
43      */
44     control: null,
45
46     /**
47      * Property: map
48      * {<OpenLayers.Map>}
49      */
50     map: null,
51
52     /**
53      * APIProperty: keyMask
54      * {Integer} Use bitwise operators and one or more of the OpenLayers.Handler
55      *     constants to construct a keyMask.  The keyMask is used by
56      *     <checkModifiers>.  If the keyMask matches the combination of keys
57      *     down on an event, checkModifiers returns true.
58      *
59      * Example:
60      * (code)
61      *     // handler only responds if the Shift key is down
62      *     handler.keyMask = OpenLayers.Handler.MOD_SHIFT;
63      *
64      *     // handler only responds if Ctrl-Shift is down
65      *     handler.keyMask = OpenLayers.Handler.MOD_SHIFT |
66      *                       OpenLayers.Handler.MOD_CTRL;
67      * (end)
68      */
69     keyMask: null,
70
71     /**
72      * Property: active
73      * {Boolean}
74      */
75     active: false,
76     
77     /**
78      * Property: evt
79      * {Event} This property references the last event handled by the handler.
80      *     Note that this property is not part of the stable API.  Use of the
81      *     evt property should be restricted to controls in the library
82      *     or other applications that are willing to update with changes to
83      *     the OpenLayers code.
84      */
85     evt: null,
86
87     /**
88      * Constructor: OpenLayers.Handler
89      * Construct a handler.
90      *
91      * Parameters:
92      * control - {<OpenLayers.Control>} The control that initialized this
93      *     handler.  The control is assumed to have a valid map property; that
94      *     map is used in the handler's own setMap method.
95      * callbacks - {Object} An object whose properties correspond to abstracted
96      *     events or sequences of browser events.  The values for these
97      *     properties are functions defined by the control that get called by
98      *     the handler.
99      * options - {Object} An optional object whose properties will be set on
100      *     the handler.
101      */
102     initialize: function(control, callbacks, options) {
103         OpenLayers.Util.extend(this, options);
104         this.control = control;
105         this.callbacks = callbacks;
106         if (control.map) {
107             this.setMap(control.map); 
108         }
109
110         OpenLayers.Util.extend(this, options);
111         
112         this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME + "_");
113     },
114     
115     /**
116      * Method: setMap
117      */
118     setMap: function (map) {
119         this.map = map;
120     },
121
122     /**
123      * Method: checkModifiers
124      * Check the keyMask on the handler.  If no <keyMask> is set, this always
125      *     returns true.  If a <keyMask> is set and it matches the combination
126      *     of keys down on an event, this returns true.
127      *
128      * Returns:
129      * {Boolean} The keyMask matches the keys down on an event.
130      */
131     checkModifiers: function (evt) {
132         if(this.keyMask == null) {
133             return true;
134         }
135         /* calculate the keyboard modifier mask for this event */
136         var keyModifiers =
137             (evt.shiftKey ? OpenLayers.Handler.MOD_SHIFT : 0) |
138             (evt.ctrlKey  ? OpenLayers.Handler.MOD_CTRL  : 0) |
139             (evt.altKey   ? OpenLayers.Handler.MOD_ALT   : 0);
140     
141         /* if it differs from the handler object's key mask,
142            bail out of the event handler */
143         return (keyModifiers == this.keyMask);
144     },
145
146     /**
147      * APIMethod: activate
148      * Turn on the handler.  Returns false if the handler was already active.
149      * 
150      * Returns: 
151      * {Boolean} The handler was activated.
152      */
153     activate: function() {
154         if(this.active) {
155             return false;
156         }
157         // register for event handlers defined on this class.
158         var events = OpenLayers.Events.prototype.BROWSER_EVENTS;
159         for (var i=0, len=events.length; i<len; i++) {
160             if (this[events[i]]) {
161                 this.register(events[i], this[events[i]]); 
162             }
163         } 
164         this.active = true;
165         return true;
166     },
167     
168     /**
169      * APIMethod: deactivate
170      * Turn off the handler.  Returns false if the handler was already inactive.
171      * 
172      * Returns:
173      * {Boolean} The handler was deactivated.
174      */
175     deactivate: function() {
176         if(!this.active) {
177             return false;
178         }
179         // unregister event handlers defined on this class.
180         var events = OpenLayers.Events.prototype.BROWSER_EVENTS;
181         for (var i=0, len=events.length; i<len; i++) {
182             if (this[events[i]]) {
183                 this.unregister(events[i], this[events[i]]); 
184             }
185         } 
186         this.active = false;
187         return true;
188     },
189
190     /**
191     * Method: callback
192     * Trigger the control's named callback with the given arguments
193     *
194     * Parameters:
195     * name - {String} The key for the callback that is one of the properties
196     *     of the handler's callbacks object.
197     * args - {Array(*)} An array of arguments (any type) with which to call 
198     *     the callback (defined by the control).
199     */
200     callback: function (name, args) {
201         if (name && this.callbacks[name]) {
202             this.callbacks[name].apply(this.control, args);
203         }
204     },
205
206     /**
207     * Method: register
208     * register an event on the map
209     */
210     register: function (name, method) {
211         // TODO: deal with registerPriority in 3.0
212         this.map.events.registerPriority(name, this, method);
213         this.map.events.registerPriority(name, this, this.setEvent);
214     },
215
216     /**
217     * Method: unregister
218     * unregister an event from the map
219     */
220     unregister: function (name, method) {
221         this.map.events.unregister(name, this, method);   
222         this.map.events.unregister(name, this, this.setEvent);
223     },
224     
225     /**
226      * Method: setEvent
227      * With each registered browser event, the handler sets its own evt
228      *     property.  This property can be accessed by controls if needed
229      *     to get more information about the event that the handler is
230      *     processing.
231      *
232      * This allows modifier keys on the event to be checked (alt, shift,
233      *     and ctrl cannot be checked with the keyboard handler).  For a
234      *     control to determine which modifier keys are associated with the
235      *     event that a handler is currently processing, it should access
236      *     (code)handler.evt.altKey || handler.evt.shiftKey ||
237      *     handler.evt.ctrlKey(end).
238      *
239      * Parameters:
240      * evt - {Event} The browser event.
241      */
242     setEvent: function(evt) {
243         this.evt = evt;
244         return true;
245     },
246
247     /**
248      * Method: destroy
249      * Deconstruct the handler.
250      */
251     destroy: function () {
252         // unregister event listeners
253         this.deactivate();
254         // eliminate circular references
255         this.control = this.map = null;        
256     },
257
258     CLASS_NAME: "OpenLayers.Handler"
259 });
260
261 /**
262  * Constant: OpenLayers.Handler.MOD_NONE
263  * If set as the <keyMask>, <checkModifiers> returns false if any key is down.
264  */
265 OpenLayers.Handler.MOD_NONE  = 0;
266
267 /**
268  * Constant: OpenLayers.Handler.MOD_SHIFT
269  * If set as the <keyMask>, <checkModifiers> returns false if Shift is down.
270  */
271 OpenLayers.Handler.MOD_SHIFT = 1;
272
273 /**
274  * Constant: OpenLayers.Handler.MOD_CTRL
275  * If set as the <keyMask>, <checkModifiers> returns false if Ctrl is down.
276  */
277 OpenLayers.Handler.MOD_CTRL  = 2;
278
279 /**
280  * Constant: OpenLayers.Handler.MOD_ALT
281  * If set as the <keyMask>, <checkModifiers> returns false if Alt is down.
282  */
283 OpenLayers.Handler.MOD_ALT   = 4;
284
285