~mortenoh/+junk/dhis2-detailed-import-export

« back to all changes in this revision

Viewing changes to gis/dhis-gis-geostat/mfbase/openlayers/lib/OpenLayers/Control/NavigationHistory.js

  • Committer: larshelge at gmail
  • Date: 2009-03-03 16:46:36 UTC
  • Revision ID: larshelge@gmail.com-20090303164636-2sjlrquo7ib1gf7r
Initial check-in

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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/Control.js
 
7
 */
 
8
 
 
9
/**
 
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.
 
17
 *
 
18
 * Inherits from:
 
19
 *  - <OpenLayers.Control>
 
20
 */
 
21
OpenLayers.Control.NavigationHistory = OpenLayers.Class(OpenLayers.Control, {
 
22
 
 
23
    /**
 
24
     * Property: type
 
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.
 
30
     */
 
31
    type: OpenLayers.Control.TYPE_TOGGLE,
 
32
 
 
33
    /**
 
34
     * APIProperty: previous
 
35
     * {<OpenLayers.Control>} A button type control whose trigger method restores
 
36
     *     the previous state managed by this control.
 
37
     */
 
38
    previous: null,
 
39
    
 
40
    /**
 
41
     * APIProperty: previousOptions
 
42
     * {Object} Set this property on the options argument of the constructor
 
43
     *     to set optional properties on the <previous> control.
 
44
     */
 
45
    previousOptions: null,
 
46
    
 
47
    /**
 
48
     * APIProperty: next
 
49
     * {<OpenLayers.Control>} A button type control whose trigger method restores
 
50
     *     the next state managed by this control.
 
51
     */
 
52
    next: null,
 
53
 
 
54
    /**
 
55
     * APIProperty: nextOptions
 
56
     * {Object} Set this property on the options argument of the constructor
 
57
     *     to set optional properties on the <next> control.
 
58
     */
 
59
    nextOptions: null,
 
60
 
 
61
    /**
 
62
     * APIProperty: limit
 
63
     * {Integer} Optional limit on the number of history items to retain.  If
 
64
     *     null, there is no limit.  Default is 50.
 
65
     */
 
66
    limit: 50,
 
67
 
 
68
    /**
 
69
     * Property: activateOnDraw
 
70
     * {Boolean} Activate the control when it is first added to the map.
 
71
     *     Default is true.
 
72
     */
 
73
    activateOnDraw: true,
 
74
 
 
75
    /**
 
76
     * Property: clearOnDeactivate
 
77
     * {Boolean} Clear the history when the control is deactivated.  Default
 
78
     *     is false.
 
79
     */
 
80
    clearOnDeactivate: false,
 
81
 
 
82
    /**
 
83
     * Property: registry
 
84
     * {Object} An object with keys corresponding to event types.  Values
 
85
     *     are functions that return an object representing the current state.
 
86
     */
 
87
    registry: null,
 
88
 
 
89
    /**
 
90
     * Property: nextStack
 
91
     * {Array} Array of items in the history.
 
92
     */
 
93
    nextStack: null,
 
94
 
 
95
    /**
 
96
     * Property: previousStack
 
97
     * {Array} List of items in the history.  First item represents the current
 
98
     *     state.
 
99
     */
 
100
    previousStack: null,
 
101
    
 
102
    /**
 
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
 
106
     *     construction.
 
107
     */
 
108
    listeners: null,
 
109
    
 
110
    /**
 
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.
 
114
     */
 
115
    restoring: false,
 
116
    
 
117
    /**
 
118
     * Constructor: OpenLayers.Control.NavigationHistory 
 
119
     * 
 
120
     * Parameters:
 
121
     * options - {Object} An optional object whose properties will be used
 
122
     *     to extend the control.
 
123
     */
 
124
    initialize: function(options) {
 
125
        OpenLayers.Control.prototype.initialize.apply(this, [options]);
 
126
        
 
127
        this.registry = OpenLayers.Util.extend({
 
128
            "moveend": function() {
 
129
                return {
 
130
                    center: this.map.getCenter(),
 
131
                    resolution: this.map.getResolution()                
 
132
                };
 
133
            }
 
134
        }, this.registry);
 
135
        
 
136
        this.clear();
 
137
 
 
138
        var previousOptions = {
 
139
            trigger: OpenLayers.Function.bind(this.previousTrigger, this),
 
140
            displayClass: this.displayClass + " " + this.displayClass + "Previous"
 
141
        };
 
142
        OpenLayers.Util.extend(previousOptions, this.previousOptions);
 
143
        this.previous = new OpenLayers.Control.Button(previousOptions);
 
144
        
 
145
        var nextOptions = {
 
146
            trigger: OpenLayers.Function.bind(this.nextTrigger, this),
 
147
            displayClass: this.displayClass + " " + this.displayClass + "Next"
 
148
        };
 
149
        OpenLayers.Util.extend(nextOptions, this.nextOptions);
 
150
        this.next = new OpenLayers.Control.Button(nextOptions);
 
151
 
 
152
    },
 
153
    
 
154
    /**
 
155
     * Method: onPreviousChange
 
156
     * Called when the previous history stack changes.
 
157
     *
 
158
     * Parameters:
 
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
 
162
     *     be restored.
 
163
     */
 
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();
 
169
        }
 
170
    },
 
