Skip to content

Commit badf134

Browse files
committed
feat: Add alignment for selected node
1 parent e27ecd1 commit badf134

1 file changed

Lines changed: 91 additions & 0 deletions

File tree

src/litegraph.js

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10294,6 +10294,96 @@ LGraphNode.prototype.executeAction = function(action)
1029410294
canvas.graph.add(group);
1029510295
};
1029610296

10297+
/**
10298+
* Determines the furthest nodes in each direction
10299+
* @param nodes {LGraphNode[]} the nodes to from which boundary nodes will be extracted
10300+
* @return {{left: LGraphNode, top: LGraphNode, right: LGraphNode, bottom: LGraphNode}}
10301+
*/
10302+
LGraphCanvas.getBoundaryNodes = function(nodes) {
10303+
let top = null;
10304+
let right = null;
10305+
let bottom = null;
10306+
let left = null;
10307+
for (const nID in nodes) {
10308+
const node = nodes[nID];
10309+
const [x, y] = node.pos;
10310+
const [width, height] = node.size;
10311+
10312+
if (top === null || y < top.pos[1]) {
10313+
top = node;
10314+
}
10315+
if (right === null || x + width > right.pos[0] + right.size[0]) {
10316+
right = node;
10317+
}
10318+
if (bottom === null || y + height > bottom.pos[1] + bottom.size[1]) {
10319+
bottom = node;
10320+
}
10321+
if (left === null || x < left.pos[0]) {
10322+
left = node;
10323+
}
10324+
}
10325+
10326+
return {
10327+
"top": top,
10328+
"right": right,
10329+
"bottom": bottom,
10330+
"left": left
10331+
};
10332+
}
10333+
/**
10334+
* Determines the furthest nodes in each direction for the currently selected nodes
10335+
* @return {{left: LGraphNode, top: LGraphNode, right: LGraphNode, bottom: LGraphNode}}
10336+
*/
10337+
LGraphCanvas.prototype.boundaryNodesForSelection = function() {
10338+
return LGraphCanvas.getBoundaryNodes(Object.values(this.selected_nodes));
10339+
}
10340+
10341+
/**
10342+
*
10343+
* @param {LGraphNode[]} nodes a list of nodes
10344+
* @param {"top"|"bottom"|"left"|"right"} direction Direction to align the nodes
10345+
*/
10346+
LGraphCanvas.alignNodes = function (nodes, direction) {
10347+
if (!nodes) {
10348+
return;
10349+
}
10350+
10351+
const canvas = LGraphCanvas.active_canvas;
10352+
const boundaryNodes = LGraphCanvas.getBoundaryNodes(nodes)
10353+
10354+
for (const [_, node] of Object.entries(canvas.selected_nodes)) {
10355+
switch (direction) {
10356+
case "right":
10357+
node.pos[0] = boundaryNodes["right"].pos[0] + boundaryNodes["right"].size[0] - node.size[0];
10358+
break;
10359+
case "left":
10360+
node.pos[0] = boundaryNodes["left"].pos[0];
10361+
break;
10362+
case "top":
10363+
node.pos[1] = boundaryNodes["top"].pos[1];
10364+
break;
10365+
case "bottom":
10366+
node.pos[1] = boundaryNodes["bottom"].pos[1] + boundaryNodes["bottom"].size[1] - node.size[1];
10367+
break;
10368+
}
10369+
}
10370+
10371+
canvas.dirty_canvas = true;
10372+
canvas.dirty_bgcanvas = true;
10373+
};
10374+
10375+
LGraphCanvas.onGroupAlign = function(value, options, event, prev_menu) {
10376+
new LiteGraph.ContextMenu(["Top", "Bottom", "Left", "Right"], {
10377+
event: event,
10378+
callback: inner_clicked,
10379+
parentMenu: prev_menu,
10380+
});
10381+
10382+
function inner_clicked(value) {
10383+
LGraphCanvas.alignNodes(LGraphCanvas.active_canvas.selected_nodes, value.toLowerCase());
10384+
}
10385+
}
10386+
1029710387
LGraphCanvas.onMenuAdd = function (node, options, e, prev_menu, callback) {
1029810388

1029910389
var canvas = LGraphCanvas.active_canvas;
@@ -12887,6 +12977,7 @@ LGraphNode.prototype.executeAction = function(action)
1288712977
callback: LGraphCanvas.onMenuAdd
1288812978
},
1288912979
{ content: "Add Group", callback: LGraphCanvas.onGroupAdd },
12980+
{ content: "Align", has_submenu: true, callback: LGraphCanvas.onGroupAlign },
1289012981
//{ content: "Arrange", callback: that.graph.arrange },
1289112982
//{content:"Collapse All", callback: LGraphCanvas.onMenuCollapseAll }
1289212983
];

0 commit comments

Comments
 (0)