From a3d4e4bca7b0180d9c853f98d41090256f4cc6da Mon Sep 17 00:00:00 2001 From: space-nuko <24979496+space-nuko@users.noreply.github.com> Date: Tue, 23 May 2023 17:29:33 -0500 Subject: [PATCH] More region widget fixes --- litegraph | 2 +- src/lib/ComfyGraph.ts | 4 ++-- src/lib/components/ComfyApp.ts | 24 +++++++++++++++++-- src/lib/components/ComfyQueue.svelte | 16 ++++++++++--- .../components/gradio/gallery/Gallery.svelte | 2 ++ src/lib/nodes/ComfyRegionToCoordsNode.ts | 15 ++++++------ src/lib/nodes/widgets/ComfyMultiRegionNode.ts | 12 +++++----- src/lib/widgets/MultiRegionWidget.svelte | 16 +++++++++++-- 8 files changed, 68 insertions(+), 23 deletions(-) diff --git a/litegraph b/litegraph index 34b0f0c..d8fa871 160000 --- a/litegraph +++ b/litegraph @@ -1 +1 @@ -Subproject commit 34b0f0c220473afc9057af88c47a5558b9ee520f +Subproject commit d8fa87185a258d362f159c04f9045c7930b884bd diff --git a/src/lib/ComfyGraph.ts b/src/lib/ComfyGraph.ts index 2aa2e96..61d4392 100644 --- a/src/lib/ComfyGraph.ts +++ b/src/lib/ComfyGraph.ts @@ -11,7 +11,7 @@ import type { ComfyComboNode, ComfyWidgetNode } from "./nodes/widgets"; import selectionState from "./stores/selectionState"; import type { WritableLayoutStateStore } from "./stores/layoutStates"; import layoutStates from "./stores/layoutStates"; -import type { ComfyWorkflow } from "./stores/workflowState"; +import type { ComfyWorkflow, WorkflowInstID } from "./stores/workflowState"; import workflowState from "./stores/workflowState"; type ComfyGraphEvents = { @@ -163,7 +163,7 @@ export default class ComfyGraph extends LGraph { // case node was cloned const reg = LiteGraph.registered_node_types[node.type] - layoutState.groupItems(dragItemIDs, { title: reg.title }) + layoutState.groupItems(dragItemIDs, { title: reg.title, variant: "accordion", openOnStartup: true }) } } diff --git a/src/lib/components/ComfyApp.ts b/src/lib/components/ComfyApp.ts index 1f79d73..798b2c8 100644 --- a/src/lib/components/ComfyApp.ts +++ b/src/lib/components/ComfyApp.ts @@ -356,6 +356,24 @@ export default class ComfyApp { ComfyApp.registerDefaultSlotHandlers(nodeId, nodeDef) } + + ComfyApp.registerComfyBoxSlotTypes() + } + + static registerComfyBoxSlotTypes() { + const reg = (type: string) => { + const lowerType = type.toLowerCase(); + if (!LiteGraph.slot_types_in.includes(lowerType)) { + LiteGraph.slot_types_in.push(lowerType); + } + if (!LiteGraph.slot_types_out.includes(type)) { + LiteGraph.slot_types_out.push(type); + } + } + + reg("COMFYBOX_IMAGE") + reg("COMFYBOX_IMAGES") + reg("COMFYBOX_REGION") } static registerDefaultSlotHandlers(nodeId: string, nodeDef: ComfyNodeDef) { @@ -771,7 +789,9 @@ export default class ComfyApp { const promptFilename = get(configState).promptForWorkflowName; - let filename = "workflow.json"; + const title = workflow.attrs.title.trim() || "workflow" + + let filename = `${title}.json`; if (promptFilename) { filename = prompt("Save workflow as:", filename); if (!filename) return; @@ -782,7 +802,7 @@ export default class ComfyApp { else { const date = new Date(); const formattedDate = date.toISOString().replace(/:/g, '-').replace(/\.\d{3}/g, '').replace('T', '_').replace("Z", ""); - filename = `workflow - ${formattedDate}.json` + filename = `${title} - ${formattedDate}.json` } const indent = 2 diff --git a/src/lib/components/ComfyQueue.svelte b/src/lib/components/ComfyQueue.svelte index fcf4180..0208c74 100644 --- a/src/lib/components/ComfyQueue.svelte +++ b/src/lib/components/ComfyQueue.svelte @@ -150,7 +150,7 @@ let submessage = `Nodes: ${Object.keys(entry.prompt).length}` if (Object.keys(entry.outputs).length > 0) { - const imageCount = Object.values(entry.outputs).flatMap(o => o.images).length + const imageCount = Object.values(entry.outputs).filter(o => o.images).flatMap(o => o.images).length submessage = `Images: ${imageCount}` } @@ -172,14 +172,24 @@ result.images = thumbnails.map(convertComfyOutputToComfyURL); } + const outputs = Object.values(entry.outputs) + .filter(o => o.images) + .flatMap(o => o.images) + .map(convertComfyOutputToComfyURL); + if (outputs) { + result.images = result.images.concat(outputs) + } + return result; } function convertCompletedEntry(entry: CompletedQueueEntry): QueueUIEntry { const result = convertEntry(entry.entry, entry.status); - const images = Object.values(entry.entry.outputs).flatMap(o => o.images) - .map(convertComfyOutputToComfyURL); + const images = Object.values(entry.entry.outputs) + .filter(o => o.images) + .flatMap(o => o.images) + .map(convertComfyOutputToComfyURL); result.images = images if (entry.message) diff --git a/src/lib/components/gradio/gallery/Gallery.svelte b/src/lib/components/gradio/gallery/Gallery.svelte index e5e6184..f6a8108 100644 --- a/src/lib/components/gradio/gallery/Gallery.svelte +++ b/src/lib/components/gradio/gallery/Gallery.svelte @@ -15,6 +15,7 @@ export let label: string; export let root: string = ""; export let root_url: null | string = null; + export let scrollOnUpdate = false; export let value: Array | Array | null = null; export let style: Styles = { grid_cols: [2], @@ -120,6 +121,7 @@ let container: HTMLDivElement; async function scroll_to_img(index: number | null) { + if (!scrollOnUpdate) return; if (typeof index !== "number") return; await tick(); diff --git a/src/lib/nodes/ComfyRegionToCoordsNode.ts b/src/lib/nodes/ComfyRegionToCoordsNode.ts index f1025af..002e740 100644 --- a/src/lib/nodes/ComfyRegionToCoordsNode.ts +++ b/src/lib/nodes/ComfyRegionToCoordsNode.ts @@ -7,10 +7,11 @@ export default class ComfyRegionToCoordsNode extends ComfyGraphNode { { name: "in", type: "COMFYBOX_REGION" }, ], outputs: [ - { name: "x", type: "number" }, - { name: "y", type: "number" }, + // same order as conditioning nodes { name: "width", type: "number" }, { name: "height", type: "number" }, + { name: "x", type: "number" }, + { name: "y", type: "number" }, ], } @@ -19,16 +20,16 @@ export default class ComfyRegionToCoordsNode extends ComfyGraphNode { if (!Array.isArray(value)) return; - this.setOutputData(0, value[0]) - this.setOutputData(1, value[1]) - this.setOutputData(2, value[2]) - this.setOutputData(3, value[3]) + this.setOutputData(0, value[2]) + this.setOutputData(1, value[3]) + this.setOutputData(2, value[0]) + this.setOutputData(3, value[1]) } } LiteGraph.registerNodeType({ class: ComfyRegionToCoordsNode, title: "Comfy.RegionToCoords", - desc: "Converts a COMFYBOX_REGION to four outputs of [x, y, width, height]", + desc: "Converts a COMFYBOX_REGION to four outputs of [width, height, x, y]", type: "utils/region_to_coords" }) diff --git a/src/lib/nodes/widgets/ComfyMultiRegionNode.ts b/src/lib/nodes/widgets/ComfyMultiRegionNode.ts index 3881608..a7297f6 100644 --- a/src/lib/nodes/widgets/ComfyMultiRegionNode.ts +++ b/src/lib/nodes/widgets/ComfyMultiRegionNode.ts @@ -41,7 +41,7 @@ export default class ComfyMultiRegionNode extends ComfyWidgetNode { name: "changed", type: BuiltInSlotType.EVENT }, // dynamic outputs, may be removed later - { name: "region1", type: "COMFYBOX_REGION" }, + { name: "region_1", type: "COMFYBOX_REGION" }, ] } @@ -145,7 +145,7 @@ export default class ComfyMultiRegionNode extends ComfyWidgetNode } for (let index = this.outputs.length - 1; index < this.properties.regionCount; index++) { - this.addOutput(`region${index + 1}`, "COMFYBOX_REGION") + this.addOutput(`region_${index + 1}`, "COMFYBOX_REGION") } this.regionsChanged.set(true); @@ -165,10 +165,10 @@ export default class ComfyMultiRegionNode extends ComfyWidgetNode value ||= this.getValue(); for (const bbox of value) { - bbox[0] = clamp(bbox[0], 0, 1 - bbox[2]); - bbox[1] = clamp(bbox[1], 0, 1 - bbox[3]); - bbox[2] = clamp(bbox[2], 0, 1 - bbox[1]) - bbox[3] = clamp(bbox[3], 0, 1 - bbox[2]) + bbox[0] = clamp(bbox[0], 0, 1); + bbox[1] = clamp(bbox[1], 0, 1); + bbox[2] = clamp(bbox[2], 0, 1) + bbox[3] = clamp(bbox[3], 0, 1) } const sizeChanged = this.properties.canvasWidth != this._prevWidth diff --git a/src/lib/widgets/MultiRegionWidget.svelte b/src/lib/widgets/MultiRegionWidget.svelte index 37f23c8..2cf8cfb 100644 --- a/src/lib/widgets/MultiRegionWidget.svelte +++ b/src/lib/widgets/MultiRegionWidget.svelte @@ -15,7 +15,6 @@ import { generateBlankCanvas, generateImageCanvas, loadImage } from "./utils"; import { clamp } from "$lib/utils"; import Row from "$lib/components/gradio/app/Row.svelte"; - import Column from "$lib/components/gradio/app/Column.svelte"; // ref: https://html-color.codes/ const COLOR_MAP: [string, string][] = [ @@ -400,6 +399,10 @@ const COLOR_MAP: [string, string][] = [ displayBoxes = await recreateDisplayBoxes(); } + function updateSelectedIndex(newIndexPlusOne: number) { + selectedIndex = clamp(newIndexPlusOne - 1, 0, $nodeValue.length - 1); + } + function updateX(newX: number) { const bbox = $nodeValue[selectedIndex] const dbox = displayBoxes[selectedIndex] @@ -440,7 +443,7 @@ const COLOR_MAP: [string, string][] = [ displayBoxes[selectedIndex] = displayBoundingBox(bbox, selectedIndex, imageElem, dbox); } - function updateValue() { + async function updateValue() { // Clamp regions const bbox = $nodeValue[selectedIndex] const dbox = displayBoxes[selectedIndex] @@ -452,6 +455,8 @@ const COLOR_MAP: [string, string][] = [ displayBoxes[selectedIndex] = displayBoundingBox(bbox, selectedIndex, imageElem, dbox); } + await updateImageAndDBoxes(); + // Force reactivity after changing a bbox's internal values $nodeValue = $nodeValue } @@ -504,6 +509,13 @@ const COLOR_MAP: [string, string][] = [ {#if selectedBBox} + + updateSelectedIndex(e.detail)} + on:release={updateValue} + /> +