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. */
6
* @requires OpenLayers/Control.js
10
* Class: OpenLayers.Control.NavigationHistory
11
* A navigation history control. This is a meta-control, that creates two
12
* dependent controls: <previous> and <next>. Call the trigger method
13
* on the <previous> and <next> controls to restore previous and next
14
* history states. The previous and next controls will become active
15
* when there are available states to restore and will become deactive
16
* when there are no states to restore.
19
* - <OpenLayers.Control>
21
OpenLayers.Control.NavigationHistory = OpenLayers.Class(OpenLayers.Control, {
25
* {String} Note that this control is not intended to be added directly
26
* to a control panel. Instead, add the sub-controls previous and
27
* next. These sub-controls are button type controls that activate
28
* and deactivate themselves. If this parent control is added to
29
* a panel, it will act as a toggle.
31
type: OpenLayers.Control.TYPE_TOGGLE,
34
* APIProperty: previous
35
* {<OpenLayers.Control>} A button type control whose trigger method restores
36
* the previous state managed by this control.
41
* APIProperty: previousOptions
42
* {Object} Set this property on the options argument of the constructor
43
* to set optional properties on the <previous> control.
45
previousOptions: null,
49
* {<OpenLayers.Control>} A button type control whose trigger method restores
50
* the next state managed by this control.
55
* APIProperty: nextOptions
56
* {Object} Set this property on the options argument of the constructor
57
* to set optional properties on the <next> control.
63
* {Integer} Optional limit on the number of history items to retain. If
64
* null, there is no limit. Default is 50.
69
* Property: activateOnDraw
70
* {Boolean} Activate the control when it is first added to the map.
76
* Property: clearOnDeactivate
77
* {Boolean} Clear the history when the control is deactivated. Default
80
clearOnDeactivate: false,
84
* {Object} An object with keys corresponding to event types. Values
85
* are functions that return an object representing the current state.
91
* {Array} Array of items in the history.
96
* Property: previousStack
97
* {Array} List of items in the history. First item represents the current
103
* Property: listeners
104
* {Object} An object containing properties corresponding to event types.
105
* This object is used to configure the control and is modified on
111
* Property: restoring
112
* {Boolean} Currently restoring a history state. This is set to true
113
* before calling restore and set to false after restore returns.
118
* Constructor: OpenLayers.Control.NavigationHistory
121
* options - {Object} An optional object whose properties will be used
122
* to extend the control.
124
initialize: function(options) {
125
OpenLayers.Control.prototype.initialize.apply(this, [options]);
127
this.registry = OpenLayers.Util.extend({
128
"moveend": function() {
130
center: this.map.getCenter(),
131
resolution: this.map.getResolution()
138
var previousOptions = {
139
trigger: OpenLayers.Function.bind(this.previousTrigger, this),
140
displayClass: this.displayClass + " " + this.displayClass + "Previous"
142
OpenLayers.Util.extend(previousOptions, this.previousOptions);
143
this.previous = new OpenLayers.Control.Button(previousOptions);
146
trigger: OpenLayers.Function.bind(this.nextTrigger, this),
147
displayClass: this.displayClass + " " + this.displayClass + "Next"
149
OpenLayers.Util.extend(nextOptions, this.nextOptions);
150
this.next = new OpenLayers.Control.Button(nextOptions);
155
* Method: onPreviousChange
156
* Called when the previous history stack changes.
159
* state - {Object} An object representing the state to be restored
160
* if previous is triggered again or null if no previous states remain.
161
* length - {Integer} The number of remaining previous states that can
164
onPreviousChange: function(state, length) {
165
if(state && !this.previous.active) {
166
this.previous.activate();
167
} else if(!state && this.previous.active) {
168
this.previous.deactivate();
173
* Method: onNextChange
174
* Called when the next history stack changes.
177
* state - {Object} An object representing the state to be restored
178
* if next is triggered again or null if no next states remain.
179
* length - {Integer} The number of remaining next states that can
182
onNextChange: function(state, length) {
183
if(state && !this.next.active) {
184
this.next.activate();
185
} else if(!state && this.next.active) {
186
this.next.deactivate();
192
* Destroy the control.
194
destroy: function() {
195
OpenLayers.Control.prototype.destroy.apply(this);
196
this.previous.destroy();
199
for(var prop in this) {
206
* Set the map property for the control and <previous> and <next> child
210
* map - {<OpenLayers.Map>}
212
setMap: function(map) {
214
this.next.setMap(map);
215
this.previous.setMap(map);
220
* Called when the control is added to the map.
223
OpenLayers.Control.prototype.draw.apply(this, arguments);
225
this.previous.draw();
226
if(this.activateOnDraw) {
232
* Method: previousTrigger
233
* Restore the previous state. If no items are in the previous history
234
* stack, this has no effect.
237
* {Object} Item representing state that was restored. Undefined if no
238
* items are in the previous history stack.
240
previousTrigger: function() {
241
var current = this.previousStack.shift();
242
var state = this.previousStack.shift();
243
if(state != undefined) {
244
this.nextStack.unshift(current);
245
this.previousStack.unshift(state);
246
this.restoring = true;
248
this.restoring = false;
249
this.onNextChange(this.nextStack[0], this.nextStack.length);
250
this.onPreviousChange(
251
this.previousStack[1], this.previousStack.length - 1
254
this.previousStack.unshift(current);
260
* APIMethod: nextTrigger
261
* Restore the next state. If no items are in the next history
262
* stack, this has no effect. The next history stack is populated
263
* as states are restored from the previous history stack.
266
* {Object} Item representing state that was restored. Undefined if no
267
* items are in the next history stack.
269
nextTrigger: function() {
270
var state = this.nextStack.shift();
271
if(state != undefined) {
272
this.previousStack.unshift(state);
273
this.restoring = true;
275
this.restoring = false;
276
this.onNextChange(this.nextStack[0], this.nextStack.length);
277
this.onPreviousChange(
278
this.previousStack[1], this.previousStack.length - 1
289
this.previousStack = [];
295
* Update the state with the given object.
298
* state - {Object} An object representing the state to restore.
300
restore: function(state) {
301
var zoom = this.map.getZoomForResolution(state.resolution);
302
this.map.setCenter(state.center, zoom);
306
* Method: setListeners
307
* Sets functions to be registered in the listeners object.
309
setListeners: function() {
311
for(var type in this.registry) {
312
this.listeners[type] = OpenLayers.Function.bind(function() {
313
if(!this.restoring) {
314
var state = this.registry[type].apply(this, arguments);
315
this.previousStack.unshift(state);
316
if(this.previousStack.length > 1) {
317
this.onPreviousChange(
318
this.previousStack[1], this.previousStack.length - 1
321
if(this.previousStack.length > (this.limit + 1)) {
322
this.previousStack.pop();
324
if(this.nextStack.length > 0) {
326
this.onNextChange(null, 0);
335
* APIMethod: activate
336
* Activate the control. This registers any listeners.
339
* {Boolean} Control successfully activated.
341
activate: function() {
342
var activated = false;
344
if(OpenLayers.Control.prototype.activate.apply(this)) {
345
if(this.listeners == null) {
348
for(var type in this.listeners) {
349
this.map.events.register(type, this, this.listeners[type]);
352
if(this.previousStack.length == 0) {
362
* Called after the control is activated if the previous history stack is
365
initStack: function() {
366
if(this.map.getCenter()) {
367
this.listeners.moveend();
372
* APIMethod: deactivate
373
* Deactivate the control. This unregisters any listeners.
376
* {Boolean} Control successfully deactivated.
378
deactivate: function() {
379
var deactivated = false;
381
if(OpenLayers.Control.prototype.deactivate.apply(this)) {
382
for(var type in this.listeners) {
383
this.map.events.unregister(
384
type, this, this.listeners[type]
387
if(this.clearOnDeactivate) {
396
CLASS_NAME: "OpenLayers.Control.NavigationHistory"