/* Custom control derived from the LayerSwitcher /** * @requires OpenLayers/Control.js */ // Global function to determine the number of elements in a non-nested array function array_size(arr) { var length = 0; for(val in arr) { length++; } return length; } /** * Class: OpenLayers.Control.Mapview_control * * Inherits from: * - */ OpenLayers.Control.Mapview_Control = OpenLayers.Class(OpenLayers.Control, { /** * Property: activeColor * {String} */ activeColor: mapviewcontrol_color, /** * Property: layerStates * {Array(Object)} Basically a copy of the "state" of the map's layers * the last time the control was drawn. We have this in order to avoid * unnecessarily redrawing the control. */ layerStates: null, /* * Offset used by up/down control (when needed) */ devIndex: 0, /* * Maximum index used by up/down control (when needed) */ devMaxIndex: 0, /* * Maximum index used by up/down control (when needed) */ devVisible: 0, // DOM Elements /** * Property: layersDiv * {DOMElement} */ layersDiv: null, /** * Property: baseLayersDiv * {DOMElement} */ baseLayersDiv: null, /** * Property: baseLayers * {Array()} */ baseLayers: null, /** * Property: dataLbl * {DOMElement} */ dataLbl: null, /** * Property: dataLayersDiv * {DOMElement} */ dataLayersDiv: null, /** * Property: dataLayers * {Array()} */ dataLayers: null, /** * Property: minimizeDiv * {DOMElement} */ minimizeDiv: null, /** * Property: maximizeDiv * {DOMElement} */ maximizeDiv: null, /** * APIProperty: ascending * {Boolean} */ ascending: true, /** * Constructor * * Parameters: * options - {Object} */ initialize: function(options) { OpenLayers.Control.prototype.initialize.apply(this, arguments); this.layerStates = []; }, /** * APIMethod: destroy */ destroy: function() { OpenLayers.Event.stopObservingElement(this.div); OpenLayers.Event.stopObservingElement(this.minimizeDiv); OpenLayers.Event.stopObservingElement(this.maximizeDiv); //clear out layers info and unregister their events this.clearLayersArray("base"); this.clearLayersArray("data"); this.map.events.un({ "addlayer": this.redraw, "changelayer": this.redraw, "removelayer": this.redraw, "changebaselayer": this.redraw, scope: this }); OpenLayers.Control.prototype.destroy.apply(this, arguments); }, /** * Method: setMap * * Properties: * map - {} */ setMap: function(map) { OpenLayers.Control.prototype.setMap.apply(this, arguments); this.map.events.on({ "addlayer": this.redraw, "changelayer": this.redraw, "removelayer": this.redraw, "changebaselayer": this.redraw, scope: this }); }, /** * Method: draw * * Returns: * {DOMElement} A reference to the DIV DOMElement containing the * switcher tabs. */ draw: function() { OpenLayers.Control.prototype.draw.apply(this); // create layout divs this.loadContents(); // set mode to minimize if(!this.outsideViewport) { this.minimizeControl(); } // populate div with current info this.redraw(); return this.div; }, /** * Method: clearLayersArray * User specifies either "base" or "data". we then clear all the * corresponding listeners, the div, and reinitialize a new array. * * Parameters: * layersType - {String} */ clearLayersArray: function(layersType) { var layers = this[layersType + "Layers"]; if (layers) { for(var i=0, len=layers.length; i"; labelSpan.style.verticalAlign = "baseline"; OpenLayers.Event.observe(labelSpan, "click", OpenLayers.Function.bindAsEventListener(this.onInputClick, context) ); // create line break var br = document.createElement("br"); this.baseLayers.push({ 'layer': layer, 'inputElem': inputElem, 'labelSpan': labelSpan }); this.baseLayersDiv.appendChild(inputElem); this.baseLayersDiv.appendChild(labelSpan); this.baseLayersDiv.appendChild(br); Items++; } } // Parse device type visibility (defined in mapview.js) var bHaveDevTypes = false; for (x in DeviceTypesVisible) { bHaveDevTypes = true; // create input element var inputElem = document.createElement("input"); inputElem.id = this.id + "_input_" + x; inputElem.className = 'checkbox_element'; inputElem.name = "devTypeVisibility_"+x; inputElem.type = "checkbox"; inputElem.value = x; inputElem.checked = DeviceTypesVisible[x]; inputElem.defaultChecked = DeviceTypesVisible[x]; var context = { 'inputElem': inputElem, 'layer': layer, 'layerSwitcher': this }; OpenLayers.Event.observe(inputElem, "mouseup", OpenLayers.Function.bindAsEventListener(this.onInputClick, context) ); // create span if (typeof(DevTypesToNames_transtbl[x]) != 'undefined') { var labelSpan = document.createElement("span"); labelSpan.innerHTML = ' '+DevTypesToNames_transtbl[x]+""; labelSpan.style.verticalAlign = "baseline"; OpenLayers.Event.observe(labelSpan, "click", OpenLayers.Function.bindAsEventListener(this.onInputClick, context) ); // create line break var br = document.createElement("br"); this.showndevicesLayers.push({ 'layer': layer, 'inputElem': inputElem, 'labelSpan': labelSpan }); this.showndevicesLayersDiv.appendChild(inputElem); this.showndevicesLayersDiv.appendChild(labelSpan); this.showndevicesLayersDiv.appendChild(br); Items++; } } // Parse devices for device finder // Detect number of visible devices for (x in ZKL_Markers) { if (typeof (ZKL_Markers[x]) != 'undefined') { if (DeviceTypesVisible[ZKL_Markers[x].s_devtype] == true || ZKL_Markers[x].s_icon == "nok") { Items++; Devices++; } } } // Add header labels to visible items Items += 3; // Get map height var VisibleItems = parseInt((getElement('map').offsetHeight/22)); // Store values this.devMaxIndex = Devices; this.devVisible = (Items <= VisibleItems) ? Devices : (VisibleItems - (Items - Devices)) - 2; // Add up button (when needed) if (Items > VisibleItems) { var inputElem = document.createElement("div"); inputElem.innerHTML = '
'; inputElem.id = this.id + "_arrow_up"; inputElem.className = 'mapviewcontrol_arrow'; var context = { 'inputElem': inputElem, 'layer': layer, 'layerSwitcher': this }; // Add event listeners OpenLayers.Event.observe(inputElem, "mouseup", OpenLayers.Function.bindAsEventListener(this.onInputClick, context)); OpenLayers.Event.observe(inputElem, "mousedown", OpenLayers.Function.bindAsEventListener(this.onInputClick, context)); OpenLayers.Event.observe(inputElem, "mouseout", OpenLayers.Function.bindAsEventListener(this.onInputClick, context)); // Add element this.devicefinderLayersDiv.appendChild(inputElem); } // Add 'view all' var bHaveDevices = false; var index = 0; var counter = 0; for (x in ZKL_Markers) { if (typeof (ZKL_Markers[x]) != 'undefined') { if (DeviceTypesVisible[ZKL_Markers[x].s_devtype] == true || ZKL_Markers[x].s_icon == "nok") { // All items visible? if ((Items <= VisibleItems) || ((index >= this.devIndex) && (counter < this.devVisible))) { bHaveDevices = true; // create input element var inputElem = document.createElement("input"); inputElem.id = this.id + "_input_" + x; inputElem.className = 'checkbox_element'; inputElem.name = "devTrack_" + x; inputElem.type = "checkbox"; inputElem.value = x; inputElem.checked = ZKL_Markers[x].ip_bTracking; inputElem.defaultChecked = ZKL_Markers[x].ip_bTracking; var context = { 'inputElem': inputElem, 'layer': layer, 'layerSwitcher': this }; OpenLayers.Event.observe(inputElem, "mouseup", OpenLayers.Function.bindAsEventListener(this.onInputClick, context) ); // Add visible/invisible image var inputElemVisible = document.createElement("span"); var image = (ZKL_Markers[x].bHidden) ? 'html/images/invisible.gif' : 'html/images/visible.gif'; inputElemVisible.innerHTML = '  '; inputElemVisible.style.height = '10px'; inputElemVisible.style.width = '20px'; var context = { 'inputElemVisible': inputElemVisible, 'layer': layer, 'layerSwitcher': this }; // create span var labelSpan = document.createElement("span"); labelSpan.id = this.id + "_input_" + x + "_label"; labelSpan.innerHTML = ''+ZKL_Markers[x].s_idcode+""; labelSpan.style.verticalAlign = "baseline"; if (ZKL_Markers[x].s_icon == "nok") { labelSpan.style.background = "red"; } else if ((typeof(ZKL_Markers[x].s_active) != 'undefined') && (ZKL_Markers[x].s_active.toLowerCase() == "active") && (ZKL_Markers[x].s_icon == "ok")) { labelSpan.style.background = "green"; } else if ((ZKL_Markers[x].s_icon == "error") && (ZKL_Markers[x].s_icon_info.toLowerCase().search("sleepmode") != -1)) { labelSpan.style.background = "yellow"; } this.devicefinderLayersDiv.appendChild(inputElem); this.devicefinderLayersDiv.appendChild(inputElemVisible); this.devicefinderLayersDiv.appendChild(labelSpan); // create line break var br = document.createElement("br"); this.devicefinderLayersDiv.appendChild(br); // Update counter counter++; } // Update index index++; } } } // Add down button (when needed) if (Items > VisibleItems) { var inputElem = document.createElement("div"); inputElem.innerHTML = '
'; inputElem.id = this.id + "_arrow_down"; inputElem.className = 'mapviewcontrol_arrow'; var context = { 'inputElem': inputElem, 'layer': layer, 'layerSwitcher': this }; // Add event listeners OpenLayers.Event.observe(inputElem, "mouseup", OpenLayers.Function.bindAsEventListener(this.onInputClick, context)); OpenLayers.Event.observe(inputElem, "mousedown", OpenLayers.Function.bindAsEventListener(this.onInputClick, context)); OpenLayers.Event.observe(inputElem, "mouseout", OpenLayers.Function.bindAsEventListener(this.onInputClick, context)); // Add element this.devicefinderLayersDiv.appendChild(inputElem); } // display device finder only if we have devices on the map this.devicefinderLbl.style.height = (bHaveDevices) ? 'auto' : '0px'; this.devicefinderLbl.style.visibility = (bHaveDevices) ? 'visible' : 'hidden'; this.devicefinderLayersDiv.style.height = (bHaveDevices) ? 'auto' : '0px'; return this.div; }, /** * Method: * A label has been clicked, check or uncheck its corresponding input * * Parameters: * e - {Event} * * Context: * - {DOMElement} inputElem * - {} layerSwitcher * - {} layer */ onInputClick: function(e) { if (!this.inputElem.disabled) { // Up/down control handler if ((this.inputElem.id.search("_arrow_up") != -1) || (this.inputElem.id.search("_arrow_down") != -1)) { if (e.type == "mousedown") { getElement(this.inputElem.id).style.borderStyle = 'inset'; if (this.inputElem.id.search("_arrow_up") != -1) { if (this.layerSwitcher.devIndex > 0) { this.layerSwitcher.devIndex--; this.layerSwitcher.NeedRedrawAnyway = true; } } else { if (this.layerSwitcher.devIndex < this.layerSwitcher.devMaxIndex) { if ((this.layerSwitcher.devMaxIndex - this.layerSwitcher.devIndex) > this.layerSwitcher.devVisible) { this.layerSwitcher.devIndex++; this.layerSwitcher.NeedRedrawAnyway = true; } } } } else { // Button pushed? if (this.layerSwitcher.NeedRedrawAnyway) { getElement(this.inputElem.id).style.borderStyle = 'outset'; this.layerSwitcher.forceRedraw(); } } } // Map control handler else if (this.inputElem.type == "radio") { this.inputElem.checked = true; this.layer.map.setBaseLayer(this.layer); } // Device control handler else { this.inputElem.checked = !this.inputElem.checked; // Is this a device-type checkbox? if (this.inputElem.name.substr(0,17) == "devTypeVisibility") { DeviceTypesVisible[this.inputElem.value] = this.inputElem.checked; this.layerSwitcher.forceRedraw(); } // Is this a device track checkbox? else if (this.inputElem.name.substr(0,9) == "devTrack_") { ZKL_Markers[this.inputElem.value].ip_bTracking = this.inputElem.checked; } } } // Reinit zoom control (only needed when map is changed!) if ((ExtendedMenu) && (this.inputElem.type == "radio")) { Extend_Zoom(ExtendedMenu); } OpenLayers.Event.stop(e); }, /** * Method: onLayerClick * Need to update the map accordingly whenever user clicks in either of * the layers. * * Parameters: * e - {Event} */ onLayerClick: function(e) { this.updateMap(); }, /** * Method: updateMap * Cycles through the loaded data and base layer input arrays and makes * the necessary calls to the Map object such that that the map's * visual state corresponds to what the user has selected in * the control. */ updateMap: function() { // set the newly selected base layer for(var i=0, len=this.baseLayers.length; i TBD autosizing this.div.style.width = "27em"; this.div.style.height = "auto"; this.showControls(false); if (e != null) { OpenLayers.Event.stop(e); } }, /** * Method: minimizeControl * Hide all the contents of the control, shrink the size, * add the maximize icon * * Parameters: * e - {Event} */ minimizeControl: function(e) { this.div.style.width = "0px"; this.div.style.height = "0px"; this.showControls(true); if (e != null) { OpenLayers.Event.stop(e); } }, /** * Method: showControls * Hide/Show all LayerSwitcher controls depending on whether we are * minimized or not * * Parameters: * minimize - {Boolean} */ showControls: function(minimize) { this.maximizeDiv.style.display = minimize ? "" : "none"; this.minimizeDiv.style.display = minimize ? "none" : ""; this.layersDiv.style.display = minimize ? "none" : ""; }, /** * Method: loadContents * Set up the labels and divs for the control */ loadContents: function() { //configure main div this.div.style.position = "absolute"; this.div.style.top = "5px"; this.div.style.right = "0px"; this.div.style.left = ""; this.div.style.fontFamily = "sans-serif"; this.div.style.fontWeight = "bold"; this.div.style.marginTop = "3px"; this.div.style.marginLeft = "3px"; this.div.style.marginBottom = "3px"; this.div.style.fontSize = "smaller"; this.div.style.color = "white"; this.div.style.backgroundColor = "transparent"; OpenLayers.Event.observe(this.div, "mouseup", OpenLayers.Function.bindAsEventListener(this.mouseUp, this)); OpenLayers.Event.observe(this.div, "click", this.ignoreEvent); OpenLayers.Event.observe(this.div, "mousedown", OpenLayers.Function.bindAsEventListener(this.mouseDown, this)); OpenLayers.Event.observe(this.div, "dblclick", this.ignoreEvent); // div containing sub layers this.layersDiv = document.createElement("div"); this.layersDiv.id = this.id + "_layersDiv"; this.layersDiv.style.paddingTop = "5px"; this.layersDiv.style.paddingLeft = "10px"; this.layersDiv.style.paddingBottom = "5px"; this.layersDiv.style.paddingRight = "75px"; this.layersDiv.style.backgroundColor = this.activeColor; this.layersDiv.style.width = "100%"; // HACK HACK (IE6 support) try { if (typeof(is_IE6) != "undefined") { this.layersDiv.style.width = "auto"; } } catch (err) { /* Silent Exception */ }; this.layersDiv.style.height = "100%"; // the basemap label this.baseLbl = document.createElement("div"); this.baseLbl.innerHTML = ''+StatusTranslationTable['baseMap']+''; this.baseLbl.style.marginTop = "1px"; this.baseLbl.style.marginLeft = "3px"; this.baseLbl.style.marginBottom = "1px"; this.baseLbl.style.fontSize = "120%"; // The basemap choices this.baseLayersDiv = document.createElement("div"); this.baseLayersDiv.style.paddingLeft = "15px"; this.baseLayersDiv.style.marginBottom = "0px"; this.baseLayersDiv.style.marginTop = "5px"; // The device types visibility label this.showndevicesLbl = document.createElement("div"); this.showndevicesLbl.innerHTML = ''+StatusTranslationTable['devTypes']+''; this.showndevicesLbl.style.marginTop = "5px"; this.showndevicesLbl.style.marginLeft = "3px"; this.showndevicesLbl.style.marginBottom = "1px"; this.showndevicesLbl.style.fontSize = "120%"; // The device types visibility control this.showndevicesLayersDiv = document.createElement("div"); this.showndevicesLayersDiv.style.paddingLeft = "15px"; this.showndevicesLayersDiv.style.marginTop = "5px"; // The device finder label this.devicefinderLbl = document.createElement("div"); this.devicefinderLbl.innerHTML = ''+StatusTranslationTable['devFinder']+''; this.devicefinderLbl.style.marginTop = "5px"; this.devicefinderLbl.style.marginLeft = "3px"; this.devicefinderLbl.style.marginBottom = "1px"; // The device finder control this.devicefinderLayersDiv = document.createElement("div"); this.devicefinderLayersDiv.style.paddingLeft = "15px"; this.devicefinderLayersDiv.style.marginTop = "5px"; // Merge DIV's this.layersDiv.appendChild(this.baseLbl); this.layersDiv.appendChild(this.baseLayersDiv); this.layersDiv.appendChild(this.showndevicesLbl); this.layersDiv.appendChild(this.showndevicesLayersDiv); this.layersDiv.appendChild(this.devicefinderLbl); this.layersDiv.appendChild(this.devicefinderLayersDiv); this.div.appendChild(this.layersDiv); OpenLayers.Rico.Corner.round(this.div, {corners: "tl bl", bgColor: "transparent", color: this.activeColor, blend: false}); OpenLayers.Rico.Corner.changeOpacity(this.layersDiv, 1.0); var imgLocation = OpenLayers.Util.getImagesLocation(); var sz = new OpenLayers.Size(18,18); // maximize button div var img = imgLocation + 'layer-switcher-maximize.png'; this.maximizeDiv = OpenLayers.Util.createAlphaImageDiv( "OpenLayers_Control_MaximizeDiv", null, sz, img, "absolute"); this.maximizeDiv.style.top = "5px"; this.maximizeDiv.style.right = "0px"; this.maximizeDiv.style.left = ""; this.maximizeDiv.style.display = "none"; OpenLayers.Event.observe(this.maximizeDiv, "click", OpenLayers.Function.bindAsEventListener(this.maximizeControl, this) ); this.div.appendChild(this.maximizeDiv); // minimize button div var img = imgLocation + 'layer-switcher-minimize.png'; var sz = new OpenLayers.Size(18,18); this.minimizeDiv = OpenLayers.Util.createAlphaImageDiv( "OpenLayers_Control_MinimizeDiv", null, sz, img, "absolute"); this.minimizeDiv.style.top = "5px"; this.minimizeDiv.style.right = "0px"; this.minimizeDiv.style.left = ""; this.minimizeDiv.style.display = "none"; OpenLayers.Event.observe(this.minimizeDiv, "click", OpenLayers.Function.bindAsEventListener(this.minimizeControl, this) ); this.div.appendChild(this.minimizeDiv); }, /** * Method: ignoreEvent * * Parameters: * evt - {Event} */ ignoreEvent: function(evt) { OpenLayers.Event.stop(evt); }, /** * Method: forceRedraw * Force a redraw of the control div * * Parameters * none */ forceRedraw: function() { this.NeedRedrawAnyway = true; this.redraw(); }, /** * Method: mouseDown * Register a local 'mouseDown' flag so that we'll know whether or not * to ignore a mouseUp event * * Parameters: * evt - {Event} */ mouseDown: function(evt) { this.isMouseDown = true; this.ignoreEvent(evt); }, /** * Method: mouseUp * If the 'isMouseDown' flag has been set, that means that the drag was * started from within the LayerSwitcher control, and thus we can * ignore the mouseup. Otherwise, let the Event continue. * * Parameters: * evt - {Event} */ mouseUp: function(evt) { if (this.isMouseDown) { this.isMouseDown = false; this.ignoreEvent(evt); } }, CLASS_NAME: "OpenLayers.Control.BvH_Control" });