Files
iD/modules/behavior/paste.js
2017-09-24 21:43:54 -04:00

95 lines
2.4 KiB
JavaScript

import _invert from 'lodash-es/invert';
import _mapValues from 'lodash-es/mapValues';
import {
event as d3_event,
select as d3_select
} from 'd3-selection';
import { d3keybinding as d3_keybinding } from '../lib/d3.keybinding.js';
import {
actionCopyEntities,
actionMove
} from '../actions';
import {
geoExtent,
geoPointInPolygon
} from '../geo/';
import { modeMove } from '../modes';
import { uiCmd } from '../ui';
export function behaviorPaste(context) {
var keybinding = d3_keybinding('paste');
function doPaste() {
d3_event.preventDefault();
var baseGraph = context.graph(),
mouse = context.mouse(),
projection = context.projection,
viewport = geoExtent(projection.clipExtent()).polygon();
if (!geoPointInPolygon(mouse, viewport)) return;
var extent = geoExtent(),
oldIDs = context.copyIDs(),
oldGraph = context.copyGraph(),
newIDs = [];
if (!oldIDs.length) return;
var action = actionCopyEntities(oldIDs, oldGraph);
context.perform(action);
var copies = action.copies();
var originals = _invert(_mapValues(copies, 'id'));
for (var id in copies) {
var oldEntity = oldGraph.entity(id),
newEntity = copies[id];
extent._extend(oldEntity.extent(oldGraph));
// Exclude child nodes from newIDs if their parent way was also copied.
var parents = context.graph().parentWays(newEntity),
parentCopied = false;
for (var i = 0; i < parents.length; i++) {
if (originals[parents[i].id]) {
parentCopied = true;
break;
}
}
if (!parentCopied) {
newIDs.push(newEntity.id);
}
}
// Put pasted objects where mouse pointer is..
var center = projection(extent.center()),
delta = [ mouse[0] - center[0], mouse[1] - center[1] ];
context.perform(actionMove(newIDs, delta, projection));
context.enter(modeMove(context, newIDs, baseGraph));
}
function paste() {
keybinding.on(uiCmd('⌘V'), doPaste);
d3_select(document).call(keybinding);
return paste;
}
paste.off = function() {
d3_select(document).call(keybinding.off);
};
return paste;
}