mirror of
https://github.com/FoggedLens/iD.git
synced 2026-06-01 12:41:36 +02:00
Add Copy/Paste behaviors, context copybuffer
This commit is contained in:
@@ -171,6 +171,7 @@
|
||||
|
||||
<script src='js/id/behavior.js'></script>
|
||||
<script src='js/id/behavior/add_way.js'></script>
|
||||
<script src='js/id/behavior/copy.js'></script>
|
||||
<script src='js/id/behavior/drag.js'></script>
|
||||
<script src='js/id/behavior/draw.js'></script>
|
||||
<script src='js/id/behavior/draw_way.js'></script>
|
||||
@@ -178,6 +179,7 @@
|
||||
<script src='js/id/behavior/hash.js'></script>
|
||||
<script src='js/id/behavior/hover.js'></script>
|
||||
<script src='js/id/behavior/lasso.js'></script>
|
||||
<script src='js/id/behavior/paste.js'></script>
|
||||
<script src='js/id/behavior/select.js'></script>
|
||||
<script src='js/id/behavior/tail.js'></script>
|
||||
|
||||
|
||||
@@ -1,11 +1,19 @@
|
||||
iD.actions.CopyEntity = function(entity, deep) {
|
||||
return function(graph) {
|
||||
var newEntities = entity.copy(deep, graph);
|
||||
var newEntities = [];
|
||||
|
||||
for (var i = 0, imax = newEntities.length; i !== imax; i++) {
|
||||
var action = function(graph) {
|
||||
newEntities = entity.copy(deep, graph);
|
||||
|
||||
for (var i = 0; i < newEntities.length; i++) {
|
||||
graph = graph.replace(newEntities[i]);
|
||||
}
|
||||
|
||||
return graph;
|
||||
};
|
||||
|
||||
action.newEntities = function() {
|
||||
return newEntities;
|
||||
};
|
||||
|
||||
return action;
|
||||
};
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
iD.behavior.Copy = function(context) {
|
||||
var keybinding = d3.keybinding('copy');
|
||||
|
||||
function groupEntities(ids, graph) {
|
||||
var entities = ids.map(function (id) { return graph.entity(id); });
|
||||
return _.extend({relation: [], way: [], node: []},
|
||||
_.groupBy(entities, function(entity) { return entity.type; }));
|
||||
}
|
||||
|
||||
function getDescendants(id, graph, descendants) {
|
||||
var entity = graph.entity(id),
|
||||
i, children;
|
||||
|
||||
descendants = descendants || {};
|
||||
|
||||
if (entity.type === 'relation') {
|
||||
children = _.pluck(entity.members, 'id');
|
||||
} else if (entity.type === 'way') {
|
||||
children = entity.nodes;
|
||||
} else {
|
||||
children = [];
|
||||
}
|
||||
|
||||
for (i = 0; i < children.length; i++) {
|
||||
if (!descendants[children[i]]) {
|
||||
descendants[children[i]] = true;
|
||||
descendants = getDescendants(children[i], graph, descendants);
|
||||
}
|
||||
}
|
||||
|
||||
return descendants;
|
||||
}
|
||||
|
||||
function doCopy() {
|
||||
d3.event.preventDefault();
|
||||
|
||||
var graph = context.graph(),
|
||||
selected = groupEntities(context.selectedIDs(), graph),
|
||||
canCopy = [],
|
||||
skip = {},
|
||||
i, entity;
|
||||
|
||||
for (i = 0; i < selected.relation.length; i++) {
|
||||
entity = selected.relation[i];
|
||||
if (!skip[entity.id] && entity.isComplete()) {
|
||||
canCopy.push(entity.id);
|
||||
skip = getDescendants(entity.id, graph, skip);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < selected.way.length; i++) {
|
||||
entity = selected.way[i];
|
||||
if (!skip[entity.id]) {
|
||||
canCopy.push(entity.id);
|
||||
skip = getDescendants(entity.id, graph, skip);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < selected.node.length; i++) {
|
||||
entity = selected.node[i];
|
||||
if (!skip[entity.id]) {
|
||||
canCopy.push(entity.id);
|
||||
}
|
||||
}
|
||||
|
||||
context.copiedIDs(canCopy);
|
||||
}
|
||||
|
||||
function copy() {
|
||||
keybinding.on(iD.ui.cmd('⌘C'), doCopy);
|
||||
d3.select(document).call(keybinding);
|
||||
return copy;
|
||||
}
|
||||
|
||||
copy.off = function() {
|
||||
d3.select(document).call(keybinding.off);
|
||||
};
|
||||
|
||||
return copy;
|
||||
};
|
||||
@@ -0,0 +1,75 @@
|
||||
iD.behavior.Paste = function(context) {
|
||||
var keybinding = d3.keybinding('paste');
|
||||
|
||||
function omitTag(v, k) {
|
||||
return (
|
||||
k === 'phone' ||
|
||||
k === 'fax' ||
|
||||
k === 'email' ||
|
||||
k === 'website' ||
|
||||
k === 'url' ||
|
||||
k === 'note' ||
|
||||
k === 'description' ||
|
||||
k.indexOf('name') !== -1 ||
|
||||
k.indexOf('wiki') === 0 ||
|
||||
k.indexOf('addr:') === 0 ||
|
||||
k.indexOf('contact:') === 0
|
||||
);
|
||||
}
|
||||
|
||||
function doPaste() {
|
||||
d3.event.preventDefault();
|
||||
|
||||
var mouse = context.mouse(),
|
||||
projection = context.projection,
|
||||
viewport = iD.geo.Extent(projection.clipExtent()).polygon();
|
||||
|
||||
if (!iD.geo.pointInPolygon(mouse, viewport)) return;
|
||||
|
||||
var graph = context.graph(),
|
||||
extent = iD.geo.Extent(),
|
||||
oldIDs = context.copiedIDs(),
|
||||
newIDs = [],
|
||||
i, j;
|
||||
|
||||
for (i = 0; i < oldIDs.length; i++) {
|
||||
var oldEntity = graph.entity(oldIDs[i]),
|
||||
action = iD.actions.CopyEntity(oldEntity, true),
|
||||
newEntities;
|
||||
|
||||
extent._extend(oldEntity.extent(graph));
|
||||
context.perform(action);
|
||||
|
||||
// First element in `newEntities` contains the copied Entity,
|
||||
// Subsequent array elements contain any descendants..
|
||||
newEntities = action.newEntities();
|
||||
newIDs.push(newEntities[0].id);
|
||||
|
||||
for (j = 0; j < newEntities.length; j++) {
|
||||
var newEntity = newEntities[j],
|
||||
tags = _.omit(newEntity.tags, omitTag);
|
||||
|
||||
context.perform(iD.actions.ChangeTags(newEntity.id, tags));
|
||||
}
|
||||
}
|
||||
|
||||
// Put pasted objects where mouse pointer is..
|
||||
var center = projection(extent.center()),
|
||||
delta = [ mouse[0] - center[0], mouse[1] - center[1] ];
|
||||
|
||||
context.perform(iD.actions.Move(newIDs, delta, projection));
|
||||
context.enter(iD.modes.Move(context, newIDs));
|
||||
}
|
||||
|
||||
function paste() {
|
||||
keybinding.on(iD.ui.cmd('⌘V'), doPaste);
|
||||
d3.select(document).call(keybinding);
|
||||
return paste;
|
||||
}
|
||||
|
||||
paste.off = function() {
|
||||
d3.select(document).call(keybinding.off);
|
||||
};
|
||||
|
||||
return paste;
|
||||
};
|
||||
@@ -204,6 +204,14 @@ window.iD = function () {
|
||||
context.surface().call(behavior.off);
|
||||
};
|
||||
|
||||
/* Copy/Paste */
|
||||
var copiedIDs = [];
|
||||
context.copiedIDs = function(_) {
|
||||
if (!arguments.length) return copiedIDs;
|
||||
copiedIDs = _;
|
||||
return context;
|
||||
};
|
||||
|
||||
/* Projection */
|
||||
context.projection = iD.geo.RawMercator();
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ iD.modes.Browse = function(context) {
|
||||
}, sidebar;
|
||||
|
||||
var behaviors = [
|
||||
iD.behavior.Paste(context),
|
||||
iD.behavior.Hover(context)
|
||||
.on('hover', context.ui().sidebar.hover),
|
||||
iD.behavior.Select(context),
|
||||
|
||||
@@ -7,6 +7,8 @@ iD.modes.Select = function(context, selectedIDs) {
|
||||
var keybinding = d3.keybinding('select'),
|
||||
timeout = null,
|
||||
behaviors = [
|
||||
iD.behavior.Copy(context),
|
||||
iD.behavior.Paste(context),
|
||||
iD.behavior.Hover(context),
|
||||
iD.behavior.Select(context),
|
||||
iD.behavior.Lasso(context),
|
||||
|
||||
@@ -150,6 +150,7 @@
|
||||
|
||||
<script src='../js/id/behavior.js'></script>
|
||||
<script src='../js/id/behavior/add_way.js'></script>
|
||||
<script src='../js/id/behavior/copy.js'></script>
|
||||
<script src='../js/id/behavior/drag.js'></script>
|
||||
<script src='../js/id/behavior/draw.js'></script>
|
||||
<script src='../js/id/behavior/draw_way.js'></script>
|
||||
@@ -157,6 +158,7 @@
|
||||
<script src='../js/id/behavior/hash.js'></script>
|
||||
<script src='../js/id/behavior/hover.js'></script>
|
||||
<script src='../js/id/behavior/lasso.js'></script>
|
||||
<script src='../js/id/behavior/paste.js'></script>
|
||||
<script src='../js/id/behavior/select.js'></script>
|
||||
<script src='../js/id/behavior/tail.js'></script>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user