mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2026-02-16 16:32:34 +08:00
wip group manage
This commit is contained in:
parent
080ef75c31
commit
bf217dc886
@ -1,5 +1,6 @@
|
|||||||
import { app } from "../../scripts/app.js";
|
import { app } from "../../scripts/app.js";
|
||||||
import { api } from "../../scripts/api.js";
|
import { api } from "../../scripts/api.js";
|
||||||
|
import { $el, ComfyDialog } from "../../scripts/ui.js";
|
||||||
import { mergeIfValid } from "./widgetInputs.js";
|
import { mergeIfValid } from "./widgetInputs.js";
|
||||||
|
|
||||||
const GROUP = Symbol();
|
const GROUP = Symbol();
|
||||||
@ -31,6 +32,110 @@ const Workflow = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$el("style", {
|
||||||
|
parent: document.body,
|
||||||
|
textContent: `
|
||||||
|
.comfy-group-manage {
|
||||||
|
background: var(--bg-color);
|
||||||
|
color: var(--fg-color);
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
padding: 0;
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
border-radius: 10px;
|
||||||
|
display: flex;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comfy-group-manage header {
|
||||||
|
flex-basis: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comfy-group-manage h3 {
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comfy-group-manage h3, .comfy-group-manage h4 {
|
||||||
|
font-weight: normal;
|
||||||
|
padding: 10px;
|
||||||
|
margin: 0;
|
||||||
|
border-bottom: 1px solid var(--border-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.comfy-group-manage ul {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
list-style: none;
|
||||||
|
background: var(--tr-odd-bg-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.comfy-group-manage li {
|
||||||
|
padding: 10px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comfy-group-manage li:hover, .comfy-group-manage li.selected {
|
||||||
|
background: var(--tr-even-bg-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.comfy-group-manage li.selected {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
|
||||||
|
.comfy-group-manage main {
|
||||||
|
border-left: 1px solid var(--border-color);
|
||||||
|
flex: auto;
|
||||||
|
background: var(--comfy-menu-bg);
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
});
|
||||||
|
|
||||||
|
class ManageGroupDialog extends ComfyDialog {
|
||||||
|
constructor(app) {
|
||||||
|
super();
|
||||||
|
this.app = app;
|
||||||
|
this.element = $el("dialog.comfy-group-manage", {
|
||||||
|
parent: document.body,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
show() {
|
||||||
|
const groupNodes = Object.keys(app.graph.extra?.groupNodes ?? {}).concat([
|
||||||
|
"something",
|
||||||
|
"another",
|
||||||
|
"prompt",
|
||||||
|
"chatgpt",
|
||||||
|
"upscale 4x",
|
||||||
|
]);
|
||||||
|
if (!groupNodes.length) return;
|
||||||
|
|
||||||
|
let selected;
|
||||||
|
const items = groupNodes.map((g) =>
|
||||||
|
$el("li", {
|
||||||
|
textContent: g,
|
||||||
|
onclick: (e) => {
|
||||||
|
if (selected) {
|
||||||
|
selected.classList.remove("selected");
|
||||||
|
}
|
||||||
|
selected = e.target;
|
||||||
|
selected.classList.add("selected");
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
const left = $el("div.comfy-group-manage-list", $el("ul", items));
|
||||||
|
|
||||||
|
const inputs = $el("div", [$el("h4", "Inputs")]);
|
||||||
|
const widgets = $el("div", [$el("h4", "Widgets")]);
|
||||||
|
const outputs = $el("div", [$el("h4", "Outputs")]);
|
||||||
|
const main = $el("main", [inputs, widgets, outputs]);
|
||||||
|
|
||||||
|
this.element.replaceChildren($el("header", $el("h3", "Group Nodes")), left, main);
|
||||||
|
this.element.showModal();
|
||||||
|
items[0].click();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class GroupNodeBuilder {
|
class GroupNodeBuilder {
|
||||||
constructor(nodes) {
|
constructor(nodes) {
|
||||||
this.nodes = nodes;
|
this.nodes = nodes;
|
||||||
@ -755,12 +860,23 @@ export class GroupNodeHandler {
|
|||||||
let optionIndex = options.findIndex((o) => o.content === "Outputs");
|
let optionIndex = options.findIndex((o) => o.content === "Outputs");
|
||||||
if (optionIndex === -1) optionIndex = options.length;
|
if (optionIndex === -1) optionIndex = options.length;
|
||||||
else optionIndex++;
|
else optionIndex++;
|
||||||
options.splice(optionIndex, 0, null, {
|
options.splice(
|
||||||
content: "Convert to nodes",
|
optionIndex,
|
||||||
callback: () => {
|
0,
|
||||||
return this.convertToNodes();
|
null,
|
||||||
|
{
|
||||||
|
content: "Convert to nodes",
|
||||||
|
callback: () => {
|
||||||
|
return this.convertToNodes();
|
||||||
|
},
|
||||||
},
|
},
|
||||||
});
|
{
|
||||||
|
content: "Manage Group Node",
|
||||||
|
callback: () => {
|
||||||
|
new ManageGroupDialog(app).show(this.type);
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Draw custom collapse icon to identity this as a group
|
// Draw custom collapse icon to identity this as a group
|
||||||
@ -1024,7 +1140,7 @@ export class GroupNodeHandler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function addConvertToGroupOptions() {
|
function addConvertToGroupOptions() {
|
||||||
function addOption(options, index) {
|
function addConvertOption(options, index) {
|
||||||
const selected = Object.values(app.canvas.selected_nodes ?? {});
|
const selected = Object.values(app.canvas.selected_nodes ?? {});
|
||||||
const disabled = selected.length < 2 || selected.find((n) => GroupNodeHandler.isGroupNode(n));
|
const disabled = selected.length < 2 || selected.find((n) => GroupNodeHandler.isGroupNode(n));
|
||||||
options.splice(index + 1, null, {
|
options.splice(index + 1, null, {
|
||||||
@ -1036,12 +1152,25 @@ function addConvertToGroupOptions() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function addManageOption(options, index) {
|
||||||
|
const groups = app.graph.extra?.groupNodes;
|
||||||
|
const disabled = !groups || !Object.keys(groups).length;
|
||||||
|
options.splice(index + 1, null, {
|
||||||
|
content: `Manage Group Nodes`,
|
||||||
|
disabled,
|
||||||
|
callback: () => {
|
||||||
|
new ManageGroupDialog(app).show();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// Add to canvas
|
// Add to canvas
|
||||||
const getCanvasMenuOptions = LGraphCanvas.prototype.getCanvasMenuOptions;
|
const getCanvasMenuOptions = LGraphCanvas.prototype.getCanvasMenuOptions;
|
||||||
LGraphCanvas.prototype.getCanvasMenuOptions = function () {
|
LGraphCanvas.prototype.getCanvasMenuOptions = function () {
|
||||||
const options = getCanvasMenuOptions.apply(this, arguments);
|
const options = getCanvasMenuOptions.apply(this, arguments);
|
||||||
const index = options.findIndex((o) => o?.content === "Add Group") + 1 || options.length;
|
const index = options.findIndex((o) => o?.content === "Add Group") + 1 || options.length;
|
||||||
addOption(options, index);
|
addConvertOption(options, index);
|
||||||
|
addManageOption(options, index + 1);
|
||||||
return options;
|
return options;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1051,7 +1180,7 @@ function addConvertToGroupOptions() {
|
|||||||
const options = getNodeMenuOptions.apply(this, arguments);
|
const options = getNodeMenuOptions.apply(this, arguments);
|
||||||
if (!GroupNodeHandler.isGroupNode(node)) {
|
if (!GroupNodeHandler.isGroupNode(node)) {
|
||||||
const index = options.findIndex((o) => o?.content === "Outputs") + 1 || options.length - 1;
|
const index = options.findIndex((o) => o?.content === "Outputs") + 1 || options.length - 1;
|
||||||
addOption(options, index);
|
addConvertOption(options, index);
|
||||||
}
|
}
|
||||||
return options;
|
return options;
|
||||||
};
|
};
|
||||||
@ -1082,3 +1211,7 @@ const ext = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
app.registerExtension(ext);
|
app.registerExtension(ext);
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
new ManageGroupDialog(app).show();
|
||||||
|
}, 200);
|
||||||
@ -1,5 +1,18 @@
|
|||||||
import {api} from "./api.js";
|
import {api} from "./api.js";
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param { string } tag HTML Element Tag and optional classes e.g. div.class1.class2
|
||||||
|
* @param { string | Element | Element[] | {
|
||||||
|
* parent?: Element,
|
||||||
|
* $?: (el: Element) => void,
|
||||||
|
* dataset?: DOMStringMap,
|
||||||
|
* style?: CSSStyleDeclaration,
|
||||||
|
* for?: string
|
||||||
|
* } | undefined } propsOrChildren
|
||||||
|
* @param { Element[] | undefined } children
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
export function $el(tag, propsOrChildren, children) {
|
export function $el(tag, propsOrChildren, children) {
|
||||||
const split = tag.split(".");
|
const split = tag.split(".");
|
||||||
const element = document.createElement(split.shift());
|
const element = document.createElement(split.shift());
|
||||||
@ -8,6 +21,11 @@ export function $el(tag, propsOrChildren, children) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (propsOrChildren) {
|
if (propsOrChildren) {
|
||||||
|
if (typeof propsOrChildren === "string") {
|
||||||
|
propsOrChildren = { textContent: propsOrChildren };
|
||||||
|
} else if (propsOrChildren instanceof Element) {
|
||||||
|
propsOrChildren = [propsOrChildren];
|
||||||
|
}
|
||||||
if (Array.isArray(propsOrChildren)) {
|
if (Array.isArray(propsOrChildren)) {
|
||||||
element.append(...propsOrChildren);
|
element.append(...propsOrChildren);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user