Skip to content

Commit

Permalink
Don't highlight-focus single ways when one of their nodes is selected
Browse files Browse the repository at this point in the history
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: openstreetmap#8264
  • Loading branch information
quincylvania authored and jleedev committed Jan 9, 2021
1 parent 26bf8a4 commit 52efda6
Showing 1 changed file with 55 additions and 47 deletions.
102 changes: 55 additions & 47 deletions modules/modes/select.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,6 @@ import {
} from '../util';


var _relatedParent;


export function modeSelect(context, selectedIDs) {
var mode = {
id: 'select',
Expand All @@ -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) {
Expand Down Expand Up @@ -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; });
Expand All @@ -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;
}
}

// 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;
}
function parentWayIdForVertexNavigation() {
var parentIds = parentWaysIdsOfSelection(true);

if (parents.indexOf(_relatedParent) !== -1) {
return _relatedParent; // prefer the previously seen parent
if (_focusedParentWayId && parentIds.indexOf(_focusedParentWayId) !== -1) {
// prefer the previously seen parent
return _focusedParentWayId;
}

return parents[0];
return parentIds.length ? parentIds[0] : null;
}


Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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);
}

Expand All @@ -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)
);
}
}
Expand All @@ -476,29 +477,32 @@ 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)
);
}
}


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;
Expand All @@ -511,18 +515,20 @@ 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 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;
Expand All @@ -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(
Expand All @@ -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) {
Expand Down

0 comments on commit 52efda6

Please sign in to comment.