mirror of
https://github.com/justUmen/Bjornulf_custom_nodes.git
synced 2026-03-21 20:52:11 -03:00
first commit
This commit is contained in:
29
web/js/BJORNULF_TYPES.js.txt
Normal file
29
web/js/BJORNULF_TYPES.js.txt
Normal file
@@ -0,0 +1,29 @@
|
||||
import { app } from "../../../scripts/app.js";
|
||||
|
||||
app.registerExtension({
|
||||
name: "Bjornulf.CustomBjornulfType",
|
||||
async beforeRegisterNodeDef(nodeType, nodeData, app) {
|
||||
if (nodeData.name === "Bjornulf_WriteImageCharacters") {
|
||||
const onNodeCreated = nodeType.prototype.onNodeCreated;
|
||||
nodeType.prototype.onNodeCreated = function () {
|
||||
onNodeCreated?.apply(this, arguments);
|
||||
const myInput = this.inputs.find(input => input.name === "BJORNULF_CHARACTER");
|
||||
if (myInput) {
|
||||
myInput.type = "BJORNULF_CHARACTER";
|
||||
}
|
||||
};
|
||||
}
|
||||
else if (nodeData.name === "Bjornulf_WriteImageCharacter") {
|
||||
|
||||
}
|
||||
},
|
||||
async setup(app) {
|
||||
app.registerCustomNodeType("BJORNULF_CHARACTER", (value) => {
|
||||
return {
|
||||
type: "BJORNULF_CHARACTER",
|
||||
data: { value: value || "" },
|
||||
name: "BJORNULF_CHARACTER"
|
||||
};
|
||||
});
|
||||
}
|
||||
});
|
||||
52
web/js/CUSTOM_STRING.js.txt
Normal file
52
web/js/CUSTOM_STRING.js.txt
Normal file
@@ -0,0 +1,52 @@
|
||||
import { app } from "../../../scripts/app.js";
|
||||
|
||||
app.registerExtension({
|
||||
name: "Bjornulf.CustomStringType",
|
||||
async beforeRegisterNodeDef(nodeType, nodeData, app) {
|
||||
if (nodeData.name === "Bjornulf_WriteImageAllInOne") {
|
||||
const onNodeCreated = nodeType.prototype.onNodeCreated;
|
||||
nodeType.prototype.onNodeCreated = function () {
|
||||
onNodeCreated?.apply(this, arguments);
|
||||
const locationInput = this.inputs.find(input => input.name === "location");
|
||||
if (locationInput) {
|
||||
locationInput.type = "CUSTOM_STRING";
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
async setup(app) {
|
||||
app.registerCustomNodeType("CUSTOM_STRING", (value) => {
|
||||
return {
|
||||
type: "CustomStringType",
|
||||
data: { value: value || "" },
|
||||
name: "CustomStringType"
|
||||
};
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// Override the default onConnectionCreated method
|
||||
const originalOnConnectionCreated = LGraphCanvas.prototype.onConnectionCreated;
|
||||
LGraphCanvas.prototype.onConnectionCreated = function(connection, e, node_for_click) {
|
||||
if (node_for_click && node_for_click.type === "WriteImageAllInOne" && connection.targetInput.name === "location") {
|
||||
// Check if the connected node is not already a CustomString
|
||||
if (connection.origin_node.type !== "CustomString") {
|
||||
// Create a new CustomString node
|
||||
const customStringNode = LiteGraph.createNode("CustomString");
|
||||
// Position the new node
|
||||
customStringNode.pos = [connection.origin_node.pos[0] + 200, connection.origin_node.pos[1]];
|
||||
this.graph.add(customStringNode);
|
||||
|
||||
// Connect the new CustomString node
|
||||
connection.origin_node.connect(connection.origin_slot, customStringNode, 0);
|
||||
customStringNode.connect(0, node_for_click, connection.target_slot);
|
||||
|
||||
// Remove the original connection
|
||||
connection.origin_node.disconnectOutput(connection.origin_slot, node_for_click);
|
||||
|
||||
return true; // Prevent the original connection
|
||||
}
|
||||
}
|
||||
return originalOnConnectionCreated.apply(this, arguments);
|
||||
};
|
||||
52
web/js/combine_texts.js
Normal file
52
web/js/combine_texts.js
Normal file
@@ -0,0 +1,52 @@
|
||||
import { app } from "../../../scripts/app.js";
|
||||
|
||||
app.registerExtension({
|
||||
name: "Bjornulf.CombineTexts",
|
||||
async nodeCreated(node) {
|
||||
if (node.comfyClass === "Bjornulf_CombineTexts") {
|
||||
const updateInputs = () => {
|
||||
const numInputsWidget = node.widgets.find(w => w.name === "number_of_inputs");
|
||||
if (!numInputsWidget) return;
|
||||
|
||||
const numInputs = numInputsWidget.value;
|
||||
|
||||
// Initialize node.inputs if it doesn't exist
|
||||
if (!node.inputs) {
|
||||
node.inputs = [];
|
||||
}
|
||||
|
||||
// Filter existing text inputs
|
||||
const existingInputs = node.inputs.filter(input => input.name.startsWith('text_'));
|
||||
|
||||
// Determine if we need to add or remove inputs
|
||||
if (existingInputs.length < numInputs) {
|
||||
// Add new text inputs if not enough existing
|
||||
for (let i = existingInputs.length + 1; i <= numInputs; i++) {
|
||||
const inputName = `text_${i}`;
|
||||
if (!node.inputs.find(input => input.name === inputName)) {
|
||||
node.addInput(inputName, "STRING");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Remove excess text inputs if too many
|
||||
node.inputs = node.inputs.filter(input => !input.name.startsWith('text_') || parseInt(input.name.split('_')[1]) <= numInputs);
|
||||
}
|
||||
|
||||
node.setSize(node.computeSize());
|
||||
};
|
||||
|
||||
// Move number_of_inputs to the top initially
|
||||
const numInputsWidget = node.widgets.find(w => w.name === "number_of_inputs");
|
||||
if (numInputsWidget) {
|
||||
node.widgets = [numInputsWidget, ...node.widgets.filter(w => w !== numInputsWidget)];
|
||||
numInputsWidget.callback = () => {
|
||||
updateInputs();
|
||||
app.graph.setDirtyCanvas(true);
|
||||
};
|
||||
}
|
||||
|
||||
// Delay the initial update to ensure node is fully initialized
|
||||
setTimeout(updateInputs, 0);
|
||||
}
|
||||
}
|
||||
});
|
||||
52
web/js/loop_texts.js
Normal file
52
web/js/loop_texts.js
Normal file
@@ -0,0 +1,52 @@
|
||||
import { app } from "../../../scripts/app.js";
|
||||
|
||||
app.registerExtension({
|
||||
name: "Bjornulf.LoopTexts",
|
||||
async nodeCreated(node) {
|
||||
if (node.comfyClass === "Bjornulf_LoopTexts") {
|
||||
const updateInputs = () => {
|
||||
const numInputsWidget = node.widgets.find(w => w.name === "number_of_inputs");
|
||||
if (!numInputsWidget) return;
|
||||
|
||||
const numInputs = numInputsWidget.value;
|
||||
|
||||
// Initialize node.inputs if it doesn't exist
|
||||
if (!node.inputs) {
|
||||
node.inputs = [];
|
||||
}
|
||||
|
||||
// Filter existing text inputs
|
||||
const existingInputs = node.inputs.filter(input => input.name.startsWith('text_'));
|
||||
|
||||
// Determine if we need to add or remove inputs
|
||||
if (existingInputs.length < numInputs) {
|
||||
// Add new text inputs if not enough existing
|
||||
for (let i = existingInputs.length + 1; i <= numInputs; i++) {
|
||||
const inputName = `text_${i}`;
|
||||
if (!node.inputs.find(input => input.name === inputName)) {
|
||||
node.addInput(inputName, "STRING");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Remove excess text inputs if too many
|
||||
node.inputs = node.inputs.filter(input => !input.name.startsWith('text_') || parseInt(input.name.split('_')[1]) <= numInputs);
|
||||
}
|
||||
|
||||
node.setSize(node.computeSize());
|
||||
};
|
||||
|
||||
// Move number_of_inputs to the top initially
|
||||
const numInputsWidget = node.widgets.find(w => w.name === "number_of_inputs");
|
||||
if (numInputsWidget) {
|
||||
node.widgets = [numInputsWidget, ...node.widgets.filter(w => w !== numInputsWidget)];
|
||||
numInputsWidget.callback = () => {
|
||||
updateInputs();
|
||||
app.graph.setDirtyCanvas(true);
|
||||
};
|
||||
}
|
||||
|
||||
// Delay the initial update to ensure node is fully initialized
|
||||
setTimeout(updateInputs, 0);
|
||||
}
|
||||
}
|
||||
});
|
||||
65
web/js/random_model_clip_vae.js
Normal file
65
web/js/random_model_clip_vae.js
Normal file
@@ -0,0 +1,65 @@
|
||||
import { app } from "../../../scripts/app.js";
|
||||
|
||||
app.registerExtension({
|
||||
name: "Bjornulf.RandomModelClipVae",
|
||||
async nodeCreated(node) {
|
||||
if (node.comfyClass === "Bjornulf_RandomModelClipVae") {
|
||||
const updateInputs = () => {
|
||||
const numInputsWidget = node.widgets.find(w => w.name === "number_of_inputs");
|
||||
if (!numInputsWidget) return;
|
||||
|
||||
const numInputs = numInputsWidget.value;
|
||||
|
||||
// Initialize node.inputs if it doesn't exist
|
||||
if (!node.inputs) {
|
||||
node.inputs = [];
|
||||
}
|
||||
|
||||
// Filter existing model, clip, and vae inputs
|
||||
const existingModelInputs = node.inputs.filter(input => input.name.startsWith('model_'));
|
||||
const existingClipInputs = node.inputs.filter(input => input.name.startsWith('clip_'));
|
||||
const existingVaeInputs = node.inputs.filter(input => input.name.startsWith('vae_'));
|
||||
|
||||
// Determine if we need to add or remove inputs
|
||||
if (existingModelInputs.length < numInputs || existingClipInputs.length < numInputs || existingVaeInputs.length < numInputs) {
|
||||
// Add new model, clip, and vae inputs if not enough existing
|
||||
for (let i = Math.max(existingModelInputs.length, existingClipInputs.length, existingVaeInputs.length) + 1; i <= numInputs; i++) {
|
||||
const modelInputName = `model_${i}`;
|
||||
const clipInputName = `clip_${i}`;
|
||||
const vaeInputName = `vae_${i}`;
|
||||
if (!node.inputs.find(input => input.name === modelInputName)) {
|
||||
node.addInput(modelInputName, "MODEL");
|
||||
}
|
||||
if (!node.inputs.find(input => input.name === clipInputName)) {
|
||||
node.addInput(clipInputName, "CLIP");
|
||||
}
|
||||
if (!node.inputs.find(input => input.name === vaeInputName)) {
|
||||
node.addInput(vaeInputName, "VAE");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Remove excess model, clip, and vae inputs if too many
|
||||
node.inputs = node.inputs.filter(input =>
|
||||
(!input.name.startsWith('model_') && !input.name.startsWith('clip_') && !input.name.startsWith('vae_')) ||
|
||||
(parseInt(input.name.split('_')[1]) <= numInputs)
|
||||
);
|
||||
}
|
||||
|
||||
node.setSize(node.computeSize());
|
||||
};
|
||||
|
||||
// Move number_of_inputs to the top initially
|
||||
const numInputsWidget = node.widgets.find(w => w.name === "number_of_inputs");
|
||||
if (numInputsWidget) {
|
||||
node.widgets = [numInputsWidget, ...node.widgets.filter(w => w !== numInputsWidget)];
|
||||
numInputsWidget.callback = () => {
|
||||
updateInputs();
|
||||
app.graph.setDirtyCanvas(true);
|
||||
};
|
||||
}
|
||||
|
||||
// Delay the initial update to ensure node is fully initialized
|
||||
setTimeout(updateInputs, 0);
|
||||
}
|
||||
}
|
||||
});
|
||||
58
web/js/random_texts.js
Normal file
58
web/js/random_texts.js
Normal file
@@ -0,0 +1,58 @@
|
||||
import { app } from "../../../scripts/app.js";
|
||||
|
||||
app.registerExtension({
|
||||
name: "Bjornulf.RandomTexts",
|
||||
async nodeCreated(node) {
|
||||
if (node.comfyClass === "Bjornulf_RandomTexts") {
|
||||
const updateInputs = () => {
|
||||
const numInputsWidget = node.widgets.find(w => w.name === "number_of_inputs");
|
||||
if (!numInputsWidget) return;
|
||||
|
||||
const numInputs = numInputsWidget.value;
|
||||
|
||||
// Initialize node.inputs if it doesn't exist
|
||||
if (!node.inputs) {
|
||||
node.inputs = [];
|
||||
}
|
||||
|
||||
// Filter existing text inputs
|
||||
const existingInputs = node.inputs.filter(input => input.name.startsWith('text_'));
|
||||
|
||||
// Determine if we need to add or remove inputs
|
||||
if (existingInputs.length < numInputs) {
|
||||
// Add new text inputs if not enough existing
|
||||
for (let i = existingInputs.length + 1; i <= numInputs; i++) {
|
||||
const inputName = `text_${i}`;
|
||||
if (!node.inputs.find(input => input.name === inputName)) {
|
||||
node.addInput(inputName, "STRING");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Remove excess text inputs if too many
|
||||
node.inputs = node.inputs.filter(input => !input.name.startsWith('text_') || parseInt(input.name.split('_')[1]) <= numInputs);
|
||||
}
|
||||
|
||||
node.setSize(node.computeSize());
|
||||
};
|
||||
|
||||
// Set seed widget to hidden input
|
||||
const seedWidget = node.widgets.find(w => w.name === "seed");
|
||||
if (seedWidget) {
|
||||
seedWidget.type = "HIDDEN";
|
||||
}
|
||||
|
||||
// Move number_of_inputs to the top initially
|
||||
const numInputsWidget = node.widgets.find(w => w.name === "number_of_inputs");
|
||||
if (numInputsWidget) {
|
||||
node.widgets = [numInputsWidget, ...node.widgets.filter(w => w !== numInputsWidget)];
|
||||
numInputsWidget.callback = () => {
|
||||
updateInputs();
|
||||
app.graph.setDirtyCanvas(true);
|
||||
};
|
||||
}
|
||||
|
||||
// Delay the initial update to ensure node is fully initialized
|
||||
setTimeout(updateInputs, 0);
|
||||
}
|
||||
}
|
||||
});
|
||||
76
web/js/show_float.js
Normal file
76
web/js/show_float.js
Normal file
@@ -0,0 +1,76 @@
|
||||
import { app } from "../../../scripts/app.js";
|
||||
import { ComfyWidgets } from "../../../scripts/widgets.js";
|
||||
|
||||
// Styles for the text area
|
||||
const textAreaStyles = {
|
||||
readOnly: true,
|
||||
opacity: 1,
|
||||
padding: '10px',
|
||||
border: '1px solid #ccc',
|
||||
borderRadius: '5px',
|
||||
backgroundColor: '#222',
|
||||
color: 'Lime',
|
||||
fontFamily: 'Arial, sans-serif',
|
||||
fontSize: '14px',
|
||||
lineHeight: '1.4',
|
||||
resize: 'vertical',
|
||||
overflowY: 'auto',
|
||||
};
|
||||
|
||||
// Displays input text on a node
|
||||
app.registerExtension({
|
||||
name: "Bjornulf.ShowFloat",
|
||||
async beforeRegisterNodeDef(nodeType, nodeData, app) {
|
||||
if (nodeData.name === "Bjornulf_ShowFloat") {
|
||||
function createStyledTextArea(text) {
|
||||
const widget = ComfyWidgets["STRING"](this, "text", ["STRING", { multiline: true }], app).widget;
|
||||
widget.inputEl.readOnly = true;
|
||||
const textArea = widget.inputEl;
|
||||
|
||||
Object.assign(textArea.style, textAreaStyles);
|
||||
textArea.classList.add('bjornulf-show-text');
|
||||
widget.value = text;
|
||||
return widget;
|
||||
}
|
||||
|
||||
function populate(text) {
|
||||
if (this.widgets) {
|
||||
for (let i = 1; i < this.widgets.length; i++) {
|
||||
this.widgets[i].onRemove?.();
|
||||
}
|
||||
this.widgets.length = 1;
|
||||
}
|
||||
|
||||
const v = Array.isArray(text) ? text : [text];
|
||||
for (const list of v) {
|
||||
if (list) {
|
||||
createStyledTextArea.call(this, list);
|
||||
}
|
||||
}
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
const sz = this.computeSize();
|
||||
if (sz[0] < this.size[0]) sz[0] = this.size[0];
|
||||
if (sz[1] < this.size[1]) sz[1] = this.size[1];
|
||||
this.onResize?.(sz);
|
||||
app.graph.setDirtyCanvas(true, false);
|
||||
});
|
||||
}
|
||||
|
||||
// When the node is executed we will be sent the input text, display this in the widget
|
||||
const onExecuted = nodeType.prototype.onExecuted;
|
||||
nodeType.prototype.onExecuted = function (message) {
|
||||
onExecuted?.apply(this, arguments);
|
||||
populate.call(this, message.text);
|
||||
};
|
||||
|
||||
const onConfigure = nodeType.prototype.onConfigure;
|
||||
nodeType.prototype.onConfigure = function () {
|
||||
onConfigure?.apply(this, arguments);
|
||||
if (this.widgets_values?.length) {
|
||||
populate.call(this, this.widgets_values);
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
76
web/js/show_int.js
Normal file
76
web/js/show_int.js
Normal file
@@ -0,0 +1,76 @@
|
||||
import { app } from "../../../scripts/app.js";
|
||||
import { ComfyWidgets } from "../../../scripts/widgets.js";
|
||||
|
||||
// Styles for the text area
|
||||
const textAreaStyles = {
|
||||
readOnly: true,
|
||||
opacity: 1,
|
||||
padding: '10px',
|
||||
border: '1px solid #ccc',
|
||||
borderRadius: '5px',
|
||||
backgroundColor: '#222',
|
||||
color: 'Lime',
|
||||
fontFamily: 'Arial, sans-serif',
|
||||
fontSize: '14px',
|
||||
lineHeight: '1.4',
|
||||
resize: 'vertical',
|
||||
overflowY: 'auto',
|
||||
};
|
||||
|
||||
// Displays input text on a node
|
||||
app.registerExtension({
|
||||
name: "Bjornulf.ShowInt",
|
||||
async beforeRegisterNodeDef(nodeType, nodeData, app) {
|
||||
if (nodeData.name === "Bjornulf_ShowInt") {
|
||||
function createStyledTextArea(text) {
|
||||
const widget = ComfyWidgets["STRING"](this, "text", ["STRING", { multiline: true }], app).widget;
|
||||
widget.inputEl.readOnly = true;
|
||||
const textArea = widget.inputEl;
|
||||
|
||||
Object.assign(textArea.style, textAreaStyles);
|
||||
textArea.classList.add('bjornulf-show-text');
|
||||
widget.value = text;
|
||||
return widget;
|
||||
}
|
||||
|
||||
function populate(text) {
|
||||
if (this.widgets) {
|
||||
for (let i = 1; i < this.widgets.length; i++) {
|
||||
this.widgets[i].onRemove?.();
|
||||
}
|
||||
this.widgets.length = 1;
|
||||
}
|
||||
|
||||
const v = Array.isArray(text) ? text : [text];
|
||||
for (const list of v) {
|
||||
if (list) {
|
||||
createStyledTextArea.call(this, list);
|
||||
}
|
||||
}
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
const sz = this.computeSize();
|
||||
if (sz[0] < this.size[0]) sz[0] = this.size[0];
|
||||
if (sz[1] < this.size[1]) sz[1] = this.size[1];
|
||||
this.onResize?.(sz);
|
||||
app.graph.setDirtyCanvas(true, false);
|
||||
});
|
||||
}
|
||||
|
||||
// When the node is executed we will be sent the input text, display this in the widget
|
||||
const onExecuted = nodeType.prototype.onExecuted;
|
||||
nodeType.prototype.onExecuted = function (message) {
|
||||
onExecuted?.apply(this, arguments);
|
||||
populate.call(this, message.text);
|
||||
};
|
||||
|
||||
const onConfigure = nodeType.prototype.onConfigure;
|
||||
nodeType.prototype.onConfigure = function () {
|
||||
onConfigure?.apply(this, arguments);
|
||||
if (this.widgets_values?.length) {
|
||||
populate.call(this, this.widgets_values);
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
76
web/js/show_text.js
Normal file
76
web/js/show_text.js
Normal file
@@ -0,0 +1,76 @@
|
||||
import { app } from "../../../scripts/app.js";
|
||||
import { ComfyWidgets } from "../../../scripts/widgets.js";
|
||||
|
||||
// Styles for the text area
|
||||
const textAreaStyles = {
|
||||
readOnly: true,
|
||||
opacity: 1,
|
||||
padding: '10px',
|
||||
border: '1px solid #ccc',
|
||||
borderRadius: '5px',
|
||||
backgroundColor: '#222',
|
||||
color: 'Lime',
|
||||
fontFamily: 'Arial, sans-serif',
|
||||
fontSize: '14px',
|
||||
lineHeight: '1.4',
|
||||
resize: 'vertical',
|
||||
overflowY: 'auto',
|
||||
};
|
||||
|
||||
// Displays input text on a node
|
||||
app.registerExtension({
|
||||
name: "Bjornulf.ShowText",
|
||||
async beforeRegisterNodeDef(nodeType, nodeData, app) {
|
||||
if (nodeData.name === "Bjornulf_ShowText") {
|
||||
function createStyledTextArea(text) {
|
||||
const widget = ComfyWidgets["STRING"](this, "text", ["STRING", { multiline: true }], app).widget;
|
||||
widget.inputEl.readOnly = true;
|
||||
const textArea = widget.inputEl;
|
||||
|
||||
Object.assign(textArea.style, textAreaStyles);
|
||||
textArea.classList.add('bjornulf-show-text');
|
||||
widget.value = text;
|
||||
return widget;
|
||||
}
|
||||
|
||||
function populate(text) {
|
||||
if (this.widgets) {
|
||||
for (let i = 1; i < this.widgets.length; i++) {
|
||||
this.widgets[i].onRemove?.();
|
||||
}
|
||||
this.widgets.length = 1;
|
||||
}
|
||||
|
||||
const v = Array.isArray(text) ? text : [text];
|
||||
for (const list of v) {
|
||||
if (list) {
|
||||
createStyledTextArea.call(this, list);
|
||||
}
|
||||
}
|
||||
|
||||
requestAnimationFrame(() => {
|
||||
const sz = this.computeSize();
|
||||
if (sz[0] < this.size[0]) sz[0] = this.size[0];
|
||||
if (sz[1] < this.size[1]) sz[1] = this.size[1];
|
||||
this.onResize?.(sz);
|
||||
app.graph.setDirtyCanvas(true, false);
|
||||
});
|
||||
}
|
||||
|
||||
// When the node is executed we will be sent the input text, display this in the widget
|
||||
const onExecuted = nodeType.prototype.onExecuted;
|
||||
nodeType.prototype.onExecuted = function (message) {
|
||||
onExecuted?.apply(this, arguments);
|
||||
populate.call(this, message.text);
|
||||
};
|
||||
|
||||
const onConfigure = nodeType.prototype.onConfigure;
|
||||
nodeType.prototype.onConfigure = function () {
|
||||
onConfigure?.apply(this, arguments);
|
||||
if (this.widgets_values?.length) {
|
||||
populate.call(this, this.widgets_values);
|
||||
}
|
||||
};
|
||||
}
|
||||
},
|
||||
});
|
||||
53
web/js/write_image_characters.js
Normal file
53
web/js/write_image_characters.js
Normal file
@@ -0,0 +1,53 @@
|
||||
import { app } from "../../../scripts/app.js";
|
||||
|
||||
app.registerExtension({
|
||||
name: "Bjornulf.WriteImageCharacters",
|
||||
async nodeCreated(node) {
|
||||
if (node.comfyClass === "Bjornulf_WriteImageCharacters") {
|
||||
const updateInputs = () => {
|
||||
const numInputsWidget = node.widgets.find(w => w.name === "number_of_characters");
|
||||
if (!numInputsWidget) return;
|
||||
|
||||
const numInputs = numInputsWidget.value;
|
||||
|
||||
// Initialize node.inputs if it doesn't exist
|
||||
if (!node.inputs) {
|
||||
node.inputs = [];
|
||||
}
|
||||
|
||||
// Filter existing text inputs
|
||||
const existingInputs = node.inputs.filter(input => input.name.startsWith('character_'));
|
||||
|
||||
// Determine if we need to add or remove inputs
|
||||
if (existingInputs.length < numInputs) {
|
||||
// Add new text inputs if not enough existing
|
||||
for (let i = existingInputs.length + 1; i <= numInputs; i++) {
|
||||
const inputName = `character_${i}`;
|
||||
if (!node.inputs.find(input => input.name === inputName)) {
|
||||
// node.addInput(inputName, "STRING");
|
||||
node.addInput(inputName, "BJORNULF_CHARACTER");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Remove excess text inputs if too many
|
||||
node.inputs = node.inputs.filter(input => !input.name.startsWith('character_') || parseInt(input.name.split('_')[1]) <= numInputs);
|
||||
}
|
||||
|
||||
node.setSize(node.computeSize());
|
||||
};
|
||||
|
||||
// Move number_of_inputs to the top initially
|
||||
const numInputsWidget = node.widgets.find(w => w.name === "number_of_characters");
|
||||
if (numInputsWidget) {
|
||||
node.widgets = [numInputsWidget, ...node.widgets.filter(w => w !== numInputsWidget)];
|
||||
numInputsWidget.callback = () => {
|
||||
updateInputs();
|
||||
app.graph.setDirtyCanvas(true);
|
||||
};
|
||||
}
|
||||
|
||||
// Delay the initial update to ensure node is fully initialized
|
||||
setTimeout(updateInputs, 0);
|
||||
}
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user