Inplace widget to input conversion (#2588)
Co-authored-by: github-actions <github-actions@github.com>
|
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 43 KiB |
|
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 66 KiB |
|
Before Width: | Height: | Size: 63 KiB After Width: | Height: | Size: 65 KiB |
|
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 63 KiB |
|
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 62 KiB |
|
Before Width: | Height: | Size: 101 KiB After Width: | Height: | Size: 101 KiB |
|
Before Width: | Height: | Size: 98 KiB After Width: | Height: | Size: 98 KiB |
8
package-lock.json
generated
@@ -11,7 +11,7 @@
|
||||
"dependencies": {
|
||||
"@atlaskit/pragmatic-drag-and-drop": "^1.3.1",
|
||||
"@comfyorg/comfyui-electron-types": "^0.4.16",
|
||||
"@comfyorg/litegraph": "^0.8.81",
|
||||
"@comfyorg/litegraph": "^0.8.82",
|
||||
"@primevue/forms": "^4.2.5",
|
||||
"@primevue/themes": "^4.2.5",
|
||||
"@sentry/vue": "^8.48.0",
|
||||
@@ -1944,9 +1944,9 @@
|
||||
"license": "GPL-3.0-only"
|
||||
},
|
||||
"node_modules/@comfyorg/litegraph": {
|
||||
"version": "0.8.81",
|
||||
"resolved": "https://registry.npmjs.org/@comfyorg/litegraph/-/litegraph-0.8.81.tgz",
|
||||
"integrity": "sha512-YJDbOXGTDUKdLooNgNlfY3Zrl9GM4t1QPYNZS/qd5xvU5pPsqZ743Hz8gqH5tr4g4xcuC94q+pCek2yAfsIwpA==",
|
||||
"version": "0.8.82",
|
||||
"resolved": "https://registry.npmjs.org/@comfyorg/litegraph/-/litegraph-0.8.82.tgz",
|
||||
"integrity": "sha512-grwCXpjSKdyH/nVt+PYnv8BLavNNdyIhCAqiAMx9V5cK4bKsFFdHweuyYD8D2ySPR1iPPhOwsvfpi42ud+mbJQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@cspotcode/source-map-support": {
|
||||
|
||||
@@ -84,7 +84,7 @@
|
||||
"dependencies": {
|
||||
"@atlaskit/pragmatic-drag-and-drop": "^1.3.1",
|
||||
"@comfyorg/comfyui-electron-types": "^0.4.16",
|
||||
"@comfyorg/litegraph": "^0.8.81",
|
||||
"@comfyorg/litegraph": "^0.8.82",
|
||||
"@primevue/forms": "^4.2.5",
|
||||
"@primevue/themes": "^4.2.5",
|
||||
"@sentry/vue": "^8.48.0",
|
||||
|
||||
@@ -13,7 +13,6 @@ useExtensionService().registerExtension({
|
||||
const widgets = node.widgets.filter((w) => w.dynamicPrompts)
|
||||
for (const widget of widgets) {
|
||||
// Override the serialization of the value to resolve dynamic prompts for all widgets supporting it in this node
|
||||
// @ts-expect-error hacky override
|
||||
widget.serializeValue = (workflowNode, widgetIndex) => {
|
||||
if (typeof widget.value !== 'string') return widget.value
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import type {
|
||||
LiteGraphCanvasEvent
|
||||
} from '@comfyorg/litegraph'
|
||||
import type { IFoundSlot } from '@comfyorg/litegraph'
|
||||
import { INodeSlot } from '@comfyorg/litegraph'
|
||||
|
||||
import { useNodeDefStore } from '@/stores/nodeDefStore'
|
||||
import { useSettingStore } from '@/stores/settingStore'
|
||||
@@ -422,11 +423,11 @@ class PrimitiveNode extends LGraphNode {
|
||||
}
|
||||
}
|
||||
|
||||
export function getWidgetConfig(slot) {
|
||||
export function getWidgetConfig(slot: INodeSlot) {
|
||||
return slot.widget[CONFIG] ?? slot.widget[GET_CONFIG]?.() ?? ['*', {}]
|
||||
}
|
||||
|
||||
function getConfig(widgetName) {
|
||||
function getConfig(widgetName: string) {
|
||||
const { nodeData } = this.constructor
|
||||
return (
|
||||
nodeData?.input?.required?.[widgetName] ??
|
||||
@@ -434,21 +435,33 @@ function getConfig(widgetName) {
|
||||
)
|
||||
}
|
||||
|
||||
function isConvertibleWidget(widget, config) {
|
||||
function isConvertibleWidget(widget: IWidget, config: InputSpec): boolean {
|
||||
return (
|
||||
(VALID_TYPES.includes(widget.type) || VALID_TYPES.includes(config[0])) &&
|
||||
!widget.options?.forceInput
|
||||
)
|
||||
}
|
||||
|
||||
function hideWidget(node, widget, suffix = '') {
|
||||
function hideWidget(
|
||||
node: LGraphNode,
|
||||
widget: IWidget,
|
||||
options: { suffix?: string; holdSpace?: boolean } = {}
|
||||
) {
|
||||
const { suffix = '', holdSpace = true } = options
|
||||
|
||||
if (widget.type?.startsWith(CONVERTED_TYPE)) return
|
||||
widget.origType = widget.type
|
||||
widget.origComputeSize = widget.computeSize
|
||||
widget.origSerializeValue = widget.serializeValue
|
||||
widget.computeSize = () => [0, -4] // -4 is due to the gap litegraph adds between widgets automatically
|
||||
// @ts-expect-error custom widget type
|
||||
widget.type = CONVERTED_TYPE + suffix
|
||||
widget.serializeValue = () => {
|
||||
if (holdSpace) {
|
||||
widget.computeSize = () => [0, LiteGraph.NODE_WIDGET_HEIGHT]
|
||||
} else {
|
||||
// -4 is due to the gap litegraph adds between widgets automatically
|
||||
widget.computeSize = () => [0, -4]
|
||||
}
|
||||
widget.serializeValue = (node: LGraphNode, index: number) => {
|
||||
// Prevent serializing the widget if we have no input linked
|
||||
if (!node.inputs) {
|
||||
return undefined
|
||||
@@ -459,19 +472,20 @@ function hideWidget(node, widget, suffix = '') {
|
||||
return undefined
|
||||
}
|
||||
return widget.origSerializeValue
|
||||
? widget.origSerializeValue()
|
||||
? widget.origSerializeValue(node, index)
|
||||
: widget.value
|
||||
}
|
||||
|
||||
// Hide any linked widgets, e.g. seed+seedControl
|
||||
if (widget.linkedWidgets) {
|
||||
for (const w of widget.linkedWidgets) {
|
||||
hideWidget(node, w, ':' + widget.name)
|
||||
hideWidget(node, w, { suffix: ':' + widget.name, holdSpace: false })
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function showWidget(widget) {
|
||||
function showWidget(widget: IWidget) {
|
||||
// @ts-expect-error custom widget type
|
||||
widget.type = widget.origType
|
||||
widget.computeSize = widget.origComputeSize
|
||||
widget.serializeValue = widget.origSerializeValue
|
||||
@@ -517,7 +531,7 @@ export function convertToInput(
|
||||
return input
|
||||
}
|
||||
|
||||
function convertToWidget(node, widget) {
|
||||
function convertToWidget(node: LGraphNode, widget: IWidget) {
|
||||
showWidget(widget)
|
||||
const [oldWidth, oldHeight] = node.size
|
||||
node.removeInput(node.inputs.findIndex((i) => i.widget?.name === widget.name))
|
||||
@@ -542,7 +556,7 @@ function getWidgetType(config: InputSpec) {
|
||||
return { type }
|
||||
}
|
||||
|
||||
function isValidCombo(combo, obj) {
|
||||
function isValidCombo(combo: string[], obj: unknown) {
|
||||
// New input isnt a combo
|
||||
if (!(obj instanceof Array)) {
|
||||
console.log(`connection rejected: tried to connect combo to ${obj}`)
|
||||
|
||||
17
src/types/litegraph-augmentation.d.ts
vendored
@@ -1,5 +1,5 @@
|
||||
import '@comfyorg/litegraph'
|
||||
import type { LLink } from '@comfyorg/litegraph'
|
||||
import type { LLink, Size } from '@comfyorg/litegraph'
|
||||
|
||||
import type { DOMWidget } from '@/scripts/domWidget'
|
||||
import type { ComfyNodeDef } from '@/types/apiTypes'
|
||||
@@ -17,13 +17,26 @@ declare module '@comfyorg/litegraph/dist/types/widgets' {
|
||||
onRemove?: () => void
|
||||
beforeQueued?: () => unknown
|
||||
afterQueued?: () => unknown
|
||||
serializeValue?: (node: LGraphNode, index: number) => Promise<unknown>
|
||||
serializeValue?: (
|
||||
node: LGraphNode,
|
||||
index: number
|
||||
) => Promise<unknown> | unknown
|
||||
|
||||
/**
|
||||
* If the widget supports dynamic prompts, this will be set to true.
|
||||
* See extensions/core/dynamicPrompts.ts
|
||||
*/
|
||||
dynamicPrompts?: boolean
|
||||
|
||||
/**
|
||||
* Widget conversion fields
|
||||
*/
|
||||
origType?: string
|
||||
origComputeSize?: (width: number) => Size
|
||||
origSerializeValue?: (
|
||||
node: LGraphNode,
|
||||
index: number
|
||||
) => Promise<unknown> | unknown
|
||||
}
|
||||
}
|
||||
|
||||
|
||||