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:
bymyself
2026-02-06 01:34:30 -08:00
parent 76373a6eea
commit c1e6d87c3d
2 changed files with 69 additions and 9 deletions

View File

@@ -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) {

View File

@@ -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