Use V2 schema in widget constructors (Part 1) (#2860)

This commit is contained in:
Chenlei Hu
2025-03-04 17:22:13 -05:00
committed by GitHub
parent 89b73429b7
commit 6255cea181
6 changed files with 139 additions and 135 deletions

View File

@@ -1,28 +1,33 @@
import type { LGraphNode } from '@comfyorg/litegraph'
import { type InputSpec, isBooleanInputSpec } from '@/schemas/nodeDefSchema'
import type { ComfyWidgetConstructor } from '@/scripts/widgets'
import {
type InputSpec,
isBooleanInputSpec
} from '@/schemas/nodeDef/nodeDefSchemaV2'
import { type ComfyWidgetConstructorV2 } from '@/scripts/widgets'
export const useBooleanWidget = () => {
const widgetConstructor: ComfyWidgetConstructor = (
const widgetConstructor: ComfyWidgetConstructorV2 = (
node: LGraphNode,
inputName: string,
inputData: InputSpec
inputSpec: InputSpec
) => {
if (!isBooleanInputSpec(inputData)) {
throw new Error(`Invalid input data: ${inputData}`)
if (!isBooleanInputSpec(inputSpec)) {
throw new Error(`Invalid input data: ${inputSpec}`)
}
const inputOptions = inputData[1] ?? {}
const defaultVal = inputOptions?.default ?? false
const defaultVal = inputSpec.default ?? false
const options = {
on: inputOptions?.label_on,
off: inputOptions?.label_off
on: inputSpec.label_on,
off: inputSpec.label_off
}
return {
widget: node.addWidget('toggle', inputName, defaultVal, () => {}, options)
}
return node.addWidget(
'toggle',
inputSpec.name,
defaultVal,
() => {},
options
)
}
return widgetConstructor

View File

@@ -2,8 +2,11 @@ import type { LGraphNode } from '@comfyorg/litegraph'
import type { INumericWidget } from '@comfyorg/litegraph/dist/types/widgets'
import _ from 'lodash'
import { type InputSpec, isFloatInputSpec } from '@/schemas/nodeDefSchema'
import type { ComfyWidgetConstructor } from '@/scripts/widgets'
import {
type InputSpec,
isFloatInputSpec
} from '@/schemas/nodeDef/nodeDefSchemaV2'
import { type ComfyWidgetConstructorV2 } from '@/scripts/widgets'
import { useSettingStore } from '@/stores/settingStore'
function onFloatValueChange(this: INumericWidget, v: number) {
@@ -22,23 +25,18 @@ export const _for_testing = {
}
export const useFloatWidget = () => {
const widgetConstructor: ComfyWidgetConstructor = (
const widgetConstructor: ComfyWidgetConstructorV2 = (
node: LGraphNode,
inputName: string,
inputData: InputSpec
inputSpec: InputSpec
) => {
if (!isFloatInputSpec(inputData)) {
throw new Error(`Invalid input data: ${inputData}`)
if (!isFloatInputSpec(inputSpec)) {
throw new Error(`Invalid input data: ${inputSpec}`)
}
// TODO: Move to outer scope to avoid re-initializing on every call
// Blocked on ComfyWidgets lazy initialization.
const settingStore = useSettingStore()
const sliderEnabled = !settingStore.get('Comfy.DisableSliders')
const inputOptions = inputData[1] ?? {}
const display_type = inputOptions?.display
const display_type = inputSpec.display
const widgetType =
sliderEnabled && display_type == 'slider'
? 'slider'
@@ -46,33 +44,31 @@ export const useFloatWidget = () => {
? 'knob'
: 'number'
const step = inputOptions.step ?? 0.5
const step = inputSpec.step ?? 0.5
const precision =
settingStore.get('Comfy.FloatRoundingPrecision') ||
Math.max(0, -Math.floor(Math.log10(step)))
const enableRounding = !settingStore.get('Comfy.DisableFloatRounding')
const defaultValue = inputOptions.default ?? 0
return {
widget: node.addWidget(
widgetType,
inputName,
defaultValue,
onFloatValueChange,
{
min: inputOptions.min ?? 0,
max: inputOptions.max ?? 2048,
round:
enableRounding && precision && !inputOptions.round
? (1_000_000 * Math.pow(0.1, precision)) / 1_000_000
: (inputOptions.round as number),
/** @deprecated Use step2 instead. The 10x value is a legacy implementation. */
step: step * 10.0,
step2: step,
precision
}
)
}
const defaultValue = inputSpec.default ?? 0
return node.addWidget(
widgetType,
inputSpec.name,
defaultValue,
onFloatValueChange,
{
min: inputSpec.min ?? 0,
max: inputSpec.max ?? 2048,
round:
enableRounding && precision && !inputSpec.round
? (1_000_000 * Math.pow(0.1, precision)) / 1_000_000
: (inputSpec.round as number),
/** @deprecated Use step2 instead. The 10x value is a legacy implementation. */
step: step * 10.0,
step2: step,
precision
}
)
}
return widgetConstructor

View File

@@ -1,10 +1,13 @@
import type { LGraphNode } from '@comfyorg/litegraph'
import type { INumericWidget } from '@comfyorg/litegraph/dist/types/widgets'
import { type InputSpec, isIntInputSpec } from '@/schemas/nodeDefSchema'
import type { ComfyApp } from '@/scripts/app'
import { transformInputSpecV2ToV1 } from '@/schemas/nodeDef/migration'
import {
type ComfyWidgetConstructor,
type InputSpec,
isIntInputSpec
} from '@/schemas/nodeDef/nodeDefSchemaV2'
import {
type ComfyWidgetConstructorV2,
addValueControlWidget
} from '@/scripts/widgets'
import { useSettingStore } from '@/stores/settingStore'
@@ -33,21 +36,17 @@ export const _for_testing = {
}
export const useIntWidget = () => {
const widgetConstructor: ComfyWidgetConstructor = (
const widgetConstructor: ComfyWidgetConstructorV2 = (
node: LGraphNode,
inputName: string,
inputData: InputSpec,
app: ComfyApp,
widgetName?: string
inputSpec: InputSpec
) => {
if (!isIntInputSpec(inputData)) {
throw new Error(`Invalid input data: ${inputData}`)
if (!isIntInputSpec(inputSpec)) {
throw new Error(`Invalid input data: ${inputSpec}`)
}
const settingStore = useSettingStore()
const sliderEnabled = !settingStore.get('Comfy.DisableSliders')
const inputOptions = inputData[1] ?? {}
const display_type = inputOptions?.display
const display_type = inputSpec.display
const widgetType =
sliderEnabled && display_type == 'slider'
? 'slider'
@@ -55,38 +54,36 @@ export const useIntWidget = () => {
? 'knob'
: 'number'
const step = inputOptions.step ?? 1
const defaultValue = inputOptions.default ?? 0
const result = {
widget: node.addWidget(
widgetType,
inputName,
defaultValue,
onValueChange,
{
min: inputOptions.min ?? 0,
max: inputOptions.max ?? 2048,
/** @deprecated Use step2 instead. The 10x value is a legacy implementation. */
step: step * 10,
step2: step,
precision: 0
}
)
}
const step = inputSpec.step ?? 1
const defaultValue = inputSpec.default ?? 0
const widget = node.addWidget(
widgetType,
inputSpec.name,
defaultValue,
onValueChange,
{
min: inputSpec.min ?? 0,
max: inputSpec.max ?? 2048,
/** @deprecated Use step2 instead. The 10x value is a legacy implementation. */
step: step * 10,
step2: step,
precision: 0
}
)
if (inputOptions.control_after_generate) {
if (inputSpec.control_after_generate) {
const seedControl = addValueControlWidget(
node,
result.widget,
widget,
'randomize',
undefined,
widgetName,
inputData
undefined,
transformInputSpecV2ToV1(inputSpec)
)
result.widget.linkedWidgets = [seedControl]
widget.linkedWidgets = [seedControl]
}
return result
return widget
}
return widgetConstructor
}

View File

@@ -1,39 +0,0 @@
import type { LGraphNode } from '@comfyorg/litegraph'
import { type InputSpec, isIntInputSpec } from '@/schemas/nodeDefSchema'
import type { ComfyWidgetConstructor } from '@/scripts/widgets'
import type { ComfyApp } from '@/types'
import { useIntWidget } from './useIntWidget'
export const useSeedWidget = () => {
const IntWidget = useIntWidget()
const widgetConstructor: ComfyWidgetConstructor = (
node: LGraphNode,
inputName: string,
inputData: InputSpec,
app: ComfyApp,
widgetName?: string
) => {
if (!isIntInputSpec(inputData)) {
throw new Error(`Invalid input data: ${inputData}`)
}
return IntWidget(
node,
inputName,
[
'INT',
{
...inputData[1],
control_after_generate: true
}
],
app,
widgetName
)
}
return widgetConstructor
}