mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-04-20 14:30:41 +00:00
feat: add 'Rename slot' to slot context menu
Amp-Thread-ID: https://ampcode.com/threads/T-019c3056-108e-7248-9c30-7d236197edcc
This commit is contained in:
@@ -26,9 +26,11 @@ import { computed, onMounted, onUnmounted, ref, watchEffect } from 'vue'
|
||||
|
||||
import { useCanvasStore } from '@/renderer/core/canvas/canvasStore'
|
||||
import {
|
||||
canRenameSlot,
|
||||
connectSlots,
|
||||
findCompatibleTargets,
|
||||
registerSlotMenuInstance
|
||||
registerSlotMenuInstance,
|
||||
renameSlot
|
||||
} from '@/renderer/extensions/vueNodes/composables/useSlotContextMenu'
|
||||
import type { SlotMenuContext } from '@/renderer/extensions/vueNodes/composables/useSlotContextMenu'
|
||||
|
||||
@@ -91,13 +93,27 @@ const menuItems = computed<MenuItem[]>(() => {
|
||||
const ctx = activeContext.value
|
||||
if (!ctx) return []
|
||||
|
||||
const targets = findCompatibleTargets(ctx)
|
||||
if (targets.length === 0) {
|
||||
return [{ label: 'No compatible nodes', disabled: true }]
|
||||
const items: MenuItem[] = []
|
||||
|
||||
if (canRenameSlot(ctx)) {
|
||||
items.push({
|
||||
label: 'Rename slot',
|
||||
command: () => {
|
||||
const newLabel = window.prompt('New slot label:')
|
||||
if (newLabel !== null) {
|
||||
renameSlot(ctx, newLabel)
|
||||
}
|
||||
hide()
|
||||
}
|
||||
})
|
||||
items.push({ separator: true })
|
||||
}
|
||||
|
||||
return [
|
||||
{
|
||||
const targets = findCompatibleTargets(ctx)
|
||||
if (targets.length === 0) {
|
||||
items.push({ label: 'No compatible nodes', disabled: true })
|
||||
} else {
|
||||
items.push({
|
||||
label: 'Connect to...',
|
||||
items: targets.map((target) => ({
|
||||
label: `${target.slotInfo.name} @ ${target.node.title || target.node.type}`,
|
||||
@@ -106,8 +122,10 @@ const menuItems = computed<MenuItem[]>(() => {
|
||||
hide()
|
||||
}
|
||||
}))
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
|
||||
return items
|
||||
})
|
||||
|
||||
function show(event: MouseEvent, context: SlotMenuContext) {
|
||||
|
||||
@@ -3,7 +3,8 @@ import type { Ref } from 'vue'
|
||||
import type { LGraphNode, NodeId } from '@/lib/litegraph/src/LGraphNode'
|
||||
import type {
|
||||
INodeInputSlot,
|
||||
INodeOutputSlot
|
||||
INodeOutputSlot,
|
||||
IWidgetInputSlot
|
||||
} from '@/lib/litegraph/src/interfaces'
|
||||
import { LiteGraph } from '@/lib/litegraph/src/litegraph'
|
||||
import { LGraphEventMode } from '@/lib/litegraph/src/types/globalEnums'
|
||||
@@ -95,6 +96,47 @@ export function findCompatibleTargets(
|
||||
return results.slice(0, maxResults)
|
||||
}
|
||||
|
||||
export function renameSlot(context: SlotMenuContext, newLabel: string): void {
|
||||
const graph = app.canvas?.graph
|
||||
if (!graph) return
|
||||
|
||||
const node = graph.getNodeById(context.nodeId)
|
||||
if (!node) return
|
||||
|
||||
const slotInfo = context.isInput
|
||||
? node.getInputInfo(context.slotIndex)
|
||||
: node.getOutputInfo(context.slotIndex)
|
||||
if (!slotInfo) return
|
||||
|
||||
graph.beforeChange()
|
||||
slotInfo.label = newLabel
|
||||
app.canvas?.setDirty(true, true)
|
||||
graph.afterChange()
|
||||
}
|
||||
|
||||
export function canRenameSlot(context: SlotMenuContext): boolean {
|
||||
const graph = app.canvas?.graph
|
||||
if (!graph) return false
|
||||
|
||||
const node = graph.getNodeById(context.nodeId)
|
||||
if (!node) return false
|
||||
|
||||
const slotInfo = context.isInput
|
||||
? node.inputs?.[context.slotIndex]
|
||||
: node.outputs?.[context.slotIndex]
|
||||
if (!slotInfo) return false
|
||||
|
||||
if (slotInfo.nameLocked) return false
|
||||
if (
|
||||
context.isInput &&
|
||||
'link' in slotInfo &&
|
||||
(slotInfo as IWidgetInputSlot).widget
|
||||
)
|
||||
return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
export function connectSlots(
|
||||
context: SlotMenuContext,
|
||||
target: CompatibleTarget
|
||||
|
||||
Reference in New Issue
Block a user