Project

General

Profile

1
/*
2
License: LGPL as per: http://www.gnu.org/copyleft/lesser.html
3
$Id: ButtonBase.js 3879 2008-02-27 14:20:29Z gjvoosten $
4
*/
5

    
6
// Ensure this object's dependancies are loaded.
7
mapbuilder.loadScript(baseDir+"/util/Util.js");
8
mapbuilder.loadScript(baseDir+"/widget/WidgetBase.js");
9

    
10
/**
11
 * Abstract base button object that all Buttons extend.  
12
 * A Button is a widget which renders an image and an optional second image 
13
 * for the enabled state.
14
 * @constructor
15
 * @base WidgetBase
16
 * @author Mike Adair mike.adairATccrs.nrcan.gc.ca
17
 * @param widgetNode The tool node from the Config XML file.
18
 * @param model The parent model object (optional).
19
 */
20
function ButtonBase(widgetNode, model) {
21
  WidgetBase.apply(this, new Array(widgetNode, model));
22

    
23
  this.htmlTagId = this.getProperty("mb:buttonBar");
24
  if (!this.htmlTagId) {
25
    this.htmlTagId = this.getProperty("mb:htmlTagId");
26
  }    
27
  if (!this.htmlTagId) {
28
    alert(mbGetMessage("buttonBarRequired", widgetNode.nodeName));
29
  }
30
  // Set button text values as parameters
31
  if (config.widgetText) {
32
    var textNodeXpath = "/mb:WidgetText/mb:widgets/mb:" + widgetNode.nodeName;
33
    var textParams = config.widgetText.selectNodes(textNodeXpath+"/*");
34
    for (var j=0;j<textParams.length;j++) {
35
      this[textParams[j].nodeName]=getNodeValue(textParams[j]);
36
    }
37
  }
38
  // html tag id of the div where OL places its panel code
39
  this.panelHtmlTagId = this.htmlTagId+'_panel';
40

    
41
  // load controlPanel.css for button base styles
42
  loadCss('controlPanel.css');
43

    
44
  //set the button type
45
  this.buttonType = this.getProperty("mb:class")
46
  this.buttonType = this.buttonType ? this.buttonType.toUpperCase() : null;
47
  if (this.buttonType == "RADIOBUTTON") this.enabled = false;
48
  
49
  // map between MB and OL button types
50
  this.olButtonType = {
51
      "RADIOBUTTON" : OpenLayers.Control.TYPE_TOOL,
52
      "TOOL"        : OpenLayers.Control.TYPE_TOOL,
53
      "BUTTON"      : OpenLayers.Control.TYPE_BUTTON,
54
      "TOGGLE"      : OpenLayers.Control.TYPE_TOGGLE
55
  }
56

    
57
  //set the button action
58
  this.action = this.getProperty("mb:action");
59
  
60
  // set the button tooltip
61
  var tooltip = this.getProperty("mb:tooltip");
62
  if (tooltip) {
63
    this.tooltip = tooltip;
64
  }
65

    
66
  //pre-load the button bar images; add them to the config
67
  var disabledImage = this.getProperty("mb:disabledSrc");
68
  if (disabledImage) {
69
    this.disabledImage = config.skinDir + disabledImage;
70
  }
71

    
72
  //optional second image to be displayed in the enabled state
73
  var enabledImage = this.getProperty("mb:enabledSrc");
74
  if (enabledImage) {
75
    this.enabledImage = config.skinDir + enabledImage;
76
  }
77

    
78
  this.cursor = 'default';
79

    
80
  // Check for cursor override
81
  this.cursor = this.getProperty("mb:cursor");
82

    
83
  //a button may be set as selected in the config file
84
  this.selected = Mapbuilder.parseBoolean(this.getProperty("mb:selected", false));
85

    
86
  /**
87
   * Gets the css classname for this button. We use this
88
   * to define the button styles.
89
   * @param objRef Reference to this object.
90
   * @param state 'Active' or 'Inactive' (case sensitive!)
91
   */
92
  this.getButtonClass = function(objRef, state) {
93
    var cssName;
94
    if (objRef.control.displayClass) {
95
      cssName = objRef.control.displayClass;
96
    } else {
97
      cssName = objRef.control.CLASS_NAME;
98
      cssName = cssName.replace(/OpenLayers/, 'ol').replace(/\./g, '');
99
    }
100
    cssName += 'Item';
101
    return '.' + cssName + state;
102
  }
103

    
104
  /**
105
   * OpenLayers control for this button.
106
   * This will be filled with the instance of the control
107
   * by the attachToOL method.
108
   */
109
  this.control = null;
110

    
111
  //TBD This is never called, but I think we can drop it
112
  // if we get rid of MB mouse handlers
113
  /**
114
   * Override this in buttons which inherit from this object to carry out the action.
115
   * This is the function that will be called either when the button is selected
116
   * via the select() method or on a mouseup event if there is an associated 
117
   * mouseHandler property in config.
118
   */
119
  this.doAction = function() {}
120

    
121
  /**
122
   * Select this button. Enables and disables associated tools,
123
   * then the control.trigger()/activate() methods make OL call
124
   * the doSelect method defined in derived classes.
125
   */
126
  this.select = function() {
127
    if (this.control.type == OpenLayers.Control.TYPE_BUTTON) {
128
      this.control.trigger();
129
    } else {
130
      this.panel.activateControl(this.control);
131
    }
132
  }
133

    
134
  /**
135
   * Method overriden by subclasses
136
   * @param objRef Reference to this object.
137
   * @param selected True when selected, false when deselected.
138
   */
139
  this.doSelect = function(objRef, selected) {
140
  }
141
  
142
  /**
143
   * Attaches the control for this button to OpenLayers
144
   * and add it to the buttonBar. When this method is called,
145
   * everything of the OL map is available.
146
   * @param {OpenLayers.Control} control to add.
147
   * @param objRef Reference to this object.
148
   */
149
  this.attachToOL = function(objRef,refreshId) {
150
    if (objRef.control) {
151
      return;
152
    }
153
  
154
    //pass in a widget ID to refresh only that widget
155
    if (refreshId && (refreshId!=objRef.id)) return;
156
    
157
    // nothing to do here if subclass does not have a
158
    // createControl method
159
    if (!objRef.createControl) return;
160

    
161
    // override the control from the subclass to add
162
    // MB-stuff to the activate and deactivate methods
163
    var SubclassControl = objRef.createControl(objRef);
164
    var type = objRef.olButtonType[objRef.buttonType] ||
165
        SubclassControl.prototype.type;
166
        
167
    var Control = OpenLayers.Class( SubclassControl, {
168
      objRef: objRef,
169
      type: type,
170
      superclass: SubclassControl.prototype,
171
      // call objRef.doSelect after OL activate from this control
172
      trigger: function() {
173
        if(this.superclass.trigger) {
174
          this.superclass.trigger.call(this);
175
        }
176
        objRef.doSelect(objRef, true);
177
      },
178
      activate: function() {
179
        if (this.superclass.activate.call(this)) {
180
          this.panel_div.style.backgroundImage = "url(\""+objRef.enabledImage+"\")";
181
      	  this.map.div.style.cursor = objRef.cursor;
182
      	  // store the cursor with the map object; this will be applied
183
      	  // to the map div again when setting the aoi on the
184
      	  // OpenLayers moveend event
185
      	  this.map.mbCursor = objRef.cursor;
186
          objRef.enabled = true;
187
          this.active = true;
188
          objRef.doSelect(objRef, true);
189
        }
190
      },
191
      // call objRef.doSelect after OL deactivate from this control
192
      deactivate: function() {
193
        if (this.superclass.deactivate.call(this)) {
194
          this.panel_div.style.backgroundImage = "url(\""+objRef.disabledImage+"\")";
195
          objRef.enabled = false;
196
          this.active = false;
197
          if (map.getControlsBy("active", true).length == 0) {
198
            this.map.div.style.cursor = "";
199
            this.map.mbCursor = "";
200
          }
201
          objRef.doSelect(objRef, false)
202
        }
203
      },
204
      destroy: function() {
205
        try {
206
          this.superclass.destroy.apply(this, arguments);
207
        } catch(e) {
208
          OpenLayers.Control.prototype.destroy.apply(this, arguments);
209
        }
210
        this.superclass = null;
211
        OpenLayers.Event.stopObservingElement(this.panel_div);
212
        this.objRef.panel.div.removeChild(this.panel_div);
213
        this.objRef.control = null;
214
        this.objRef = null;
215
        this.panel_div = null;
216
        this.div = null;
217
      }
218
    });
219

    
220
    // if the subclass provides an instantiateControl() method,
221
    // use it for instantiation. If not, instantiate directly
222
    if (!objRef.control) {
223
      objRef.control = objRef.instantiateControl ? objRef.instantiateControl(objRef, Control) : new Control();
224
    }
225
    
226
    // get the control from the createControl method of the subclass
227
    //objRef.control = objRef.createControl(objRef);
228
    var map = objRef.targetContext.map;
229
    objRef.panel = objRef.targetContext.buttonBars[objRef.htmlTagId];
230
    // create a panel, if we do not have one yet for this buttonBar
231
    // or if the old map.panel was destroyed
232
    if (!objRef.panel || objRef.panel.map == null) {
233
      // create a dom node for OL to use as panel
234
      if (!document.getElementById(objRef.panelHtmlTagId)) {
235
        var olPanelNode = document.createElement('div');
236
        olPanelNode.setAttribute('id', objRef.panelHtmlTagId);
237
        olPanelNode.setAttribute('class', 'olControlPanel');
238
        var parentNode = objRef.getNode();
239
        parentNode.appendChild(olPanelNode);
240
        parentNode.innerHTML += " ";
241
      }
242
      var Panel = OpenLayers.Class( OpenLayers.Control.Panel, {
243
        div: document.getElementById(objRef.panelHtmlTagId),
244
        defaultControl: null,
245
        destroy: function() {
246
          parentNode.removeChild(this.div);
247
          OpenLayers.Control.prototype.destroy.apply(this, arguments);
248
          this.div = null;
249
          objRef.panel = null;
250
        }
251
      });
252
      objRef.panel = new Panel();
253
      objRef.targetContext.buttonBars[objRef.htmlTagId] = objRef.panel;
254
      map.addControl(objRef.panel);
255
    }
256
    
257
    // add the control to the panel
258
    if (OpenLayers.Util.indexOf(objRef.control, objRef.panel.controls) == -1) {
259
      // we do not want to stop event propagation. So we save the original
260
      // Event.stop function...
261
      var originalStop = OpenLayers.Event.stop;
262
      // and overwrite it with a new one...
263
      OpenLayers.Event.stop = function(){};
264
      // now, thanks to boxing, this one will be assigned in addControls...
265
      objRef.panel.addControls(objRef.control);
266
      // and we can switch back to the original one.
267
      OpenLayers.Event.stop = originalStop;
268
    }
269
     
270
    // set tooltip for the button
271
    if (objRef.tooltip) {
272
      objRef.control.panel_div.title=objRef.tooltip;
273
    }
274
    
275
    //set default css style properties
276
    objRef.control.panel_div.style.backgroundImage = "url(\""+objRef.disabledImage+"\")";
277
          
278
    // activate the control if it is defined as selected in config
279
    if(objRef.selected == true) {
280
      objRef.control.activate();      
281
    }    
282
  }
283

    
284
  /**
285
   * Set the target context for the button, initialise the
286
   * buttonBars array in the context document and add a
287
   * listener to the target model for adding controls
288
   * to the OL map as soon as the map is initialized.
289
   * @param objRef Reference to this object.
290
   */  
291
  this.buttonInit = function(objRef) {
292
     //set the target context
293
    var targetContext = objRef.widgetNode.selectSingleNode("mb:targetContext");
294
    if (targetContext) {
295
      objRef.targetContext = window.config.objects[getNodeValue(targetContext)];
296
      if ( !objRef.targetModel ) {
297
        alert(mbGetMessage("noTargetContext", getNodeValue(targetContext), objRef.id));
298
      }
299
    } else {
300
      objRef.targetContext = objRef.targetModel;
301
    }
302
    
303
    // initialize button bars for the context
304
    if (!objRef.targetContext.buttonBars) {
305
      // this array in the context will hold all
306
      // buttonBars used by button widgets
307
      objRef.targetContext.buttonBars = new Array();
308
    }
309
    
310
    // add another event listener for the loaded context,
311
    // because we need the map to add panel and buttons,
312
    // and we do not have tha map yet
313
    objRef.targetContext.addListener("refresh", objRef.attachToOL, objRef);
314
  }
315

    
316
  this.model.addListener("init",this.buttonInit,this);
317
  this.model.removeListener("newNodel", this.clearWidget, this);
318
}
(14-14/145)