File: ia\ui\LayerList.js
/**
* A class for rendering a layer list.
*
* @author J Clare
* @class ia.LayerList
* @extends ia.EventDispatcher
* @constructor
* @param {String} The id of the list.
*/
ia.LayerList = function(id)
{
ia.LayerList.baseConstructor.call(this);
this.id = id;
this.container = $j("<div id='"+id+"' class='ia-layer-list'>");
// The table used to render the data.
this.$tableContainer = $j("<div id='"+id+"-container' class='ia-layer-list-scrollbox'>");
this._scrollBox = new ia.ScrollBox(this.$tableContainer);
this.container.append(this.$tableContainer);
// A table used to render the layer list.
this.$tableList = $j("<table class='ia-layer-list-table'>");
this.$tableContainer.append(this.$tableList);
var me = this;
this.container.resize(function(e){me._size();});
};
ia.extend(ia.EventDispatcher, ia.LayerList);
/**
* The id.
*
* @property id
* @type String
*/
ia.LayerList.prototype.id;
/**
* The container that holds the object.
*
* @property container
* @type JQUERY Element
*/
ia.LayerList.prototype.container;
/**
* The map data object.
*
* @property mapData
* @type ia.MapData
*/
ia.LayerList.prototype.mapData;
/**
* The discrete legend.
*
* @property discreteLegend
* @type ia.DiscreteLegend
*/
ia.LayerList.prototype.discreteLegend;
/**
* The gradient legend.
*
* @property gradientLegend
* @type ia.GradientLegend
*/
ia.LayerList.prototype.gradientLegend;
/**
* Sizes all the element to make the scrolling work.
*
* @method _size
* @private
*/
ia.LayerList.prototype._size = function()
{
this.$tableContainer.height(this.container.height());
this.$tableContainer.width(this.container.width());
};
/**
* Renders the layer list.
*
* @method render
*/
ia.LayerList.prototype.render = function()
{
// Empty the previous list.
this.$tableList.empty();
// Insert base layer here.
if (this.mapData && this.mapData.baseLayer) this._buildLayerItem(this.mapData.baseLayer, true);
// Insert legend here.
var tr = $j("<tr>");
this.$tableList.append(tr);
var td = $j("<td colspan='2' class='ia-layer-list-legend-td'>");
tr.append(td);
var me = this;
if (this.gradientLegend)
{
td.append(this.gradientLegend.container);
this.gradientLegend.container.resize(function(e){me._size();});
}
if (this.discreteLegend)
{
td.append(this.discreteLegend.container);
this.discreteLegend.scrollBox = this._scrollBox;
this.discreteLegend.container.resize(function(e){me._size();});
}
// Insert the rest of the layers.
if (this.mapData)
{
// Loop through the layers backwards to get order correct.
var n = this.mapData.noneBaseLayers.length;
for (var i = n-1; i >= 0; i--)
{
var layer = this.mapData.noneBaseLayers[i];
this._buildLayerItem(layer);
}
}
this._scrollBox.refresh();
};
/**
* Draws the layer symbol.
*
* @method _buildLayerItem
* @param {HTML Canvas} canvas The canvas to draw to.
* @param {Boolean} isBaseLayer Is it a base layer.
* @private
*/
ia.LayerList.prototype._buildLayerItem = function(layer, isBaseLayer)
{
if (layer.showInLayerList)
{
var me = this;
layer.addEventListener(ia.Event.LAYER_VISIBLE_CHANGED, this._layerEventHandler.bind(this));
// Add a row
var tr = $j("<tr id='"+this.id+"_"+layer.id+"' class='ia-list-item'>");
this.$tableList.append(tr);
// Add symbol.
if (!isBaseLayer && layer.geometry !== "image")
{
// Layer symbol.
var td = $j("<td class='ia-legend-item' style='text-align:center'>");
tr.append(td);
if (layer.iconPath !== "") // Icon layer
{
var imgSymbol = $j("<img>").attr('src', layer.iconPath);
td.append(imgSymbol);
}
else // Contextual layer
{
// Take into account the border of the symbol when sizing the canvas.
var borderWidth = layer.style.lineWidth;
var canvasWidth = layer.symbolSize + (borderWidth * 2);
/*if (layer.geometry === ia.Shape.LINE) canvasWidth = 30;*/
var canvasHeight = layer.symbolSize + (borderWidth * 2);
// We need to place the canvas in a div otherwise the positioning of the canvas doesnt work.
var divSymbol = $j("<div class='ia-legend-symbol' style='width:"+canvasWidth+";height:"+canvasHeight+";'>");
td.append(divSymbol);
// Create a canvas to contain the symbol.
var canvas = document.createElement('canvas');
canvas.width = canvasWidth;
canvas.height = canvasHeight;
divSymbol.append($j(canvas));
// Draw the symbol.
this._drawSymbol(canvas, layer);
}
}
// Add the label.
var td = $j("<td style='width:100%' id='"+layer.id+"' class='ia-layer-list-item ia-layer-list-item-unchecked'>");
if (isBaseLayer || layer.geometry === "image") td.attr('colspan', 2);
td.html(layer.name);
tr.append(td);
// Set selection.
if (layer.getVisible() === true) td.addClass('ia-layer-list-item-checked');
// Add onclick handler to checkbox.
(function() // Execute immediately
{
var l = layer;
var cell = td;
tr.bind(ia.CLICK_TYPE, function(e)
{
if (!me._scrollBox.isScrolling)
{
e.preventDefault();
if (cell.hasClass('ia-layer-list-item-checked'))
{
cell.removeClass('ia-layer-list-item-checked');
l.setVisible(false);
}
else
{
cell.addClass('ia-layer-list-item-checked');
l.setVisible(true);
if (!l.isLoaded) l.loadSource();
}
}
});
})();
}
};
/**
* Shows a layer.
*
* @method showLayer
* @param {String} id The layer id.
*/
ia.LayerList.prototype.showLayer = function(id)
{
this.$tableList.find("tr[id='"+this.id+"_"+id+"']").show();
};
/**
* Hides a layer.
*
* @method hideLayer
* @param {String} id The layer id.
*/
ia.LayerList.prototype.hideLayer = function(id)
{
this.$tableList.find("tr[id='"+this.id+"_"+id+"']").hide();
};
/**
* Supplies the click function for when the legend editor button is pressed
*
* @method clickFunction
* @param {Event} e The event.
*/
ia.LayerList.prototype.clickFunction = function(e) {};
/**
* Draws the layer symbol.
*
* @method _drawSymbol
* @param {HTML Canvas} canvas The canvas to draw to.
* @param {ia.LayerBase} layer The layer.
* @private
*/
ia.LayerList.prototype._drawSymbol = function(canvas, layer)
{
// Get the canvas context.
var context = canvas.getContext("2d");
var style = layer.style;
for (var p in style) {context[p] = style[p];}
if (layer.geometry === "line")
{
context.beginPath();
ia.Shape.draw(ia.Shape.LINE, context, canvas.width/2, canvas.height/2, layer.symbolSize);
context.stroke();
}
else
{
context.beginPath();
var symbol = ia.Shape.SQUARE; // Polygon.
if (layer.geometry === "point") symbol = ia.Shape.CIRCLE;
ia.Shape.draw(symbol, context, canvas.width/2, canvas.height/2, layer.symbolSize);
context.fill();
context.stroke();
}
};
/**
* Updates the checkbox when a layers visibility has changed.
*
* @method _layerEventHandler
* @param {ia.Event} event A <code>ia.Event</code> dispatched by a layer.
* @private
*/
ia.LayerList.prototype._layerEventHandler = function(event)
{
if (event.type === ia.Event.LAYER_VISIBLE_CHANGED)
{
var layer = event.object
if (layer.getVisible()) this.$tableList.find("#"+layer.id).addClass('ia-layer-list-item-checked');
else this.$tableList.find("#"+layer.id).removeClass('ia-layer-list-item-checked');
}
};