mirror of
				https://github.com/node-red/node-red.git
				synced 2025-03-01 10:36:34 +00:00 
			
		
		
		
	Add distribute-horizontally/vertically actions to editor
This commit is contained in:
		| @@ -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() }) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user