171
    
 
172
    /**
 
173
     * Method: onNextChange
 
174
     * Called when the next history stack changes.
 
175
     *
 
176
     * Parameters:
 
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
 
180
     *     be restored.
 
181
     */
 
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();
 
187
        }
 
188
    },
 
189
    
 
190
    /**
 
191
     * APIMethod: destroy
 
192
     * Destroy the control.
 
193
     */
 
194
    destroy: function() {
 
195
        OpenLayers.Control.prototype.destroy.apply(this);
 
196
        this.previous.destroy();
 
197
        this.next.destroy();
 
198
        this.deactivate();
 
199
        for(var prop in this) {
 
200
            this[prop] = null;
 
201
        }
 
202
    },
 
203
    
 
204
    /** 
 
205
     * Method: setMap
 
206
     * Set the map property for the control and <previous> and <next> child
 
207
     *     controls.
 
208
     *
 
209
     * Parameters:
 
210
     * map - {<OpenLayers.Map>} 
 
211
     */
 
212
    setMap: function(map) {
 
213
        this.map = map;
 
214
        this.next.setMap(map);
 
215
        this.previous.setMap(map);
 
216
    },
 
217
 
 
218
    /**
 
219
     * Method: draw
 
220
     * Called when the control is added to the map.
 
221
     */
 
222
    draw: function() {
 
223
        OpenLayers.Control.prototype.draw.apply(this, arguments);
 
224
        this.next.draw();
 
225
        this.previous.draw();
 
226
        if(this.activateOnDraw) {
 
227
            this.activate();
 
228
        }
 
229
    },
 
230
    
 
231
    /**
 
232
     * Method: previousTrigger
 
233
     * Restore the previous state.  If no items are in the previous history
 
234
     *     stack, this has no effect.
 
235
     *
 
236
     * Returns:
 
237
     * {Object} Item representing state that was restored.  Undefined if no
 
238
     *     items are in the previous history stack.
 
239
     */
 
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;
 
247
            this.restore(state);
 
248
            this.restoring = false;
 
249
            this.onNextChange(this.nextStack[0], this.nextStack.length);
 
250
            this.onPreviousChange(
 
251
                this.previousStack[1], this.previousStack.length - 1
 
252
            );
 
253
        } else {
 
254
            this.previousStack.unshift(current);
 
255
        }
 
256
        return state;
 
257
    },
 
258
    
 
259
    /**
 
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.
 
264
     *
 
265
     * Returns:
 
266
     * {Object} Item representing state that was restored.  Undefined if no
 
267
     *     items are in the next history stack.
 
268
     */
 
