Use v2 input spec for combo widget (#2878)

This commit is contained in:
Chenlei Hu
2025-03-05 13:12:51 -05:00
committed by GitHub
parent 8a479979b1
commit 35e6cabfe7
7 changed files with 75 additions and 122 deletions

View File

@@ -1,70 +1,76 @@
import type { LGraphNode } from '@comfyorg/litegraph'
import type { IComboWidget } from '@comfyorg/litegraph/dist/types/widgets'
import { transformInputSpecV2ToV1 } from '@/schemas/nodeDef/migration'
import {
ComboInputSpec,
type InputSpec,
getComboSpecComboOptions,
isComboInputSpec
} from '@/schemas/nodeDefSchema'
import { addValueControlWidgets } from '@/scripts/widgets'
import type { ComfyWidgetConstructor } from '@/scripts/widgets'
import { useWidgetStore } from '@/stores/widgetStore'
} from '@/schemas/nodeDef/nodeDefSchemaV2'
import {
type ComfyWidgetConstructorV2,
addValueControlWidgets
} from '@/scripts/widgets'
import { useRemoteWidget } from './useRemoteWidget'
const getDefaultValue = (inputSpec: ComboInputSpec) => {
if (inputSpec.default) return inputSpec.default
if (inputSpec.options?.length) return inputSpec.options[0]
if (inputSpec.remote) return 'Loading...'
return undefined
}
export const useComboWidget = () => {
const widgetConstructor: ComfyWidgetConstructor = (
const widgetConstructor: ComfyWidgetConstructorV2 = (
node: LGraphNode,
inputName: string,
inputData: InputSpec
inputSpec: InputSpec
) => {
if (!isComboInputSpec(inputData)) {
throw new Error(`Invalid input data: ${inputData}`)
if (!isComboInputSpec(inputSpec)) {
throw new Error(`Invalid input data: ${inputSpec}`)
}
const widgetStore = useWidgetStore()
const inputOptions = inputData[1] ?? {}
const comboOptions = getComboSpecComboOptions(inputData)
const comboOptions = inputSpec.options ?? []
const defaultValue = getDefaultValue(inputSpec)
const defaultValue = widgetStore.getDefaultValue(inputData)
const res = {
widget: node.addWidget('combo', inputName, defaultValue, () => {}, {
const widget = node.addWidget(
'combo',
inputSpec.name,
defaultValue,
() => {},
{
values: comboOptions
}) as IComboWidget
}
}
) as IComboWidget
if (inputOptions.remote) {
if (inputSpec.remote) {
const remoteWidget = useRemoteWidget({
inputData,
remoteConfig: inputSpec.remote,
defaultValue,
node,
widget: res.widget
widget
})
if (inputOptions.remote.refresh_button) remoteWidget.addRefreshButton()
if (inputSpec.remote.refresh_button) remoteWidget.addRefreshButton()
const origOptions = res.widget.options
res.widget.options = new Proxy(
origOptions as Record<string | symbol, any>,
{
get(target, prop: string | symbol) {
if (prop !== 'values') return target[prop]
return remoteWidget.getValue()
}
const origOptions = widget.options
widget.options = new Proxy(origOptions as Record<string | symbol, any>, {
get(target, prop: string | symbol) {
if (prop !== 'values') return target[prop]
return remoteWidget.getValue()
}
)
})
}
if (inputOptions.control_after_generate) {
res.widget.linkedWidgets = addValueControlWidgets(
if (inputSpec.control_after_generate) {
widget.linkedWidgets = addValueControlWidgets(
node,
res.widget,
widget,
undefined,
undefined,
inputData
transformInputSpecV2ToV1(inputSpec)
)
}
return res
return widget
}
return widgetConstructor