mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-03-13 00:50:01 +00:00
Subgraph widget promotion - Part 1 (#5537)
* Prerequisite tweaks for subgraph widget promotion * Clean up DOMWidget tracking on graph change * Mark migrated CombOWidget functions private * Cleanup placeholder node cast
This commit is contained in:
@@ -25,7 +25,9 @@ const config: KnipConfig = {
|
||||
'src/types/generatedManagerTypes.ts',
|
||||
'src/types/comfyRegistryTypes.ts',
|
||||
// Used by a custom node (that should move off of this)
|
||||
'src/scripts/ui/components/splitButton.ts'
|
||||
'src/scripts/ui/components/splitButton.ts',
|
||||
// Staged for for use with subgraph widget promotion
|
||||
'src/lib/litegraph/src/widgets/DisconnectedWidget.ts'
|
||||
],
|
||||
compilers: {
|
||||
// https://github.com/webpro-nl/knip/issues/1008#issuecomment-3207756199
|
||||
|
||||
@@ -34,7 +34,7 @@ const updateWidgets = () => {
|
||||
const widget = widgetState.widget
|
||||
|
||||
// Early exit for non-visible widgets
|
||||
if (!widget.isVisible()) {
|
||||
if (!widget.isVisible() || !widgetState.active) {
|
||||
widgetState.visible = false
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -45,7 +45,7 @@ export class ComboWidget
|
||||
return typeof this.value === 'number' ? String(this.value) : this.value
|
||||
}
|
||||
|
||||
#getValues(node: LGraphNode): Values {
|
||||
private getValues(node: LGraphNode): Values {
|
||||
const { values } = this.options
|
||||
if (values == null) throw new Error('[ComboWidget]: values is required')
|
||||
|
||||
@@ -57,7 +57,7 @@ export class ComboWidget
|
||||
* @param increment `true` if checking the use of the increment button, `false` for decrement
|
||||
* @returns `true` if the value is at the given index, otherwise `false`.
|
||||
*/
|
||||
#canUseButton(increment: boolean): boolean {
|
||||
private canUseButton(increment: boolean): boolean {
|
||||
const { values } = this.options
|
||||
// If using legacy duck-typed method, false is the most permissive return value
|
||||
if (typeof values === 'function') return false
|
||||
@@ -78,23 +78,23 @@ export class ComboWidget
|
||||
* Handles edge case where the value is both the first and last item in the list.
|
||||
*/
|
||||
override canIncrement(): boolean {
|
||||
return this.#canUseButton(true)
|
||||
return this.canUseButton(true)
|
||||
}
|
||||
|
||||
override canDecrement(): boolean {
|
||||
return this.#canUseButton(false)
|
||||
return this.canUseButton(false)
|
||||
}
|
||||
|
||||
override incrementValue(options: WidgetEventOptions): void {
|
||||
this.#tryChangeValue(1, options)
|
||||
this.tryChangeValue(1, options)
|
||||
}
|
||||
|
||||
override decrementValue(options: WidgetEventOptions): void {
|
||||
this.#tryChangeValue(-1, options)
|
||||
this.tryChangeValue(-1, options)
|
||||
}
|
||||
|
||||
#tryChangeValue(delta: number, options: WidgetEventOptions): void {
|
||||
const values = this.#getValues(options.node)
|
||||
private tryChangeValue(delta: number, options: WidgetEventOptions): void {
|
||||
const values = this.getValues(options.node)
|
||||
const indexedValues = toArray(values)
|
||||
|
||||
// avoids double click event
|
||||
@@ -128,7 +128,7 @@ export class ComboWidget
|
||||
if (x > width - 40) return this.incrementValue({ e, node, canvas })
|
||||
|
||||
// Otherwise, show dropdown menu
|
||||
const values = this.#getValues(node)
|
||||
const values = this.getValues(node)
|
||||
const values_list = toArray(values)
|
||||
|
||||
// Handle center click - show dropdown menu
|
||||
|
||||
38
src/lib/litegraph/src/widgets/DisconnectedWidget.ts
Normal file
38
src/lib/litegraph/src/widgets/DisconnectedWidget.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import { LGraphNode } from '@/lib/litegraph/src/LGraphNode'
|
||||
import type { IButtonWidget } from '@/lib/litegraph/src/types/widgets'
|
||||
|
||||
import { BaseWidget, type DrawWidgetOptions } from './BaseWidget'
|
||||
|
||||
class DisconnectedWidget extends BaseWidget<IButtonWidget> {
|
||||
constructor(widget: IButtonWidget) {
|
||||
super(widget, new LGraphNode('DisconnectedPlaceholder'))
|
||||
this.disabled = true
|
||||
}
|
||||
|
||||
override drawWidget(
|
||||
ctx: CanvasRenderingContext2D,
|
||||
{ width, showText = true }: DrawWidgetOptions
|
||||
) {
|
||||
ctx.save()
|
||||
this.drawWidgetShape(ctx, { width, showText })
|
||||
if (showText) {
|
||||
this.drawTruncatingText({ ctx, width, leftPadding: 0, rightPadding: 0 })
|
||||
}
|
||||
ctx.restore()
|
||||
}
|
||||
|
||||
override onClick() {}
|
||||
|
||||
override get _displayValue() {
|
||||
return 'Disconnected'
|
||||
}
|
||||
}
|
||||
const conf: IButtonWidget = {
|
||||
type: 'button',
|
||||
value: undefined,
|
||||
name: 'Disconnected',
|
||||
options: {},
|
||||
y: 0,
|
||||
clicked: false
|
||||
}
|
||||
export const disconnectedWidget = new DisconnectedWidget(conf)
|
||||
@@ -35,6 +35,7 @@ import {
|
||||
isComboInputSpecV1,
|
||||
isComboInputSpecV2
|
||||
} from '@/schemas/nodeDefSchema'
|
||||
import { type BaseDOMWidget, DOMWidgetImpl } from '@/scripts/domWidget'
|
||||
import { getFromWebmFile } from '@/scripts/metadata/ebml'
|
||||
import { getGltfBinaryMetadata } from '@/scripts/metadata/gltf'
|
||||
import { getFromIsobmffFile } from '@/scripts/metadata/isobmff'
|
||||
@@ -837,22 +838,29 @@ export class ComfyApp {
|
||||
this.canvas.canvas.addEventListener<'litegraph:set-graph'>(
|
||||
'litegraph:set-graph',
|
||||
(e) => {
|
||||
// Assertion: Not yet defined in litegraph.
|
||||
const { newGraph } = e.detail
|
||||
|
||||
const nodeSet = new Set(newGraph.nodes)
|
||||
const widgetStore = useDomWidgetStore()
|
||||
|
||||
// Assertions: UnwrapRef
|
||||
for (const { widget } of widgetStore.activeWidgetStates) {
|
||||
if (!nodeSet.has(widget.node)) {
|
||||
widgetStore.deactivateWidget(widget.id)
|
||||
}
|
||||
}
|
||||
const activeWidgets: Record<
|
||||
string,
|
||||
BaseDOMWidget<object | string>
|
||||
> = Object.fromEntries(
|
||||
newGraph.nodes
|
||||
.flatMap((node) => node.widgets ?? [])
|
||||
.filter((w) => w instanceof DOMWidgetImpl)
|
||||
.map((w) => [w.id, w])
|
||||
)
|
||||
|
||||
for (const { widget } of widgetStore.inactiveWidgetStates) {
|
||||
if (nodeSet.has(widget.node)) {
|
||||
widgetStore.activateWidget(widget.id)
|
||||
for (const [
|
||||
widgetId,
|
||||
widgetState
|
||||
] of widgetStore.widgetStates.entries()) {
|
||||
if (widgetId in activeWidgets) {
|
||||
widgetState.active = true
|
||||
widgetState.widget = activeWidgets[widgetId]
|
||||
} else {
|
||||
widgetState.active = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user