]> git.openstreetmap.org Git - rails.git/commitdiff
Introduce a new layer switcher
authorTom MacWright <tom@macwright.org>
Fri, 23 Mar 2012 21:45:50 +0000 (17:45 -0400)
committerTom Hughes <tom@compton.nu>
Wed, 28 Mar 2012 20:06:08 +0000 (21:06 +0100)
The new layer switcher behaves the same as the standard one but
has less cruft and more attractive styling.

app/assets/images/carat.png [new file with mode: 0644]
app/assets/javascripts/map.js.erb
app/assets/javascripts/openlayers.js.erb
app/assets/javascripts/simplelayerswitcher.js [new file with mode: 0644]
app/assets/stylesheets/common.css.scss
app/views/layouts/site.html.erb
app/views/site/index.html.erb
config/locales/en.yml

diff --git a/app/assets/images/carat.png b/app/assets/images/carat.png
new file mode 100644 (file)
index 0000000..7fdf17e
Binary files /dev/null and b/app/assets/images/carat.png differ
index aff258ad2d33ea9175acad77c29bc78a9fab76da..d05d00993066d621311c7df93a1757c7bd398d43 100644 (file)
@@ -11,7 +11,7 @@ function createMap(divName, options) {
       controls: options.controls || [
          new OpenLayers.Control.ArgParser(),
          new OpenLayers.Control.Attribution(),
-         new OpenLayers.Control.LayerSwitcher(),
+         new SimpleLayerSwitcher(),
          new OpenLayers.Control.Navigation(),
          new OpenLayers.Control.PanZoom(),
          new OpenLayers.Control.PanZoomBar(),
index c428da0147dd73fe535f73f7631d1605d3a47e3d..9119a7b43961660b9c4dec2bd4f840c3d2c7a504 100644 (file)
@@ -1,5 +1,6 @@
 //= require OpenLayers
 //= require OpenStreetMap
+//= require simplelayerswitcher
 
 OpenLayers.Util.imageURLs = {
     "404.png": "<%= asset_path 'img/404.png' %>",
diff --git a/app/assets/javascripts/simplelayerswitcher.js b/app/assets/javascripts/simplelayerswitcher.js
new file mode 100644 (file)
index 0000000..db3c720
--- /dev/null
@@ -0,0 +1,175 @@
+var SimpleLayerSwitcher = OpenLayers.Class(OpenLayers.Control, {
+    layerStates: null,
+    layersDiv: null,
+    ascending: true,
+
+    initialize: function(options) {
+        OpenLayers.Control.prototype.initialize.apply(this, arguments);
+        this.layerStates = [];
+    },
+
+    destroy: function() {
+        OpenLayers.Event.stopObservingElement(this.div);
+
+        //clear out layers info and unregister their events 
+        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);
+    },
+
+    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
+        });
+    },
+
+    draw: function() {
+        OpenLayers.Control.prototype.draw.apply(this);
+        this.loadContents();
+        this.redraw();
+        return this.div;
+    },
+
+    checkRedraw: function() {
+        var redraw = false;
+        if ( !this.layerStates.length ||
+             (this.map.layers.length != this.layerStates.length) ) {
+            redraw = true;
+        } else {
+            for (var i=0, len=this.layerStates.length; i<len; i++) {
+                var layerState = this.layerStates[i];
+                var layer = this.map.layers[i];
+                if ( (layerState.name != layer.name) ||
+                     (layerState.inRange != layer.inRange) ||
+                     (layerState.id != layer.id) ||
+                     (layerState.visibility != layer.visibility) ) {
+                    redraw = true;
+                    break;
+                }
+            }
+        }
+        return redraw;
+    },
+
+    redraw: function() {
+        if (!this.checkRedraw()) {
+            return this.div;
+        }
+
+        this.div.innerHTML = '';
+        var len = this.map.layers.length;
+        this.layerStates = [];
+        for (var i = 0; i < this.map.layers.length; i++) {
+            var layer = this.map.layers[i];
+            this.layerStates[i] = {
+                'name': layer.name,
+                'visibility': layer.visibility,
+                'inRange': layer.inRange,
+                'id': layer.id
+            };
+        }
+
+        var layers = this.map.layers.slice();
+        if (!this.ascending) { layers.reverse(); }
+        for (var i = 0; i < layers.length; i++) {
+            var layer = layers[i];
+            var baseLayer = layer.isBaseLayer;
+
+            if (layer.displayInLayerSwitcher && baseLayer) {
+                var on = (baseLayer) ? (layer == this.map.baseLayer)
+                          : layer.getVisibility();
+                var layerElem = document.createElement('a');
+                layerElem.id = this.id + '_input_' + layer.name;
+                layerElem.innerHTML = layer.name;
+                layerElem.href = '#';
+
+                OpenLayers.Element.addClass(layerElem, 'basey');
+                OpenLayers.Element.addClass(layerElem,
+                    'basey-' + (on ? 'on' : 'off'));
+
+                if (!baseLayer && !layer.inRange) {
+                    layerElem.disabled = true;
+                }
+                var context = {
+                    'layer': layer
+                };
+                OpenLayers.Event.observe(layerElem, 'mouseup',
+                    OpenLayers.Function.bindAsEventListener(
+                        this.onInputClick,
+                        context)
+                );
+
+                this.div.appendChild(layerElem);
+            }
+        }
+
+        return this.div;
+    },
+
+    onInputClick: function(e) {
+        if (this.layer.isBaseLayer) {
+            this.layer.map.setBaseLayer(this.layer);
+        } else {
+            this.layer.setVisibility(!this.layer.getVisibility());
+        }
+        OpenLayers.Event.stop(e);
+    },
+
+    updateMap: function() {
+
+        // set the newly selected base layer
+        for(var i=0, len=this.baseLayers.length; i<len; i++) {
+            var layerEntry = this.baseLayers[i];
+            if (layerEntry.inputElem.checked) {
+                this.map.setBaseLayer(layerEntry.layer, false);
+            }
+        }
+
+        // set the correct visibilities for the overlays
+        for(var i=0, len=this.dataLayers.length; i<len; i++) {
+            var layerEntry = this.dataLayers[i];
+            layerEntry.layer.setVisibility(layerEntry.inputElem.checked);
+        }
+
+    },
+
+    loadContents: function() {
+        //configure main div
+        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);
+    },
+
+    ignoreEvent: function(evt) {
+        OpenLayers.Event.stop(evt);
+    },
+
+    mouseDown: function(evt) {
+        this.isMouseDown = true;
+        this.ignoreEvent(evt);
+    },
+
+    mouseUp: function(evt) {
+        if (this.isMouseDown) {
+            this.isMouseDown = false;
+            this.ignoreEvent(evt);
+        }
+    },
+
+    CLASS_NAME: "SimpleLayerSwitcher"
+});
index b6aaf7371b4ce80768cb503b255127340eb9053c..ef2c46a8d8364462fc368a8b87fe200bd3468280 100644 (file)
@@ -1113,3 +1113,50 @@ abbr.geo {
     }
   }
 }
