Skip to content

Commit c43a499

Browse files
authored
Fix: Vue Node Align/Distribute (#6712)
## Summary Fixes the issue of the nodes not moving when in Vue mode (but changing if switching back to litegraph) ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-6712-Fix-Vue-Node-Align-Distribute-2ad6d73d365081339aa6f61e18832bc4) by [Unito](https://www.unito.io)
1 parent 8dd5a99 commit c43a499

File tree

4 files changed

+77
-28
lines changed

4 files changed

+77
-28
lines changed

src/composables/graph/useNodeArrangement.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,8 @@ export function useNodeArrangement() {
7979
return
8080
}
8181

82-
alignNodes(selectedNodes, alignOption.value)
82+
const newPositions = alignNodes(selectedNodes, alignOption.value)
83+
canvasStore.canvas?.repositionNodesVueMode(newPositions)
8384

8485
canvasRefresh.refreshCanvas()
8586
}
@@ -93,7 +94,8 @@ export function useNodeArrangement() {
9394
return
9495
}
9596

96-
distributeNodes(selectedNodes, distributeOption.value)
97+
const newPositions = distributeNodes(selectedNodes, distributeOption.value)
98+
canvasStore.canvas?.repositionNodesVueMode(newPositions)
9799
canvasRefresh.refreshCanvas()
98100
}
99101

src/lib/litegraph/src/LGraphCanvas.ts

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ import type {
4949
ISlotType,
5050
LinkNetwork,
5151
LinkSegment,
52+
NewNodePosition,
5253
NullableProperties,
5354
Point,
5455
Positionable,
@@ -1011,7 +1012,8 @@ export class LGraphCanvas
10111012
direction: Direction,
10121013
align_to?: LGraphNode
10131014
): void {
1014-
alignNodes(Object.values(nodes), direction, align_to)
1015+
const newPositions = alignNodes(Object.values(nodes), direction, align_to)
1016+
LGraphCanvas.active_canvas.repositionNodesVueMode(newPositions)
10151017
LGraphCanvas.active_canvas.setDirty(true, true)
10161018
}
10171019

@@ -1031,11 +1033,12 @@ export class LGraphCanvas
10311033
})
10321034

10331035
function inner_clicked(value: string) {
1034-
alignNodes(
1036+
const newPositions = alignNodes(
10351037
Object.values(LGraphCanvas.active_canvas.selected_nodes),
10361038
value.toLowerCase() as Direction,
10371039
node
10381040
)
1041+
LGraphCanvas.active_canvas.repositionNodesVueMode(newPositions)
10391042
LGraphCanvas.active_canvas.setDirty(true, true)
10401043
}
10411044
}
@@ -1055,10 +1058,11 @@ export class LGraphCanvas
10551058
})
10561059

10571060
function inner_clicked(value: string) {
1058-
alignNodes(
1061+
const newPositions = alignNodes(
10591062
Object.values(LGraphCanvas.active_canvas.selected_nodes),
10601063
value.toLowerCase() as Direction
10611064
)
1065+
LGraphCanvas.active_canvas.repositionNodesVueMode(newPositions)
10621066
LGraphCanvas.active_canvas.setDirty(true, true)
10631067
}
10641068
}
@@ -1079,10 +1083,11 @@ export class LGraphCanvas
10791083

10801084
function inner_clicked(value: string) {
10811085
const canvas = LGraphCanvas.active_canvas
1082-
distributeNodes(
1086+
const newPositions = distributeNodes(
10831087
Object.values(canvas.selected_nodes),
10841088
value === 'Horizontally'
10851089
)
1090+
canvas.repositionNodesVueMode(newPositions)
10861091
canvas.setDirty(true, true)
10871092
}
10881093
}
@@ -8557,10 +8562,7 @@ export class LGraphCanvas
85578562
) {
85588563
const mutations = this.initLayoutMutations()
85598564
const nodesInMovingGroups = this.collectNodesInGroups(allItems)
8560-
const nodesToMove: Array<{
8561-
node: LGraphNode
8562-
newPos: { x: number; y: number }
8563-
}> = []
8565+
const nodesToMove: NewNodePosition[] = []
85648566

85658567
// First, collect all the moves we need to make
85668568
for (const item of allItems) {
@@ -8586,4 +8588,9 @@ export class LGraphCanvas
85868588
// Now apply all the node moves at once
85878589
this.applyNodePositionUpdates(nodesToMove, mutations)
85888590
}
8591+
8592+
repositionNodesVueMode(nodesToReposition: NewNodePosition[]) {
8593+
const mutations = this.initLayoutMutations()
8594+
this.applyNodePositionUpdates(nodesToReposition, mutations)
8595+
}
85898596
}

