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
|
|