mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-09 09:30:06 +00:00
Allow creating floating reroutes from new link menu (#818)
Adds an `Add Reroute` option to the new link menu. Creates a new floating reroute connected to the source slot.
This commit is contained in:
@@ -5292,8 +5292,7 @@ export class LGraphCanvas implements ConnectionColorContext {
|
||||
const node_left = graph.getNodeById(origin_id)
|
||||
const fromType = node_left?.outputs?.[origin_slot]?.type
|
||||
|
||||
const options = ["Add Node", null, "Delete", null]
|
||||
options.splice(1, 0, "Add Reroute")
|
||||
const options = ["Add Node", "Add Reroute", null, "Delete", null]
|
||||
|
||||
const menu = new LiteGraph.ContextMenu<string>(options, {
|
||||
event: e,
|
||||
@@ -5511,6 +5510,7 @@ export class LGraphCanvas implements ConnectionColorContext {
|
||||
showSearchBox: this.showSearchBox,
|
||||
}, optPass || {})
|
||||
const that = this
|
||||
const { graph } = this
|
||||
const { afterRerouteId } = opts
|
||||
|
||||
const isFrom = opts.nodeFrom && opts.slotFrom
|
||||
@@ -5553,7 +5553,7 @@ export class LGraphCanvas implements ConnectionColorContext {
|
||||
return
|
||||
}
|
||||
|
||||
const options = ["Add Node", null]
|
||||
const options = ["Add Node", "Add Reroute", null]
|
||||
|
||||
if (opts.allow_searchbox) {
|
||||
options.push("Search", null)
|
||||
@@ -5577,6 +5577,7 @@ export class LGraphCanvas implements ConnectionColorContext {
|
||||
// build menu
|
||||
const menu = new LiteGraph.ContextMenu<string>(options, {
|
||||
event: opts.e,
|
||||
extra: slotX,
|
||||
title:
|
||||
(slotX && slotX.name != ""
|
||||
? slotX.name + (fromSlotType ? " | " : "")
|
||||
@@ -5584,8 +5585,10 @@ export class LGraphCanvas implements ConnectionColorContext {
|
||||
callback: inner_clicked,
|
||||
})
|
||||
|
||||
const dirty = () => this.#dirty()
|
||||
|
||||
// callback
|
||||
function inner_clicked(v: string, options: unknown, e: MouseEvent) {
|
||||
function inner_clicked(v: string | undefined, options: IContextMenuOptions<string, INodeInputSlot | INodeOutputSlot>, e: MouseEvent) {
|
||||
// console.log("Process showConnectionMenu selection");
|
||||
switch (v) {
|
||||
case "Add Node":
|
||||
@@ -5599,6 +5602,21 @@ export class LGraphCanvas implements ConnectionColorContext {
|
||||
}
|
||||
})
|
||||
break
|
||||
case "Add Reroute":{
|
||||
const node = isFrom ? opts.nodeFrom : opts.nodeTo
|
||||
const slot = options.extra
|
||||
|
||||
if (!graph) throw new NullGraphError()
|
||||
if (!node) throw new TypeError("Cannot add reroute: node was null")
|
||||
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)
|
||||
if (!reroute) throw new Error("Failed to create reroute")
|
||||
|
||||
dirty()
|
||||
break
|
||||
}
|
||||
case "Search":
|
||||
if (isFrom) {
|
||||
opts.showSearchBox(e, { node_from: opts.nodeFrom, slot_from: slotX, type_filter_in: fromSlotType })
|
||||
|
||||
@@ -20,7 +20,7 @@ import type {
|
||||
Size,
|
||||
} from "./interfaces"
|
||||
import type { LGraph } from "./LGraph"
|
||||
import type { RerouteId } from "./Reroute"
|
||||
import type { Reroute, RerouteId } from "./Reroute"
|
||||
import type { CanvasMouseEvent } from "./types/events"
|
||||
import type { ISerialisedNode } from "./types/serialisation"
|
||||
import type { IBaseWidget, IWidget, IWidgetOptions, TWidgetType, TWidgetValue } from "./types/widgets"
|
||||
@@ -2545,6 +2545,31 @@ export class LGraphNode implements Positionable, IPinnable, IColorable {
|
||||
return link
|
||||
}
|
||||
|
||||
connectFloatingReroute(pos: Point, slot: INodeInputSlot | INodeOutputSlot): Reroute {
|
||||
const { graph, id } = this
|
||||
if (!graph) throw new NullGraphError()
|
||||
|
||||
// Assertion: It's either there or it isn't.
|
||||
const inputIndex = this.inputs.indexOf(slot as INodeInputSlot)
|
||||
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 } })
|
||||
|
||||
link.parentId = reroute.id
|
||||
graph.addFloatingLink(link)
|
||||
return reroute
|
||||
}
|
||||
|
||||
/**
|
||||
* disconnect one output to an specific node
|
||||
* @param slot (could be the number of the slot or the string with the name of the slot)
|
||||
|
||||
@@ -341,11 +341,11 @@ interface IContextMenuBase {
|
||||
}
|
||||
|
||||
/** ContextMenu */
|
||||
export interface IContextMenuOptions<TValue = unknown> extends IContextMenuBase {
|
||||
export interface IContextMenuOptions<TValue = unknown, TExtra = unknown> extends IContextMenuBase {
|
||||
ignore_item_callbacks?: boolean
|
||||
parentMenu?: ContextMenu<TValue>
|
||||
event?: MouseEvent
|
||||
extra?: unknown
|
||||
extra?: TExtra
|
||||
/** @deprecated Context menu scrolling is now controlled by the browser */
|
||||
scroll_speed?: number
|
||||
left?: number
|
||||
|
||||
Reference in New Issue
Block a user