diff --git a/modules/behavior/select.js b/modules/behavior/select.js index a0203c5ee..4ec87f9ca 100644 --- a/modules/behavior/select.js +++ b/modules/behavior/select.js @@ -118,31 +118,16 @@ export function behaviorSelect(context) { var datum = d3_event.target.__data__ || (lastMouse && lastMouse.target.__data__); var mode = context.mode(); - var entity; - - // check if datum is a note - if (datum instanceof osmNote) { - if (!isMultiselect) entity = datum; - else { entity = 'multiselectedNote'; } // if multiselected, ignore notes TODO: possibly give warning - } - - else { entity = datum && datum.properties && datum.properties.entity; } - + var entity = datum && datum.properties && datum.properties.entity; if (entity) datum = entity; if (datum && datum.type === 'midpoint') { datum = datum.parents[0]; } - if (!(datum instanceof osmEntity) && !(datum instanceof osmNote)) { - // clicked nothing.. - if (!isMultiselect && mode.id !== 'browse') { - context.enter(modeBrowse(context)); - } - - } else { - // clicked an entity.. + if (datum instanceof osmEntity) { // clicked an entity.. var selectedIDs = context.selectedIDs(); + context.selectedNoteID(null); if (!isMultiselect) { if (selectedIDs.length > 1 && (!suppressMenu && !isShowAlways)) { @@ -170,6 +155,15 @@ export function behaviorSelect(context) { context.enter(modeSelect(context, selectedIDs).suppressMenu(suppressMenu)); } } + + } else if (datum instanceof osmNote && !isMultiselect) { // clicked a Note.. + context.selectedNoteID(datum.id); + + } else { // clicked nothing.. + context.selectedNoteID(null); + if (!isMultiselect && mode.id !== 'browse') { + context.enter(modeBrowse(context)); + } } // reset for next time.. diff --git a/modules/core/context.js b/modules/core/context.js index 7e3ea68eb..4d758066e 100644 --- a/modules/core/context.js +++ b/modules/core/context.js @@ -255,10 +255,18 @@ export function coreContext() { return []; } }; + context.activeID = function() { return mode && mode.activeID && mode.activeID(); }; + var _selectedNoteID; + context.selectedNoteID = function(noteID) { + if (!arguments.length) return _selectedNoteID; + _selectedNoteID = noteID; + return context; + }; + /* Behaviors */ context.install = function(behavior) { diff --git a/modules/modes/select.js b/modules/modes/select.js index eeb7cfb66..01ca1dd99 100644 --- a/modules/modes/select.js +++ b/modules/modes/select.js @@ -443,91 +443,93 @@ export function modeSelect(context, selectedIDs) { if (noteFound) { context.ui().sidebar.show(noteEditor.note('context.selectedNoteID')); // TODO: update to noteID reference - } else { - var operations = _without(_values(Operations), Operations.operationDelete) - .map(function(o) { return o(selectedIDs, context); }) - .filter(function(o) { return o.available(); }); - - // deprecation warning - Radial Menu to be removed in iD v3 - var isRadialMenu = context.storage('edit-menu-style') === 'radial'; - if (isRadialMenu) { - operations = operations.slice(0,7); - operations.unshift(Operations.operationDelete(selectedIDs, context)); - } else { - operations.push(Operations.operationDelete(selectedIDs, context)); - } - - operations.forEach(function(operation) { - if (operation.behavior) { - behaviors.push(operation.behavior); - } - }); - - behaviors.forEach(function(behavior) { - context.install(behavior); - }); - - keybinding - .on(['[', 'pgup'], previousVertex) - .on([']', 'pgdown'], nextVertex) - .on(['{', uiCmd('⌘['), 'home'], firstVertex) - .on(['}', uiCmd('⌘]'), 'end'], lastVertex) - .on(['\\', 'pause'], nextParent) - .on('⎋', esc, true) - .on('space', toggleMenu); - - d3_select(document) - .call(keybinding); - - - // deprecation warning - Radial Menu to be removed in iD v3 - editMenu = isRadialMenu - ? uiRadialMenu(context, operations) - : uiEditMenu(context, operations); - - context.ui().sidebar - .select(singular() ? singular().id : null, newFeature); - - context.history() - .on('undone.select', update) - .on('redone.select', update); - - context.map() - .on('move.select', closeMenu) - .on('drawn.select', selectElements); - - context.surface() - .on('dblclick.select', dblclick); - - - selectElements(); - - if (selectedIDs.length > 1) { - var entities = uiSelectionList(context, selectedIDs); - context.ui().sidebar.show(entities); - } - - if (follow) { - var extent = geoExtent(); - var graph = context.graph(); - selectedIDs.forEach(function(id) { - var entity = context.entity(id); - extent._extend(entity.extent(graph)); - }); - - var loc = extent.center(); - context.map().centerEase(loc); - } else if (singular() && singular().type === 'way') { - context.map().pan([0,0]); // full redraw, to adjust z-sorting #2914 - } - - timeout = window.setTimeout(function() { - positionMenu(); - if (!suppressMenu) { - showMenu(); - } - }, 270); /* after any centerEase completes */ + return; } + + + var operations = _without(_values(Operations), Operations.operationDelete) + .map(function(o) { return o(selectedIDs, context); }) + .filter(function(o) { return o.available(); }); + + // deprecation warning - Radial Menu to be removed in iD v3 + var isRadialMenu = context.storage('edit-menu-style') === 'radial'; + if (isRadialMenu) { + operations = operations.slice(0,7); + operations.unshift(Operations.operationDelete(selectedIDs, context)); + } else { + operations.push(Operations.operationDelete(selectedIDs, context)); + } + + operations.forEach(function(operation) { + if (operation.behavior) { + behaviors.push(operation.behavior); + } + }); + + behaviors.forEach(function(behavior) { + context.install(behavior); + }); + + keybinding + .on(['[', 'pgup'], previousVertex) + .on([']', 'pgdown'], nextVertex) + .on(['{', uiCmd('⌘['), 'home'], firstVertex) + .on(['}', uiCmd('⌘]'), 'end'], lastVertex) + .on(['\\', 'pause'], nextParent) + .on('⎋', esc, true) + .on('space', toggleMenu); + + d3_select(document) + .call(keybinding); + + + // deprecation warning - Radial Menu to be removed in iD v3 + editMenu = isRadialMenu + ? uiRadialMenu(context, operations) + : uiEditMenu(context, operations); + + context.ui().sidebar + .select(singular() ? singular().id : null, newFeature); + + context.history() + .on('undone.select', update) + .on('redone.select', update); + + context.map() + .on('move.select', closeMenu) + .on('drawn.select', selectElements); + + context.surface() + .on('dblclick.select', dblclick); + + + selectElements(); + + if (selectedIDs.length > 1) { + var entities = uiSelectionList(context, selectedIDs); + context.ui().sidebar.show(entities); + } + + if (follow) { + var extent = geoExtent(); + var graph = context.graph(); + selectedIDs.forEach(function(id) { + var entity = context.entity(id); + extent._extend(entity.extent(graph)); + }); + + var loc = extent.center(); + context.map().centerEase(loc); + } else if (singular() && singular().type === 'way') { + context.map().pan([0,0]); // full redraw, to adjust z-sorting #2914 + } + + timeout = window.setTimeout(function() { + positionMenu(); + if (!suppressMenu) { + showMenu(); + } + }, 270); /* after any centerEase completes */ }; diff --git a/modules/services/osm.js b/modules/services/osm.js index 2d599faee..ae438562c 100644 --- a/modules/services/osm.js +++ b/modules/services/osm.js @@ -226,6 +226,7 @@ var parsers = { var note = new osmNote(props); var item = { minX: note.loc[0], minY: note.loc[1], maxX: note.loc[0], maxY: note.loc[1], data: note }; _noteCache.rtree.insert(item); + _noteCache.note[id] = note; return note; } }; @@ -728,12 +729,8 @@ export default { } if (loadingNotes) { - var notes = parsed.map(function(d) { - cache.note[d.id] = d; - return { minX: d.loc[0], minY: d.loc[1], maxX: d.loc[0], maxY: d.loc[1], data: d }; - }); - cache.rtree.load(notes); dispatch.call('loadedNotes'); + } else { if (callback) { callback(err, _extend({ data: parsed }, tile)); diff --git a/modules/svg/notes.js b/modules/svg/notes.js index 6cc9b47f9..7a2d174b4 100644 --- a/modules/svg/notes.js +++ b/modules/svg/notes.js @@ -9,12 +9,11 @@ import { uiNoteEditor } from '../ui'; export function svgNotes(projection, context, dispatch) { var throttledRedraw = _throttle(function () { dispatch.call('change'); }, 1000); + // var noteEditor = uiNoteEditor(context); var minZoom = 12; var layer = d3_select(null); var _notes; - var _selected; - var noteEditor = uiNoteEditor(context); function init() { if (svgNotes.initialized) return; // run once @@ -66,40 +65,41 @@ export function svgNotes(projection, context, dispatch) { function click(which) { - _selected = which; + // _selected = which; context.map().centerEase(which.loc); - layer.selectAll('.note') - .classed('selected', function(d) { return d === _selected; }); + // layer.selectAll('.note') + // .classed('selected', function(d) { return d === _selected; }); // context.ui().sidebar.show(noteEditor.note(which)); } - function mouseover(which) { - layer.selectAll('.note') - .classed('hovered', function(d) { return d === which; }); + // function mouseover(which) { + // layer.selectAll('.note') + // .classed('hovered', function(d) { return d === which; }); - // context.ui().sidebar.show(noteEditor.note(which)); - } + // // context.ui().sidebar.show(noteEditor.note(which)); + // } - function mouseout() { - layer.selectAll('.note') - .classed('hovered', false); + // function mouseout() { + // layer.selectAll('.note') + // .classed('hovered', false); - // TODO: check if the item was clicked. If so, it should remain on the sidebar. - // TODO: handle multi-clicks. Otherwise, utilize behavior/select.js - // context.ui().sidebar.hide(); - } + // // TODO: check if the item was clicked. If so, it should remain on the sidebar. + // // TODO: handle multi-clicks. Otherwise, utilize behavior/select.js + // // context.ui().sidebar.hide(); + // } function update() { var service = getService(); + var selectedID = context.selectedNoteID(); var data = (service ? service.notes(projection) : []); var transform = svgPointTransform(projection); var notes = layer.selectAll('.note') - .data(data, function(d) { return d.key; }); + .data(data, function(d) { return d.id; }); // exit notes.exit() @@ -108,7 +108,8 @@ export function svgNotes(projection, context, dispatch) { // enter var notesEnter = notes.enter() .append('g') - .attr('class', function(d) { return 'note note-' + d.id + ' ' + d.status; }); + .attr('class', function(d) { return 'note note-' + d.id + ' ' + d.status; }) + .on('click', click); notesEnter .append('use') @@ -144,11 +145,11 @@ export function svgNotes(projection, context, dispatch) { notes .merge(notesEnter) .sort(function(a, b) { - return (a === _selected) ? 1 - : (b === _selected) ? -1 + return (a.id === selectedID) ? 1 + : (b.id === selectedID) ? -1 : b.loc[1] - a.loc[1]; // sort Y }) - .classed('selected', function(d) { return d === _selected; }) + .classed('selected', function(d) { return d.id === selectedID; }) .attr('transform', transform); }