Skip to content

Commit a9f2c4d

Browse files
committed
Make node non-virtual
1 parent 7e0e0d2 commit a9f2c4d

File tree

1 file changed

+93
-95
lines changed

1 file changed

+93
-95
lines changed

src/extensions/core/customCombo.ts

Lines changed: 93 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -1,115 +1,113 @@
11
import { useChainCallback } from '@/composables/functional/useChainCallback'
22
import type { CanvasPointerEvent } from '@/lib/litegraph/src/types/events'
33
import { LGraphNode } from '@/lib/litegraph/src/LGraphNode'
4-
import { LiteGraph, LLink } from '@/lib/litegraph/src/litegraph'
4+
import { LLink } from '@/lib/litegraph/src/litegraph'
55
import { app } from '@/scripts/app'
66

7-
class CustomCombo extends LGraphNode {
8-
override title = 'Custom Combo'
9-
constructor(title?: string) {
10-
super(title ?? 'Custom Combo')
11-
this.serialize_widgets = true
12-
const options: { values: string[] } = { values: [] }
13-
Object.defineProperty(options, 'values', {
14-
get: () => {
15-
return this.widgets!.filter(
16-
(w) => w.name.startsWith('option') && w.value
17-
).map((w) => w.value)
18-
}
19-
})
20-
this.addWidget('combo', 'choice', '', () => {}, options)
21-
const comboWidget = this.widgets?.at(-1)!
22-
function updateCombo() {
23-
if (app.configuringGraph) return
24-
const { values } = options
25-
if (values.includes(`${comboWidget.value}`)) return
26-
comboWidget.value = values[0] ?? ''
7+
function applyToGraph(this: LGraphNode, extraLinks: LLink[] = []) {
8+
if (!this.outputs[0].links?.length || !this.graph) return
9+
10+
const links = [
11+
...this.outputs[0].links.map((l) => this.graph!.links[l]),
12+
...extraLinks
13+
]
14+
let v = this.widgets?.[0].value
15+
// For each output link copy our value over the original widget value
16+
for (const linkInfo of links) {
17+
const node = this.graph?.getNodeById(linkInfo.target_id)
18+
const input = node?.inputs[linkInfo.target_slot]
19+
if (!input) {
20+
console.warn('Unable to resolve node or input for link', linkInfo)
21+
continue
2722
}
28-
comboWidget.callback = useChainCallback(comboWidget.callback, () =>
29-
this.applyToGraph()
30-
)
31-
function addOption(node: LGraphNode) {
32-
if (!node.widgets) return
33-
const widgetPostfix =
34-
node.widgets
35-
.findLast((w) => w.name.startsWith('option'))
36-
?.name?.slice(6) || '-1'
37-
const newCount = parseInt(widgetPostfix) + 1
38-
node.addWidget('string', `option${newCount}`, '', () => {})
39-
const widget = node.widgets.at(-1)
40-
if (!widget) return
4123

42-
let value = ''
43-
Object.defineProperty(widget, 'value', {
44-
get() {
45-
return value
46-
},
47-
set(v) {
48-
value = v
49-
updateCombo()
50-
if (!node.widgets) return
51-
const lastWidget = node.widgets.at(-1)
52-
if (lastWidget === this) {
53-
if (v) addOption(node)
54-
return
55-
}
56-
if (v || node.widgets.at(-2) !== this || lastWidget?.value) return
57-
node.widgets.pop()
58-
node.computeSize(node.size)
59-
}
60-
})
24+
const widgetName = input.widget?.name
25+
if (!widgetName) {
26+
console.warn('Invalid widget or widget name', input.widget)
27+
continue
6128
}
62-
this.addOutput('output', 'string')
63-
addOption(this)
64-
// This node is purely frontend and does not impact the resulting prompt so should not be serialized
65-
this.isVirtualNode = true
66-
}
67-
override applyToGraph(extraLinks: LLink[] = []) {
68-
if (!this.outputs[0].links?.length || !this.graph) return
6929

70-
const links = [
71-
...this.outputs[0].links.map((l) => this.graph!.links[l]),
72-
...extraLinks
73-
]
74-
let v = this.widgets?.[0].value
75-
// For each output link copy our value over the original widget value
76-
for (const linkInfo of links) {
77-
const node = this.graph?.getNodeById(linkInfo.target_id)
78-
const input = node?.inputs[linkInfo.target_slot]
79-
if (!input) {
80-
console.warn('Unable to resolve node or input for link', linkInfo)
81-
continue
82-
}
30+
const widget = node.widgets?.find((w) => w.name === widgetName)
31+
if (!widget) {
32+
console.warn(`Unable to find widget "${widgetName}" on node [${node.id}]`)
33+
continue
34+
}
8335

84-
const widgetName = input.widget?.name
85-
if (!widgetName) {
86-
console.warn('Invalid widget or widget name', input.widget)
87-
continue
88-
}
36+
widget.value = v
37+
widget.callback?.(
38+
widget.value,
39+
app.canvas,
40+
node,
41+
app.canvas.graph_mouse,
42+
{} as CanvasPointerEvent
43+
)
44+
}
45+
}
8946

90-
const widget = node.widgets?.find((w) => w.name === widgetName)
91-
if (!widget) {
92-
console.warn(
93-
`Unable to find widget "${widgetName}" on node [${node.id}]`
94-
)
95-
continue
96-
}
47+
function onNodeCreated(this: LGraphNode) {
48+
this.applyToGraph = useChainCallback(this.applyToGraph, applyToGraph)
9749

98-
widget.value = v
99-
widget.callback?.(
100-
widget.value,
101-
app.canvas,
102-
node,
103-
app.canvas.graph_mouse,
104-
{} as CanvasPointerEvent
105-
)
50+
const comboWidget = this.widgets![0]
51+
Object.defineProperty(comboWidget.options, 'values', {
52+
get: () => {
53+
return this.widgets!.filter(
54+
(w) => w.name.startsWith('option') && w.value
55+
).map((w) => w.value)
10656
}
57+
})
58+
const options = comboWidget.options as { values: string[] }
59+
60+
function updateCombo() {
61+
if (app.configuringGraph) return
62+
const { values } = options
63+
if (values.includes(`${comboWidget.value}`)) return
64+
comboWidget.value = values[0] ?? ''
65+
}
66+
comboWidget.callback = useChainCallback(comboWidget.callback, () =>
67+
this.applyToGraph!()
68+
)
69+
70+
function addOption(node: LGraphNode) {
71+
if (!node.widgets) return
72+
const widgetPostfix =
73+
node.widgets
74+
.findLast((w) => w.name.startsWith('option'))
75+
?.name?.slice(6) || '-1'
76+
const newCount = parseInt(widgetPostfix) + 1
77+
node.addWidget('string', `option${newCount}`, '', () => {})
78+
const widget = node.widgets.at(-1)
79+
if (!widget) return
80+
81+
let value = ''
82+
Object.defineProperty(widget, 'value', {
83+
get() {
84+
return value
85+
},
86+
set(v) {
87+
value = v
88+
updateCombo()
89+
if (!node.widgets) return
90+
const lastWidget = node.widgets.at(-1)
91+
if (lastWidget === this) {
92+
if (v) addOption(node)
93+
return
94+
}
95+
if (v || node.widgets.at(-2) !== this || lastWidget?.value) return
96+
node.widgets.pop()
97+
node.computeSize(node.size)
98+
}
99+
})
107100
}
101+
addOption(this)
108102
}
109103

110104
app.registerExtension({
111105
name: 'Comfy.CustomCombo',
112-
registerCustomNodes() {
113-
LiteGraph.registerNodeType('CustomCombo', CustomCombo)
106+
beforeRegisterNodeDef(nodeType, nodeData) {
107+
if (nodeData?.name !== 'CustomCombo') return
108+
nodeType.prototype.onNodeCreated = useChainCallback(
109+
nodeType.prototype.onNodeCreated,
110+
onNodeCreated
111+
)
114112
}
115113
})

0 commit comments

Comments
 (0)