mirror of
https://github.com/FoggedLens/iD.git
synced 2026-02-13 17:23:02 +00:00
153 lines
4.2 KiB
JavaScript
153 lines
4.2 KiB
JavaScript
import * as d3 from 'd3';
|
|
import _ from 'lodash';
|
|
import { geoEuclideanDistance } from '../geo';
|
|
import { modeBrowse, modeSelect } from '../modes';
|
|
import { osmEntity } from '../osm';
|
|
|
|
|
|
export function behaviorSelect(context) {
|
|
var suppressMenu = true,
|
|
tolerance = 4,
|
|
p1 = null;
|
|
|
|
|
|
function keydown() {
|
|
if (d3.event && d3.event.shiftKey) {
|
|
context.surface()
|
|
.classed('behavior-multiselect', true);
|
|
}
|
|
}
|
|
|
|
|
|
function keyup() {
|
|
if (!d3.event || !d3.event.shiftKey) {
|
|
context.surface()
|
|
.classed('behavior-multiselect', false);
|
|
}
|
|
}
|
|
|
|
|
|
function point() {
|
|
return d3.mouse(context.container().node());
|
|
}
|
|
|
|
|
|
function contextmenu() {
|
|
if (!p1) p1 = point();
|
|
d3.event.preventDefault();
|
|
suppressMenu = false;
|
|
click();
|
|
}
|
|
|
|
|
|
function mousedown() {
|
|
if (!p1) p1 = point();
|
|
d3.select(window)
|
|
.on('mouseup.select', mouseup, true);
|
|
|
|
var isShowAlways = +context.storage('edit-menu-show-always') === 1;
|
|
suppressMenu = !isShowAlways;
|
|
}
|
|
|
|
|
|
function mouseup() {
|
|
click();
|
|
}
|
|
|
|
|
|
function click() {
|
|
d3.select(window)
|
|
.on('mouseup.select', null, true);
|
|
|
|
if (!p1) return;
|
|
var p2 = point(),
|
|
dist = geoEuclideanDistance(p1, p2);
|
|
|
|
p1 = null;
|
|
if (dist > tolerance) {
|
|
return;
|
|
}
|
|
|
|
var isMultiselect = d3.event.shiftKey || d3.select('#surface .lasso').node(),
|
|
isShowAlways = +context.storage('edit-menu-show-always') === 1,
|
|
datum = d3.event.target.__data__,
|
|
mode = context.mode();
|
|
|
|
|
|
if (datum && datum.type === 'midpoint') {
|
|
datum = datum.parents[0];
|
|
}
|
|
|
|
if (!(datum instanceof osmEntity)) {
|
|
// clicked nothing..
|
|
if (!isMultiselect && mode.id !== 'browse') {
|
|
context.enter(modeBrowse(context));
|
|
}
|
|
|
|
} else {
|
|
// clicked an entity..
|
|
var selectedIDs = context.selectedIDs();
|
|
|
|
if (!isMultiselect) {
|
|
if (selectedIDs.length > 1 && (!suppressMenu && !isShowAlways)) {
|
|
// multiple things already selected, just show the menu...
|
|
mode.suppressMenu(false).reselect();
|
|
} else {
|
|
// select a single thing..
|
|
context.enter(modeSelect(context, [datum.id]).suppressMenu(suppressMenu));
|
|
}
|
|
|
|
} else {
|
|
if (selectedIDs.indexOf(datum.id) !== -1) {
|
|
// clicked entity is already in the selectedIDs list..
|
|
if (!suppressMenu && !isShowAlways) {
|
|
// don't deselect clicked entity, just show the menu.
|
|
mode.suppressMenu(false).reselect();
|
|
} else {
|
|
// deselect clicked entity, then reenter select mode or return to browse mode..
|
|
selectedIDs = _.without(selectedIDs, datum.id);
|
|
context.enter(selectedIDs.length ? modeSelect(context, selectedIDs) : modeBrowse(context));
|
|
}
|
|
} else {
|
|
// clicked entity is not in the selected list, add it..
|
|
selectedIDs = selectedIDs.concat([datum.id]);
|
|
context.enter(modeSelect(context, selectedIDs).suppressMenu(suppressMenu));
|
|
}
|
|
}
|
|
}
|
|
|
|
// reset for next time..
|
|
suppressMenu = true;
|
|
}
|
|
|
|
|
|
var behavior = function(selection) {
|
|
d3.select(window)
|
|
.on('keydown.select', keydown)
|
|
.on('keyup.select', keyup);
|
|
|
|
selection
|
|
.on('mousedown.select', mousedown)
|
|
.on('contextmenu.select', contextmenu);
|
|
|
|
keydown();
|
|
};
|
|
|
|
|
|
behavior.off = function(selection) {
|
|
d3.select(window)
|
|
.on('keydown.select', null)
|
|
.on('keyup.select', null)
|
|
.on('mouseup.select', null, true);
|
|
|
|
selection
|
|
.on('mousedown.select', null)
|
|
.on('contextmenu.select', null);
|
|
|
|
keyup();
|
|
};
|
|
|
|
|
|
return behavior;
|
|
}
|