+
+/* Rules for the layer switcher */
+
+.SimpleLayerSwitcher {
+  position:absolute;
+  top:10px;
+  right:10px;
+  background:#fff;
+  border:1px solid #ccc;
+  min-width:150px;
+  background: #fff;
+}
+
+.SimpleLayerSwitcher a.basey {
+  display:block;
+  text-decoration:none;
+  color:#838383;
+  padding:2px 5px 2px 20px;
+}
+
+.SimpleLayerSwitcher a.basey-on {
+  color:#000;
+  background-color: #fff;
+  background-image: url('carat.png');
+  background-repeat: no-repeat;
+  background-position: 7px 9px;
+}
+
+.SimpleLayerSwitcher a.basey-off {
+  display:none;
+}
+
+.SimpleLayerSwitcher:hover a {
+  border-top:1px solid #eee;
+}
+
+.SimpleLayerSwitcher a:hover {
+  background-color:#f5f5f5;
+}
+
+.SimpleLayerSwitcher:hover a:first-child {
+  border-top:none;
+}
+
+.SimpleLayerSwitcher:hover a.basey-off {
+  display:block;
+}
index 1123ff55532789b1a3af2a06f8c8d4757d46df4b..423a7b72c205da523f154bed807d641823e04686 100644 (file)
@@ -51,6 +51,9 @@
         <% Editors::ALL_EDITORS.each do |editor| %>
           <li><%= link_to t('layouts.edit_with', :editor => t("editor.#{editor}.description")), {:controller => 'site', :action => 'edit', :editor => editor}, {:id => editor + 'anchor', :class => "geolink llz object"} %></li>
         <% end %>
+        <% unless STATUS == :api_offline or STATUS == :database_offline %>
+            <li><%= link_to_function(t('browse.start_rjs.data_layer_name'), 'toggleData()') %></li>
+        <% end %>
       </ul>
     </div>
 
index 9102214afb54190953150739b59017bf5c22ed22..fb8f4462e1bbd63f988a7182aed03eaa8ebdf02b 100644 (file)
@@ -135,8 +135,10 @@ end
     map = createMap("map");
 
     <% unless STATUS == :api_offline or STATUS == :database_offline %>
-      map.dataLayer = new OpenLayers.Layer("<%= I18n.t 'browse.start_rjs.data_layer_name' %>", { "visibility": false });
-      map.dataLayer.events.register("visibilitychanged", map.dataLayer, toggleData);
+      map.dataLayer = new OpenLayers.Layer("<%= I18n.t 'browse.start_rjs.data_layer_name' %>", {
+          visibility: false,
+          displayInLayerSwitcher: false
+      });
       map.addLayer(map.dataLayer);
     <% end %>
 
@@ -187,11 +189,7 @@ end
   }
 
   function toggleData() {
-    if (map.dataLayer.visibility) {
-      $.ajax({ url: "<%= url_for :controller => :browse, :action => :start %>" });
-    } else if (map.dataLayer.active) {
-      closeSidebar();
-    }
+    $.ajax({ url: "<%= url_for :controller => :browse, :action => :start %>" });
   }
 
   function setPosition(lat, lon, zoom, min_lon, min_lat, max_lon, max_lat) {
index 70b95fb65b82d4ab2b130a42ed22536783ebdd17..f31330ed710a20c35b75da3d1d8758f77eca12b2 100644 (file)
@@ -221,7 +221,7 @@ en:
       view_data: "View data for current map view"
       manually_select: "Manually select a different area"
     start_rjs:
-      data_layer_name: "Data"
+      data_layer_name: "Browse Map Data"
       data_frame_title: "Data"
       zoom_or_select: "Zoom in or select an area of the map to view"
       drag_a_box: "Drag a box on the map to select an area"