Merge branch 'master' of github.com:systemed/iD

This commit is contained in:
Tom MacWright
2013-01-29 18:48:55 -05:00
9 changed files with 156 additions and 76 deletions
+17 -3
View File
@@ -1181,10 +1181,13 @@ a.success-action {
border-radius: 4px;
}
.radial-menu-background {
stroke: #aaa;
stroke-opacity: 0.4;
}
.radial-menu-item {
fill: white;
stroke: black;
stroke-width: 1;
fill: black;
cursor:url(../img/cursor-pointer.png) 6 1, auto;
}
@@ -1202,6 +1205,17 @@ a.success-action {
fill: rgba(255,255,255,.5);
}
.radial-menu image {
pointer-events: none;
}
.radial-menu-tooltip {
background: rgba(255, 255, 255, 0.8);
padding: 5px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
}
/* Media Queries
------------------------------------------------------- */
+13 -17
View File
@@ -10,20 +10,6 @@ iD.modes.Select = function(entity, initial) {
behaviors,
radialMenu;
function remove() {
if (entity.type === 'way') {
mode.history.perform(
iD.actions.DeleteWay(entity.id),
'deleted a way');
} else if (entity.type === 'node') {
mode.history.perform(
iD.actions.DeleteNode(entity.id),
'deleted a node');
}
mode.controller.exit();
}
function changeTags(d, tags) {
if (!_.isEqual(entity.tags, tags)) {
mode.history.perform(
@@ -49,6 +35,18 @@ iD.modes.Select = function(entity, initial) {
behavior(surface);
});
var operations = d3.values(iD.operations)
.map(function (o) { return o(entity.id, mode); })
.filter(function (o) { return o.available(); });
operations.forEach(function(operation) {
keybinding.on(operation.key, function () {
if (operation.enabled()) {
operation();
}
});
});
var q = iD.util.stringQs(location.hash.substring(1));
location.replace('#' + iD.util.qsString(_.assign(q, {
id: entity.id
@@ -126,8 +124,6 @@ iD.modes.Select = function(entity, initial) {
surface.on('click.select', click)
.on('dblclick.select', dblclick);
keybinding.on('⌫', remove);
d3.select(document)
.call(keybinding);
@@ -137,7 +133,7 @@ iD.modes.Select = function(entity, initial) {
})
.classed('selected', true);
radialMenu = iD.ui.RadialMenu(entity, mode);
radialMenu = iD.ui.RadialMenu(operations);
if (d3.event && !initial) {
var loc = map.mouseCoordinates();
+10 -5
View File
@@ -1,7 +1,8 @@
iD.operations.Circular = function(entityId, mode) {
var action = iD.actions.Circular(entityId, mode.map);
var history = mode.map.history(),
action = iD.actions.Circular(entityId, mode.map);
var operation = function(history) {
var operation = function() {
var graph = history.graph(),
entity = graph.entity(entityId),
geometry = entity.geometry(graph);
@@ -18,17 +19,21 @@ iD.operations.Circular = function(entityId, mode) {
}
};
operation.available = function(graph) {
var entity = graph.entity(entityId);
operation.available = function() {
var graph = history.graph(),
entity = graph.entity(entityId);
return entity.geometry(graph) === 'area' || entity.geometry(graph) === 'line';
};
operation.enabled = function(graph) {
operation.enabled = function() {
var graph = history.graph();
return action.enabled(graph);
};
operation.id = "circular";
operation.key = "O";
operation.title = "Circular";
operation.description = "Make this round";
return operation;
};
+9 -4
View File
@@ -1,5 +1,7 @@
iD.operations.Delete = function(entityId) {
var operation = function(history) {
iD.operations.Delete = function(entityId, mode) {
var history = mode.map.history();
var operation = function() {
var graph = history.graph(),
entity = graph.entity(entityId),
geometry = entity.geometry(graph);
@@ -26,8 +28,9 @@ iD.operations.Delete = function(entityId) {
}
};
operation.available = function(graph) {
var entity = graph.entity(entityId);
operation.available = function() {
var graph = history.graph(),
entity = graph.entity(entityId);
return _.contains(['vertex', 'point', 'line', 'area'], entity.geometry(graph));
};
@@ -36,7 +39,9 @@ iD.operations.Delete = function(entityId) {
};
operation.id = "delete";
operation.key = "⌫";
operation.title = "Delete";
operation.description = "Remove this from the map";
return operation;
};
+6 -1
View File
@@ -1,9 +1,12 @@
iD.operations.Move = function(entityId, mode) {
var history = mode.map.history();
var operation = function() {
mode.controller.enter(iD.modes.MoveWay(entityId));
};
operation.available = function(graph) {
operation.available = function() {
var graph = history.graph();
return graph.entity(entityId).type === 'way';
};
@@ -12,7 +15,9 @@ iD.operations.Move = function(entityId, mode) {
};
operation.id = "move";
operation.key = "M";
operation.title = "Move";
operation.description = "Move this to a different location";
return operation;
};
+9 -4
View File
@@ -1,12 +1,15 @@
iD.operations.Reverse = function(entityId) {
var operation = function(history) {
iD.operations.Reverse = function(entityId, mode) {
var history = mode.map.history();
var operation = function() {
history.perform(
iD.actions.ReverseWay(entityId),
'reversed a line');
};
operation.available = function(graph) {
var entity = graph.entity(entityId);
operation.available = function() {
var graph = history.graph(),
entity = graph.entity(entityId);
return entity.geometry(graph) === 'line';
};
@@ -15,7 +18,9 @@ iD.operations.Reverse = function(entityId) {
};
operation.id = "reverse";
operation.key = "V";
operation.title = "Reverse";
operation.description = "Make this way go in the opposite direction";
return operation;
};
+11 -6
View File
@@ -1,21 +1,26 @@
iD.operations.Split = function(entityId) {
var action = iD.actions.SplitWay(entityId);
iD.operations.Split = function(entityId, mode) {
var history = mode.map.history(),
action = iD.actions.SplitWay(entityId);
var operation = function(history) {
var operation = function() {
history.perform(action, 'split a way');
};
operation.available = function(graph) {
var entity = graph.entity(entityId);
operation.available = function() {
var graph = history.graph(),
entity = graph.entity(entityId);
return entity.geometry(graph) === 'vertex';
};
operation.enabled = function(graph) {
operation.enabled = function() {
var graph = history.graph();
return action.enabled(graph);
};
operation.id = "split";
operation.key = "X";
operation.title = "Split";
operation.description = "Split this into two ways at this point";
return operation;
};
+11 -6
View File
@@ -1,21 +1,26 @@
iD.operations.Unjoin = function(entityId) {
var action = iD.actions.UnjoinNode(entityId);
iD.operations.Unjoin = function(entityId, mode) {
var history = mode.map.history(),
action = iD.actions.UnjoinNode(entityId);
var operation = function(history) {
var operation = function() {
history.perform(action, 'unjoined lines');
};
operation.available = function(graph) {
var entity = graph.entity(entityId);
operation.available = function() {
var graph = history.graph(),
entity = graph.entity(entityId);
return entity.geometry(graph) === 'vertex';
};
operation.enabled = function(graph) {
operation.enabled = function() {
var graph = history.graph();
return action.enabled(graph);
};
operation.id = "unjoin";
operation.key = "⇧-J";
operation.title = "Unjoin";
operation.description = "Disconnect these ways from each other";
return operation;
};
+70 -30
View File
@@ -1,50 +1,90 @@
iD.ui.RadialMenu = function(entity, mode) {
var arcs;
iD.ui.RadialMenu = function(operations) {
var menu;
var radialMenu = function(selection, center) {
var history = mode.map.history(),
graph = history.graph(),
operations = d3.values(iD.operations)
.map(function (o) { return o(entity.id, mode); })
.filter(function (o) { return o.available(graph); });
if (!operations.length)
return;
function click(operation) {
d3.event.stopPropagation();
operation(history);
operation();
}
var arc = d3.svg.arc()
.outerRadius(70)
.innerRadius(30)
.startAngle(function (d, i) { return 2 * Math.PI / operations.length * i; })
.endAngle(function (d, i) { return 2 * Math.PI / operations.length * (i + 1); });
arcs = selection.selectAll()
.data(operations)
.enter().append('g')
menu = selection.append('g')
.attr('class', 'radial-menu')
.attr('transform', "translate(" + center + ")")
.attr('opacity', 0);
arcs.transition()
menu.transition()
.attr('opacity', 0.8);
arcs.append('path')
.attr('class', function (d) { return 'radial-menu-item radial-menu-item-' + d.id; })
.attr('d', arc)
.classed('disabled', function (d) { return !d.enabled(graph); })
.on('click', click);
var r = 50,
a = Math.PI / 4,
a0 = -Math.PI / 4,
a1 = a0 + (operations.length - 1) * a;
arcs.append('text')
.attr("transform", function(d, i) { return "translate(" + arc.centroid(d, i) + ")"; })
.attr("dy", ".35em")
.style("text-anchor", "middle")
.text(function(d) { return d.title; });
menu.append('path')
.attr('class', 'radial-menu-background')
.attr('d', 'M' + r * Math.sin(a0) + ',' +
r * Math.cos(a0) +
' A' + r + ',' + r + ' 0 0,0 ' +
r * Math.sin(a1) + ',' +
r * Math.cos(a1))
.attr('stroke-width', 50)
.attr('stroke-linecap', 'round');
var button = menu.selectAll()
.data(operations)
.enter().append('g')
.attr('transform', function(d, i) {
return 'translate(' + r * Math.sin(a0 + i * a) + ',' +
r * Math.cos(a0 + i * a) + ')';
});
button.append('circle')
.attr('class', function (d) { return 'radial-menu-item radial-menu-item-' + d.id; })
.attr('r', 15)
.attr('title', function (d) { return d.title; })
.classed('disabled', function (d) { return !d.enabled(); })
.on('click', click)
.on('mouseover', mouseover)
.on('mouseout', mouseout);
button.append('image')
.attr('width', 16)
.attr('height', 16)
.attr('transform', 'translate(-8, -8)')
.attr('xlink:href', 'icons/helipad.png');
var tooltip = menu.append('foreignObject')
.style('display', 'none')
.attr('width', 200)
.attr('height', 400);
tooltip.append('xhtml:div')
.attr('class', 'radial-menu-tooltip');
function mouseover(d, i) {
var angle = a0 + i * a,
dx = angle < 0 ? -200 : 0,
dy = 0;
tooltip
.attr('x', (r + 30) * Math.sin(angle) + dx)
.attr('y', (r + 30) * Math.cos(angle) + dy)
.style('display', 'block')
.select('div')
.text(d.description);
}
function mouseout() {
tooltip.style('display', 'none');
}
};
radialMenu.close = function(selection) {
if (arcs) {
arcs.transition()
if (menu) {
menu.transition()
.attr('opacity', 0)
.remove();
}