diff --git a/modules/ui/background.js b/modules/ui/background.js index 5ad890c3e..732188deb 100644 --- a/modules/ui/background.js +++ b/modules/ui/background.js @@ -147,7 +147,7 @@ export function uiBackground(context) { } - function drawList(layerList, type, change, filter) { + function drawListItems(layerList, type, change, filter) { var sources = context.background() .sources(context.map().extent()) .filter(filter); @@ -204,10 +204,10 @@ export function uiBackground(context) { function update() { backgroundList - .call(drawList, 'radio', clickSetSource, function(d) { return !d.isHidden() && !d.overlay; }); + .call(drawListItems, 'radio', clickSetSource, function(d) { return !d.isHidden() && !d.overlay; }); overlayList - .call(drawList, 'checkbox', clickSetOverlay, function(d) { return !d.isHidden() && d.overlay; }); + .call(drawListItems, 'checkbox', clickSetOverlay, function(d) { return !d.isHidden() && d.overlay; }); selectLayer(); diff --git a/modules/ui/disclosure.js b/modules/ui/disclosure.js index 9d84c02f8..45c6315a5 100644 --- a/modules/ui/disclosure.js +++ b/modules/ui/disclosure.js @@ -20,7 +20,7 @@ export function uiDisclosure(context, key, expandedDefault) { hideToggle = hideToggle.enter() .append('a') .attr('href', '#') - .attr('class', 'hide-toggle') + .attr('class', 'hide-toggle hide-toggle-' + key) .merge(hideToggle); hideToggle @@ -29,11 +29,12 @@ export function uiDisclosure(context, key, expandedDefault) { .classed('expanded', _expanded); - var wrap = selection.selectAll('div') + var wrap = selection.selectAll('.disclosure-wrap') .data([0]); wrap = wrap.enter() .append('div') + .attr('class', 'disclosure-wrap disclosure-wrap-' + key) .merge(wrap); wrap diff --git a/modules/ui/map_data.js b/modules/ui/map_data.js index fb522c098..a928bd649 100644 --- a/modules/ui/map_data.js +++ b/modules/ui/map_data.js @@ -5,380 +5,424 @@ import { import { d3keybinding as d3_keybinding } from '../lib/d3.keybinding.js'; -import { t, textDirection } from '../util/locale'; import { svgIcon } from '../svg'; -import { uiTooltipHtml } from './tooltipHtml'; +import { t, textDirection } from '../util/locale'; import { tooltip } from '../util/tooltip'; +import { uiDisclosure } from './disclosure'; +import { uiTooltipHtml } from './tooltipHtml'; export function uiMapData(context) { - var key = t('map_data.key'), - features = context.features().keys(), - layers = context.layers(), - fills = ['wireframe', 'partial', 'full'], - fillDefault = context.storage('area-fill') || 'partial', - fillSelected = fillDefault; + var key = t('map_data.key'); + var features = context.features().keys(); + var layers = context.layers(); + var fills = ['wireframe', 'partial', 'full']; + + var _fillDefault = context.storage('area-fill') || 'partial'; + var _fillSelected = _fillDefault; + var _shown = false; + var _dataLayerContainer = d3_select(null); + var _fillList = d3_select(null); + var _featureList = d3_select(null); - function map_data(selection) { - function showsFeature(d) { - return context.features().enabled(d); + function showsFeature(d) { + return context.features().enabled(d); + } + + + function autoHiddenFeature(d) { + return context.features().autoHidden(d); + } + + + function clickFeature(d) { + context.features().toggle(d); + update(); + } + + + function showsFill(d) { + return _fillSelected === d; + } + + + function setFill(d) { + fills.forEach(function(opt) { + context.surface().classed('fill-' + opt, Boolean(opt === d)); + }); + + _fillSelected = d; + if (d !== 'wireframe') { + _fillDefault = d; + context.storage('area-fill', d); } + update(); + } - function autoHiddenFeature(d) { - return context.features().autoHidden(d); + function showsLayer(which) { + var layer = layers.layer(which); + if (layer) { + return layer.enabled(); } + return false; + } - function clickFeature(d) { - context.features().toggle(d); + function setLayer(which, enabled) { + var layer = layers.layer(which); + if (layer) { + layer.enabled(enabled); update(); } + } - function showsFill(d) { - return fillSelected === d; + function toggleLayer(which) { + setLayer(which, !showsLayer(which)); + } + + + function drawPhotoItems(selection) { + var photoKeys = ['mapillary-images', 'mapillary-signs', 'openstreetcam-images']; + var photoLayers = layers.all().filter(function(obj) { return photoKeys.indexOf(obj.id) !== -1; }); + var data = photoLayers.filter(function(obj) { return obj.layer.supported(); }); + + function layerSupported(d) { + return d.layer && d.layer.supported(); + } + function layerEnabled(d) { + return layerSupported(d) && d.layer.enabled(); } + var ul = selection + .selectAll('.layer-list-photos') + .data([0]); - function setFill(d) { - fills.forEach(function(opt) { - context.surface().classed('fill-' + opt, Boolean(opt === d)); + ul = ul.enter() + .append('ul') + .attr('class', 'layer-list layer-list-photos') + .merge(ul); + + var li = ul.selectAll('.list-item-photos') + .data(data); + + li.exit() + .remove(); + + var liEnter = li.enter() + .append('li') + .attr('class', function(d) { return 'list-item-photos list-item-' + d.id; }); + + var labelEnter = liEnter + .append('label') + .each(function(d) { + d3_select(this) + .call(tooltip() + .title(t(d.id.replace('-', '_') + '.tooltip')) + .placement('top') + ); }); - fillSelected = d; - if (d !== 'wireframe') { - fillDefault = d; - context.storage('area-fill', d); - } - update(); - } + labelEnter + .append('input') + .attr('type', 'checkbox') + .on('change', function(d) { toggleLayer(d.id); }); + + labelEnter + .append('span') + .text(function(d) { return t(d.id.replace('-', '_') + '.title'); }); - function showsLayer(which) { - var layer = layers.layer(which); - if (layer) { - return layer.enabled(); - } - return false; - } + // Update + li = li + .merge(liEnter); + + li + .classed('active', layerEnabled) + .selectAll('input') + .property('checked', layerEnabled); + } - function setLayer(which, enabled) { - var layer = layers.layer(which); - if (layer) { - layer.enabled(enabled); - update(); - } - } + function drawOsmItem(selection) { + var osm = layers.layer('osm'), + showsOsm = osm.enabled(); + + var ul = selection + .selectAll('.layer-list-osm') + .data(osm ? [0] : []); + + // Exit + ul.exit() + .remove(); + + // Enter + var ulEnter = ul.enter() + .append('ul') + .attr('class', 'layer-list layer-list-osm'); + + var liEnter = ulEnter + .append('li') + .attr('class', 'list-item-osm'); + + var labelEnter = liEnter + .append('label') + .call(tooltip() + .title(t('map_data.layers.osm.tooltip')) + .placement('top') + ); + + labelEnter + .append('input') + .attr('type', 'checkbox') + .on('change', function() { toggleLayer('osm'); }); + + labelEnter + .append('span') + .text(t('map_data.layers.osm.title')); + + // Update + ul = ul + .merge(ulEnter); + + ul.selectAll('.list-item-osm') + .classed('active', showsOsm) + .selectAll('input') + .property('checked', showsOsm); + } - function toggleLayer(which) { - setLayer(which, !showsLayer(which)); - } + function drawGpxItem(selection) { + var gpx = layers.layer('gpx'), + hasGpx = gpx && gpx.hasGpx(), + showsGpx = hasGpx && gpx.enabled(); + var ul = selection + .selectAll('.layer-list-gpx') + .data(gpx ? [0] : []); - function drawPhotoItems(selection) { - var photoKeys = ['mapillary-images', 'mapillary-signs', 'openstreetcam-images']; - var photoLayers = layers.all().filter(function(obj) { return photoKeys.indexOf(obj.id) !== -1; }); - var data = photoLayers.filter(function(obj) { return obj.layer.supported(); }); + // Exit + ul.exit() + .remove(); - function layerSupported(d) { - return d.layer && d.layer.supported(); - } - function layerEnabled(d) { - return layerSupported(d) && d.layer.enabled(); - } + // Enter + var ulEnter = ul.enter() + .append('ul') + .attr('class', 'layer-list layer-list-gpx'); - var ul = selection - .selectAll('.layer-list-photos') - .data([0]); + var liEnter = ulEnter + .append('li') + .attr('class', 'list-item-gpx'); - ul = ul.enter() - .append('ul') - .attr('class', 'layer-list layer-list-photos') - .merge(ul); + liEnter + .append('button') + .attr('class', 'list-item-gpx-extent') + .call(tooltip() + .title(t('gpx.zoom')) + .placement((textDirection === 'rtl') ? 'right' : 'left') + ) + .on('click', function() { + d3_event.preventDefault(); + d3_event.stopPropagation(); + gpx.fitZoom(); + }) + .call(svgIcon('#icon-search')); - var li = ul.selectAll('.list-item-photos') - .data(data); - - li.exit() - .remove(); - - var liEnter = li.enter() - .append('li') - .attr('class', function(d) { return 'list-item-photos list-item-' + d.id; }); - - var labelEnter = liEnter - .append('label') - .each(function(d) { - d3_select(this) - .call(tooltip() - .title(t(d.id.replace('-', '_') + '.tooltip')) - .placement('top') - ); - }); - - labelEnter - .append('input') - .attr('type', 'checkbox') - .on('change', function(d) { toggleLayer(d.id); }); - - labelEnter - .append('span') - .text(function(d) { return t(d.id.replace('-', '_') + '.title'); }); - - - // Update - li = li - .merge(liEnter); - - li - .classed('active', layerEnabled) - .selectAll('input') - .property('checked', layerEnabled); - } - - - function drawOsmItem(selection) { - var osm = layers.layer('osm'), - showsOsm = osm.enabled(); - - var ul = selection - .selectAll('.layer-list-osm') - .data(osm ? [0] : []); - - // Exit - ul.exit() - .remove(); - - // Enter - var ulEnter = ul.enter() - .append('ul') - .attr('class', 'layer-list layer-list-osm'); - - var liEnter = ulEnter - .append('li') - .attr('class', 'list-item-osm'); - - var labelEnter = liEnter - .append('label') - .call(tooltip() - .title(t('map_data.layers.osm.tooltip')) - .placement('top') - ); - - labelEnter - .append('input') - .attr('type', 'checkbox') - .on('change', function() { toggleLayer('osm'); }); - - labelEnter - .append('span') - .text(t('map_data.layers.osm.title')); - - // Update - ul = ul - .merge(ulEnter); - - ul.selectAll('.list-item-osm') - .classed('active', showsOsm) - .selectAll('input') - .property('checked', showsOsm); - } - - - function drawGpxItem(selection) { - var gpx = layers.layer('gpx'), - hasGpx = gpx && gpx.hasGpx(), - showsGpx = hasGpx && gpx.enabled(); - - var ul = selection - .selectAll('.layer-list-gpx') - .data(gpx ? [0] : []); - - // Exit - ul.exit() - .remove(); - - // Enter - var ulEnter = ul.enter() - .append('ul') - .attr('class', 'layer-list layer-list-gpx'); - - var liEnter = ulEnter - .append('li') - .attr('class', 'list-item-gpx'); - - liEnter - .append('button') - .attr('class', 'list-item-gpx-extent') - .call(tooltip() - .title(t('gpx.zoom')) - .placement((textDirection === 'rtl') ? 'right' : 'left')) - .on('click', function() { - d3_event.preventDefault(); - d3_event.stopPropagation(); - gpx.fitZoom(); - }) - .call(svgIcon('#icon-search')); - - liEnter - .append('button') - .attr('class', 'list-item-gpx-browse') - .call(tooltip() - .title(t('gpx.browse')) - .placement((textDirection === 'rtl') ? 'right' : 'left') - ) - .on('click', function() { - d3_select(document.createElement('input')) - .attr('type', 'file') - .on('change', function() { - gpx.files(d3_event.target.files); - }) - .node().click(); - }) - .call(svgIcon('#icon-geolocate')); - - var labelEnter = liEnter - .append('label') - .call(tooltip() - .title(t('gpx.drag_drop')) - .placement('top') - ); - - labelEnter - .append('input') - .attr('type', 'checkbox') - .on('change', function() { toggleLayer('gpx'); }); - - labelEnter - .append('span') - .text(t('gpx.local_layer')); - - // Update - ul = ul - .merge(ulEnter); - - ul.selectAll('.list-item-gpx') - .classed('active', showsGpx) - .selectAll('label') - .classed('deemphasize', !hasGpx) - .selectAll('input') - .property('disabled', !hasGpx) - .property('checked', showsGpx); - } - - - function drawList(selection, data, type, name, change, active) { - var items = selection.selectAll('li') - .data(data); - - // Exit - items.exit() - .remove(); - - // Enter - var enter = items.enter() - .append('li') - .attr('class', 'layer') - .call(tooltip() - .html(true) - .title(function(d) { - var tip = t(name + '.' + d + '.tooltip'), - key = (d === 'wireframe' ? t('area_fill.wireframe.key') : null); - - if (name === 'feature' && autoHiddenFeature(d)) { - var msg = showsLayer('osm') ? t('map_data.autohidden') : t('map_data.osmhidden'); - tip += '