mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-14 21:28:11 +02:00
Add context menu
This commit is contained in:
+1
-3
@@ -3167,9 +3167,7 @@ img.tile-removing {
|
||||
}
|
||||
|
||||
.radial-menu-background {
|
||||
fill: none;
|
||||
stroke: black;
|
||||
stroke-opacity: 0.5;
|
||||
fill: black;
|
||||
}
|
||||
|
||||
.radial-menu-item circle {
|
||||
|
||||
@@ -23,6 +23,11 @@ export function behaviorSelect(context) {
|
||||
|
||||
|
||||
function click() {
|
||||
|
||||
if (d3.event.type === 'contextmenu') {
|
||||
d3.event.preventDefault();
|
||||
}
|
||||
|
||||
var datum = d3.event.target.__data__,
|
||||
lasso = d3.select('#surface .lasso').node(),
|
||||
mode = context.mode();
|
||||
@@ -56,6 +61,7 @@ export function behaviorSelect(context) {
|
||||
.on('keyup.select', keyup);
|
||||
|
||||
selection.on('click.select', click);
|
||||
selection.on('contextmenu.select', click);
|
||||
|
||||
keydown();
|
||||
};
|
||||
|
||||
+23
-26
@@ -28,7 +28,7 @@ import {
|
||||
import { modeBrowse } from './browse';
|
||||
import { modeDragNode } from './drag_node';
|
||||
import * as Operations from '../operations/index';
|
||||
import { uiRadialMenu, uiSelectionList } from '../ui/index';
|
||||
import { uiEditMenu, uiSelectionList } from '../ui/index';
|
||||
import { uiCmd } from '../ui/cmd';
|
||||
import { utilEntityOrMemberSelector, utilEntitySelector } from '../util/index';
|
||||
|
||||
@@ -54,7 +54,7 @@ export function modeSelect(context, selectedIDs) {
|
||||
modeDragNode(context).selectedIDs(selectedIDs).behavior
|
||||
],
|
||||
inspector,
|
||||
radialMenu,
|
||||
editMenu,
|
||||
newFeature = false,
|
||||
suppressMenu = false,
|
||||
follow = false;
|
||||
@@ -139,36 +139,30 @@ export function modeSelect(context, selectedIDs) {
|
||||
|
||||
|
||||
function closeMenu() {
|
||||
if (radialMenu) {
|
||||
context.surface().call(radialMenu.close);
|
||||
if (editMenu) {
|
||||
context.surface().call(editMenu.close);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function positionMenu() {
|
||||
if (suppressMenu || !radialMenu) { return; }
|
||||
if (!editMenu) { return; }
|
||||
var point = context.mouse(),
|
||||
viewport = geoExtent(context.projection.clipExtent()).polygon(),
|
||||
offset = (viewport[1][1] - 30) - point[1]; // 30 to account for the infoblock
|
||||
|
||||
var entity = singular();
|
||||
if (entity && context.geometry(entity.id) === 'relation') {
|
||||
suppressMenu = true;
|
||||
} else if (entity && entity.type === 'node') {
|
||||
radialMenu.center(context.projection(entity.loc));
|
||||
} else {
|
||||
var point = context.mouse(),
|
||||
viewport = geoExtent(context.projection.clipExtent()).polygon();
|
||||
if (geoPointInPolygon(point, viewport)) {
|
||||
radialMenu.center(point);
|
||||
} else {
|
||||
suppressMenu = true;
|
||||
}
|
||||
if (geoPointInPolygon(point, viewport)) {
|
||||
editMenu
|
||||
.center(point)
|
||||
.offset(offset);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function showMenu() {
|
||||
closeMenu();
|
||||
if (!suppressMenu && radialMenu) {
|
||||
context.surface().call(radialMenu);
|
||||
if (editMenu) {
|
||||
context.surface().call(editMenu);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,7 +190,9 @@ export function modeSelect(context, selectedIDs) {
|
||||
}
|
||||
|
||||
positionMenu();
|
||||
showMenu();
|
||||
if (d3.event && d3.event.type === 'contextmenu') {
|
||||
showMenu();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -425,7 +421,7 @@ export function modeSelect(context, selectedIDs) {
|
||||
d3.select(document)
|
||||
.call(keybinding);
|
||||
|
||||
radialMenu = uiRadialMenu(context, operations);
|
||||
editMenu = uiEditMenu(context, operations);
|
||||
|
||||
context.ui().sidebar
|
||||
.select(singular() ? singular().id : null, newFeature);
|
||||
@@ -440,8 +436,9 @@ export function modeSelect(context, selectedIDs) {
|
||||
|
||||
selectElements();
|
||||
|
||||
var show = d3.event && !suppressMenu;
|
||||
|
||||
var show = d3.event;
|
||||
var rtClick = d3.event && d3.event.type === 'contextmenu';
|
||||
|
||||
if (show) {
|
||||
positionMenu();
|
||||
}
|
||||
@@ -459,7 +456,7 @@ export function modeSelect(context, selectedIDs) {
|
||||
}
|
||||
|
||||
timeout = window.setTimeout(function() {
|
||||
if (show) {
|
||||
if (rtClick) {
|
||||
showMenu();
|
||||
}
|
||||
|
||||
@@ -485,7 +482,7 @@ export function modeSelect(context, selectedIDs) {
|
||||
|
||||
keybinding.off();
|
||||
closeMenu();
|
||||
radialMenu = undefined;
|
||||
editMenu = undefined;
|
||||
|
||||
context.history()
|
||||
.on('undone.select', null)
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
import * as d3 from 'd3';
|
||||
import { geoRoundCoords } from '../geo/index';
|
||||
import { uiTooltipHtml } from './tooltipHtml';
|
||||
|
||||
|
||||
export function uiEditMenu(context, operations) {
|
||||
var rect,
|
||||
menu,
|
||||
center = [0, 0],
|
||||
offset = 0,
|
||||
tooltip;
|
||||
|
||||
var p = 5,
|
||||
l = 10, // left padding
|
||||
a = 30,
|
||||
a1 = (operations.length) * (a + p) + p;
|
||||
|
||||
var editMenu = function(selection) {
|
||||
if (!operations.length) return;
|
||||
|
||||
selection.node().parentNode.focus();
|
||||
|
||||
function click(operation) {
|
||||
d3.event.stopPropagation();
|
||||
if (operation.disabled()) return;
|
||||
operation();
|
||||
editMenu.close();
|
||||
}
|
||||
|
||||
menu = selection
|
||||
.append('g')
|
||||
.attr('class', 'radial-menu')
|
||||
.attr('transform', 'translate(' + [center[0] + l, center[1]] + ')')
|
||||
.attr('opacity', 0);
|
||||
|
||||
menu
|
||||
.transition()
|
||||
.attr('opacity', 1);
|
||||
|
||||
rect = menu
|
||||
.append('g')
|
||||
.attr('class', 'radial-menu-rectangle')
|
||||
.attr('transform', function() {
|
||||
var pos = [0, 0];
|
||||
if (offset <= a1) {
|
||||
pos = [0, offset - a1];
|
||||
}
|
||||
return 'translate(' + pos + ')';
|
||||
});
|
||||
|
||||
menu
|
||||
.append('path')
|
||||
.attr('class', 'radial-menu-background')
|
||||
.attr('transform', 'translate(1, 1)')
|
||||
.attr('d', 'M0 8 L8 14 L8 8 L8 2 Z');
|
||||
|
||||
rect
|
||||
.append('rect')
|
||||
.attr('class', 'radial-menu-background')
|
||||
.attr('x', 8)
|
||||
.attr('rx', 4)
|
||||
.attr('ry', 4)
|
||||
.attr('width', 44)
|
||||
.attr('height', a1)
|
||||
.attr('stroke-linecap', 'round');
|
||||
|
||||
|
||||
var button = rect.selectAll()
|
||||
.data(operations)
|
||||
.enter()
|
||||
.append('g')
|
||||
.attr('class', function(d) { return 'radial-menu-item radial-menu-item-' + d.id; })
|
||||
.classed('disabled', function(d) { return d.disabled(); })
|
||||
.attr('transform', function(d, i) {
|
||||
return 'translate(' +geoRoundCoords([
|
||||
a/2 + l + p,
|
||||
a/2 + p * (i + 1) + i * a]).join(',') + ')';
|
||||
});
|
||||
|
||||
button
|
||||
.append('circle')
|
||||
.attr('r', 15)
|
||||
.on('click', click)
|
||||
.on('mousedown', mousedown)
|
||||
.on('mouseover', mouseover)
|
||||
.on('mouseout', mouseout);
|
||||
|
||||
button
|
||||
.append('use')
|
||||
.attr('transform', 'translate(-10,-10)')
|
||||
.attr('width', '20')
|
||||
.attr('height', '20')
|
||||
.attr('xlink:href', function(d) { return '#operation-' + d.id; });
|
||||
|
||||
tooltip = d3.select(document.body)
|
||||
.append('div')
|
||||
.attr('class', 'tooltip-inner radial-menu-tooltip');
|
||||
|
||||
function mousedown() {
|
||||
d3.event.stopPropagation(); // https://github.com/openstreetmap/iD/issues/1869
|
||||
}
|
||||
|
||||
function mouseover(d, i) {
|
||||
var rect = context.surfaceRect(),
|
||||
pos = [center[0], offset <= a1 ? center[1] - (a1 - offset) : center[1]],
|
||||
top = rect.top + i * (p + a)+ pos[1] + 'px',
|
||||
left = rect.left + (65) + pos[0] + 'px';
|
||||
|
||||
tooltip
|
||||
.style('top', top)
|
||||
.style('left', left)
|
||||
.style('display', 'block')
|
||||
.html(uiTooltipHtml(d.tooltip(), d.keys[0]));
|
||||
}
|
||||
|
||||
function mouseout() {
|
||||
tooltip.style('display', 'none');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
editMenu.close = function() {
|
||||
if (menu) {
|
||||
menu
|
||||
.style('pointer-events', 'none')
|
||||
.transition()
|
||||
.attr('opacity', 0)
|
||||
.remove();
|
||||
}
|
||||
|
||||
if (tooltip) {
|
||||
tooltip.remove();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
editMenu.center = function(_) {
|
||||
if (!arguments.length) return center;
|
||||
center = _;
|
||||
return editMenu;
|
||||
};
|
||||
|
||||
editMenu.offset = function(_) {
|
||||
if (!arguments.length) return offset;
|
||||
offset = _;
|
||||
return editMenu;
|
||||
};
|
||||
|
||||
return editMenu;
|
||||
}
|
||||
@@ -47,3 +47,5 @@ export { uiTooltipHtml } from './tooltipHtml';
|
||||
export { uiUndoRedo } from './undo_redo';
|
||||
export { uiViewOnOSM } from './view_on_osm';
|
||||
export { uiZoom } from './zoom';
|
||||
|
||||
export { uiEditMenu } from './edit_menu';
|
||||
|
||||
Reference in New Issue
Block a user