Files
kk8bit-KayTool/web/quickaddsetget.js
T
2025-05-15 19:07:06 +08:00

178 lines
7.3 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { app } from "../../../scripts/app.js";
import { api } from "../../../scripts/api.js";
const UNSUPPORTED_NODES = new Set(["Group", "Reroute", "Note"]);
function addNode(name, nextTo, options = {}) {
options = { side: "left", select: true, shiftY: 0, shiftX: 0, ...options };
const node = LiteGraph.createNode(name);
app.graph.add(node);
node.pos = [
options.side === "left" ? nextTo.pos[0] - (node.size[0] + options.offset) : nextTo.pos[0] + nextTo.size[0] + options.offset,
nextTo.pos[1] + options.shiftY,
];
if (options.select) {
app.canvas.selectNode(node, false);
}
return node;
}
function kayGetUpstreamNodes(node, graph) {
const upstreamNodes = new Set();
function traverse(node) {
if (!node.inputs) return;
for (const input of node.inputs) {
if (input.link) {
const link = graph.links[input.link];
if (link) {
const originNode = graph._nodes_by_id[link.origin_id];
if (originNode && !upstreamNodes.has(originNode)) {
upstreamNodes.add(originNode);
traverse(originNode);
}
}
}
}
}
traverse(node);
return Array.from(upstreamNodes);
}
function kayGetOutputNodes(nodes) {
return (nodes?.filter((n) => n.mode != LiteGraph.NEVER && n.constructor.nodeData?.output_node) || []);
}
function kayRecursiveAddNodes(nodeId, oldOutput, newOutput) {
let currentId = nodeId;
let currentNode = oldOutput[currentId];
if (!currentNode || newOutput[currentId]) return;
newOutput[currentId] = currentNode;
for (const inputValue of Object.values(currentNode.inputs || {})) {
if (Array.isArray(inputValue)) {
kayRecursiveAddNodes(inputValue[0], oldOutput, newOutput);
}
}
return newOutput;
}
const KayToolState = {
queueNodeIds: null,
mousePos: null,
activeGroup: null
};
async function kayExecuteNodes(graph, nodesToRun) {
KayToolState.queueNodeIds = nodesToRun.map(n => n.id);
try {
return await app.queuePrompt(0);
} finally {
KayToolState.queueNodeIds = null;
}
}
app.registerExtension({
name: "KayTool.QuickAdd",
setup() {
const originalApiQueuePrompt = api.queuePrompt;
api.queuePrompt = async function (index, prompt) {
if (KayToolState.queueNodeIds?.length && prompt.output) {
const oldOutput = prompt.output;
let newOutput = {};
for (const queueNodeId of KayToolState.queueNodeIds) {
kayRecursiveAddNodes(String(queueNodeId), oldOutput, newOutput);
}
prompt.output = newOutput;
}
return originalApiQueuePrompt.apply(this, [index, prompt]);
};
const originalDraw = LGraphCanvas.prototype.draw;
LGraphCanvas.prototype.draw = function() {
if (this.canvas_mouse) {
KayToolState.mousePos = [this.canvas_mouse[0], this.canvas_mouse[1]];
KayToolState.activeGroup = app.graph.getGroupOnPos(...KayToolState.mousePos);
}
return originalDraw.apply(this, arguments);
};
const originalGetCanvasMenuOptions = LGraphCanvas.prototype.getCanvasMenuOptions;
LGraphCanvas.prototype.getCanvasMenuOptions = function() {
const options = originalGetCanvasMenuOptions.apply(this, arguments);
const showRunOption = app.ui.settings.getSettingValue("KayTool.ShowRunOption");
if (KayToolState.activeGroup && KayToolState.mousePos && showRunOption) {
const groupNodes = KayToolState.activeGroup._nodes || [];
if (groupNodes.length > 0) {
const allNodesToRun = new Set(groupNodes);
groupNodes.forEach(node => {
const upstream = kayGetUpstreamNodes(node, app.graph);
upstream.forEach(upNode => allNodesToRun.add(upNode));
});
const nodesToRun = Array.from(allNodesToRun);
const outputNodes = kayGetOutputNodes(nodesToRun);
options.unshift({
content: "𝙆 ▶️ Run (Group)",
disabled: !outputNodes.length,
callback: async () => {
await kayExecuteNodes(app.graph, nodesToRun);
app.graph.setDirtyCanvas(true, true);
}
});
}
}
return options;
};
document.addEventListener('keydown', async (e) => {
const shiftR = app.ui.settings.getSettingValue("KayTool.ShiftR");
if (!shiftR) return;
if (e.altKey && (e.key === 'r' || e.key === '®')) {
e.preventDefault();
e.stopPropagation();
const selectedNodes = app.canvas.selected_nodes ? Object.values(app.canvas.selected_nodes) : [];
if (selectedNodes.length === 0) return;
const selectedNode = selectedNodes[0];
if (UNSUPPORTED_NODES.has(selectedNode.type)) return;
const upstreamNodes = kayGetUpstreamNodes(selectedNode, app.graph);
const nodesToRun = [selectedNode, ...upstreamNodes];
const outputNodes = kayGetOutputNodes(nodesToRun);
if (!outputNodes.length) return;
await kayExecuteNodes(app.graph, nodesToRun);
app.graph.setDirtyCanvas(true, true);
}
});
},
beforeRegisterNodeDef(nodeType, nodeData) {
if (nodeData.input?.required && !UNSUPPORTED_NODES.has(nodeData.name)) {
const originalGetExtraMenuOptions = nodeType.prototype.getExtraMenuOptions;
nodeType.prototype.getExtraMenuOptions = function(_, options) {
originalGetExtraMenuOptions?.apply(this, arguments);
if (UNSUPPORTED_NODES.has(this.type)) return;
const upstreamNodes = kayGetUpstreamNodes(this, app.graph);
const nodesToRun = [this, ...upstreamNodes];
const outputNodes = kayGetOutputNodes(nodesToRun);
const showRunOption = app.ui.settings.getSettingValue("KayTool.ShowRunOption");
const showSetGetOptions = app.ui.settings.getSettingValue("KayTool.ShowSetGetOptions");
if (showRunOption) {
options.unshift({
content: "𝙆 ▶️ Run",
disabled: !outputNodes.length,
callback: async () => {
await kayExecuteNodes(app.graph, nodesToRun);
app.graph.setDirtyCanvas(true, true);
}
});
}
if (showSetGetOptions) {
options.unshift(
{ content: "𝙆 🛜 Set", callback: () => { addNode("KaySetNode", this, { side: "right", offset: 20 }); } },
{ content: "𝙆 🛜 Get", callback: () => { addNode("KayGetNode", this, { side: "left", offset: 20 }); } }
);
}
};
}
}
});