mirror of
https://github.com/Comfy-Org/ComfyUI_frontend.git
synced 2026-02-07 08:30:06 +00:00
Migrate groupNode (#35)
This commit is contained in:
@@ -2,6 +2,7 @@ import { app } from "../../scripts/app";
|
||||
import { api } from "../../scripts/api";
|
||||
import { mergeIfValid } from "./widgetInputs";
|
||||
import { ManageGroupDialog } from "./groupNodeManage";
|
||||
import type { LGraphNode } from "/types/litegraph";
|
||||
|
||||
const GROUP = Symbol();
|
||||
|
||||
@@ -14,7 +15,9 @@ const Workflow = {
|
||||
isInUseGroupNode(name) {
|
||||
const id = `workflow/${name}`;
|
||||
// Check if lready registered/in use in this workflow
|
||||
// @ts-ignore
|
||||
if (app.graph.extra?.groupNodes?.[name]) {
|
||||
// @ts-ignore
|
||||
if (app.graph._nodes.find((n) => n.type === id)) {
|
||||
return Workflow.InUse.InWorkflow;
|
||||
} else {
|
||||
@@ -24,7 +27,9 @@ const Workflow = {
|
||||
return Workflow.InUse.Free;
|
||||
},
|
||||
storeGroupNode(name, data) {
|
||||
// @ts-ignore
|
||||
let extra = app.graph.extra;
|
||||
// @ts-ignore
|
||||
if (!extra) app.graph.extra = extra = {};
|
||||
let groupNodes = extra.groupNodes;
|
||||
if (!groupNodes) extra.groupNodes = groupNodes = {};
|
||||
@@ -33,6 +38,9 @@ const Workflow = {
|
||||
};
|
||||
|
||||
class GroupNodeBuilder {
|
||||
nodes: LGraphNode[];
|
||||
nodeData: any;
|
||||
|
||||
constructor(nodes) {
|
||||
this.nodes = nodes;
|
||||
}
|
||||
@@ -120,6 +128,8 @@ class GroupNodeBuilder {
|
||||
// Use the built in copyToClipboard function to generate the node data we need
|
||||
const backup = localStorage.getItem("litegrapheditor_clipboard");
|
||||
try {
|
||||
// @ts-ignore
|
||||
// TODO Figure out if copyToClipboard is really taking this param
|
||||
app.canvas.copyToClipboard(this.nodes);
|
||||
const config = JSON.parse(localStorage.getItem("litegrapheditor_clipboard"));
|
||||
|
||||
@@ -134,6 +144,25 @@ class GroupNodeBuilder {
|
||||
}
|
||||
|
||||
export class GroupNodeConfig {
|
||||
name: string;
|
||||
nodeData: any;
|
||||
inputCount: number;
|
||||
oldToNewOutputMap: {};
|
||||
newToOldOutputMap: {};
|
||||
oldToNewInputMap: {};
|
||||
oldToNewWidgetMap: {};
|
||||
newToOldWidgetMap: {};
|
||||
primitiveDefs: {};
|
||||
widgetToPrimitive: {};
|
||||
primitiveToWidget: {};
|
||||
nodeInputs: {};
|
||||
outputVisibility: any[];
|
||||
nodeDef: any;
|
||||
inputs: any[];
|
||||
linksFrom: {};
|
||||
linksTo: {};
|
||||
externalFrom: {};
|
||||
|
||||
constructor(name, nodeData) {
|
||||
this.name = name;
|
||||
this.nodeData = nodeData;
|
||||
@@ -289,6 +318,7 @@ export class GroupNodeConfig {
|
||||
null,
|
||||
widget
|
||||
);
|
||||
// @ts-ignore
|
||||
config = res?.customConfig ?? config;
|
||||
}
|
||||
}
|
||||
@@ -312,6 +342,7 @@ export class GroupNodeConfig {
|
||||
}
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
config.forceInput = true;
|
||||
return {
|
||||
input: {
|
||||
@@ -328,7 +359,7 @@ export class GroupNodeConfig {
|
||||
console.warn("Skipping virtual node " + node.type + " when building group node " + this.name);
|
||||
}
|
||||
|
||||
getInputConfig(node, inputName, seenInputs, config, extra) {
|
||||
getInputConfig(node, inputName, seenInputs, config, extra?) {
|
||||
const customConfig = this.nodeData.config?.[node.index]?.input?.[inputName];
|
||||
let name = customConfig?.name ?? node.inputs?.find((inp) => inp.name === inputName)?.label ?? inputName;
|
||||
let key = name;
|
||||
@@ -580,6 +611,7 @@ export class GroupNodeConfig {
|
||||
export class GroupNodeHandler {
|
||||
node;
|
||||
groupData;
|
||||
innerNodes: any;
|
||||
|
||||
constructor(node) {
|
||||
this.node = node;
|
||||
@@ -624,6 +656,8 @@ export class GroupNodeHandler {
|
||||
let link = app.graph.links[linkId];
|
||||
|
||||
// Use the outer link, but update the target to the inner node
|
||||
// @ts-ignore
|
||||
// TODO: Fix this
|
||||
link = {
|
||||
...link,
|
||||
target_id: innerNode.id,
|
||||
@@ -676,6 +710,7 @@ export class GroupNodeHandler {
|
||||
this.groupData.nodeData.nodes.map((n, i) => {
|
||||
const innerNode = LiteGraph.createNode(n.type);
|
||||
innerNode.configure(n);
|
||||
// @ts-ignore
|
||||
innerNode.id = `${this.node.id}:${i}`;
|
||||
return innerNode;
|
||||
})
|
||||
@@ -1225,7 +1260,9 @@ function addConvertToGroupOptions() {
|
||||
}
|
||||
|
||||
// Add to canvas
|
||||
// @ts-ignore
|
||||
const getCanvasMenuOptions = LGraphCanvas.prototype.getCanvasMenuOptions;
|
||||
// @ts-ignore
|
||||
LGraphCanvas.prototype.getCanvasMenuOptions = function () {
|
||||
const options = getCanvasMenuOptions.apply(this, arguments);
|
||||
const index = options.findIndex((o) => o?.content === "Add Group") + 1 || options.length;
|
||||
@@ -1235,7 +1272,9 @@ function addConvertToGroupOptions() {
|
||||
};
|
||||
|
||||
// Add to nodes
|
||||
// @ts-ignore
|
||||
const getNodeMenuOptions = LGraphCanvas.prototype.getNodeMenuOptions;
|
||||
// @ts-ignore
|
||||
LGraphCanvas.prototype.getNodeMenuOptions = function (node) {
|
||||
const options = getNodeMenuOptions.apply(this, arguments);
|
||||
if (!GroupNodeHandler.isGroupNode(node)) {
|
||||
@@ -158,11 +158,11 @@ export function mergeIfValid(output, config2, forceUpdate, recreateWidget, confi
|
||||
}
|
||||
|
||||
if (config1[0] instanceof Array) {
|
||||
if (!isValidCombo(config1[0], config2[0])) return false;
|
||||
if (!isValidCombo(config1[0], config2[0])) return;
|
||||
} else if (config1[0] !== config2[0]) {
|
||||
// Types dont match
|
||||
console.log(`connection rejected: types dont match`, config1[0], config2[0]);
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
const keys = new Set([...Object.keys(config1[1] ?? {}), ...Object.keys(config2[1] ?? {})]);
|
||||
@@ -192,7 +192,7 @@ export function mergeIfValid(output, config2, forceUpdate, recreateWidget, confi
|
||||
const theirMax = config2[1]?.["max"];
|
||||
if (theirMax != null && v1 > theirMax) {
|
||||
console.log("connection rejected: min > max", v1, theirMax);
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
getCustomConfig()[k] = v1 == null ? v2 : v2 == null ? v1 : Math.max(v1, v2);
|
||||
continue;
|
||||
@@ -200,7 +200,7 @@ export function mergeIfValid(output, config2, forceUpdate, recreateWidget, confi
|
||||
const theirMin = config2[1]?.["min"];
|
||||
if (theirMin != null && v1 < theirMin) {
|
||||
console.log("connection rejected: max < min", v1, theirMin);
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
getCustomConfig()[k] = v1 == null ? v2 : v2 == null ? v1 : Math.min(v1, v2);
|
||||
continue;
|
||||
@@ -221,7 +221,7 @@ export function mergeIfValid(output, config2, forceUpdate, recreateWidget, confi
|
||||
}
|
||||
if (v1 % v2) {
|
||||
console.log("connection rejected: steps not divisible", "current:", v1, "new:", v2);
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
step = v1;
|
||||
@@ -233,7 +233,7 @@ export function mergeIfValid(output, config2, forceUpdate, recreateWidget, confi
|
||||
}
|
||||
|
||||
console.log(`connection rejected: config ${k} values dont match`, v1, v2);
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -302,7 +302,7 @@ app.registerExtension({
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//Convert.. main menu
|
||||
if (toInput.length) {
|
||||
if (useConversionSubmenusSetting.value) {
|
||||
|
||||
9
src/types/litegraph.d.ts
vendored
9
src/types/litegraph.d.ts
vendored
@@ -52,6 +52,9 @@ export type WidgetCallback<T extends IWidget = IWidget> = (
|
||||
) => void;
|
||||
|
||||
export interface IWidget<TValue = any, TOptions = any> {
|
||||
// linked widgets, e.g. seed+seedControl
|
||||
linkedWidgets: IWidget[];
|
||||
|
||||
name: string | null;
|
||||
value: TValue;
|
||||
options?: TOptions;
|
||||
@@ -162,6 +165,7 @@ export declare class LGraph {
|
||||
static supported_types: string[];
|
||||
static STATUS_STOPPED: 1;
|
||||
static STATUS_RUNNING: 2;
|
||||
extra: any;
|
||||
|
||||
constructor(o?: object);
|
||||
|
||||
@@ -407,6 +411,11 @@ export type SerializedLGraphNode<T extends LGraphNode = LGraphNode> = {
|
||||
|
||||
/** https://github.com/jagenjo/litegraph.js/blob/master/guides/README.md#lgraphnode */
|
||||
export declare class LGraphNode {
|
||||
// Used in group node
|
||||
setInnerNodes(nodes: any) {
|
||||
throw new Error("Method not implemented.");
|
||||
}
|
||||
|
||||
static title_color: string;
|
||||
static title: string;
|
||||
static type: null | string;
|
||||
|
||||
Reference in New Issue
Block a user