From fe3efe1154a2204ae39414a4db00ee1a5ae09713 Mon Sep 17 00:00:00 2001 From: space-nuko <24979496+space-nuko@users.noreply.github.com> Date: Wed, 17 May 2023 15:51:05 -0500 Subject: [PATCH] Set known slot in/out types --- litegraph | 2 +- src/lib/ComfyNodeDef.ts | 2 +- src/lib/api.ts | 4 +- src/lib/components/ComfyApp.ts | 44 ++++++++++++-- src/lib/init.ts | 15 ++++- src/lib/stores/layoutState.ts | 5 +- src/scss/global.scss | 11 ++-- src/scss/litegraph.scss | 108 +++++++++++++++++++++++++++++++++ 8 files changed, 173 insertions(+), 18 deletions(-) create mode 100644 src/scss/litegraph.scss diff --git a/litegraph b/litegraph index 97895e1..2d963a6 160000 --- a/litegraph +++ b/litegraph @@ -1 +1 @@ -Subproject commit 97895e1103c44cb801a9c2d6eee6fd07f617f617 +Subproject commit 2d963a609f5bdc6f01ca142ec8d07bd7519ac178 diff --git a/src/lib/ComfyNodeDef.ts b/src/lib/ComfyNodeDef.ts index d0fb5d0..584b673 100644 --- a/src/lib/ComfyNodeDef.ts +++ b/src/lib/ComfyNodeDef.ts @@ -17,7 +17,7 @@ export type ComfyNodeDefInputs = { optional?: Record } export type ComfyNodeDefInput = [ComfyNodeDefInputType, ComfyNodeDefInputOptions | null] -export type ComfyNodeDefInputType = string[] | keyof typeof ComfyWidgets | string +export type ComfyNodeDefInputType = any[] | keyof typeof ComfyWidgets | string export type ComfyNodeDefInputOptions = { forceInput?: boolean } diff --git a/src/lib/api.ts b/src/lib/api.ts index 445a01e..8e5097c 100644 --- a/src/lib/api.ts +++ b/src/lib/api.ts @@ -253,7 +253,7 @@ export default class ComfyAPI { postBody = JSON.stringify(body) } catch (error) { - return Promise.reject({ error }) + return Promise.reject({ error: error.toString() }) } return fetch(this.getBackendUrl() + "/prompt", { @@ -270,7 +270,7 @@ export default class ComfyAPI { return res.json() }) .then(raw => { return { promptID: raw.prompt_id } }) - .catch(error => { return { error } }) + .catch(error => { return error }) } /** diff --git a/src/lib/components/ComfyApp.ts b/src/lib/components/ComfyApp.ts index 4e74f0e..07bb15d 100644 --- a/src/lib/components/ComfyApp.ts +++ b/src/lib/components/ComfyApp.ts @@ -121,9 +121,6 @@ export default class ComfyApp { this.lCanvas = new ComfyGraphCanvas(this, this.canvasEl); this.canvasCtx = this.canvasEl.getContext("2d"); - LiteGraph.release_link_on_empty_shows_menu = true; - LiteGraph.alt_drag_do_clone_nodes = true; - const uiUnlocked = get(uiState).uiUnlocked; this.lCanvas.allow_dragnodes = uiUnlocked; this.lCanvas.allow_interaction = uiUnlocked; @@ -242,13 +239,50 @@ export default class ComfyApp { for (const [inputName, [inputType, _inputOpts]] of iterateNodeDefInputs(nodeDef)) { if (isBackendNodeDefInputType(inputName, inputType)) { - LiteGraph.slot_types_default_out[inputType] ||= [] + LiteGraph.slot_types_default_out[inputType] ||= ["utils/reroute"] LiteGraph.slot_types_default_out[inputType].push(nodeTypeSpec) + + // Input types have to be stored as lower case + // Store each node that can handle this input type + const lowerType = inputType.toLocaleLowerCase(); + if (!(lowerType in LiteGraph.registered_slot_in_types)) { + LiteGraph.registered_slot_in_types[lowerType] = { nodes: [] }; + } + LiteGraph.registered_slot_in_types[lowerType].nodes.push(nodeId); + + if (!LiteGraph.slot_types_in.includes(lowerType)) { + LiteGraph.slot_types_in.push(lowerType); + } + } + else { + // inputType is an array of combo box entries (["euler", "karras", ...]) + // or a widget input type ("INT"). } } + for (const output of iterateNodeDefOutputs(nodeDef)) { - LiteGraph.slot_types_default_in[output.type] ||= [] + LiteGraph.slot_types_default_in[output.type] ||= ["utils/reroute"] LiteGraph.slot_types_default_in[output.type].push(nodeTypeSpec) + + // Store each node that can handle this output type + if (!(output.type in LiteGraph.registered_slot_out_types)) { + LiteGraph.registered_slot_out_types[output.type] = { nodes: [] }; + } + LiteGraph.registered_slot_out_types[output.type].nodes.push(nodeId); + + if (!LiteGraph.slot_types_out.includes(output.type)) { + LiteGraph.slot_types_out.push(output.type); + } + } + + const maxNodeSuggestions = 5 // TODO config + + // TODO config beforeChanged + for (const key of Object.keys(LiteGraph.slot_types_default_in)) { + LiteGraph.slot_types_default_in[key] = LiteGraph.slot_types_default_in[key].slice(0, maxNodeSuggestions) + } + for (const key of Object.keys(LiteGraph.slot_types_default_out)) { + LiteGraph.slot_types_default_out[key] = LiteGraph.slot_types_default_out[key].slice(0, maxNodeSuggestions) } } diff --git a/src/lib/init.ts b/src/lib/init.ts index 9a97fd7..83ea48d 100644 --- a/src/lib/init.ts +++ b/src/lib/init.ts @@ -5,12 +5,23 @@ import { get } from 'svelte/store'; export function configureLitegraph(isMobile: boolean = false) { LiteGraph.catch_exceptions = false; + + // Must be enabled, otherwise subgraphs won't work (because of non-unique node/link IDs) LiteGraph.use_uuids = true; + + + LiteGraph.search_filter_enabled = true; + LiteGraph.release_link_on_empty_shows_menu = true; + LiteGraph.alt_drag_do_clone_nodes = true; + LiteGraph.middle_click_slot_add_default_node = true; + LiteGraph.dialog_close_on_mouse_leave = false; + LiteGraph.search_hide_on_mouse_leave = false; + LiteGraph.graph_inputs_outputs_use_combo_widget = true; + LiteGraph.search_box_refresh_interval_ms = 150; + LiteGraph.CANVAS_GRID_SIZE = 32; if (isMobile) { - LiteGraph.dialog_close_on_mouse_leave = false; - LiteGraph.search_hide_on_mouse_leave = false; LiteGraph.pointerevents_method = "pointer"; } diff --git a/src/lib/stores/layoutState.ts b/src/lib/stores/layoutState.ts index 35b58bb..3bd4778 100644 --- a/src/lib/stores/layoutState.ts +++ b/src/lib/stores/layoutState.ts @@ -771,7 +771,7 @@ function addContainer(parent: ContainerLayout | null, attrs: Partial console.debug("[layoutState] addContainer", state) store.set(state) - runOnChangedForWidgetDefaults(dragItem) + // runOnChangedForWidgetDefaults(dragItem) return dragItem; } @@ -786,7 +786,6 @@ function addWidget(parent: ContainerLayout, node: ComfyWidgetNode, attrs: Partia attrs: { ...defaultWidgetAttributes, title: widgetName, - nodeDisabledState: "disabled", ...attrs } } @@ -803,7 +802,7 @@ function addWidget(parent: ContainerLayout, node: ComfyWidgetNode, attrs: Partia console.debug("[layoutState] addWidget", state) moveItem(dragItem, parent, index) - runOnChangedForWidgetDefaults(dragItem) + // runOnChangedForWidgetDefaults(dragItem) return dragItem; } diff --git a/src/scss/global.scss b/src/scss/global.scss index e391436..ca7e934 100644 --- a/src/scss/global.scss +++ b/src/scss/global.scss @@ -1,4 +1,5 @@ @import "gradio"; +@import "litegraph"; body { overflow: hidden; @@ -110,10 +111,12 @@ input, textarea { border-radius: 0 !important; } -select { - color: var(--body-text-color); - background: var(--input-background-fill); - border: var(--input-border-width) solid var(--input-border-color) +:not(.litegraph) { + select { + color: var(--body-text-color); + background: var(--input-background-fill); + border: var(--input-border-width) solid var(--input-border-color) + } } .container { diff --git a/src/scss/litegraph.scss b/src/scss/litegraph.scss new file mode 100644 index 0000000..0087d53 --- /dev/null +++ b/src/scss/litegraph.scss @@ -0,0 +1,108 @@ +// Improvements to litegraph's css. +// Taken from ComfyUI. + +:root { + --litegraph-fg-color: #000; + --litegraph-bg-color: #fff; + --litegraph-comfy-menu-bg: #353535; + --litegraph-comfy-input-bg: #222; + --litegraph-input-text: #ddd; + --litegraph-descrip-text: #999; + --litegraph-drag-text: #ccc; + --litegraph-error-text: #ff4444; + --litegraph-border-color: #4e4e4e; +} + +.litegraph { + /* Input popup */ + &.graphdialog { + min-height: 1em; + background-color: var(--litegraph-comfy-menu-bg); + .name { + font-size: 14px; + font-family: sans-serif; + color: var(--litegraph-descrip-text); + } + button { + margin-top: unset; + vertical-align: unset; + height: 1.6em; + padding-right: 8px; + } + } + .graphdialog input, .graphdialog textarea, .graphdialog select { + background-color: var(--litegraph-comfy-input-bg); + border: 2px solid; + border-color: var(--litegraph-border-color); + color: var(--litegraph-input-text); + border-radius: 12px 0 0 12px; + } + + /* Context Menu */ + .litemenu-entry { + &.has_submenu { + position: relative; + padding-right: 20px; + } + } + &.litecontextmenu { + .litemenu-entry { + &:hover { + &:not(.disabled):not(.separator) { + background-color: var(--litegraph-comfy-menu-bg) !important; + filter: brightness(155%); + color: var(--litegraph-input-text); + } + } + } + input { + background-color: var(--litegraph-comfy-input-bg) !important; + color: var(--litegraph-input-text) !important; + } + } + &.litesearchbox { + z-index: 9999 !important; + background-color: var(--litegraph-comfy-menu-bg) !important; + overflow: hidden; + } + &.lite-search-item { + color: var(--litegraph-input-text); + background-color: var(--litegraph-comfy-input-bg); + filter: brightness(80%); + padding-left: 0.2em; + &.generic_type { + color: var(--litegraph-input-text); + filter: brightness(50%); + } + } +} + +.litemenu-entry { + &.has_submenu { + &::after { + content: ">"; + position: absolute; + top: 0; + right: 2px; + } + } +} + +.litegraph.litecontextmenu, +.litegraph.litecontextmenu.dark { + z-index: 9999 !important; + background-color: var(--litegraph-comfy-menu-bg) !important; + filter: brightness(95%); +} + +.litegraph.litecontextmenu .litemenu-entry.submenu, +.litegraph.litecontextmenu.dark .litemenu-entry.submenu { + background-color: var(--litegraph-comfy-menu-bg) !important; + color: var(--litegraph-input-text); +} + +.litegraph.litesearchbox input, +.litegraph.litesearchbox select { + background-color: var(--litegraph-comfy-input-bg) !important; + color: var(--litegraph-input-text); +}