1
|
/* Copyright (c) 2006 MetaCarta, Inc., published under the BSD license.
|
2
|
* See http://svn.openlayers.org/trunk/openlayers/license.txt for the full
|
3
|
* text of the license. */
|
4
|
|
5
|
/**
|
6
|
* @class
|
7
|
*/
|
8
|
OpenLayers.Events = Class.create();
|
9
|
OpenLayers.Events.prototype = {
|
10
|
|
11
|
/** @final @type Array: supported events */
|
12
|
BROWSER_EVENTS: [
|
13
|
"mouseover", "mouseout",
|
14
|
"mousedown", "mouseup", "mousemove",
|
15
|
"click", "dblclick",
|
16
|
"resize", "focus", "blur"
|
17
|
],
|
18
|
|
19
|
/** Hashtable of Array(Function): events listener functions
|
20
|
* @type Object */
|
21
|
listeners: null,
|
22
|
|
23
|
/** @type Object: the code object issuing application events */
|
24
|
object: null,
|
25
|
|
26
|
/** @type DOMElement: the DOM element receiving browser events */
|
27
|
element: null,
|
28
|
|
29
|
/** @type Array: list of support application events */
|
30
|
eventTypes: null,
|
31
|
|
32
|
|
33
|
/**
|
34
|
* @constructor
|
35
|
*
|
36
|
* @param {OpenLayers.Map} object The js object to which this Events object
|
37
|
* is being added
|
38
|
* @param {DOMElement} element A dom element to respond to browser events
|
39
|
* @param {Array} eventTypes Array of custom application events
|
40
|
*/
|
41
|
initialize: function (object, element, eventTypes) {
|
42
|
this.object = object;
|
43
|
this.element = element;
|
44
|
this.eventTypes = eventTypes;
|
45
|
this.listeners = new Object();
|
46
|
|
47
|
// if eventTypes is specified, create a listeners list for each
|
48
|
// custom application event.
|
49
|
if (this.eventTypes != null)
|
50
|
for (var i = 0; i < this.eventTypes.length; i++)
|
51
|
this.listeners[ this.eventTypes[i] ] = new Array();
|
52
|
|
53
|
// if a dom element is specified, add a listeners list
|
54
|
// for browser events on the element and register them
|
55
|
if (this.element != null)
|
56
|
this.attachToElement(element);
|
57
|
},
|
58
|
|
59
|
/**
|
60
|
* @param {HTMLDOMElement} element a DOM element to attach browser events to
|
61
|
*/
|
62
|
attachToElement: function (element) {
|
63
|
for (var i = 0; i < this.BROWSER_EVENTS.length; i++) {
|
64
|
var eventType = this.BROWSER_EVENTS[i];
|
65
|
|
66
|
// every browser event has a corresponding application event
|
67
|
// (whether it's listened for or not).
|
68
|
if (this.listeners[eventType] == null)
|
69
|
this.listeners[eventType] = new Array();
|
70
|
|
71
|
// use Prototype to register the event cross-browser
|
72
|
Event.observe(element, eventType,
|
73
|
this.handleBrowserEvent.bindAsEventListener(this));
|
74
|
}
|
75
|
// disable dragstart in IE so that mousedown/move/up works normally
|
76
|
Event.observe(element, "dragstart", Event.stop);
|
77
|
},
|
78
|
|
79
|
/**
|
80
|
* @param {String} type Name of the event to register
|
81
|
* @param {Object} obj The object to bind the context to for the callback#.
|
82
|
* If no object is specified, default is the Events's
|
83
|
* 'object' property.
|
84
|
* @param {Function} func The callback function. If no callback is
|
85
|
* specified, this function does nothing.
|
86
|
*
|
87
|
* #When the event is triggered, the 'func' function will be called, in the
|
88
|
* context of 'obj'. Imagine we were to register an event, specifying an
|
89
|
* OpenLayers.Bounds Object as 'obj'. When the event is triggered, the
|
90
|
* context in the callback function will be our Bounds object. This means
|
91
|
* that within our callback function, we can access the properties and
|
92
|
* methods of the Bounds object through the "this" variable. So our
|
93
|
* callback could execute something like:
|
94
|
*
|
95
|
* leftStr = "Left: " + this.left;
|
96
|
*
|
97
|
* or
|
98
|
*
|
99
|
* centerStr = "Center: " + this.getCenterLonLat();
|
100
|
*
|
101
|
*/
|
102
|
register: function (type, obj, func) {
|
103
|
|
104
|
if (func != null) {
|
105
|
if (obj == null) {
|
106
|
obj = this.object;
|
107
|
}
|
108
|
var listeners = this.listeners[type];
|
109
|
if (listeners != null) {
|
110
|
listeners.push( {obj: obj, func: func} );
|
111
|
}
|
112
|
}
|
113
|
},
|
114
|
|
115
|
/**
|
116
|
* @param {String} type
|
117
|
* @param {Object} obj If none specified, defaults to this.object
|
118
|
* @param {Function} func
|
119
|
*/
|
120
|
unregister: function (type, obj, func) {
|
121
|
if (obj == null) {
|
122
|
obj = this.object;
|
123
|
}
|
124
|
var listeners = this.listeners[type];
|
125
|
if (listeners != null) {
|
126
|
for (var i = 0; i < listeners.length; i++) {
|
127
|
if (listeners[i].obj == obj && listeners[i].func == func) {
|
128
|
listeners.splice(i, 1);
|
129
|
break;
|
130
|
}
|
131
|
}
|
132
|
}
|
133
|
},
|
134
|
|
135
|
/** Remove all listeners for a given event type. If type is not registered,
|
136
|
* does nothing.
|
137
|
*
|
138
|
* @param {String} type
|
139
|
*/
|
140
|
remove: function(type) {
|
141
|
if (this.listeners[type] != null) {
|
142
|
this.listeners[type] = new Array();
|
143
|
}
|
144
|
},
|
145
|
|
146
|
/** Trigger a specified registered event
|
147
|
*
|
148
|
* @param {String} type
|
149
|
* @param {Event} evt
|
150
|
*/
|
151
|
triggerEvent: function (type, evt) {
|
152
|
|
153
|
// prep evt object with object & div references
|
154
|
if (evt == null) {
|
155
|
evt = new Object();
|
156
|
}
|
157
|
evt.object = this.object;
|
158
|
evt.element = this.element;
|
159
|
|
160
|
// execute all callbacks registered for specified type
|
161
|
var listeners = this.listeners[type];
|
162
|
if (listeners != null) {
|
163
|
|
164
|
for (var i = 0; i < listeners.length; i++) {
|
165
|
var callback = listeners[i];
|
166
|
var continueChain;
|
167
|
if (callback.obj != null) {
|
168
|
// use the 'call' method to bind the context to callback.obj
|
169
|
continueChain = callback.func.call(callback.obj, evt);
|
170
|
} else {
|
171
|
continueChain = callback.func(evt);
|
172
|
}
|
173
|
|
174
|
if ((continueChain != null) && (continueChain == false)) {
|
175
|
// if callback returns false, execute no more callbacks.
|
176
|
break;
|
177
|
}
|
178
|
}
|
179
|
}
|
180
|
},
|
181
|
|
182
|
/** Basically just a wrapper to the triggerEvent() function, but takes
|
183
|
* care to set a property 'xy' on the event with the current mouse
|
184
|
* position.
|
185
|
*
|
186
|
* @private
|
187
|
*
|
188
|
* @param {Event} evt
|
189
|
*/
|
190
|
handleBrowserEvent: function (evt) {
|
191
|
evt.xy = this.getMousePosition(evt);
|
192
|
this.triggerEvent(evt.type, evt)
|
193
|
},
|
194
|
|
195
|
/**
|
196
|
* @private
|
197
|
*
|
198
|
* @param {Event} evt
|
199
|
*
|
200
|
* @returns The current xy coordinate of the mouse, adjusted for offsets
|
201
|
* @type OpenLayers.Pixel
|
202
|
*/
|
203
|
getMousePosition: function (evt) {
|
204
|
if (!this.element.offsets) {
|
205
|
this.element.offsets = Position.page(this.element);
|
206
|
}
|
207
|
return new OpenLayers.Pixel(
|
208
|
evt.clientX - this.element.offsets[0],
|
209
|
evt.clientY - this.element.offsets[1]);
|
210
|
},
|
211
|
|
212
|
/** @final @type String */
|
213
|
CLASS_NAME: "OpenLayers.Events"
|
214
|
};
|