diff --git a/src/LGraphCanvas.ts b/src/LGraphCanvas.ts index dbf5ea0cb6..d3d1efe348 100644 --- a/src/LGraphCanvas.ts +++ b/src/LGraphCanvas.ts @@ -636,14 +636,16 @@ export class LGraphCanvas implements ConnectionColorContext { type_filter_out: firstLink.fromSlot.type, } + const afterRerouteId = firstLink.fromReroute?.id + if ("shiftKey" in e && e.shiftKey) { if (this.allow_searchbox) { this.showSearchBox(e as unknown as MouseEvent, linkReleaseContext) } } else if (this.linkConnector.state.connectingTo === "input") { - this.showConnectionMenu({ nodeFrom: firstLink.node, slotFrom: firstLink.fromSlot, e }) + this.showConnectionMenu({ nodeFrom: firstLink.node, slotFrom: firstLink.fromSlot, e, afterRerouteId }) } else { - this.showConnectionMenu({ nodeTo: firstLink.node, slotTo: firstLink.fromSlot, e }) + this.showConnectionMenu({ nodeTo: firstLink.node, slotTo: firstLink.fromSlot, e, afterRerouteId }) } } }) @@ -5627,7 +5629,7 @@ export class LGraphCanvas implements ConnectionColorContext { if (!slot) throw new TypeError("Cannot add reroute: slot was null") if (!opts.e) throw new TypeError("Cannot add reroute: CanvasPointerEvent was null") - const reroute = node.connectFloatingReroute([opts.e.canvasX, opts.e.canvasY], slot) + const reroute = node.connectFloatingReroute([opts.e.canvasX, opts.e.canvasY], slot, afterRerouteId) if (!reroute) throw new Error("Failed to create reroute") dirty() diff --git a/src/LGraphNode.ts b/src/LGraphNode.ts index 3ca7ac10da..02f6c60834 100644 --- a/src/LGraphNode.ts +++ b/src/LGraphNode.ts @@ -2547,7 +2547,7 @@ export class LGraphNode implements Positionable, IPinnable, IColorable { return link } - connectFloatingReroute(pos: Point, slot: INodeInputSlot | INodeOutputSlot): Reroute { + connectFloatingReroute(pos: Point, slot: INodeInputSlot | INodeOutputSlot, afterRerouteId?: RerouteId): Reroute { const { graph, id } = this if (!graph) throw new NullGraphError() @@ -2556,19 +2556,42 @@ export class LGraphNode implements Positionable, IPinnable, IColorable { const outputIndex = this.outputs.indexOf(slot as INodeOutputSlot) if (inputIndex === -1 && outputIndex === -1) throw new Error("Invalid slot") - const link = new LLink( - -1, - slot.type, - outputIndex === -1 ? -1 : id, - outputIndex, - inputIndex === -1 ? -1 : id, - inputIndex, - ) const slotType = outputIndex === -1 ? "input" : "output" - const reroute = graph.setReroute({ pos, linkIds: [], floating: { slotType } }) + const reroute = graph.setReroute({ + pos, + parentId: afterRerouteId, + linkIds: [], + floating: { slotType }, + }) + + const parentReroute = graph.getReroute(afterRerouteId) + const fromLastFloatingReroute = parentReroute?.floating?.slotType === "output" + + // Adding from an ouput, or a floating reroute that is NOT the tip of an existing floating chain + if (afterRerouteId == null || !fromLastFloatingReroute) { + const link = new LLink( + -1, + slot.type, + outputIndex === -1 ? -1 : id, + outputIndex, + inputIndex === -1 ? -1 : id, + inputIndex, + ) + link.parentId = reroute.id + graph.addFloatingLink(link) + return reroute + } + + // Adding a new floating reroute from the tip of a floating chain. + if (!parentReroute) throw new Error("[connectFloatingReroute] Parent reroute not found") + + const link = parentReroute.getFloatingLinks("output")?.[0] + if (!link) throw new Error("[connectFloatingReroute] Floating link not found") + + reroute.floatingLinkIds.add(link.id) link.parentId = reroute.id - graph.addFloatingLink(link) + delete parentReroute.floating return reroute }