137 lines
3.6 KiB
JavaScript
137 lines
3.6 KiB
JavaScript
import { app } from "../../scripts/app.js";
|
|
|
|
const MAX = 10;
|
|
const TARGETS = new Set([
|
|
"Texturaizer_SwitchSmart",
|
|
"Texturaizer_SwitchLazy",
|
|
]);
|
|
|
|
function getInput(node, name) {
|
|
return node.inputs?.find(i => i?.name === name);
|
|
}
|
|
|
|
function getDataInputs(node) {
|
|
return node.inputs?.filter(i => typeof i?.name === "string" && /^input\d+$/.test(i.name)) ?? [];
|
|
}
|
|
|
|
function visibleInputCount(node) {
|
|
const inputs = getDataInputs(node);
|
|
let lastLinked = 0;
|
|
for (let i = 0; i < inputs.length; i++) {
|
|
if (inputs[i].link != null) lastLinked = i + 1;
|
|
}
|
|
// Always show at least input1; if inputN is linked, show next one too (up to MAX)
|
|
return Math.min(MAX, Math.max(1, lastLinked + 1));
|
|
}
|
|
|
|
function ensureInputs(node, count) {
|
|
if (!getInput(node, "input1")) node.addInput("input1", "*");
|
|
|
|
for (let i = 2; i <= count; i++) {
|
|
if (!getInput(node, `input${i}`)) node.addInput(`input${i}`, "*");
|
|
}
|
|
|
|
// remove from the end only if unlinked
|
|
for (let i = MAX; i > count; i--) {
|
|
const inp = getInput(node, `input${i}`);
|
|
if (inp && inp.link == null) {
|
|
node.removeInput(node.inputs.indexOf(inp));
|
|
}
|
|
}
|
|
}
|
|
|
|
/* -------------------- Trigger widgets (SwitchSmart only) -------------------- */
|
|
|
|
function takeTriggerValues(node) {
|
|
const map = {};
|
|
for (const w of node.widgets || []) {
|
|
if (typeof w?.name === "string" && /^trigger\d+$/.test(w.name)) {
|
|
map[w.name] = w.value ?? "";
|
|
}
|
|
}
|
|
return map;
|
|
}
|
|
|
|
function removeAllTriggerWidgets(node) {
|
|
if (!node.widgets) return;
|
|
node.widgets = node.widgets.filter(w => !(typeof w?.name === "string" && /^trigger\d+$/.test(w.name)));
|
|
if (node.widgets_values) delete node.widgets_values;
|
|
}
|
|
|
|
function addTriggerWidgets(node, count, prevValues) {
|
|
for (let i = 1; i <= count; i++) {
|
|
const name = `trigger${i}`;
|
|
const value = prevValues?.[name] ?? "";
|
|
|
|
const w = node.addWidget(
|
|
"text",
|
|
name,
|
|
value,
|
|
(v) => { w.value = v; },
|
|
{ multiline: false }
|
|
);
|
|
|
|
// Ensure stable identity for serialization + editing
|
|
w.name = name;
|
|
w.value = value;
|
|
}
|
|
}
|
|
|
|
function refreshTriggersIfSmart(node, count) {
|
|
if (node.comfyClass !== "Texturaizer_SwitchSmart") return;
|
|
const prev = takeTriggerValues(node);
|
|
removeAllTriggerWidgets(node);
|
|
addTriggerWidgets(node, count, prev);
|
|
}
|
|
|
|
/* -------------------- Auto shrink (only reduces height) -------------------- */
|
|
|
|
function autoShrink(node) {
|
|
const min = node.computeSize?.();
|
|
if (!Array.isArray(min) || min.length !== 2) return;
|
|
|
|
const minH = min[1];
|
|
if (typeof minH === "number" && node.size?.[1] > minH) {
|
|
node.size[1] = minH;
|
|
}
|
|
}
|
|
|
|
/* -------------------- refresh -------------------- */
|
|
|
|
function refresh(node) {
|
|
const count = visibleInputCount(node);
|
|
ensureInputs(node, count);
|
|
refreshTriggersIfSmart(node, count);
|
|
autoShrink(node);
|
|
node.setDirtyCanvas(true, true);
|
|
}
|
|
|
|
app.registerExtension({
|
|
name: "texturaizer.switchSmart.dynamic",
|
|
|
|
beforeRegisterNodeDef(nodeType, nodeData) {
|
|
if (!TARGETS.has(nodeData.name)) return;
|
|
|
|
const onCreated = nodeType.prototype.onNodeCreated;
|
|
nodeType.prototype.onNodeCreated = function () {
|
|
const r = onCreated?.apply(this, arguments);
|
|
setTimeout(() => refresh(this), 0);
|
|
return r;
|
|
};
|
|
|
|
const onConnectionsChange = nodeType.prototype.onConnectionsChange;
|
|
nodeType.prototype.onConnectionsChange = function () {
|
|
const r = onConnectionsChange?.apply(this, arguments);
|
|
refresh(this);
|
|
return r;
|
|
};
|
|
|
|
const configure = nodeType.prototype.configure;
|
|
nodeType.prototype.configure = function () {
|
|
const r = configure?.apply(this, arguments);
|
|
setTimeout(() => refresh(this), 0);
|
|
return r;
|
|
};
|
|
}
|
|
});
|