LayerControl class
class LayerControl extends MapControl {
static const _TEMPLATE = """
<div class="layer-control">
<table>
</table>
</div>
""";
LayerControl([MapViewport map]) : super(map);
final Map<int, StreamSubscription> _layerSubscriptions
= new Map<int, StreamSubscription>();
static const _ROW_TEMPLATE = """
<tr>
<td class="layer-visibility"><input type="checkbox"></td>
<td class="layer-name"><span title=""></span></td>
</tr>
""";
void detach() {
super.detach();
_layerSubscriptions.keys.forEach((id) {
_layerSubscriptions[id].cancel();
});
_layerSubscriptions.clear();
}
Element _buildLayerRow(Layer layer) {
//TODO: replace with a kind of builder. Element.html will probably disapear
var tr = new Element.html(_ROW_TEMPLATE);
var span = tr.query("td.layer-name").query("span");
span.innerHtml = layer.name;
span.attributes["title"] = layer.name; // tooltip
var cb = tr.query("input");
_cbSetChecked(cb, layer.visible);
cb.dataset["layerId"] = layer.id.toString();
tr.dataset["layerId"] = layer.id.toString();
return tr;
}
_buildHtml() {
_root = new Element.html(_TEMPLATE);
var size = _map.viewportSize;
var left = size.width - 20 - 200;
_root.style
..left = "${left}px"
..top = "20px";
var rows = _map.layers.map((l) => _buildLayerRow(l));
_root.query("table").children
..clear()
..addAll(rows);
}
_wireEventListeners() {
// click events in the layer control
_subscriptions.add(
_root.onClick.listen(_handleClick)
);
// layer events (add, remove, move) in the map viewport
_subscriptions.add(
_map.onLayersChanged.listen(_handleLayerEvent)
);
// layer properties (name, visible) in a layer
_map.layers.forEach((l) {
_layerSubscriptions[l.id] =
l.onPropertyChanged.listen(_handleLayerPropertyChange);
});
}
_handleClick(evt) {
var target = evt.target;
if (evt.target is InputElement) {
_toggleLayerVisibility(evt);
}
}
_layerTr(lid) => _root
.queryAll("tr")
.firstWhere((e)=>e.dataset["layerId"] == lid.toString());
_handleLayerEvent(LayerEvent evt) {
handleAdded(LayerEvent evt) {
var tr = _buildLayerRow(evt.layer);
_root.query("table").children.add(tr);
_layerSubscriptions[evt.layer.id] =
evt.layer.onPropertyChanged.listen(_handleLayerPropertyChange);
}
handleRemoved(LayerEvent evt) {
var lid = evt.layer.id;
var tr = _layerTr(lid);
if (tr == null) {
print("warning: didn't find table row for layer with id $lid");
return;
}
var table = _root.query("table");
table.children.remove(tr);
var subscription = _layerSubscriptions[lid];
if (subscription != null) {
subscription.cancel();
}
}
switch(evt.type) {
case LayerEvent.ADDED:
handleAdded(evt);
break;
case LayerEvent.REMOVED:
handleRemoved(evt);
break;
default: /* ignore */
}
}
_cbSetChecked(cb, value) {
if (value) {
cb.attributes["checked"] = "checked";
} else {
cb.attributes.remove("checked");
}
}
_handleLayerPropertyChange(evt) {
handleNameChange(evt) {
var lid = evt.source.id;
var span = _layerTr(lid).query("span");
span.innerHtml = evt.newValue;
}
handleVisibleChange(evt) {
var lid = evt.source.id;
var cb = _layerTr(lid).query("input");
_cbSetChecked(cb, evt.newValue);
}
switch(evt.name) {
case "name": handleNameChange(evt); break;
case "visible": handleVisibleChange(evt);break;
default: /* ignore */
}
}
_toggleLayerVisibility(evt) {
if (evt.target is! InputElement) return;
var cb = evt.target;
var lid = cb.dataset["layerId"];
if (lid == null) return; //TODO: warning
try {
lid = int.parse(lid);
} catch(e) {
//TODO: warning
return;
}
var layer = _map.layers.firstWhere((l) => l.id == lid);
if (layer == null) {
//TODO: warning
return;
}
var visible = !layer.visible;
layer.visible = visible;
}
@override
void build() {
_buildHtml();
_wireEventListeners();
}
var _defaultPosition = null;
@override
get defaultPosition {
if (_defaultPosition == null && map != null) {
var vs = map.viewportSize;
_defaultPosition = new Point2D(vs.width-200, 20);
}
return _defaultPosition;
}
}
Extends
MapControl > LayerControl
Constructors
new LayerControl([MapViewport map]) #
LayerControl([MapViewport map]) : super(map);
Properties
final defaultPosition #
the default position of the control if no position has been
set explicitly using placeAt.
Override in subclasses.
docs inherited from MapControl
@override
get defaultPosition {
if (_defaultPosition == null && map != null) {
var vs = map.viewportSize;
_defaultPosition = new Point2D(vs.width-200, 20);
}
return _defaultPosition;
}
final MapViewport map #
inherited from MapControl
the map this control is attached to, or null
MapViewport get map => _map;
final Element root #
inherited from MapControl
the root DOM element for this map control
Element get root => _root;
Methods
void applyPosition() #
inherited from MapControl
Applies the current position to the appropriate DOM element.
void applyPosition() {
if (root == null) return;
var pos = _position == null ? defaultPosition : _position;
if (pos == null) {
//TODO: log a warning ?
return;
}
root.style
..left = "${pos.x}px"
..top = "${pos.y}px";
}
void attach(MapViewport viewport) #
inherited from MapControl
Attaches this control to the map viewport.
void attach(MapViewport viewport) {
_require(viewport != null, "viewport must not be null");
// already attached ?
if (_map != null) {
if (_map == viewport) {
return; // don't attach again
} else {
detach(); // detach the currently attached, then attach the new one
}
}
this._map = viewport;
var controlsPane = _map.controlsPane;
//TODO: log a warning?
if (controlsPane == null) return;
build();
controlsPane.controls.add(this);
controlsPane.root.children.add(root);
applyPosition();
}
void build() #
Abstract method which builds the DOM tree for the control. Override in subclasses.
docs inherited from MapControl
@override
void build() {
_buildHtml();
_wireEventListeners();
}
void detach() #
Detaches this control from the map viewport it is currently attached to (if any).
docs inherited from MapControl
void detach() {
super.detach();
_layerSubscriptions.keys.forEach((id) {
_layerSubscriptions[id].cancel();
});
_layerSubscriptions.clear();
}
void layout() #
inherited from MapControl
Invoke this to force to (re-)layout the map control in the current map viewport.
void layout() {}
void placeAt(int x, int y) #
inherited from MapControl
Places the control at the position ( x, y).
void placeAt(int x, int y) {
_position = new Point2D(x,y);
applyPosition();
}