154 lines
5.4 KiB
JavaScript
154 lines
5.4 KiB
JavaScript
import { app } from '../../../../scripts/app.js';
|
|
export const nodesFromLink = (node, link) => {
|
|
const fromNode = app.graph.getNodeById(link.origin_id);
|
|
const toNode = app.graph.getNodeById(link.target_id);
|
|
let tp = 'error';
|
|
if (fromNode.id === node.id) {
|
|
tp = 'outgoing';
|
|
}
|
|
else if (toNode.id === node.id) {
|
|
tp = 'incoming';
|
|
}
|
|
return { to: toNode, from: fromNode, type: tp };
|
|
};
|
|
export const setupDynamicConnections = (nodeType, prefix, inputType, opts = undefined) => {
|
|
const options = Object.assign({
|
|
separator: '_',
|
|
start_index: 1,
|
|
}, opts || {});
|
|
const onNodeCreated = nodeType.prototype.onNodeCreated;
|
|
const inputList = typeof inputType === 'object';
|
|
nodeType.prototype.onNodeCreated = function () {
|
|
const r = onNodeCreated ? onNodeCreated.apply(this, []) : undefined;
|
|
this.addInput(`${prefix}${options.separator}${options.start_index}`, inputList ? '*' : inputType);
|
|
return r;
|
|
};
|
|
const onConnectionsChange = nodeType.prototype.onConnectionsChange;
|
|
nodeType.prototype.onConnectionsChange = function (...args) {
|
|
const [type, slotIndex, isConnected, link, ioSlot] = args;
|
|
options.link = link;
|
|
options.ioSlot = ioSlot;
|
|
const r = onConnectionsChange
|
|
? onConnectionsChange.apply(this, [
|
|
type,
|
|
slotIndex,
|
|
isConnected,
|
|
link,
|
|
ioSlot,
|
|
])
|
|
: undefined;
|
|
options.DEBUG = {
|
|
node: this,
|
|
type,
|
|
slotIndex,
|
|
isConnected,
|
|
link,
|
|
ioSlot,
|
|
};
|
|
const oldSize = [this.size[0], this.size[1]];
|
|
const oldComputedSize = this.computeSize();
|
|
dynamicConnection(this, slotIndex, isConnected, `${prefix}${options.separator}`, inputType, options);
|
|
for (const widget of this.widgets || []) {
|
|
delete widget.y;
|
|
delete widget.last_y;
|
|
delete widget.computedHeight;
|
|
}
|
|
const newComputedSize = this.computeSize();
|
|
this.setSize([
|
|
oldSize[0],
|
|
oldSize[1] + newComputedSize[1] - oldComputedSize[1],
|
|
]);
|
|
return r;
|
|
};
|
|
};
|
|
export const dynamicConnection = (node, index, connected, connectionPrefix = 'input_', connectionType = '*', opts = undefined) => {
|
|
const options = Object.assign({
|
|
start_index: 1,
|
|
}, opts || {});
|
|
const isDynamicInput = (inputName) => inputName.startsWith(connectionPrefix);
|
|
if (node.inputs.length > 0 && !isDynamicInput(node.inputs[index].name)) {
|
|
return;
|
|
}
|
|
const listConnection = typeof connectionType === 'object';
|
|
const conType = listConnection ? '*' : connectionType;
|
|
const nameArray = options.nameArray || [];
|
|
const clean_inputs = () => {
|
|
if (node.inputs.length === 0)
|
|
return;
|
|
let i_count = node.inputs?.length || 0;
|
|
const to_remove = [];
|
|
for (let n = 1; n < node.inputs.length; n++) {
|
|
const element = node.inputs[n];
|
|
if (!element.link && isDynamicInput(element.name)) {
|
|
if (node.widgets) {
|
|
const w = node.widgets.find((w) => w.name === element.name);
|
|
if (w) {
|
|
w.onRemoved?.();
|
|
node.widgets.length = node.widgets.length - 1;
|
|
}
|
|
}
|
|
to_remove.push(n);
|
|
}
|
|
}
|
|
for (let i = 0; i < to_remove.length; i++) {
|
|
const id = to_remove[i];
|
|
node.removeInput(id);
|
|
i_count -= 1;
|
|
}
|
|
node.inputs.length = i_count;
|
|
i_count = node.inputs?.length || 0;
|
|
let prefixed_idx = options.start_index;
|
|
for (let i = 0; i < node.inputs.length; i++) {
|
|
let name = '';
|
|
if (isDynamicInput(node.inputs[i].name)) {
|
|
name = `${connectionPrefix}${prefixed_idx}`;
|
|
prefixed_idx += 1;
|
|
}
|
|
else {
|
|
name = node.inputs[i].name;
|
|
}
|
|
if (nameArray.length > 0) {
|
|
name = i < nameArray.length ? nameArray[i] : name;
|
|
}
|
|
node.inputs[i].label = node.inputs[i].label || name;
|
|
node.inputs[i].name = name;
|
|
}
|
|
};
|
|
if (!connected) {
|
|
if (!options.link) {
|
|
clean_inputs();
|
|
}
|
|
else {
|
|
if (!options.ioSlot.link) {
|
|
node.connectionTransit = true;
|
|
}
|
|
else {
|
|
node.connectionTransit = false;
|
|
clean_inputs();
|
|
}
|
|
}
|
|
}
|
|
if (connected) {
|
|
if (options.link) {
|
|
const link = nodesFromLink(node, options.link);
|
|
if (link.type === 'outgoing')
|
|
return;
|
|
}
|
|
else {
|
|
}
|
|
if (node.connectionTransit) {
|
|
node.connectionTransit = false;
|
|
}
|
|
clean_inputs();
|
|
if (node.inputs.length === 0)
|
|
return;
|
|
if (node.inputs[node.inputs.length - 1].link !== null) {
|
|
const nextIndex = node.inputs.reduce((acc, cur) => isDynamicInput(cur.name) ? ++acc : acc, 0);
|
|
const name = nextIndex < nameArray.length
|
|
? nameArray[nextIndex]
|
|
: `${connectionPrefix}${nextIndex + options.start_index}`;
|
|
node.addInput(name, conType);
|
|
}
|
|
}
|
|
};
|