diff --git a/data/core.yaml b/data/core.yaml index 491e05cc5..12688876c 100644 --- a/data/core.yaml +++ b/data/core.yaml @@ -2053,6 +2053,8 @@ en: split: "Split a line into two at the selected node" reverse: "Reverse selected features" move: "Move selected features" + nudge: "Nudge selected features" + nudge_more: "Nudge selected features by a lot" rotate: "Rotate selected features" orthogonalize: "Square corners of a line or area" straighten: "Straighten a line or points" diff --git a/data/shortcuts.json b/data/shortcuts.json index fec11cba0..7620679d9 100644 --- a/data/shortcuts.json +++ b/data/shortcuts.json @@ -269,6 +269,18 @@ "shortcuts": ["operations.move.key"], "text": "shortcuts.editing.operations.move" }, + { + "modifiers": ["⇧"], + "shortcuts": ["↓", "↑", "←", "→"], + "text": "shortcuts.editing.operations.nudge", + "separator": "," + }, + { + "modifiers": ["⌘", "⇧"], + "shortcuts": ["↓", "↑", "←", "→"], + "text": "shortcuts.editing.operations.nudge_more", + "separator": "," + }, { "shortcuts": ["operations.rotate.key"], "text": "shortcuts.editing.operations.rotate" diff --git a/dist/locales/en.json b/dist/locales/en.json index 302e16402..06ab7bf57 100644 --- a/dist/locales/en.json +++ b/dist/locales/en.json @@ -2528,6 +2528,8 @@ "split": "Split a line into two at the selected node", "reverse": "Reverse selected features", "move": "Move selected features", + "nudge": "Nudge selected features", + "nudge_more": "Nudge selected features by a lot", "rotate": "Rotate selected features", "orthogonalize": "Square corners of a line or area", "straighten": "Straighten a line or points", diff --git a/modules/modes/select.js b/modules/modes/select.js index 11572c71c..7cf00981b 100644 --- a/modules/modes/select.js +++ b/modules/modes/select.js @@ -4,6 +4,7 @@ import { t } from '../core/localizer'; import { actionAddMidpoint } from '../actions/add_midpoint'; import { actionDeleteRelation } from '../actions/delete_relation'; +import { actionMove } from '../actions/move'; import { behaviorBreathe } from '../behavior/breathe'; import { behaviorHover } from '../behavior/hover'; @@ -11,6 +12,8 @@ import { behaviorLasso } from '../behavior/lasso'; import { behaviorPaste } from '../behavior/paste'; import { behaviorSelect } from '../behavior/select'; +import { operationMove } from '../operations/move'; + import { geoExtent, geoChooseEdge } from '../geo'; import { modeBrowse } from './browse'; import { modeDragNode } from './drag_node'; @@ -212,6 +215,14 @@ export function modeSelect(context, selectedIDs) { .on([']', 'pgdown'], nextVertex) .on(['{', uiCmd('⌘['), 'home'], firstVertex) .on(['}', uiCmd('⌘]'), 'end'], lastVertex) + .on(uiCmd('⇧←'), nudgeSelection([-10, 0])) + .on(uiCmd('⇧↑'), nudgeSelection([0, -10])) + .on(uiCmd('⇧→'), nudgeSelection([10, 0])) + .on(uiCmd('⇧↓'), nudgeSelection([0, 10])) + .on(uiCmd('⇧⌘←'), nudgeSelection([-100, 0])) + .on(uiCmd('⇧⌘↑'), nudgeSelection([0, -100])) + .on(uiCmd('⇧⌘→'), nudgeSelection([100, 0])) + .on(uiCmd('⇧⌘↓'), nudgeSelection([0, 100])) .on(['\\', 'pause'], nextParent) .on('⎋', esc, true); @@ -258,6 +269,24 @@ export function modeSelect(context, selectedIDs) { } + function nudgeSelection(delta) { + return function() { + d3_event.stopImmediatePropagation(); + + var moveOp = operationMove(context, selectedIDs); + if (moveOp.disabled()) { + context.ui().flash + .duration(4000) + .iconName('#iD-operation-' + moveOp.id) + .iconClass('operation disabled') + .text(moveOp.tooltip)(); + } else { + context.perform(actionMove(selectedIDs, delta, context.projection), moveOp.annotation()); + } + }; + } + + function didDoubleUp(loc) { if (!context.map().withinEditableZoom()) return; diff --git a/modules/ui/init.js b/modules/ui/init.js index 0e9eaabb8..a9bed76e1 100644 --- a/modules/ui/init.js +++ b/modules/ui/init.js @@ -319,10 +319,10 @@ export function uiInit(context) { .on('↑', pan([0, panPixels])) .on('→', pan([-panPixels, 0])) .on('↓', pan([0, -panPixels])) - .on(['⇧←', uiCmd('⌘←')], pan([map.dimensions()[0], 0])) - .on(['⇧↑', uiCmd('⌘↑')], pan([0, map.dimensions()[1]])) - .on(['⇧→', uiCmd('⌘→')], pan([-map.dimensions()[0], 0])) - .on(['⇧↓', uiCmd('⌘↓')], pan([0, -map.dimensions()[1]])) + .on(uiCmd('⌘←'), pan([map.dimensions()[0], 0])) + .on(uiCmd('⌘↑'), pan([0, map.dimensions()[1]])) + .on(uiCmd('⌘→'), pan([-map.dimensions()[0], 0])) + .on(uiCmd('⌘↓'), pan([0, -map.dimensions()[1]])) .on(uiCmd('⌘' + t('background.key')), function quickSwitch() { if (d3_event) { d3_event.stopImmediatePropagation(); @@ -399,6 +399,7 @@ export function uiInit(context) { function pan(d) { return function() { + if (d3_event.shiftKey) return; if (context.container().select('.combobox').size()) return; d3_event.preventDefault(); context.map().pan(d, 100);