269
    nextTrigger: function() {
 
270
        var state = this.nextStack.shift();
 
271
        if(state != undefined) {
 
272
            this.previousStack.unshift(state);
 
273
            this.restoring = true;
 
274
            this.restore(state);
 
275
            this.restoring = false;
 
276
            this.onNextChange(this.nextStack[0], this.nextStack.length);
 
277
            this.onPreviousChange(
 
278
                this.previousStack[1], this.previousStack.length - 1
 
279
            );
 
280
        }
 
281
        return state;
 
282
    },
 
283
    
 
284
    /**
 
285
     * APIMethod: clear
 
286
     * Clear history.
 
287
     */
 
288
    clear: function() {
 
289
        this.previousStack = [];
 
290
        this.nextStack = [];
 
291
    },
 
292
 
 
293
    /**
 
294
     * Method: restore
 
295
     * Update the state with the given object.
 
296
     *
 
297
     * Parameters:
 
298
     * state - {Object} An object representing the state to restore.
 
299
     */
 
300
    restore: function(state) {
 
301
        var zoom = this.map.getZoomForResolution(state.resolution);
 
302
        this.map.setCenter(state.center, zoom);
 
303
    },
 
304
    
 
305
    /**
 
306
     * Method: setListeners
 
307
     * Sets functions to be registered in the listeners object.
 
308
     */
 
309
    setListeners: function() {
 
310
        this.listeners = {};
 
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
 
319
                        );
 
320
                    }
 
321
                    if(this.previousStack.length > (this.limit + 1)) {
 
322
                        this.previousStack.pop();
 
323
                    }
 
324
                    if(this.nextStack.length > 0) {
 
325
                        this.nextStack = [];
 
326
                        this.onNextChange(null, 0);
 
327
                    }
 
328
                }
 
329
                return true;
 
330
            }, this);
 
331
        }
 
332
    },
 
333
 
 
334
    /**
 
335
     * APIMethod: activate
 
336
     * Activate the control.  This registers any listeners.
 
337
     *
 
338
     * Returns:
 
339
     * {Boolean} Control successfully activated.
 
340
     */
 
341
    activate: function() {
 
342
        var activated = false;
 
343
        if(this.map) {
 
344
            if(OpenLayers.Control.prototype.activate.apply(this)) {
 
345
                if(this.listeners == null) {
 
346
                    this.setListeners();
 
347
                }
 
348
                for(var type in this.listeners) {
 
349
                    this.map.events.register(type, this, this.listeners[type]);
 
350
                }
 
351
                activated = true;
 
352
                if(this.previousStack.length == 0) {
 
353
                    this.initStack();
 
354
                }
 
355
            }
 
356
        }
 
357
        return activated;
 
358
    },
 
359
    
 
360
    /**
 
361
     * Method: initStack
 
362
     * Called after the control is activated if the previous history stack is
 
363
     *     empty.
 
364
     */
 
365
    initStack: function() {
 
366
        if(this.map.getCenter()) {
 
367
            this.listeners.moveend();
 
368
        }
 
369
    },
 
370
    
 
371
    /**
 
372
     * APIMethod: deactivate
 
373
     * Deactivate the control.  This unregisters any listeners.
 
374
     *
 
375
     * Returns:
 
376
     * {Boolean} Control successfully deactivated.
 
377
     */
 
378
    deactivate: function() {
 
379
        var deactivated = false;
 
380
        if(this.map) {
 
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]
 
385
                    );
 
386
                }
 
387
                if(this.clearOnDeactivate) {
 
388
                    this.clear();
 
389
                }
 
390
                deactivated = true;
 
391
            }
 
392
        }
 
393
        return deactivated;
 
394
    },
 
395
    
 
396
    CLASS_NAME: "OpenLayers.Control.NavigationHistory"
 
397
});
 
398