src/lib/litegraph/src/interfaces.ts

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,13 @@ type KeysOfType<T, Match> = Exclude<
254254

255255
/** The names of all (optional) methods and functions in T */
256256
export type MethodNames<T> = KeysOfType<T, ((...args: any) => any) | undefined>
257-
257+
export interface NewNodePosition {
258+
node: LGraphNode
259+
newPos: {
260+
x: number
261+
y: number
262+
}
263+
}
258264
export interface IBoundaryNodes {
259265
top: LGraphNode
260266
right: LGraphNode

src/lib/litegraph/src/utils/arrange.ts

Lines changed: 51 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { LGraphNode } from '../LGraphNode'
2-
import type { Direction, IBoundaryNodes } from '../interfaces'
2+
import type { Direction, IBoundaryNodes, NewNodePosition } from '../interfaces'
33

44
/**
55
* Finds the nodes that are farthest in all four directions, representing the boundary of the nodes.
@@ -43,9 +43,9 @@ export function getBoundaryNodes(nodes: LGraphNode[]): IBoundaryNodes | null {
4343
export function distributeNodes(
4444
nodes: LGraphNode[],
4545
horizontal?: boolean
46-
): void {
46+
): NewNodePosition[] {
4747
const nodeCount = nodes?.length
48-
if (!(nodeCount > 1)) return
48+
if (!(nodeCount > 1)) return []
4949

5050
const index = horizontal ? 0 : 1
5151

@@ -68,6 +68,16 @@ export function distributeNodes(
6868
node.pos[index] = startAt + gap * i
6969
startAt += node.size[index]
7070
}
71+
const newPositions = sorted.map(
72+
(node): NewNodePosition => ({
73+
node,
74+
newPos: {
75+
x: node.pos[0],
76+
y: node.pos[1]
77+
}
78+
})
79+
)
80+
return newPositions
7181
}
7282

7383
/**
@@ -80,32 +90,56 @@ export function alignNodes(
8090
nodes: LGraphNode[],
8191
direction: Direction,
8292
align_to?: LGraphNode
83-
): void {
84-
if (!nodes) return
93+
): NewNodePosition[] {
94+
if (!nodes) return []
8595

8696
const boundary =
8797
align_to === undefined
8898
? getBoundaryNodes(nodes)
8999
: { top: align_to, right: align_to, bottom: align_to, left: align_to }
90100

91-
if (boundary === null) return
101+
if (boundary === null) return []
92102

93-
for (const node of nodes) {
103+
const nodePositions = nodes.map((node): NewNodePosition => {
94104
switch (direction) {
95105
case 'right':
96-
node.pos[0] =
97-
boundary.right.pos[0] + boundary.right.size[0] - node.size[0]
98-
break
106+
return {
107+
node,
108+
newPos: {
109+
x: boundary.right.pos[0] + boundary.right.size[0] - node.size[0],
110+
y: node.pos[1]
111+
}
112+
}
99113
case 'left':
100-
node.pos[0] = boundary.left.pos[0]
101-
break
114+
return {
115+
node,
116+
newPos: {
117+
x: boundary.left.pos[0],
118+
y: node.pos[1]
119+
}
120+
}
102121
case 'top':
103-
node.pos[1] = boundary.top.pos[1]
104-
break
122+
return {
123+
node,
124+
newPos: {
125+
x: node.pos[0],
126+
y: boundary.top.pos[1]
127+
}
128+
}
105129
case 'bottom':
106-
node.pos[1] =
107-
boundary.bottom.pos[1] + boundary.bottom.size[1] - node.size[1]
108-
break
130+
return {
131+
node,
132+
newPos: {
133+
x: node.pos[0],
134+
y: boundary.bottom.pos[1] + boundary.bottom.size[1] - node.size[1]
135+
}
136+
}
109137
}
138+
})
139+
140+
for (const { node, newPos } of nodePositions) {
141+
node.pos[0] = newPos.x
142+
node.pos[1] = newPos.y
110143
}
144+
return nodePositions
111145
}

0 commit comments

Comments
 (0)