diff --git a/css/app.css b/css/app.css index ae88d830a..d34087bbb 100644 --- a/css/app.css +++ b/css/app.css @@ -2816,6 +2816,7 @@ img.wiki-image { } .map-overlay .tooltip-inner, +.map-overlay .keyhint-wrap, .entity-editor-pane .tooltip-inner, .warning-section .tooltip-inner { background: #000; diff --git a/data/core.yaml b/data/core.yaml index 5bd0c3703..7f5a8f245 100644 --- a/data/core.yaml +++ b/data/core.yaml @@ -242,8 +242,9 @@ en: map_data: title: Map Data description: Map Data - show_features: Show Features - show_layers: Show Layers + show_features: Show Map Features + show_layers: Show Data Layers + fill_area: Fill Areas feature: points: description: Points @@ -281,6 +282,16 @@ en: others: description: Others tooltip: "Everything Else" + area_fill: + wireframe: + description: No Fill (Wireframe) + tooltip: "Enabling wireframe mode makes it easy to see the background imagery." + partial: + description: Partial Fill + tooltip: "Areas are drawn with fill only around their inner edges. (Recommended for beginner mappers)" + full: + description: Full Fill + tooltip: "Areas are drawn fully filled." restore: heading: You have unsaved changes description: "Do you wish to restore unsaved changes from a previous editing session?" diff --git a/dist/locales/en.json b/dist/locales/en.json index e6eaa4354..fcb5e38d2 100644 --- a/dist/locales/en.json +++ b/dist/locales/en.json @@ -297,8 +297,9 @@ "map_data": { "title": "Map Data", "description": "Map Data", - "show_features": "Show Features", - "show_layers": "Show Layers" + "show_features": "Show Map Features", + "show_layers": "Show Data Layers", + "fill_area": "Fill Areas" }, "feature": { "points": { @@ -350,6 +351,20 @@ "tooltip": "Everything Else" } }, + "area_fill": { + "wireframe": { + "description": "No Fill (Wireframe)", + "tooltip": "Enabling wireframe mode makes it easy to see the background imagery." + }, + "partial": { + "description": "Partial Fill", + "tooltip": "Areas are drawn with fill only around their inner edges. (Recommended for beginner mappers)" + }, + "full": { + "description": "Full Fill", + "tooltip": "Areas are drawn fully filled." + } + }, "restore": { "heading": "You have unsaved changes", "description": "Do you wish to restore unsaved changes from a previous editing session?", diff --git a/js/id/ui.js b/js/id/ui.js index 3e8652162..66505eef0 100644 --- a/js/id/ui.js +++ b/js/id/ui.js @@ -203,5 +203,11 @@ iD.ui = function(context) { }; iD.ui.tooltipHtml = function(text, key) { - return '' + text + '' + '
' + ' ' + (t('tooltip_keyhint')) + ' ' + ' ' + key + '
'; + var s = '' + text + ''; + if (key) { + s += '
' + + ' ' + (t('tooltip_keyhint')) + ' ' + + ' ' + key + '
'; + } + return s; }; diff --git a/js/id/ui/background.js b/js/id/ui/background.js index 623a664df..f2e240f6a 100644 --- a/js/id/ui/background.js +++ b/js/id/ui/background.js @@ -1,5 +1,5 @@ iD.ui.Background = function(context) { - var key = 'b', + var key = 'B', opacities = [1, 0.75, 0.5, 0.25], directions = [ ['left', [1, 0]], @@ -296,9 +296,6 @@ iD.ui.Background = function(context) { var keybinding = d3.keybinding('background'); keybinding.on(key, toggle); - keybinding.on('m', function() { - context.enter(iD.modes.SelectImage(context)); - }); d3.select(document) .call(keybinding); diff --git a/js/id/ui/help.js b/js/id/ui/help.js index eef828b1d..c4e073c80 100644 --- a/js/id/ui/help.js +++ b/js/id/ui/help.js @@ -1,5 +1,5 @@ iD.ui.Help = function(context) { - var key = 'h'; + var key = 'H'; var docKeys = [ 'help.help', diff --git a/js/id/ui/map_data.js b/js/id/ui/map_data.js index 7b09e50c4..df84ecb18 100644 --- a/js/id/ui/map_data.js +++ b/js/id/ui/map_data.js @@ -1,7 +1,11 @@ iD.ui.MapData = function(context) { - var key = 'f'; + var key = 'F', + features = context.features().keys(), + fills = ['wireframe', 'partial', 'full'], + fillDefault = context.storage('area-fill') || 'partial', + fillSelected = fillDefault; - function features(selection) { + function map_data(selection) { function showsFeature(d) { return context.features().enabled(d); @@ -9,6 +13,24 @@ iD.ui.MapData = function(context) { function clickFeature(d) { context.features().toggle(d); + update(); + } + + function showsFill(d) { + return fillSelected === d; + } + + function setFill(d) { + _.each(fills, function(opt) { + context.surface().classed('fill-' + opt, Boolean(opt === d)); + }); + + fillSelected = d; + if (d !== 'wireframe') { + fillDefault = d; + context.storage('area-fill', d); + } + update(); } function clickGpx() { @@ -21,50 +43,51 @@ iD.ui.MapData = function(context) { update(); } - function drawFeatureList(selection) { - var data = context.features().keys(); - - var layerLinks = selection.selectAll('li.layer') + function drawList(selection, data, type, name, change, active) { + var items = selection.selectAll('li') .data(data); //enter - var enter = layerLinks.enter() - .insert('li', '.custom_layer') - .attr('class', 'layer'); - - enter.filter(function(d) { return d; }) + var enter = items.enter() + .append('li') + .attr('class', 'layer') .call(bootstrap.tooltip() - .title(function(d) { return t('feature.' + d + '.tooltip'); }) + .html(true) + .title(function(d) { + return iD.ui.tooltipHtml( + t(name + '.' + d + '.tooltip'), (d === 'wireframe' ? 'W' : null) + ); + }) .placement('top')); var label = enter.append('label'); label.append('input') - .attr('type', 'checkbox') - .attr('name', function(d) { return d; }) - .on('change', clickFeature); + .attr('type', type) + .attr('name', name) + .on('change', change); label.append('span') - .text(function(d) { return t('feature.' + d + '.description'); }); + .text(function(d) { return t(name + '.' + d + '.description'); }); //update - layerLinks - .classed('active', showsFeature) + items + .classed('active', active) .selectAll('input') - .property('checked', showsFeature); + .property('checked', active); //exit - layerLinks.exit() + items.exit() .remove(); - - selection.style('display', selection.selectAll('li.layer').data().length > 0 ? 'block' : 'none'); } function update() { - featureList.call(drawFeatureList); + featureList.call(drawList, features, 'checkbox', 'feature', clickFeature, showsFeature); + fillList.call(drawList, fills, 'radio', 'area_fill', setFill, showsFill); var hasGpx = context.background().hasGpxLayer(), - showsGpx = context.background().showsGpxLayer(); + showsGpx = context.background().showsGpxLayer(), + showsMapillary = context.background().showsMapillaryLayer(); gpxLayerItem .classed('active', showsGpx) @@ -72,8 +95,6 @@ iD.ui.MapData = function(context) { .property('disabled', !hasGpx) .property('checked', showsGpx); - var showsMapillary = context.background().showsMapillaryLayer(); - mapillaryLayerItem .classed('active', showsMapillary) .selectAll('input') @@ -87,14 +108,22 @@ iD.ui.MapData = function(context) { .html(true) .title(iD.ui.tooltipHtml(t('map_data.description'), key)); - function hide() { setVisible(false); } + function hidePanel() { setVisible(false); } - function toggle() { + function togglePanel() { if (d3.event) d3.event.preventDefault(); tooltip.hide(button); setVisible(!button.classed('active')); } + function toggleWireframe() { + if (d3.event) { + d3.event.preventDefault(); + d3.event.stopPropagation(); + } + setFill((fillSelected === 'wireframe' ? fillDefault : 'wireframe')); + } + function setVisible(show) { if (show !== shown) { button.classed('active', show); @@ -125,7 +154,7 @@ iD.ui.MapData = function(context) { var button = selection.append('button') .attr('tabindex', -1) - .on('click', toggle) + .on('click', togglePanel) .call(tooltip), shown = false; @@ -135,6 +164,7 @@ iD.ui.MapData = function(context) { content.append('h4') .text(t('map_data.title')); + // feature filters content.append('a') .text(t('map_data.show_features')) .attr('href', '#') @@ -154,7 +184,7 @@ iD.ui.MapData = function(context) { var featureList = featureContainer.append('ul') .attr('class', 'layer-list'); - + // data layers content.append('a') .text(t('map_data.show_layers')) .attr('href', '#') @@ -236,44 +266,47 @@ iD.ui.MapData = function(context) { .text(t('gpx.local_layer')); + // area fills + content.append('a') + .text(t('map_data.fill_area')) + .attr('href', '#') + .classed('hide-toggle', true) + .classed('expanded', true) + .on('click', function() { + var exp = d3.select(this).classed('expanded'); + fillContainer.style('display', exp ? 'none' : 'block'); + d3.select(this).classed('expanded', !exp); + d3.event.preventDefault(); + }); + + var fillContainer = content.append('div') + .attr('class', 'filters') + .style('display', 'block'); + + var fillList = fillContainer.append('ul') + .attr('class', 'layer-list'); + + context.features() .on('change.map_data-update', update); update(); + setFill(fillDefault); var keybinding = d3.keybinding('features') - .on(key, toggle) - .on('w', function toggleWireframe() { - if (d3.event) d3.event.preventDefault(); + .on(key, togglePanel) + .on('W', toggleWireframe); - var surface = context.surface(), - fw = surface.classed('fill-wireframe'), - fp = surface.classed('fill-partial'); - - if (fw) { - surface - .classed('fill-wireframe', false) - .classed('fill-partial', true); - } - else if (fp) { - surface - .classed('fill-wireframe', false) - .classed('fill-partial', false); - - } else { - surface - .classed('fill-wireframe', true) - .classed('fill-partial', false); - } - - }); + // keybinding.on('m', function() { + // context.enter(iD.modes.SelectImage(context)); + // }); d3.select(document) .call(keybinding); - context.surface().on('mousedown.map_data-outside', hide); - context.container().on('mousedown.map_data-outside', hide); + context.surface().on('mousedown.map_data-outside', hidePanel); + context.container().on('mousedown.map_data-outside', hidePanel); } - return features; + return map_data; };