Add "Continue" operation

This commit is contained in:
John Firebaugh
2013-08-22 16:31:53 -07:00
parent 57cfe50ec7
commit 8a215cac81
8 changed files with 96 additions and 24 deletions
+5
View File
@@ -31,6 +31,11 @@ en:
line: Started a line.
area: Started an area.
continue:
key: A
title: Continue
description: Continue this line.
not_eligible: No line can be continued here.
multiple: Several lines can be continued here. To choose a line, press the Shift key and click on it to select it.
annotation:
line: Continued a line.
area: Continued an area.
+5
View File
@@ -41,6 +41,11 @@
}
},
"continue": {
"key": "A",
"title": "Continue",
"description": "Continue this line.",
"not_eligible": "No line can be continued here.",
"multiple": "Several lines can be continued here. To choose a line, press the Shift key and click on it to select it.",
"annotation": {
"line": "Continued a line.",
"area": "Continued an area."
+1
View File
@@ -174,6 +174,7 @@
<script src='js/id/modes/select.js'></script>
<script src='js/id/operations.js'></script>
<script src='js/id/operations/continue.js'></script>
<script src='js/id/operations/circularize.js'></script>
<script src='js/id/operations/orthogonalize.js'></script>
<script src='js/id/operations/delete.js'></script>
+5 -17
View File
@@ -41,25 +41,13 @@ iD.modes.AddLine = function(context) {
}
function startFromNode(node) {
var graph = context.graph(),
parent = graph.parentWays(node)[0],
isLine = parent && parent.geometry(graph) === 'line';
var way = iD.Way();
if (isLine && parent.first() === node.id) {
context.enter(iD.modes.DrawLine(context, parent.id, 'backward', graph));
context.perform(
iD.actions.AddEntity(way),
iD.actions.AddVertex(way.id, node.id));
} else if (isLine && parent.last() === node.id) {
context.enter(iD.modes.DrawLine(context, parent.id, 'forward', graph));
} else {
var way = iD.Way();
context.perform(
iD.actions.AddEntity(way),
iD.actions.AddVertex(way.id, node.id));
context.enter(iD.modes.DrawLine(context, way.id, 'forward', graph));
}
context.enter(iD.modes.DrawLine(context, way.id, 'forward', context.graph()));
}
mode.enter = function() {
+49
View File
@@ -0,0 +1,49 @@
iD.operations.Continue = function(selectedIDs, context) {
var graph = context.graph(),
entities = selectedIDs.map(function(id) { return graph.entity(id); }),
geometries = _.extend({line: [], vertex: []},
_.groupBy(entities, function(entity) { return entity.geometry(graph); })),
vertex = geometries.vertex[0];
function candidateWays() {
return graph.parentWays(vertex).filter(function(parent) {
return parent.geometry(graph) === 'line' &&
(parent.first() === vertex.id || parent.last() === vertex.id) &&
(geometries.line.length === 0 || geometries.line[0] === parent);
});
}
var operation = function() {
var candidate = candidateWays()[0];
context.enter(iD.modes.DrawLine(
context,
candidate.id,
candidate.first() === vertex.id ? 'backward' : 'forward',
context.graph()));
};
operation.available = function() {
return geometries.vertex.length === 1 && geometries.line.length <= 1;
};
operation.disabled = function() {
var candidates = candidateWays();
if (candidates.length === 0)
return 'not_eligible';
if (candidates.length > 1)
return 'multiple';
};
operation.tooltip = function() {
var disable = operation.disabled();
return disable ?
t('operations.continue.' + disable) :
t('operations.continue.description');
};
operation.id = "continue";
operation.keys = [t('operations.continue.key')];
operation.title = t('operations.continue.title');
return operation;
};
+7 -2
View File
@@ -20,7 +20,8 @@ iD.Map = function(context) {
midpoints = iD.svg.Midpoints(roundedProjection, context),
labels = iD.svg.Labels(roundedProjection, context),
supersurface, surface,
mouse;
mouse,
mousemove;
function map(selection) {
context.history()
@@ -52,6 +53,10 @@ iD.Map = function(context) {
.attr('id', 'surface')
.call(iD.svg.Surface(context));
surface.on('mousemove.map', function() {
mousemove = d3.event;
});
surface.on('mouseover.vertices', function() {
if (map.editable() && !transformed) {
var hover = d3.event.target.__data__;
@@ -249,7 +254,7 @@ iD.Map = function(context) {
}
map.mouse = function() {
var e = d3.event, s;
var e = mousemove, s;
while (s = e.sourceEvent) e = s;
return mouse(e);
};
+23 -5
View File
@@ -34,7 +34,7 @@ iD.ui.RadialMenu = function(context, operations) {
.attr('class', 'radial-menu-background')
.attr('d', 'M' + r * Math.sin(a0) + ',' +
r * Math.cos(a0) +
' A' + r + ',' + r + ' 0 0,0 ' +
' A' + r + ',' + r + ' 0 ' + (operations.length > 5 ? '1' : '0') + ',0 ' +
(r * Math.sin(a1) + 1e-3) + ',' +
(r * Math.cos(a1) + 1e-3)) // Force positive-length path (#1305)
.attr('stroke-width', 50)
@@ -68,14 +68,32 @@ iD.ui.RadialMenu = function(context, operations) {
function mouseover(d, i) {
var rect = context.surfaceRect(),
angle = a0 + i * a,
dx = rect.left - (angle < 0 ? 200 : 0),
dy = rect.top;
top = rect.top + (r + 25) * Math.cos(angle) + center[1] + 'px',
left = rect.left + (r + 25) * Math.sin(angle) + center[0] + 'px',
bottom = rect.height - (r + 25) * Math.cos(angle) - center[1] + 'px',
right = rect.width - (r + 25) * Math.sin(angle) - center[0] + 'px';
tooltip
.style('left', (r + 25) * Math.sin(angle) + dx + center[0] + 'px')
.style('top', (r + 25) * Math.cos(angle) + dy + center[1]+ 'px')
.style('top', null)
.style('left', null)
.style('bottom', null)
.style('right', null)
.style('display', 'block')
.html(iD.ui.tooltipHtml(d.tooltip(), d.keys[0]));
if (i === 0) {
tooltip
.style('right', right)
.style('top', top);
} else if (i >= 4) {
tooltip
.style('left', left)
.style('bottom', bottom);
} else {
tooltip
.style('left', left)
.style('top', top);
}
}
function mouseout() {
+1
View File
@@ -155,6 +155,7 @@
<script src='../js/id/modes/select.js'></script>
<script src='../js/id/operations.js'></script>
<script src='../js/id/operations/operations.js'></script>
<script src='../js/id/operations/circularize.js'></script>
<script src='../js/id/operations/orthogonalize.js'></script>
<script src='../js/id/operations/delete.js'></script>