mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-26 17:54:14 +00:00
Road to No Explicit Any Part 4: LiteGraph Cleanup (#7970)
## Summary - Remove all remaining `any` types from LiteGraph module - Define proper `Panel` interface for createPanel function and related callbacks - Type `SlotTypeDefaultNodeOpts` for slot type defaults configuration - Fix type inference issues in sendActionToCanvas and contextMenuCompat ## Changes - **SubgraphIONodeBase.ts**: Remove unnecessary `as any` cast in showSlotContextMenu - **interfaces.ts**: Add Panel, PanelButton, PanelWidget, PanelWidgetOptions, PanelWidgetCallback types - **LGraphNode.ts**: Type panel callbacks (onShowCustomPanelInfo, onAddPropertyToPanel) and onGetPropertyInfo - **LGraphCanvas.ts**: - Type node_panel and options_panel as Panel - Type inner_clicked callback parameters - Type local variables (nodeNewType, nodeNewOpts, prevent_timeout, iS, sIn, sOut) - Add SlotTypeDefaultNodeOpts interface for slot type configuration - **LGraph.ts**: Fix sendActionToCanvas type inference with proper array handling - **contextMenuCompat.ts**: Add null guard for newImpl parameter ## Test plan - [x] pnpm typecheck passes - [x] pnpm lint passes - [x] knip passes (no unused exports) ┆Issue is synchronized with this [Notion page](https://www.notion.so/PR-7970-Road-to-No-Explicit-Any-Part-4-LiteGraph-Cleanup-2e66d73d3650812c939bf9b2cb0ff2f5) by [Unito](https://www.unito.io) --------- Co-authored-by: GitHub Action <action@github.com>
This commit is contained in:
committed by
GitHub
parent
81df0102f8
commit
3412a0908d
@@ -842,8 +842,13 @@ export class LGraph
|
||||
if (!list_of_graphcanvas) return
|
||||
|
||||
for (const c of list_of_graphcanvas) {
|
||||
// eslint-disable-next-line prefer-spread
|
||||
c[action]?.apply(c, params)
|
||||
const method = c[action]
|
||||
|
||||
if (typeof method === 'function') {
|
||||
const args =
|
||||
params == null ? [] : Array.isArray(params) ? params : [params]
|
||||
;(method as (...args: unknown[]) => unknown).apply(c, args)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -52,6 +52,11 @@ import type {
|
||||
LinkSegment,
|
||||
NewNodePosition,
|
||||
NullableProperties,
|
||||
Panel,
|
||||
PanelButton,
|
||||
PanelWidget,
|
||||
PanelWidgetCallback,
|
||||
PanelWidgetOptions,
|
||||
Point,
|
||||
Positionable,
|
||||
ReadOnlyRect,
|
||||
@@ -94,7 +99,7 @@ import type {
|
||||
SubgraphIO
|
||||
} from './types/serialisation'
|
||||
import type { NeverNever, PickNevers } from './types/utility'
|
||||
import type { IBaseWidget } from './types/widgets'
|
||||
import type { IBaseWidget, TWidgetValue } from './types/widgets'
|
||||
import { alignNodes, distributeNodes, getBoundaryNodes } from './utils/arrange'
|
||||
import { findFirstNode, getAllNestedItems } from './utils/collections'
|
||||
import { resolveConnectingLinkColor } from './utils/linkColors'
|
||||
@@ -232,6 +237,15 @@ interface ICreatePanelOptions {
|
||||
height?: number | string
|
||||
}
|
||||
|
||||
interface SlotTypeDefaultNodeOpts {
|
||||
node?: string
|
||||
title?: string
|
||||
properties?: Record<string, NodeProperty>
|
||||
inputs?: [string, string][]
|
||||
outputs?: [string, string][]
|
||||
json?: Parameters<LGraphNode['configure']>[0]
|
||||
}
|
||||
|
||||
const cursors = {
|
||||
NE: 'nesw-resize',
|
||||
SE: 'nwse-resize',
|
||||
@@ -693,9 +707,9 @@ export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap>
|
||||
_highlight_input?: INodeInputSlot
|
||||
// TODO: Check if panels are used
|
||||
/** @deprecated Panels */
|
||||
node_panel?: any
|
||||
node_panel?: Panel
|
||||
/** @deprecated Panels */
|
||||
options_panel?: any
|
||||
options_panel?: Panel
|
||||
_bg_img?: HTMLImageElement
|
||||
_pattern?: CanvasPattern
|
||||
_pattern_img?: HTMLImageElement
|
||||
@@ -1249,11 +1263,13 @@ export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap>
|
||||
|
||||
function inner_clicked(
|
||||
this: ContextMenuDivElement<INodeSlotContextItem>,
|
||||
v: IContextMenuValue<INodeSlotContextItem>,
|
||||
e: any,
|
||||
prev: any
|
||||
v?: string | IContextMenuValue<INodeSlotContextItem>,
|
||||
_options?: unknown,
|
||||
e?: MouseEvent,
|
||||
prev?: ContextMenu<INodeSlotContextItem>
|
||||
) {
|
||||
if (!node) return
|
||||
if (!v || typeof v === 'string') return
|
||||
|
||||
// TODO: This is a static method, so the below "that" appears broken.
|
||||
if (v.callback) void v.callback.call(this, node, v, e, prev)
|
||||
@@ -6354,8 +6370,7 @@ export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap>
|
||||
? LiteGraph.slot_types_default_out
|
||||
: LiteGraph.slot_types_default_in
|
||||
if (slotTypesDefault?.[fromSlotType]) {
|
||||
// TODO: Remove "any" kludge
|
||||
let nodeNewType: any = false
|
||||
let nodeNewType: string | Record<string, unknown> | false = false
|
||||
if (typeof slotTypesDefault[fromSlotType] == 'object') {
|
||||
for (const typeX in slotTypesDefault[fromSlotType]) {
|
||||
if (
|
||||
@@ -6373,11 +6388,13 @@ export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap>
|
||||
nodeNewType = slotTypesDefault[fromSlotType]
|
||||
}
|
||||
if (nodeNewType) {
|
||||
// TODO: Remove "any" kludge
|
||||
let nodeNewOpts: any = false
|
||||
if (typeof nodeNewType == 'object' && nodeNewType.node) {
|
||||
nodeNewOpts = nodeNewType
|
||||
nodeNewType = nodeNewType.node
|
||||
let nodeNewOpts: SlotTypeDefaultNodeOpts | undefined
|
||||
let nodeTypeStr: string
|
||||
if (typeof nodeNewType == 'object') {
|
||||
nodeNewOpts = nodeNewType as SlotTypeDefaultNodeOpts
|
||||
nodeTypeStr = nodeNewOpts.node ?? ''
|
||||
} else {
|
||||
nodeTypeStr = nodeNewType
|
||||
}
|
||||
|
||||
// that.graph.beforeChange();
|
||||
@@ -6386,7 +6403,7 @@ export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap>
|
||||
const nodeX = opts.position[0] + opts.posAdd[0] + xSizeFix
|
||||
const nodeY = opts.position[1] + opts.posAdd[1] + ySizeFix
|
||||
const pos = [nodeX, nodeY]
|
||||
const newNode = LiteGraph.createNode(nodeNewType, nodeNewOpts.title, {
|
||||
const newNode = LiteGraph.createNode(nodeTypeStr, nodeNewOpts?.title, {
|
||||
pos
|
||||
})
|
||||
if (newNode) {
|
||||
@@ -6399,20 +6416,14 @@ export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap>
|
||||
}
|
||||
if (nodeNewOpts.inputs) {
|
||||
newNode.inputs = []
|
||||
for (const i in nodeNewOpts.inputs) {
|
||||
newNode.addOutput(
|
||||
nodeNewOpts.inputs[i][0],
|
||||
nodeNewOpts.inputs[i][1]
|
||||
)
|
||||
for (const input of nodeNewOpts.inputs) {
|
||||
newNode.addInput(input[0], input[1])
|
||||
}
|
||||
}
|
||||
if (nodeNewOpts.outputs) {
|
||||
newNode.outputs = []
|
||||
for (const i in nodeNewOpts.outputs) {
|
||||
newNode.addOutput(
|
||||
nodeNewOpts.outputs[i][0],
|
||||
nodeNewOpts.outputs[i][1]
|
||||
)
|
||||
for (const output of nodeNewOpts.outputs) {
|
||||
newNode.addOutput(output[0], output[1])
|
||||
}
|
||||
}
|
||||
if (nodeNewOpts.json) {
|
||||
@@ -6909,8 +6920,7 @@ export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap>
|
||||
|
||||
// hide on mouse leave
|
||||
if (options.hide_on_mouse_leave) {
|
||||
// FIXME: Remove "any" kludge
|
||||
let prevent_timeout: any = false
|
||||
let prevent_timeout = 0
|
||||
let timeout_close: ReturnType<typeof setTimeout> | null = null
|
||||
LiteGraph.pointerListenerAdd(dialog, 'enter', function () {
|
||||
if (timeout_close) {
|
||||
@@ -7104,8 +7114,7 @@ export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap>
|
||||
|
||||
// join node after inserting
|
||||
if (options.node_from) {
|
||||
// FIXME: any
|
||||
let iS: any = false
|
||||
let iS: number | false = false
|
||||
switch (typeof options.slot_from) {
|
||||
case 'string':
|
||||
iS = options.node_from.findOutputSlot(options.slot_from)
|
||||
@@ -7131,8 +7140,8 @@ export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap>
|
||||
// try with first if no name set
|
||||
iS = 0
|
||||
}
|
||||
if (options.node_from.outputs[iS] !== undefined) {
|
||||
if (iS !== false && iS > -1) {
|
||||
if (iS !== false && options.node_from.outputs[iS] !== undefined) {
|
||||
if (iS > -1) {
|
||||
if (node == null)
|
||||
throw new TypeError(
|
||||
'options.slot_from was null when showing search box'
|
||||
@@ -7149,8 +7158,7 @@ export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap>
|
||||
}
|
||||
}
|
||||
if (options.node_to) {
|
||||
// FIXME: any
|
||||
let iS: any = false
|
||||
let iS: number | false = false
|
||||
switch (typeof options.slot_from) {
|
||||
case 'string':
|
||||
iS = options.node_to.findInputSlot(options.slot_from)
|
||||
@@ -7176,8 +7184,8 @@ export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap>
|
||||
// try with first if no name set
|
||||
iS = 0
|
||||
}
|
||||
if (options.node_to.inputs[iS] !== undefined) {
|
||||
if (iS !== false && iS > -1) {
|
||||
if (iS !== false && options.node_to.inputs[iS] !== undefined) {
|
||||
if (iS > -1) {
|
||||
if (node == null)
|
||||
throw new TypeError(
|
||||
'options.slot_from was null when showing search box'
|
||||
@@ -7240,13 +7248,16 @@ export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap>
|
||||
|
||||
const filter = graphcanvas.filter || graphcanvas.graph.filter
|
||||
|
||||
// FIXME: any
|
||||
// filter by type preprocess
|
||||
let sIn: any = false
|
||||
let sOut: any = false
|
||||
let sIn: HTMLSelectElement | null = null
|
||||
let sOut: HTMLSelectElement | null = null
|
||||
if (options.do_type_filter && that.search_box) {
|
||||
sIn = that.search_box.querySelector('.slot_in_type_filter')
|
||||
sOut = that.search_box.querySelector('.slot_out_type_filter')
|
||||
sIn = that.search_box.querySelector<HTMLSelectElement>(
|
||||
'.slot_in_type_filter'
|
||||
)
|
||||
sOut = that.search_box.querySelector<HTMLSelectElement>(
|
||||
'.slot_out_type_filter'
|
||||
)
|
||||
}
|
||||
|
||||
const keys = Object.keys(LiteGraph.registered_node_types)
|
||||
@@ -7264,7 +7275,7 @@ export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap>
|
||||
// add general type if filtering
|
||||
if (
|
||||
options.show_general_after_typefiltered &&
|
||||
(sIn.value || sOut.value)
|
||||
(sIn?.value || sOut?.value)
|
||||
) {
|
||||
const filtered_extra: string[] = []
|
||||
for (const i in LiteGraph.registered_node_types) {
|
||||
@@ -7289,7 +7300,7 @@ export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap>
|
||||
|
||||
// check il filtering gave no results
|
||||
if (
|
||||
(sIn.value || sOut.value) &&
|
||||
(sIn?.value || sOut?.value) &&
|
||||
helper.childNodes.length == 0 &&
|
||||
options.show_general_if_none_on_typefilter
|
||||
) {
|
||||
@@ -7337,8 +7348,10 @@ export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap>
|
||||
if (options.do_type_filter && !opts.skipFilter) {
|
||||
const sType = type
|
||||
|
||||
let sV =
|
||||
opts.inTypeOverride !== false ? opts.inTypeOverride : sIn.value
|
||||
let sV: string | undefined =
|
||||
typeof opts.inTypeOverride === 'string'
|
||||
? opts.inTypeOverride
|
||||
: sIn?.value
|
||||
// type is stored
|
||||
if (sIn && sV && LiteGraph.registered_slot_in_types[sV]?.nodes) {
|
||||
const doesInc =
|
||||
@@ -7346,8 +7359,9 @@ export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap>
|
||||
if (doesInc === false) return false
|
||||
}
|
||||
|
||||
sV = sOut.value
|
||||
if (opts.outTypeOverride !== false) sV = opts.outTypeOverride
|
||||
sV = sOut?.value
|
||||
if (typeof opts.outTypeOverride === 'string')
|
||||
sV = opts.outTypeOverride
|
||||
// type is stored
|
||||
if (sOut && sV && LiteGraph.registered_slot_out_types[sV]?.nodes) {
|
||||
const doesInc =
|
||||
@@ -7628,15 +7642,14 @@ export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap>
|
||||
return dialog
|
||||
}
|
||||
|
||||
createPanel(title: string, options: ICreatePanelOptions) {
|
||||
createPanel(title: string, options: ICreatePanelOptions): Panel {
|
||||
options = options || {}
|
||||
|
||||
// TODO: any kludge
|
||||
const root: any = document.createElement('div')
|
||||
const root = document.createElement('div') as Panel
|
||||
root.className = 'litegraph dialog'
|
||||
root.innerHTML =
|
||||
"<div class='dialog-header'><span class='dialog-title'></span></div><div class='dialog-content'></div><div style='display:none;' class='dialog-alt-content'></div><div class='dialog-footer'></div>"
|
||||
root.header = root.querySelector('.dialog-header')
|
||||
root.header = root.querySelector('.dialog-header')!
|
||||
|
||||
if (options.width)
|
||||
root.style.width =
|
||||
@@ -7653,11 +7666,11 @@ export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap>
|
||||
})
|
||||
root.header.append(close)
|
||||
}
|
||||
root.title_element = root.querySelector('.dialog-title')
|
||||
root.title_element = root.querySelector('.dialog-title')!
|
||||
root.title_element.textContent = title
|
||||
root.content = root.querySelector('.dialog-content')
|
||||
root.alt_content = root.querySelector('.dialog-alt-content')
|
||||
root.footer = root.querySelector('.dialog-footer')
|
||||
root.content = root.querySelector('.dialog-content')!
|
||||
root.alt_content = root.querySelector('.dialog-alt-content')!
|
||||
root.footer = root.querySelector('.dialog-footer')!
|
||||
root.footer.style.marginTop = '-96px'
|
||||
|
||||
root.close = function () {
|
||||
@@ -7667,7 +7680,7 @@ export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap>
|
||||
}
|
||||
|
||||
// function to swap panel content
|
||||
root.toggleAltContent = function (force: unknown) {
|
||||
root.toggleAltContent = function (force?: boolean) {
|
||||
let vTo: string
|
||||
let vAlt: string
|
||||
if (force !== undefined) {
|
||||
@@ -7681,7 +7694,7 @@ export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap>
|
||||
root.content.style.display = vAlt
|
||||
}
|
||||
|
||||
root.toggleFooterVisibility = function (force: unknown) {
|
||||
root.toggleFooterVisibility = function (force?: boolean) {
|
||||
let vTo: string
|
||||
if (force !== undefined) {
|
||||
vTo = force ? 'block' : 'none'
|
||||
@@ -7695,7 +7708,11 @@ export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap>
|
||||
this.content.innerHTML = ''
|
||||
}
|
||||
|
||||
root.addHTML = function (code: string, classname: string, on_footer: any) {
|
||||
root.addHTML = function (
|
||||
code: string,
|
||||
classname?: string,
|
||||
on_footer?: boolean
|
||||
) {
|
||||
const elem = document.createElement('div')
|
||||
if (classname) elem.className = classname
|
||||
elem.innerHTML = code
|
||||
@@ -7704,9 +7721,12 @@ export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap>
|
||||
return elem
|
||||
}
|
||||
|
||||
root.addButton = function (name: any, callback: any, options: any) {
|
||||
// TODO: any kludge
|
||||
const elem: any = document.createElement('button')
|
||||
root.addButton = function (
|
||||
name: string,
|
||||
callback: () => void,
|
||||
options?: unknown
|
||||
): PanelButton {
|
||||
const elem = document.createElement('button') as PanelButton
|
||||
elem.textContent = name
|
||||
elem.options = options
|
||||
elem.classList.add('btn')
|
||||
@@ -7723,20 +7743,18 @@ export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap>
|
||||
|
||||
root.addWidget = function (
|
||||
type: string,
|
||||
name: any,
|
||||
value: unknown,
|
||||
options: { label?: any; type?: any; values?: any; callback?: any },
|
||||
callback: (arg0: any, arg1: any, arg2: any) => void
|
||||
) {
|
||||
name: string,
|
||||
value: TWidgetValue,
|
||||
options?: PanelWidgetOptions,
|
||||
callback?: PanelWidgetCallback
|
||||
): PanelWidget {
|
||||
options = options || {}
|
||||
let str_value = String(value)
|
||||
type = type.toLowerCase()
|
||||
if (type == 'number' && typeof value === 'number')
|
||||
str_value = value.toFixed(3)
|
||||
|
||||
// FIXME: any kludge
|
||||
const elem: HTMLDivElement & { options?: unknown; value?: unknown } =
|
||||
document.createElement('div')
|
||||
const elem: PanelWidget = document.createElement('div') as PanelWidget
|
||||
elem.className = 'property'
|
||||
elem.innerHTML =
|
||||
"<span class='property_name'></span><span class='property_value'></span>"
|
||||
@@ -7744,7 +7762,6 @@ export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap>
|
||||
if (!nameSpan) throw new TypeError('Property name element was null.')
|
||||
|
||||
nameSpan.textContent = options.label || name
|
||||
// TODO: any kludge
|
||||
const value_element: HTMLSpanElement | null =
|
||||
elem.querySelector('.property_value')
|
||||
if (!value_element) throw new TypeError('Property name element was null.')
|
||||
@@ -7756,7 +7773,8 @@ export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap>
|
||||
|
||||
if (type == 'code') {
|
||||
elem.addEventListener('click', function () {
|
||||
root.inner_showCodePad(this.dataset['property'])
|
||||
const property = this.dataset['property']
|
||||
if (property) root.inner_showCodePad?.(property)
|
||||
})
|
||||
} else if (type == 'boolean') {
|
||||
elem.classList.add('boolean')
|
||||
@@ -7799,19 +7817,16 @@ export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap>
|
||||
value_element.textContent = str_value ?? ''
|
||||
|
||||
value_element.addEventListener('click', function (event) {
|
||||
const values = options.values || []
|
||||
const values = options?.values || []
|
||||
const propname = this.parentElement?.dataset['property']
|
||||
const inner_clicked = (v: string | null) => {
|
||||
// node.setProperty(propname,v);
|
||||
// graphcanvas.dirty_canvas = true;
|
||||
this.textContent = v
|
||||
const inner_clicked = (v?: string) => {
|
||||
this.textContent = v ?? null
|
||||
innerChange(propname, v)
|
||||
return false
|
||||
}
|
||||
new LiteGraph.ContextMenu(values, {
|
||||
event,
|
||||
className: 'dark',
|
||||
// @ts-expect-error fixme ts strict error - callback signature mismatch
|
||||
callback: inner_clicked
|
||||
})
|
||||
})
|
||||
@@ -7819,9 +7834,10 @@ export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap>
|
||||
|
||||
root.content.append(elem)
|
||||
|
||||
function innerChange(name: string | undefined, value: unknown) {
|
||||
options.callback?.(name, value, options)
|
||||
callback?.(name, value, options)
|
||||
function innerChange(name: string | undefined, value: TWidgetValue) {
|
||||
const opts = options || {}
|
||||
opts.callback?.(name, value, opts)
|
||||
callback?.(name, value, opts)
|
||||
}
|
||||
|
||||
return elem
|
||||
@@ -7850,7 +7866,7 @@ export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap>
|
||||
},
|
||||
onClose: () => {
|
||||
this.NODEPANEL_IS_OPEN = false
|
||||
this.node_panel = null
|
||||
this.node_panel = undefined
|
||||
}
|
||||
})
|
||||
this.node_panel = panel
|
||||
@@ -7871,11 +7887,9 @@ export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap>
|
||||
|
||||
panel.addHTML('<h3>Properties</h3>')
|
||||
|
||||
const fUpdate = (
|
||||
name: string,
|
||||
value: string | number | boolean | object | undefined
|
||||
) => {
|
||||
const fUpdate: PanelWidgetCallback = (name, value) => {
|
||||
if (!this.graph) throw new NullGraphError()
|
||||
if (!name) return
|
||||
this.graph.beforeChange(node)
|
||||
switch (name) {
|
||||
case 'Title':
|
||||
@@ -7979,7 +7993,7 @@ export class LGraphCanvas implements CustomEventDispatcher<LGraphCanvasEventMap>
|
||||
|
||||
panel.alt_content.innerHTML = "<textarea class='code'></textarea>"
|
||||
const textarea: HTMLTextAreaElement =
|
||||
panel.alt_content.querySelector('textarea')
|
||||
panel.alt_content.querySelector('textarea')!
|
||||
const fDoneWith = function () {
|
||||
panel.toggleAltContent(false)
|
||||
panel.toggleFooterVisibility(true)
|
||||
|
||||
@@ -41,6 +41,7 @@ import type {
|
||||
INodeSlotContextItem,
|
||||
IPinnable,
|
||||
ISlotType,
|
||||
Panel,
|
||||
Point,
|
||||
Positionable,
|
||||
ReadOnlyRect,
|
||||
@@ -96,9 +97,12 @@ export type NodeId = number | string
|
||||
export type NodeProperty = string | number | boolean | object
|
||||
|
||||
interface INodePropertyInfo {
|
||||
name: string
|
||||
name?: string
|
||||
type?: string
|
||||
default_value: NodeProperty | undefined
|
||||
default_value?: NodeProperty
|
||||
widget?: string
|
||||
label?: string
|
||||
values?: TWidgetValue[]
|
||||
}
|
||||
|
||||
interface IMouseOverData {
|
||||
@@ -606,8 +610,8 @@ export class LGraphNode
|
||||
target_slot: number,
|
||||
requested_slot?: number | string
|
||||
): number | false | null
|
||||
onShowCustomPanelInfo?(this: LGraphNode, panel: any): void
|
||||
onAddPropertyToPanel?(this: LGraphNode, pName: string, panel: any): boolean
|
||||
onShowCustomPanelInfo?(this: LGraphNode, panel: Panel): void
|
||||
onAddPropertyToPanel?(this: LGraphNode, pName: string, panel: Panel): boolean
|
||||
onWidgetChanged?(
|
||||
this: LGraphNode,
|
||||
name: string,
|
||||
@@ -667,8 +671,7 @@ export class LGraphNode
|
||||
index: number,
|
||||
e: CanvasPointerEvent
|
||||
): void
|
||||
// TODO: Return type
|
||||
onGetPropertyInfo?(this: LGraphNode, property: string): any
|
||||
onGetPropertyInfo?(this: LGraphNode, property: string): INodePropertyInfo
|
||||
onNodeOutputAdd?(this: LGraphNode, value: unknown): void
|
||||
onNodeInputAdd?(this: LGraphNode, value: unknown): void
|
||||
onMenuNodeInputs?(
|
||||
|
||||
@@ -81,6 +81,7 @@ class LegacyMenuCompat {
|
||||
return currentImpl
|
||||
},
|
||||
set: (newImpl: LGraphCanvas[K]) => {
|
||||
if (!newImpl) return
|
||||
const fnKey = `${methodName as string}:${newImpl.toString().slice(0, 100)}`
|
||||
if (!this.hasWarned.has(fnKey) && this.currentExtension) {
|
||||
this.hasWarned.add(fnKey)
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { Rectangle } from '@/lib/litegraph/src/infrastructure/Rectangle'
|
||||
import type { CanvasPointerEvent } from '@/lib/litegraph/src/types/events'
|
||||
import type { TWidgetValue } from '@/lib/litegraph/src/types/widgets'
|
||||
|
||||
import type { ContextMenu } from './ContextMenu'
|
||||
import type { LGraphNode, NodeId } from './LGraphNode'
|
||||
@@ -493,3 +494,68 @@ export interface Hoverable extends HasBoundingRect {
|
||||
onPointerEnter?(e?: CanvasPointerEvent): void
|
||||
onPointerLeave?(e?: CanvasPointerEvent): void
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for panel widget value changes.
|
||||
*/
|
||||
export type PanelWidgetCallback = (
|
||||
name: string | undefined,
|
||||
value: TWidgetValue,
|
||||
options: PanelWidgetOptions
|
||||
) => void
|
||||
|
||||
/**
|
||||
* Options for panel widgets.
|
||||
*/
|
||||
export interface PanelWidgetOptions {
|
||||
label?: string
|
||||
type?: string
|
||||
widget?: string
|
||||
values?: Array<string | IContextMenuValue<unknown, unknown, unknown> | null>
|
||||
callback?: PanelWidgetCallback
|
||||
}
|
||||
|
||||
/**
|
||||
* A button element with optional options property.
|
||||
*/
|
||||
export interface PanelButton extends HTMLButtonElement {
|
||||
options?: unknown
|
||||
}
|
||||
|
||||
/**
|
||||
* A widget element with options and value properties.
|
||||
*/
|
||||
export interface PanelWidget extends HTMLDivElement {
|
||||
options?: PanelWidgetOptions
|
||||
value?: TWidgetValue
|
||||
}
|
||||
|
||||
/**
|
||||
* A dialog panel created by LGraphCanvas.createPanel().
|
||||
* Extends HTMLDivElement with additional properties and methods for panel management.
|
||||
*/
|
||||
export interface Panel extends HTMLDivElement {
|
||||
header: HTMLElement
|
||||
title_element: HTMLSpanElement
|
||||
content: HTMLDivElement
|
||||
alt_content: HTMLDivElement
|
||||
footer: HTMLDivElement
|
||||
node?: LGraphNode
|
||||
onOpen?: () => void
|
||||
onClose?: () => void
|
||||
close(): void
|
||||
toggleAltContent(force?: boolean): void
|
||||
toggleFooterVisibility(force?: boolean): void
|
||||
clear(): void
|
||||
addHTML(code: string, classname?: string, on_footer?: boolean): HTMLDivElement
|
||||
addButton(name: string, callback: () => void, options?: unknown): PanelButton
|
||||
addSeparator(): void
|
||||
addWidget(
|
||||
type: string,
|
||||
name: string,
|
||||
value: TWidgetValue,
|
||||
options?: PanelWidgetOptions,
|
||||
callback?: PanelWidgetCallback
|
||||
): PanelWidget
|
||||
inner_showCodePad?(property: string): void
|
||||
}
|
||||
|
||||
@@ -195,7 +195,7 @@ export abstract class SubgraphIONodeBase<
|
||||
if (!(options.length > 0)) return
|
||||
|
||||
new LiteGraph.ContextMenu(options, {
|
||||
event: event as any,
|
||||
event,
|
||||
title: slot.name || 'Subgraph Output',
|
||||
callback: (item: IContextMenuValue) => {
|
||||
this.#onSlotMenuAction(item, slot, event)
|
||||
|
||||
Reference in New Issue
Block a user