mirror of
https://github.com/node-red/node-red.git
synced 2023-10-10 13:36:53 +02:00
Add distribute-horizontally/vertically actions to editor
This commit is contained in:
parent
56121203bf
commit
d2cdc67ec7
@ -84,6 +84,8 @@
|
||||
"alt-a t": "core:align-selection-to-top",
|
||||
"alt-a b": "core:align-selection-to-bottom",
|
||||
"alt-a m": "core:align-selection-to-middle",
|
||||
"alt-a c": "core:align-selection-to-center"
|
||||
"alt-a c": "core:align-selection-to-center",
|
||||
"alt-a h": "core:distribute-selection-horizontally",
|
||||
"alt-a v": "core:distribute-selection-vertically"
|
||||
}
|
||||
}
|
||||
|
@ -531,6 +531,165 @@ RED.view.tools = (function() {
|
||||
}
|
||||
|
||||
|
||||
function distributeSelection(direction) {
|
||||
var selection = RED.view.selection();
|
||||
|
||||
if (selection.nodes && selection.nodes.length > 2) {
|
||||
var changedNodes = [];
|
||||
var bounds = {
|
||||
minX: Number.MAX_SAFE_INTEGER,
|
||||
minY: Number.MAX_SAFE_INTEGER,
|
||||
maxX: Number.MIN_SAFE_INTEGER,
|
||||
maxY: Number.MIN_SAFE_INTEGER
|
||||
}
|
||||
var startAnchors = [];
|
||||
var endAnchors = [];
|
||||
|
||||
selection.nodes.forEach(function(n) {
|
||||
var nx,ny;
|
||||
if (n.type === "group") {
|
||||
nx = n.x + n.w/2;
|
||||
ny = n.y + n.h/2;
|
||||
} else {
|
||||
nx = n.x;
|
||||
ny = n.y;
|
||||
}
|
||||
if (direction === "h") {
|
||||
if (nx < bounds.minX) {
|
||||
startAnchors = [];
|
||||
bounds.minX = nx;
|
||||
}
|
||||
if (nx === bounds.minX) {
|
||||
startAnchors.push(n);
|
||||
}
|
||||
if (nx > bounds.maxX) {
|
||||
endAnchors = [];
|
||||
bounds.maxX = nx;
|
||||
}
|
||||
if (nx === bounds.maxX) {
|
||||
endAnchors.push(n);
|
||||
}
|
||||
} else {
|
||||
if (ny < bounds.minY) {
|
||||
startAnchors = [];
|
||||
bounds.minY = ny;
|
||||
}
|
||||
if (ny === bounds.minY) {
|
||||
startAnchors.push(n);
|
||||
}
|
||||
if (ny > bounds.maxY) {
|
||||
endAnchors = [];
|
||||
bounds.maxY = ny;
|
||||
}
|
||||
if (ny === bounds.maxY) {
|
||||
endAnchors.push(n);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
var startAnchor = startAnchors[0];
|
||||
var endAnchor = endAnchors[0];
|
||||
|
||||
var nodeSpace = 0;
|
||||
var nodesToMove = selection.nodes.filter(function(n) {
|
||||
if (n.id !== startAnchor.id && n.id !== endAnchor.id) {
|
||||
nodeSpace += direction === 'h'?n.w:n.h;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}).sort(function(A,B) {
|
||||
if (direction === 'h') {
|
||||
return A.x - B.x
|
||||
} else {
|
||||
return A.y - B.y
|
||||
}
|
||||
})
|
||||
|
||||
var saX = startAnchor.x + startAnchor.w/2;
|
||||
var saY = startAnchor.y + startAnchor.h/2;
|
||||
if (startAnchor.type === "group") {
|
||||
saX = startAnchor.x + startAnchor.w;
|
||||
saY = startAnchor.y + startAnchor.h;
|
||||
}
|
||||
var eaX = endAnchor.x;
|
||||
var eaY = endAnchor.y;
|
||||
if (endAnchor.type !== "group") {
|
||||
eaX -= endAnchor.w/2;
|
||||
eaY -= endAnchor.h/2;
|
||||
}
|
||||
var spaceToFill = direction === 'h'?(eaX - saX - nodeSpace): (eaY - saY - nodeSpace);
|
||||
var spaceBetweenNodes = spaceToFill / (nodesToMove.length + 1);
|
||||
|
||||
var tx = saX;
|
||||
var ty = saY;
|
||||
while(nodesToMove.length > 0) {
|
||||
if (direction === 'h') {
|
||||
tx += spaceBetweenNodes;
|
||||
} else {
|
||||
ty += spaceBetweenNodes;
|
||||
}
|
||||
var nextNode = nodesToMove.shift();
|
||||
var isGroup = nextNode.type==="group";
|
||||
|
||||
var nx = nextNode.x;
|
||||
var ny = nextNode.y;
|
||||
if (!isGroup) {
|
||||
tx += nextNode.w/2;
|
||||
ty += nextNode.h/2;
|
||||
}
|
||||
if ((direction === 'h' && nx !== tx) || (direction === 'v' && ny !== ty)) {
|
||||
if (!isGroup) {
|
||||
changedNodes.push({
|
||||
n:nextNode,
|
||||
ox: nextNode.x,
|
||||
oy: nextNode.y,
|
||||
moved: nextNode.moved
|
||||
});
|
||||
if (direction === 'h') {
|
||||
nextNode.x = tx;
|
||||
} else {
|
||||
nextNode.y = ty;
|
||||
}
|
||||
nextNode.dirty = true;
|
||||
nextNode.moved = true;
|
||||
} else {
|
||||
var groupNodes = RED.group.getNodes(nextNode, true);
|
||||
var deltaX = direction === 'h'? nx - tx : 0;
|
||||
var deltaY = direction === 'v'? ny - ty : 0;
|
||||
groupNodes.forEach(function(gn) {
|
||||
if (gn.type !== "group" ) {
|
||||
changedNodes.push({
|
||||
n:gn,
|
||||
ox: gn.x,
|
||||
oy: gn.y,
|
||||
moved: gn.moved
|
||||
});
|
||||
gn.x = gn.x - deltaX;
|
||||
gn.y = gn.y - deltaY;
|
||||
gn.dirty = true;
|
||||
gn.moved = true;
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
if (isGroup) {
|
||||
tx += nextNode.w;
|
||||
ty += nextNode.h;
|
||||
} else {
|
||||
tx += nextNode.w/2;
|
||||
ty += nextNode.h/2;
|
||||
}
|
||||
}
|
||||
|
||||
if (changedNodes.length > 0) {
|
||||
RED.history.push({t:"move",nodes:changedNodes,dirty:RED.nodes.dirty()});
|
||||
RED.nodes.dirty(true);
|
||||
RED.view.redraw(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return {
|
||||
init: function() {
|
||||
RED.actions.add("core:show-selected-node-labels", function() { setSelectedNodeLabelState(true); })
|
||||
@ -580,6 +739,8 @@ RED.view.tools = (function() {
|
||||
RED.actions.add("core:align-selection-to-middle", function() { alignSelectionToEdge('middle') })
|
||||
RED.actions.add("core:align-selection-to-center", function() { alignSelectionToEdge('center') })
|
||||
|
||||
RED.actions.add("core:distribute-selection-horizontally", function() { distributeSelection('h') })
|
||||
RED.actions.add("core:distribute-selection-vertically", function() { distributeSelection('v') })
|
||||
|
||||
|
||||
// RED.actions.add("core:add-node", function() { addNode() })
|
||||
|
Loading…
Reference in New Issue
Block a user