diff --git a/css/app.css b/css/app.css index c0600f15e..40fba9bd0 100644 --- a/css/app.css +++ b/css/app.css @@ -712,6 +712,10 @@ a:hover .icon.out-link { background-position: -500px -14px;} top: 60px; } +.selection-list-pane .inspector-body { + top: 60px; +} + .inspector-inner { padding: 20px; position: relative; diff --git a/data/core.yaml b/data/core.yaml index 342a9d86d..817b8dea7 100644 --- a/data/core.yaml +++ b/data/core.yaml @@ -200,6 +200,7 @@ en: back_tooltip: Change feature remove: Remove search: Search + multiselect: Selected items unknown: Unknown incomplete: feature_list: Search features diff --git a/dist/locales/en.json b/dist/locales/en.json index 726a8ff6e..27d52960d 100644 --- a/dist/locales/en.json +++ b/dist/locales/en.json @@ -247,6 +247,7 @@ "back_tooltip": "Change feature", "remove": "Remove", "search": "Search", + "multiselect": "Selected items", "unknown": "Unknown", "incomplete": "", "feature_list": "Search features", diff --git a/index.html b/index.html index f36b434f7..c88bace38 100644 --- a/index.html +++ b/index.html @@ -102,6 +102,7 @@ + diff --git a/js/id/modes/select.js b/js/id/modes/select.js index 550a7bdf2..13ef663b8 100644 --- a/js/id/modes/select.js +++ b/js/id/modes/select.js @@ -171,6 +171,11 @@ iD.modes.Select = function(context, selectedIDs) { context.surface() .on('dblclick.select', dblclick); }, 200); + + if (selectedIDs.length > 1) { + var entities = iD.ui.SelectionList(context, selectedIDs); + context.ui().sidebar.show(entities); + } }; mode.exit = function() { @@ -198,6 +203,7 @@ iD.modes.Select = function(context, selectedIDs) { .classed('selected', false); context.map().on('drawn.select', null); + context.ui().sidebar.hide(); }; return mode; diff --git a/js/id/ui/selection_list.js b/js/id/ui/selection_list.js new file mode 100644 index 000000000..59551cde7 --- /dev/null +++ b/js/id/ui/selection_list.js @@ -0,0 +1,100 @@ +iD.ui.SelectionList = function(context, selectedIDs) { + + function selectionList(selection) { + selection.classed('selection-list-pane', true); + + var header = selection.append('div') + .attr('class', 'header fillL cf'); + + header.append('h3') + .text(t('inspector.multiselect')); + + var listWrap = selection.append('div') + .attr('class', 'inspector-body'); + + var list = listWrap.append('div') + .attr('class', 'feature-list cf'); + + drawList(); + + function features() { + var entities = {}, + result = [], + graph = context.graph(); + + function addEntity(entity) { + var name = iD.util.displayName(entity) || ''; + result.push({ + id: entity.id, + entity: entity, + geometry: context.geometry(entity.id), + type: context.presets().match(entity, graph).name(), + name: name + }); + } + + for (var i = 0; i < selectedIDs.length; i++) { + addEntity(context.entity(selectedIDs[i])); + } + + return result; + } + + function drawList() { + var results = features(); + + var items = list.selectAll('.feature-list-item') + .data(results, function(d) { return d.id; }); + + var enter = items.enter().insert('button', '.geocode-item') + .attr('class', 'feature-list-item') + .on('mouseover', mouseover) + .on('mouseout', mouseout) + .on('click', click); + + var label = enter.append('div') + .attr('class', 'label'); + + label.append('span') + .attr('class', function(d) { return d.geometry + ' icon icon-pre-text'; }); + + label.append('span') + .attr('class', 'entity-type') + .text(function(d) { return d.type; }); + + label.append('span') + .attr('class', 'entity-name') + .text(function(d) { return d.name; }); + + enter.style('opacity', 0) + .transition() + .style('opacity', 1); + + items.order(); + + items.exit() + .remove(); + } + + function mouseover(d) { + context.surface().selectAll(iD.util.entityOrMemberSelector([d.id], context.graph())) + .classed('hover', true); + } + + function mouseout() { + context.surface().selectAll('.hover') + .classed('hover', false); + } + + function click(d) { + if (d.entity) { + context.enter(iD.modes.Select(context, [d.entity.id])); + } else { + context.loadEntity(d.id); + } + } + } + + return selectionList; + +};