Project

General

Profile

Download (10.4 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/BaseTypes/Class.js
8
 * @requires OpenLayers/Events.js
9
 */
10

    
11
/**
12
 * Class: OpenLayers.Handler
13
 * Base class to construct a higher-level handler for event sequences.  All
14
 *     handlers have activate and deactivate methods.  In addition, they have
15
 *     methods named like browser events.  When a handler is activated, any
16
 *     additional methods named like a browser event is registered as a
17
 *     listener for the corresponding event.  When a handler is deactivated,
18
 *     those same methods are unregistered as event listeners.
19
 *
20
 * Handlers also typically have a callbacks object with keys named like
21
 *     the abstracted events or event sequences that they are in charge of
22
 *     handling.  The controls that wrap handlers define the methods that
23
 *     correspond to these abstract events - so instead of listening for
24
 *     individual browser events, they only listen for the abstract events
25
 *     defined by the handler.
26
 *     
27
 * Handlers are created by controls, which ultimately have the responsibility
28
 *     of making changes to the the state of the application.  Handlers
29
 *     themselves may make temporary changes, but in general are expected to
30
 *     return the application in the same state that they found it.
31
 */
32
OpenLayers.Handler = OpenLayers.Class({
33

    
34
    /**
35
     * Property: id
36
     * {String}
37
     */
38
    id: null,
39
        
40
    /**
41
     * APIProperty: control
42
     * {<OpenLayers.Control>}. The control that initialized this handler.  The
43
     *     control is assumed to have a valid map property - that map is used
44
     *     in the handler's own setMap method.
45
     */
46
    control: null,
47

    
48
    /**
49
     * Property: map
50
     * {<OpenLayers.Map>}
51
     */
52
    map: null,
53

    
54
    /**
55
     * APIProperty: keyMask
56
     * {Integer} Use bitwise operators and one or more of the OpenLayers.Handler
57
     *     constants to construct a keyMask.  The keyMask is used by
58
     *     <checkModifiers>.  If the keyMask matches the combination of keys
59
     *     down on an event, checkModifiers returns true.
60
     *
61
     * Example:
62
     * (code)
63
     *     // handler only responds if the Shift key is down
64
     *     handler.keyMask = OpenLayers.Handler.MOD_SHIFT;
65
     *
66
     *     // handler only responds if Ctrl-Shift is down
67
     *     handler.keyMask = OpenLayers.Handler.MOD_SHIFT |
68
     *                       OpenLayers.Handler.MOD_CTRL;
69
     * (end)
70
     */
71
    keyMask: null,
72

    
73
    /**
74
     * Property: active
75
     * {Boolean}
76
     */
77
    active: false,
78
    
79
    /**
80
     * Property: evt
81
     * {Event} This property references the last event handled by the handler.
82
     *     Note that this property is not part of the stable API.  Use of the
83
     *     evt property should be restricted to controls in the library
84
     *     or other applications that are willing to update with changes to
85
     *     the OpenLayers code.
86
     */
87
    evt: null,
88
    
89
    /**
90
     * Property: touch
91
     * {Boolean} Indicates the support of touch events. When touch events are 
92
     *     started touch will be true and all mouse related listeners will do 
93
     *     nothing.
94
     */
95
    touch: false,
96

    
97
    /**
98
     * Constructor: OpenLayers.Handler
99
     * Construct a handler.
100
     *
101
     * Parameters:
102
     * control - {<OpenLayers.Control>} The control that initialized this
103
     *     handler.  The control is assumed to have a valid map property; that
104
     *     map is used in the handler's own setMap method.  If a map property
105
     *     is present in the options argument it will be used instead.
106
     * callbacks - {Object} An object whose properties correspond to abstracted
107
     *     events or sequences of browser events.  The values for these
108
     *     properties are functions defined by the control that get called by
109
     *     the handler.
110
     * options - {Object} An optional object whose properties will be set on
111
     *     the handler.
112
     */
113
    initialize: function(control, callbacks, options) {
114
        OpenLayers.Util.extend(this, options);
115
        this.control = control;
116
        this.callbacks = callbacks;
117

    
118
        var map = this.map || control.map;
119
        if (map) {
120
            this.setMap(map); 
121
        }
122
        
123
        this.id = OpenLayers.Util.createUniqueID(this.CLASS_NAME + "_");
124
    },
125
    
126
    /**
127
     * Method: setMap
128
     */
129
    setMap: function (map) {
130
        this.map = map;
131
    },
132

    
133
    /**
134
     * Method: checkModifiers
135
     * Check the keyMask on the handler.  If no <keyMask> is set, this always
136
     *     returns true.  If a <keyMask> is set and it matches the combination
137
     *     of keys down on an event, this returns true.
138
     *
139
     * Returns:
140
     * {Boolean} The keyMask matches the keys down on an event.
141
     */
142
    checkModifiers: function (evt) {
143
        if(this.keyMask == null) {
144
            return true;
145
        }
146
        /* calculate the keyboard modifier mask for this event */
147
        var keyModifiers =
148
            (evt.shiftKey ? OpenLayers.Handler.MOD_SHIFT : 0) |
149
            (evt.ctrlKey  ? OpenLayers.Handler.MOD_CTRL  : 0) |
150
            (evt.altKey   ? OpenLayers.Handler.MOD_ALT   : 0) |
151
            (evt.metaKey  ? OpenLayers.Handler.MOD_META  : 0);
152
    
153
        /* if it differs from the handler object's key mask,
154
           bail out of the event handler */
155
        return (keyModifiers == this.keyMask);
156
    },
157

    
158
    /**
159
     * APIMethod: activate
160
     * Turn on the handler.  Returns false if the handler was already active.
161
     * 
162
     * Returns: 
163
     * {Boolean} The handler was activated.
164
     */
165
    activate: function() {
166
        if(this.active) {
167
            return false;
168
        }
169
        // register for event handlers defined on this class.
170
        var events = OpenLayers.Events.prototype.BROWSER_EVENTS;
171
        for (var i=0, len=events.length; i<len; i++) {
172
            if (this[events[i]]) {
173
                this.register(events[i], this[events[i]]); 
174
            }
175
        } 
176
        this.active = true;
177
        return true;
178
    },
179
    
180
    /**
181
     * APIMethod: deactivate
182
     * Turn off the handler.  Returns false if the handler was already inactive.
183
     * 
184
     * Returns:
185
     * {Boolean} The handler was deactivated.
186
     */
187
    deactivate: function() {
188
        if(!this.active) {
189
            return false;
190
        }
191
        // unregister event handlers defined on this class.
192
        var events = OpenLayers.Events.prototype.BROWSER_EVENTS;
193
        for (var i=0, len=events.length; i<len; i++) {
194
            if (this[events[i]]) {
195
                this.unregister(events[i], this[events[i]]); 
196
            }
197
        } 
198
        this.touch = false;
199
        this.active = false;
200
        return true;
201
    },
202

    
203
    /**
204
     * Method: startTouch
205
     * Start touch events, this method must be called by subclasses in 
206
     *     "touchstart" method. When touch events are started <touch> will be
207
     *     true and all mouse related listeners will do nothing.
208
     */
209
    startTouch: function() {
210
        if (!this.touch) {
211
            this.touch = true;
212
            var events = [
213
                "mousedown", "mouseup", "mousemove", "click", "dblclick",
214
                "mouseout"
215
            ];
216
            for (var i=0, len=events.length; i<len; i++) {
217
                if (this[events[i]]) {
218
                    this.unregister(events[i], this[events[i]]); 
219
                }
220
            } 
221
        }
222
    },
223

    
224
    /**
225
    * Method: callback
226
    * Trigger the control's named callback with the given arguments
227
    *
228
    * Parameters:
229
    * name - {String} The key for the callback that is one of the properties
230
    *     of the handler's callbacks object.
231
    * args - {Array(*)} An array of arguments (any type) with which to call 
232
    *     the callback (defined by the control).
233
    */
234
    callback: function (name, args) {
235
        if (name && this.callbacks[name]) {
236
            this.callbacks[name].apply(this.control, args);
237
        }
238
    },
239

    
240
    /**
241
    * Method: register
242
    * register an event on the map
243
    */
244
    register: function (name, method) {
245
        // TODO: deal with registerPriority in 3.0
246
        this.map.events.registerPriority(name, this, method);
247
        this.map.events.registerPriority(name, this, this.setEvent);
248
    },
249

    
250
    /**
251
    * Method: unregister
252
    * unregister an event from the map
253
    */
254
    unregister: function (name, method) {
255
        this.map.events.unregister(name, this, method);   
256
        this.map.events.unregister(name, this, this.setEvent);
257
    },
258
    
259
    /**
260
     * Method: setEvent
261
     * With each registered browser event, the handler sets its own evt
262
     *     property.  This property can be accessed by controls if needed
263
     *     to get more information about the event that the handler is
264
     *     processing.
265
     *
266
     * This allows modifier keys on the event to be checked (alt, shift, ctrl,
267
     *     and meta cannot be checked with the keyboard handler).  For a
268
     *     control to determine which modifier keys are associated with the
269
     *     event that a handler is currently processing, it should access
270
     *     (code)handler.evt.altKey || handler.evt.shiftKey ||
271
     *     handler.evt.ctrlKey || handler.evt.metaKey(end).
272
     *
273
     * Parameters:
274
     * evt - {Event} The browser event.
275
     */
276
    setEvent: function(evt) {
277
        this.evt = evt;
278
        return true;
279
    },
280

    
281
    /**
282
     * Method: destroy
283
     * Deconstruct the handler.
284
     */
285
    destroy: function () {
286
        // unregister event listeners
287
        this.deactivate();
288
        // eliminate circular references
289
        this.control = this.map = null;        
290
    },
291

    
292
    CLASS_NAME: "OpenLayers.Handler"
293
});
294

    
295
/**
296
 * Constant: OpenLayers.Handler.MOD_NONE
297
 * If set as the <keyMask>, <checkModifiers> returns false if any key is down.
298
 */
299
OpenLayers.Handler.MOD_NONE  = 0;
300

    
301
/**
302
 * Constant: OpenLayers.Handler.MOD_SHIFT
303
 * If set as the <keyMask>, <checkModifiers> returns false if Shift is down.
304
 */
305
OpenLayers.Handler.MOD_SHIFT = 1;
306

    
307
/**
308
 * Constant: OpenLayers.Handler.MOD_CTRL
309
 * If set as the <keyMask>, <checkModifiers> returns false if Ctrl is down.
310
 */
311
OpenLayers.Handler.MOD_CTRL  = 2;
312

    
313
/**
314
 * Constant: OpenLayers.Handler.MOD_ALT
315
 * If set as the <keyMask>, <checkModifiers> returns false if Alt is down.
316
 */
317
OpenLayers.Handler.MOD_ALT   = 4;
318

    
319
/**
320
 * Constant: OpenLayers.Handler.MOD_META
321
 * If set as the <keyMask>, <checkModifiers> returns false if Cmd is down.
322
 */
323
OpenLayers.Handler.MOD_META  = 8;
324

    
325

    
(10-10/35)