mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-16 05:49:16 +02:00
Move map features and map style options to their own pane section objects (re: #7368)
Handle area fill and change highlighting logic in the rendererMap object and issue change events
This commit is contained in:
+47
-1
@@ -30,7 +30,7 @@ function clamp(num, min, max) {
|
||||
|
||||
|
||||
export function rendererMap(context) {
|
||||
var dispatch = d3_dispatch('move', 'drawn', 'crossEditableZoom');
|
||||
var dispatch = d3_dispatch('move', 'drawn', 'crossEditableZoom', 'changeHighlighting', 'changeAreaFill');
|
||||
var projection = context.projection;
|
||||
var curtainProjection = context.curtainProjection;
|
||||
var drawLayers = svgLayers(projection, context);
|
||||
@@ -182,6 +182,9 @@ export function rendererMap(context) {
|
||||
}
|
||||
});
|
||||
|
||||
// must call after surface init
|
||||
updateAreaFill();
|
||||
|
||||
context.on('enter.map', function() {
|
||||
if (map.editableDataEnabled(true /* skip zoom check */) && !_isTransformed) {
|
||||
// redraw immediately any objects affected by a change in selectedIDs.
|
||||
@@ -980,6 +983,49 @@ export function rendererMap(context) {
|
||||
};
|
||||
|
||||
|
||||
map.toggleHighlightEdited = function() {
|
||||
surface.classed('highlight-edited', !surface.classed('highlight-edited'));
|
||||
map.pan([0,0]); // trigger a redraw
|
||||
dispatch.call('changeHighlighting', this);
|
||||
};
|
||||
|
||||
|
||||
map.areaFillOptions = ['wireframe', 'partial', 'full'];
|
||||
|
||||
map.activeAreaFill = function(val) {
|
||||
if (!arguments.length) return context.storage('area-fill') || 'partial';
|
||||
|
||||
context.storage('area-fill', val);
|
||||
if (val !== 'wireframe') {
|
||||
context.storage('area-fill-toggle', val);
|
||||
}
|
||||
updateAreaFill();
|
||||
map.pan([0,0]); // trigger a redraw
|
||||
dispatch.call('changeAreaFill', this);
|
||||
return map;
|
||||
};
|
||||
|
||||
map.toggleWireframe = function() {
|
||||
|
||||
var activeFill = map.activeAreaFill();
|
||||
|
||||
if (activeFill === 'wireframe') {
|
||||
activeFill = context.storage('area-fill-toggle') || 'partial';
|
||||
} else {
|
||||
activeFill = 'wireframe';
|
||||
}
|
||||
|
||||
map.activeAreaFill(activeFill);
|
||||
};
|
||||
|
||||
function updateAreaFill() {
|
||||
var activeFill = map.activeAreaFill();
|
||||
map.areaFillOptions.forEach(function(opt) {
|
||||
surface.classed('fill-' + opt, Boolean(opt === activeFill));
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
map.layers = drawLayers;
|
||||
|
||||
|
||||
|
||||
+28
-173
@@ -14,29 +14,22 @@ import { uiTooltipHtml } from '../tooltipHtml';
|
||||
import { uiCmd } from '../cmd';
|
||||
import { uiPane } from '../pane';
|
||||
|
||||
import { uiSectionMapFeatures } from '../sections/map_features';
|
||||
import { uiSectionMapStyleOptions } from '../sections/map_style_options';
|
||||
|
||||
export function uiPaneMapData(context) {
|
||||
var osmDataToggleKey = uiCmd('⌥' + t('area_fill.wireframe.key'));
|
||||
var features = context.features().keys();
|
||||
var layers = context.layers();
|
||||
var fills = ['wireframe', 'partial', 'full'];
|
||||
|
||||
var settingsCustomData = uiSettingsCustomData(context)
|
||||
.on('change', customChanged);
|
||||
|
||||
var _fillSelected = context.storage('area-fill') || 'partial';
|
||||
var _dataLayerContainer = d3_select(null);
|
||||
var _photoOverlayContainer = d3_select(null);
|
||||
var _fillList = d3_select(null);
|
||||
var _featureList = d3_select(null);
|
||||
var _visualDiffList = d3_select(null);
|
||||
var _QAList = d3_select(null);
|
||||
|
||||
|
||||
function showsFeature(d) {
|
||||
return context.features().enabled(d);
|
||||
}
|
||||
|
||||
var _mapStyleOptionsSection = uiSectionMapStyleOptions(context);
|
||||
var _mapFeaturesSection = uiSectionMapFeatures(context);
|
||||
|
||||
function autoHiddenFeature(d) {
|
||||
if (d.type === 'kr_error') return context.errors().autoHidden(d);
|
||||
@@ -44,12 +37,6 @@ export function uiPaneMapData(context) {
|
||||
}
|
||||
|
||||
|
||||
function clickFeature(d) {
|
||||
context.features().toggle(d);
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
function showsQA(d) {
|
||||
var QAKeys = [d];
|
||||
var QALayers = layers.all().filter(function(obj) { return QAKeys.indexOf(obj.id) !== -1; });
|
||||
@@ -66,32 +53,9 @@ export function uiPaneMapData(context) {
|
||||
}
|
||||
|
||||
|
||||
function showsFill(d) {
|
||||
return _fillSelected === d;
|
||||
}
|
||||
|
||||
|
||||
function setFill(d) {
|
||||
fills.forEach(function(opt) {
|
||||
context.surface().classed('fill-' + opt, Boolean(opt === d));
|
||||
});
|
||||
|
||||
_fillSelected = d;
|
||||
context.storage('area-fill', d);
|
||||
if (d !== 'wireframe') {
|
||||
context.storage('area-fill-toggle', d);
|
||||
}
|
||||
update();
|
||||
}
|
||||
|
||||
|
||||
function toggleHighlightEdited() {
|
||||
d3_event.preventDefault();
|
||||
var surface = context.surface();
|
||||
surface.classed('highlight-edited', !surface.classed('highlight-edited'));
|
||||
updateVisualDiffList();
|
||||
|
||||
context.map().pan([0,0]); // trigger a redraw
|
||||
context.map().toggleHighlightEdited();
|
||||
}
|
||||
|
||||
|
||||
@@ -610,14 +574,11 @@ export function uiPaneMapData(context) {
|
||||
.html(true)
|
||||
.title(function(d) {
|
||||
var tip = t(name + '.' + d + '.tooltip');
|
||||
var key = (d === 'wireframe' ? t('area_fill.wireframe.key') : null);
|
||||
if (d === 'highlight_edits') key = t('map_data.highlight_edits.key');
|
||||
|
||||
if ((name === 'feature' || name === 'keepRight') && autoHiddenFeature(d)) {
|
||||
if (name === 'keepRight' && autoHiddenFeature(d)) {
|
||||
var msg = showsLayer('osm') ? t('map_data.autohidden') : t('map_data.osmhidden');
|
||||
tip += '<div>' + msg + '</div>';
|
||||
}
|
||||
return uiTooltipHtml(tip, key);
|
||||
return uiTooltipHtml(tip);
|
||||
})
|
||||
.placement('top')
|
||||
);
|
||||
@@ -644,7 +605,7 @@ export function uiPaneMapData(context) {
|
||||
.selectAll('input')
|
||||
.property('checked', active)
|
||||
.property('indeterminate', function(d) {
|
||||
return ((name === 'feature' || name === 'keepRight') && autoHiddenFeature(d));
|
||||
return name === 'keepRight' && autoHiddenFeature(d);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -673,73 +634,6 @@ export function uiPaneMapData(context) {
|
||||
updatePhotoOverlays();
|
||||
}
|
||||
|
||||
|
||||
function renderStyleOptions(selection) {
|
||||
var container = selection.selectAll('.layer-fill-list')
|
||||
.data([0]);
|
||||
|
||||
_fillList = container.enter()
|
||||
.append('ul')
|
||||
.attr('class', 'layer-list layer-fill-list')
|
||||
.merge(container);
|
||||
|
||||
updateFillList();
|
||||
|
||||
var container2 = selection.selectAll('.layer-visual-diff-list')
|
||||
.data([0]);
|
||||
|
||||
_visualDiffList = container2.enter()
|
||||
.append('ul')
|
||||
.attr('class', 'layer-list layer-visual-diff-list')
|
||||
.merge(container2);
|
||||
|
||||
updateVisualDiffList();
|
||||
}
|
||||
|
||||
|
||||
function renderFeatureList(selection) {
|
||||
var container = selection.selectAll('.layer-feature-list-container')
|
||||
.data([0]);
|
||||
|
||||
var containerEnter = container.enter()
|
||||
.append('div')
|
||||
.attr('class', 'layer-feature-list-container');
|
||||
|
||||
containerEnter
|
||||
.append('ul')
|
||||
.attr('class', 'layer-list layer-feature-list');
|
||||
|
||||
var footer = containerEnter
|
||||
.append('div')
|
||||
.attr('class', 'feature-list-links section-footer');
|
||||
|
||||
footer
|
||||
.append('a')
|
||||
.attr('class', 'feature-list-link')
|
||||
.attr('href', '#')
|
||||
.text(t('issues.enable_all'))
|
||||
.on('click', function() {
|
||||
context.features().enableAll();
|
||||
});
|
||||
|
||||
footer
|
||||
.append('a')
|
||||
.attr('class', 'feature-list-link')
|
||||
.attr('href', '#')
|
||||
.text(t('issues.disable_all'))
|
||||
.on('click', function() {
|
||||
context.features().disableAll();
|
||||
});
|
||||
|
||||
// Update
|
||||
container = container
|
||||
.merge(containerEnter);
|
||||
|
||||
_featureList = container.selectAll('.layer-feature-list');
|
||||
|
||||
updateFeatureList();
|
||||
}
|
||||
|
||||
function updatePhotoOverlays() {
|
||||
_photoOverlayContainer
|
||||
.call(drawPhotoItems)
|
||||
@@ -754,40 +648,23 @@ export function uiPaneMapData(context) {
|
||||
.call(drawVectorItems); // Beta - Detroit mapping challenge
|
||||
}
|
||||
|
||||
function updateFillList() {
|
||||
_fillList
|
||||
.call(drawListItems, fills, 'radio', 'area_fill', setFill, showsFill);
|
||||
}
|
||||
|
||||
function updateVisualDiffList() {
|
||||
_visualDiffList
|
||||
.call(drawListItems, ['highlight_edits'], 'checkbox', 'visual_diff', toggleHighlightEdited, function() {
|
||||
return context.surface().classed('highlight-edited');
|
||||
});
|
||||
}
|
||||
|
||||
function updateFeatureList() {
|
||||
_featureList
|
||||
.call(drawListItems, features, 'checkbox', 'feature', clickFeature, showsFeature);
|
||||
}
|
||||
|
||||
function update() {
|
||||
|
||||
if (!mapDataPane.selection().select('.disclosure-wrap-data_layers').classed('hide')) {
|
||||
updateDataLayers();
|
||||
|
||||
_QAList
|
||||
.call(drawListItems, ['keep-right'], 'checkbox', 'QA', function(d) { toggleLayer(d); }, showsQA);
|
||||
}
|
||||
if (!mapDataPane.selection().select('.disclosure-wrap-photo_overlays').classed('hide')) {
|
||||
updatePhotoOverlays();
|
||||
}
|
||||
if (!mapDataPane.selection().select('.disclosure-wrap-fill_area').classed('hide')) {
|
||||
updateFillList();
|
||||
}
|
||||
if (!mapDataPane.selection().select('.disclosure-wrap-map_features').classed('hide')) {
|
||||
updateFeatureList();
|
||||
}
|
||||
|
||||
_QAList
|
||||
.call(drawListItems, ['keep-right'], 'checkbox', 'QA', function(d) { toggleLayer(d); }, showsQA);
|
||||
mapDataPane.selection().select('.map-data-area-fills')
|
||||
.call(_mapStyleOptionsSection.render);
|
||||
|
||||
mapDataPane.selection().select('.map-data-feature-filters')
|
||||
.call(_mapFeaturesSection.render);
|
||||
}
|
||||
|
||||
|
||||
@@ -796,15 +673,7 @@ export function uiPaneMapData(context) {
|
||||
d3_event.preventDefault();
|
||||
d3_event.stopPropagation();
|
||||
}
|
||||
|
||||
if (_fillSelected === 'wireframe') {
|
||||
_fillSelected = context.storage('area-fill-toggle') || 'partial';
|
||||
} else {
|
||||
_fillSelected = 'wireframe';
|
||||
}
|
||||
|
||||
setFill(_fillSelected);
|
||||
context.map().pan([0,0]); // trigger a redraw
|
||||
context.map().toggleWireframe();
|
||||
}
|
||||
|
||||
var mapDataPane = uiPane('map-data', context)
|
||||
@@ -836,38 +705,24 @@ export function uiPaneMapData(context) {
|
||||
// area fills
|
||||
content
|
||||
.append('div')
|
||||
.attr('class', 'map-data-area-fills')
|
||||
.call(uiDisclosure(context, 'fill_area', false)
|
||||
.title(t('map_data.style_options'))
|
||||
.content(renderStyleOptions)
|
||||
);
|
||||
.attr('class', 'map-data-area-fills');
|
||||
|
||||
// feature filters
|
||||
content
|
||||
.append('div')
|
||||
.attr('class', 'map-data-feature-filters')
|
||||
.call(uiDisclosure(context, 'map_features', false)
|
||||
.title(t('map_data.map_features'))
|
||||
.content(renderFeatureList)
|
||||
);
|
||||
|
||||
|
||||
// add listeners
|
||||
context.features()
|
||||
.on('change.map_data-update', update);
|
||||
.attr('class', 'map-data-feature-filters');
|
||||
|
||||
update();
|
||||
setFill(_fillSelected);
|
||||
|
||||
context.keybinding()
|
||||
.on(t('area_fill.wireframe.key'), toggleWireframe)
|
||||
.on(osmDataToggleKey, function() {
|
||||
d3_event.preventDefault();
|
||||
d3_event.stopPropagation();
|
||||
toggleLayer('osm');
|
||||
})
|
||||
.on(t('map_data.highlight_edits.key'), toggleHighlightEdited);
|
||||
};
|
||||
|
||||
context.keybinding()
|
||||
.on(t('area_fill.wireframe.key'), toggleWireframe)
|
||||
.on(osmDataToggleKey, function() {
|
||||
d3_event.preventDefault();
|
||||
d3_event.stopPropagation();
|
||||
toggleLayer('osm');
|
||||
})
|
||||
.on(t('map_data.highlight_edits.key'), toggleHighlightEdited);
|
||||
|
||||
return mapDataPane;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,127 @@
|
||||
import { t } from '../../util/locale';
|
||||
import { tooltip } from '../../util/tooltip';
|
||||
import { uiSection } from '../section';
|
||||
import { uiTooltipHtml } from '../tooltipHtml';
|
||||
|
||||
export function uiSectionMapFeatures(context) {
|
||||
|
||||
var _features = context.features().keys();
|
||||
|
||||
var section = uiSection('map-features', context)
|
||||
.title(t('map_data.map_features'))
|
||||
.expandedByDefault(false);
|
||||
|
||||
section.renderDisclosureContent = function(selection) {
|
||||
|
||||
var container = selection.selectAll('.layer-feature-list-container')
|
||||
.data([0]);
|
||||
|
||||
var containerEnter = container.enter()
|
||||
.append('div')
|
||||
.attr('class', 'layer-feature-list-container');
|
||||
|
||||
containerEnter
|
||||
.append('ul')
|
||||
.attr('class', 'layer-list layer-feature-list');
|
||||
|
||||
var footer = containerEnter
|
||||
.append('div')
|
||||
.attr('class', 'feature-list-links section-footer');
|
||||
|
||||
footer
|
||||
.append('a')
|
||||
.attr('class', 'feature-list-link')
|
||||
.attr('href', '#')
|
||||
.text(t('issues.enable_all'))
|
||||
.on('click', function() {
|
||||
context.features().enableAll();
|
||||
});
|
||||
|
||||
footer
|
||||
.append('a')
|
||||
.attr('class', 'feature-list-link')
|
||||
.attr('href', '#')
|
||||
.text(t('issues.disable_all'))
|
||||
.on('click', function() {
|
||||
context.features().disableAll();
|
||||
});
|
||||
|
||||
// Update
|
||||
container = container
|
||||
.merge(containerEnter);
|
||||
|
||||
container.selectAll('.layer-feature-list')
|
||||
.call(drawListItems, _features, 'checkbox', 'feature', clickFeature, showsFeature);
|
||||
};
|
||||
|
||||
function drawListItems(selection, data, type, name, change, active) {
|
||||
var items = selection.selectAll('li')
|
||||
.data(data);
|
||||
|
||||
// Exit
|
||||
items.exit()
|
||||
.remove();
|
||||
|
||||
// Enter
|
||||
var enter = items.enter()
|
||||
.append('li')
|
||||
.call(tooltip()
|
||||
.html(true)
|
||||
.title(function(d) {
|
||||
var tip = t(name + '.' + d + '.tooltip');
|
||||
if (autoHiddenFeature(d)) {
|
||||
var msg = showsLayer('osm') ? t('map_data.autohidden') : t('map_data.osmhidden');
|
||||
tip += '<div>' + msg + '</div>';
|
||||
}
|
||||
return uiTooltipHtml(tip);
|
||||
})
|
||||
.placement('top')
|
||||
);
|
||||
|
||||
var label = enter
|
||||
.append('label');
|
||||
|
||||
label
|
||||
.append('input')
|
||||
.attr('type', type)
|
||||
.attr('name', name)
|
||||
.on('change', change);
|
||||
|
||||
label
|
||||
.append('span')
|
||||
.text(function(d) { return t(name + '.' + d + '.description'); });
|
||||
|
||||
// Update
|
||||
items = items
|
||||
.merge(enter);
|
||||
|
||||
items
|
||||
.classed('active', active)
|
||||
.selectAll('input')
|
||||
.property('checked', active)
|
||||
.property('indeterminate', autoHiddenFeature);
|
||||
}
|
||||
|
||||
function autoHiddenFeature(d) {
|
||||
return context.features().autoHidden(d);
|
||||
}
|
||||
|
||||
function showsFeature(d) {
|
||||
return context.features().enabled(d);
|
||||
}
|
||||
|
||||
function clickFeature(d) {
|
||||
context.features().toggle(d);
|
||||
}
|
||||
|
||||
function showsLayer(id) {
|
||||
var layer = context.layers().layer(id);
|
||||
return layer && layer.enabled();
|
||||
}
|
||||
|
||||
// add listeners
|
||||
context.features()
|
||||
.on('change.map_features', section.rerenderContent);
|
||||
|
||||
return section;
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
import {
|
||||
event as d3_event
|
||||
} from 'd3-selection';
|
||||
|
||||
import { t } from '../../util/locale';
|
||||
import { tooltip } from '../../util/tooltip';
|
||||
import { uiSection } from '../section';
|
||||
import { uiTooltipHtml } from '../tooltipHtml';
|
||||
|
||||
export function uiSectionMapStyleOptions(context) {
|
||||
|
||||
var section = uiSection('fill-area', context)
|
||||
.title(t('map_data.style_options'))
|
||||
.expandedByDefault(false);
|
||||
|
||||
section.renderDisclosureContent = function(selection) {
|
||||
var container = selection.selectAll('.layer-fill-list')
|
||||
.data([0]);
|
||||
|
||||
container.enter()
|
||||
.append('ul')
|
||||
.attr('class', 'layer-list layer-fill-list')
|
||||
.merge(container)
|
||||
.call(drawListItems, context.map().areaFillOptions, 'radio', 'area_fill', setFill, isActiveFill);
|
||||
|
||||
var container2 = selection.selectAll('.layer-visual-diff-list')
|
||||
.data([0]);
|
||||
|
||||
container2.enter()
|
||||
.append('ul')
|
||||
.attr('class', 'layer-list layer-visual-diff-list')
|
||||
.merge(container2)
|
||||
.call(drawListItems, ['highlight_edits'], 'checkbox', 'visual_diff', toggleHighlightEdited, function() {
|
||||
return context.surface().classed('highlight-edited');
|
||||
});
|
||||
};
|
||||
|
||||
function drawListItems(selection, data, type, name, change, active) {
|
||||
var items = selection.selectAll('li')
|
||||
.data(data);
|
||||
|
||||
// Exit
|
||||
items.exit()
|
||||
.remove();
|
||||
|
||||
// Enter
|
||||
var enter = items.enter()
|
||||
.append('li')
|
||||
.call(tooltip()
|
||||
.html(true)
|
||||
.title(function(d) {
|
||||
var tip = t(name + '.' + d + '.tooltip');
|
||||
var key = (d === 'wireframe' ? t('area_fill.wireframe.key') : null);
|
||||
if (d === 'highlight_edits') key = t('map_data.highlight_edits.key');
|
||||
return uiTooltipHtml(tip, key);
|
||||
})
|
||||
.placement('top')
|
||||
);
|
||||
|
||||
var label = enter
|
||||
.append('label');
|
||||
|
||||
label
|
||||
.append('input')
|
||||
.attr('type', type)
|
||||
.attr('name', name)
|
||||
.on('change', change);
|
||||
|
||||
label
|
||||
.append('span')
|
||||
.text(function(d) { return t(name + '.' + d + '.description'); });
|
||||
|
||||
// Update
|
||||
items = items
|
||||
.merge(enter);
|
||||
|
||||
items
|
||||
.classed('active', active)
|
||||
.selectAll('input')
|
||||
.property('checked', active)
|
||||
.property('indeterminate', false);
|
||||
}
|
||||
|
||||
function isActiveFill(d) {
|
||||
return context.map().activeAreaFill() === d;
|
||||
}
|
||||
|
||||
function toggleHighlightEdited() {
|
||||
d3_event.preventDefault();
|
||||
context.map().toggleHighlightEdited();
|
||||
}
|
||||
|
||||
function setFill(d) {
|
||||
context.map().activeAreaFill(d);
|
||||
}
|
||||
|
||||
context.map()
|
||||
.on('changeHighlighting.ui_style, changeAreaFill.ui_style', section.rerenderContent);
|
||||
|
||||
return section;
|
||||
}
|
||||
Reference in New Issue
Block a user