Don't highlight-focus single ways when one of their nodes is selected

Fix stale highlight-focus of parent way when selecting an unrelated vertex
Rename some confusing identifiers in modeSelect
Move global _relatedParent functionality into modeSelect proper
Re: #8264
This commit is contained in:
Quincy Morgan
2021-01-06 12:26:08 -05:00
parent 872d820b5a
commit b0df3139e4

View File

@@ -28,9 +28,6 @@ import {
} from '../util';
var _relatedParent;
export function modeSelect(context, selectedIDs) {
var mode = {
id: 'select',
@@ -48,6 +45,10 @@ export function modeSelect(context, selectedIDs) {
var _newFeature = false;
var _follow = false;
// `_focusedParentWayId` is used when we visit a vertex with multiple
// parents, and we want to remember which parent line we started on.
var _focusedParentWayId;
function singular() {
if (selectedIDs && selectedIDs.length === 1) {
@@ -86,14 +87,14 @@ export function modeSelect(context, selectedIDs) {
// find the parent ways for nextVertex, previousVertex, and selectParent
function multipleParents(onlyCommonParents) {
function parentWaysIdsOfSelection(onlyCommonParents) {
var graph = context.graph();
var parents = [];
for (var i = 0; i < selectedIDs.length; i++) {
var entity = context.hasEntity(selectedIDs[i]);
if (!entity || entity.geometry(graph) !== 'vertex') {
return []; // selection includes some not vertices
return []; // selection includes some non-vertices
}
var currParents = graph.parentWays(entity).map(function(w) { return w.id; });
@@ -112,26 +113,23 @@ export function modeSelect(context, selectedIDs) {
}
function singularParent() {
var parents = multipleParents(true);
if (!parents || parents.length === 0) {
_relatedParent = null;
return null;
function checkFocusedParent() {
if (_focusedParentWayId) {
var parents = parentWaysIdsOfSelection(true);
if (parents.indexOf(_focusedParentWayId) === -1) _focusedParentWayId = null;
}
}
function parentWayIdForVertexNavigation() {
var parentIds = parentWaysIdsOfSelection(true);
if (_focusedParentWayId && parentIds.indexOf(_focusedParentWayId) !== -1) {
// prefer the previously seen parent
return _focusedParentWayId;
}
// relatedParent is used when we visit a vertex with multiple
// parents, and we want to remember which parent line we started on.
if (parents.length === 1) {
_relatedParent = parents[0]; // remember this parent for later
return _relatedParent;
}
if (parents.indexOf(_relatedParent) !== -1) {
return _relatedParent; // prefer the previously seen parent
}
return parents[0];
return parentIds.length ? parentIds[0] : null;
}
@@ -244,7 +242,7 @@ export function modeSelect(context, selectedIDs) {
.on(utilKeybinding.plusKeys.map((key) => uiCmd('⇧⌥' + key)), scaleSelection(Math.pow(1.05, 5)))
.on(utilKeybinding.minusKeys.map((key) => uiCmd('⇧' + key)), scaleSelection(1/1.05))
.on(utilKeybinding.minusKeys.map((key) => uiCmd('⇧⌥' + key)), scaleSelection(1/Math.pow(1.05, 5)))
.on(['\\', 'pause'], nextParent)
.on(['\\', 'pause'], focusNextParent)
.on(uiCmd('⌘↑'), selectParent)
.on('⎋', esc, true);
@@ -427,9 +425,10 @@ export function modeSelect(context, selectedIDs) {
surface.selectAll('.related')
.classed('related', false);
singularParent();
if (_relatedParent) {
surface.selectAll(utilEntitySelector([_relatedParent]))
// reload `_focusedParentWayId` based on the current selection
checkFocusedParent();
if (_focusedParentWayId) {
surface.selectAll(utilEntitySelector([_focusedParentWayId]))
.classed('related', true);
}
@@ -456,18 +455,20 @@ export function modeSelect(context, selectedIDs) {
function firstVertex(d3_event) {
d3_event.preventDefault();
var entity = singular();
var parent = singularParent();
var parentId = parentWayIdForVertexNavigation();
var way;
if (entity && entity.type === 'way') {
way = entity;
} else if (parent) {
way = context.entity(parent);
} else if (parentId) {
way = context.entity(parentId);
}
_focusedParentWayId = way && way.id;
if (way) {
context.enter(
modeSelect(context, [way.first()]).follow(true)
mode.selectedIDs([way.first()])
.follow(true)
);
}
}
@@ -476,18 +477,20 @@ export function modeSelect(context, selectedIDs) {
function lastVertex(d3_event) {
d3_event.preventDefault();
var entity = singular();
var parent = singularParent();
var parentId = parentWayIdForVertexNavigation();
var way;
if (entity && entity.type === 'way') {
way = entity;
} else if (parent) {
way = context.entity(parent);
} else if (parentId) {
way = context.entity(parentId);
}
_focusedParentWayId = way && way.id;
if (way) {
context.enter(
modeSelect(context, [way.last()]).follow(true)
mode.selectedIDs([way.last()])
.follow(true)
);
}
}
@@ -495,10 +498,11 @@ export function modeSelect(context, selectedIDs) {
function previousVertex(d3_event) {
d3_event.preventDefault();
var parent = singularParent();
if (!parent) return;
var parentId = parentWayIdForVertexNavigation();
_focusedParentWayId = parentId;
if (!parentId) return;
var way = context.entity(parent);
var way = context.entity(parentId);
var length = way.nodes.length;
var curr = way.nodes.indexOf(selectedIDs[0]);
var index = -1;
@@ -511,7 +515,8 @@ export function modeSelect(context, selectedIDs) {
if (index !== -1) {
context.enter(
modeSelect(context, [way.nodes[index]]).follow(true)
mode.selectedIDs([way.nodes[index]])
.follow(true)
);
}
}
@@ -519,10 +524,11 @@ export function modeSelect(context, selectedIDs) {
function nextVertex(d3_event) {
d3_event.preventDefault();
var parent = singularParent();
if (!parent) return;
var parentId = parentWayIdForVertexNavigation();
_focusedParentWayId = parentId;
if (!parentId) return;
var way = context.entity(parent);
var way = context.entity(parentId);
var length = way.nodes.length;
var curr = way.nodes.indexOf(selectedIDs[0]);
var index = -1;
@@ -535,37 +541,38 @@ export function modeSelect(context, selectedIDs) {
if (index !== -1) {
context.enter(
modeSelect(context, [way.nodes[index]]).follow(true)
mode.selectedIDs([way.nodes[index]])
.follow(true)
);
}
}
function nextParent(d3_event) {
function focusNextParent(d3_event) {
d3_event.preventDefault();
var parents = multipleParents(true);
var parents = parentWaysIdsOfSelection(true);
if (!parents || parents.length < 2) return;
var index = parents.indexOf(_relatedParent);
var index = parents.indexOf(_focusedParentWayId);
if (index < 0 || index > parents.length - 2) {
_relatedParent = parents[0];
_focusedParentWayId = parents[0];
} else {
_relatedParent = parents[index + 1];
_focusedParentWayId = parents[index + 1];
}
var surface = context.surface();
surface.selectAll('.related')
.classed('related', false);
if (_relatedParent) {
surface.selectAll(utilEntitySelector([_relatedParent]))
if (_focusedParentWayId) {
surface.selectAll(utilEntitySelector([_focusedParentWayId]))
.classed('related', true);
}
}
function selectParent(d3_event) {
d3_event.preventDefault();
var parents = _relatedParent ? [_relatedParent] : multipleParents(false);
var parents = _focusedParentWayId ? [_focusedParentWayId] : parentWaysIdsOfSelection(false);
if (!parents || parents.length === 0) return;
context.enter(
@@ -577,6 +584,7 @@ export function modeSelect(context, selectedIDs) {
mode.exit = function() {
// we could enter the mode multiple times but it's only new the first time
_newFeature = false;
_operations.forEach(function(operation) {