mirror of
https://github.com/FoggedLens/iD.git
synced 2026-05-14 21:28:11 +02:00
Add drag-and-drop reordering of relation members (close #2283)
This commit is contained in:
+15
-3
@@ -2522,9 +2522,12 @@ img.tag-reference-wiki-image {
|
||||
|
||||
/* Raw Member / Membership Editor
|
||||
------------------------------------------------------- */
|
||||
.raw-member-editor .member-list li:first-child,
|
||||
.raw-membership-editor .member-list li:first-child {
|
||||
padding-top: 10px;
|
||||
.raw-member-editor .member-list li,
|
||||
.raw-membership-editor .member-list li {
|
||||
position: relative;
|
||||
border-radius: 4px;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
.raw-member-editor .member-row .member-entity-name,
|
||||
.raw-membership-editor .member-row .member-entity-name {
|
||||
@@ -2560,6 +2563,15 @@ img.tag-reference-wiki-image {
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.raw-member-editor .member-row.dragging {
|
||||
opacity: 0.75;
|
||||
z-index: 3000;
|
||||
-webkit-box-shadow: 0px 0px 5px 0px rgba(0,0,0,0.3);
|
||||
-moz-box-shadow: 0px 0px 5px 0px rgba(0,0,0,0.3);
|
||||
box-shadow: 0px 0px 5px 0px rgba(0,0,0,0.3);
|
||||
}
|
||||
.raw-member-editor .member-row.dragging
|
||||
|
||||
/* preserve extra space at bottom of inspector to allow for dropdown options - #5280 */
|
||||
.raw-membership-editor.inspector-inner {
|
||||
margin-bottom: 150px;
|
||||
|
||||
@@ -142,6 +142,8 @@ en:
|
||||
annotation: Added a member to a relation.
|
||||
delete_member:
|
||||
annotation: Removed a member from a relation.
|
||||
reorder_members:
|
||||
annotation: Reordered a relation's members.
|
||||
connect:
|
||||
annotation:
|
||||
from_vertex:
|
||||
|
||||
Vendored
+3
@@ -186,6 +186,9 @@
|
||||
"delete_member": {
|
||||
"annotation": "Removed a member from a relation."
|
||||
},
|
||||
"reorder_members": {
|
||||
"annotation": "Reordered a relation's members."
|
||||
},
|
||||
"connect": {
|
||||
"annotation": {
|
||||
"from_vertex": {
|
||||
|
||||
@@ -21,6 +21,7 @@ export { actionMergeNodes } from './merge_nodes';
|
||||
export { actionMergePolygon } from './merge_polygon';
|
||||
export { actionMergeRemoteChanges } from './merge_remote_changes';
|
||||
export { actionMove } from './move';
|
||||
export { actionMoveMember } from './move_member';
|
||||
export { actionMoveNode } from './move_node';
|
||||
export { actionNoop } from './noop';
|
||||
export { actionOrthogonalize } from './orthogonalize';
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
export function actionMoveMember(relationId, fromIndex, toIndex) {
|
||||
return function(graph) {
|
||||
return graph.replace(graph.entity(relationId).moveMember(fromIndex, toIndex));
|
||||
};
|
||||
}
|
||||
@@ -167,6 +167,12 @@ _extend(osmRelation.prototype, {
|
||||
return this.update({members: members});
|
||||
},
|
||||
|
||||
moveMember: function(fromIndex, toIndex) {
|
||||
var members = this.members.slice();
|
||||
members.splice(toIndex, 0, members.splice(fromIndex, 1)[0]);
|
||||
return this.update({members: members});
|
||||
},
|
||||
|
||||
|
||||
// Wherever a member appears with id `needle.id`, replace it with a member
|
||||
// with id `replacement.id`, type `replacement.type`, and the original role,
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import { drag as d3_drag } from 'd3-drag';
|
||||
import {
|
||||
event as d3_event,
|
||||
select as d3_select
|
||||
} from 'd3-selection';
|
||||
|
||||
import { t } from '../util/locale';
|
||||
import { actionChangeMember, actionDeleteMember } from '../actions';
|
||||
import { actionChangeMember, actionDeleteMember, actionMoveMember } from '../actions';
|
||||
import { modeBrowse, modeSelect } from '../modes';
|
||||
import { osmEntity } from '../osm';
|
||||
import { svgIcon } from '../svg';
|
||||
@@ -229,6 +230,70 @@ export function uiRawMemberEditor(context) {
|
||||
wrapEnter.each(bindTypeahead);
|
||||
}
|
||||
|
||||
var dragOrigin, targetIndex;
|
||||
|
||||
itemsEnter.call(d3_drag()
|
||||
.on('start', function() {
|
||||
dragOrigin = {
|
||||
x: d3_event.x,
|
||||
y: d3_event.y
|
||||
};
|
||||
targetIndex = null;
|
||||
})
|
||||
.on('drag', function(d, index) {
|
||||
var x = d3_event.x - dragOrigin.x,
|
||||
y = d3_event.y - dragOrigin.y;
|
||||
|
||||
if (!d3_select(this).classed('dragging') &&
|
||||
// don't display drag until dragging beyond a distance threshold
|
||||
Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)) <= 5) return;
|
||||
|
||||
d3_select(this)
|
||||
.classed('dragging', true);
|
||||
|
||||
targetIndex = null;
|
||||
|
||||
selection.selectAll('li.member-row')
|
||||
.style('transform', function(d2, index2) {
|
||||
var node = d3_select(this).node();
|
||||
if (index === index2) {
|
||||
return 'translate(' + x + 'px, ' + y + 'px)';
|
||||
} else if (index2 > index && d3_event.y > node.offsetTop - node.offsetHeight) {
|
||||
if (targetIndex === null || index2 > targetIndex) {
|
||||
targetIndex = index2;
|
||||
}
|
||||
return 'translateY(-100%)';
|
||||
} else if (index2 < index && d3_event.y < node.offsetTop) {
|
||||
if (targetIndex === null || index2 < targetIndex) {
|
||||
targetIndex = index2;
|
||||
}
|
||||
return 'translateY(100%)';
|
||||
}
|
||||
return null;
|
||||
});
|
||||
})
|
||||
.on('end', function(d, index) {
|
||||
|
||||
if (!d3_select(this).classed('dragging')) {
|
||||
return;
|
||||
}
|
||||
|
||||
d3_select(this)
|
||||
.classed('dragging', false);
|
||||
|
||||
selection.selectAll('li.member-row')
|
||||
.style('transform', null);
|
||||
|
||||
if (targetIndex !== null) {
|
||||
// dragged to a new position, reorder
|
||||
context.perform(
|
||||
actionMoveMember(d.relation.id, index, targetIndex),
|
||||
t('operations.reorder_members.annotation')
|
||||
);
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
// update
|
||||
items = items
|
||||
|
||||
Reference in New Issue
Block a user