175 lines
7.1 KiB
JavaScript
175 lines
7.1 KiB
JavaScript
import { app } from "/scripts/app.js";
|
|
import { ComfyWidgets } from "/scripts/widgets.js";
|
|
|
|
app.registerExtension({
|
|
name: "Comfy.IFLLMDisplayTextWildcardNode",
|
|
async beforeRegisterNodeDef(nodeType, nodeData, app) {
|
|
if (nodeData.name === "IF_LLM_DisplayTextWildcard") {
|
|
// Store original node methods
|
|
const onNodeCreated = nodeType.prototype.onNodeCreated;
|
|
const onExecuted = nodeType.prototype.onExecuted;
|
|
const onDrawForeground = nodeType.prototype.onDrawForeground;
|
|
const getExtraMenuOptions = nodeType.prototype.getExtraMenuOptions;
|
|
|
|
// Add counter status display
|
|
nodeType.prototype.counterStatus = {
|
|
count: -1,
|
|
blocked: false
|
|
};
|
|
|
|
nodeType.prototype.onNodeCreated = function () {
|
|
const ret = onNodeCreated?.apply(this, arguments);
|
|
|
|
// Set output labels
|
|
if (this.outputs) {
|
|
this.outputs[0].name = "text";
|
|
this.outputs[1].name = "text_list";
|
|
this.outputs[2].name = "count";
|
|
this.outputs[3].name = "selected";
|
|
|
|
// Set the text_list output to use grid shape
|
|
this.outputs[1].shape = LiteGraph.GRID_SHAPE;
|
|
}
|
|
|
|
// Create unique name for node instance
|
|
let nodeName = `${nodeData.name}_${app.graph._nodes.filter(n => n.type === nodeData.name).length}`;
|
|
console.log(`Create ${nodeData.name}: ${nodeName}`);
|
|
|
|
// Create text display widget
|
|
const wi = ComfyWidgets.STRING(
|
|
this,
|
|
nodeName,
|
|
["STRING", {
|
|
default: "",
|
|
placeholder: "Message will appear here ...",
|
|
multiline: true,
|
|
}],
|
|
app
|
|
);
|
|
wi.widget.inputEl.readOnly = true;
|
|
|
|
return ret;
|
|
};
|
|
|
|
// Handle counter status updates
|
|
nodeType.prototype.onExecuted = function (message) {
|
|
const ret = onExecuted?.apply(this, arguments);
|
|
|
|
// Update counter status
|
|
const widgets = this.widgets || [];
|
|
const counterWidget = widgets.find(w => w.name === "counter");
|
|
|
|
if (counterWidget) {
|
|
// Get counter value from widget
|
|
this.counterStatus.count = counterWidget.value;
|
|
|
|
// Check if execution was blocked
|
|
if (message?.error?.includes("Counter reached 0")) {
|
|
this.counterStatus.blocked = true;
|
|
} else {
|
|
this.counterStatus.blocked = false;
|
|
}
|
|
}
|
|
|
|
// Update text display
|
|
if (message?.string) {
|
|
const widget_id = this.widgets.findIndex(w => w.type === "customtext");
|
|
if (widget_id !== -1) {
|
|
let texts = message.string;
|
|
if (Array.isArray(texts)) {
|
|
texts = texts
|
|
.filter(text => text != null)
|
|
.map(text => String(text).trim())
|
|
.join("\n");
|
|
} else {
|
|
texts = String(texts).trim();
|
|
}
|
|
this.widgets[widget_id].value = texts;
|
|
}
|
|
}
|
|
|
|
app.graph.setDirtyCanvas(true);
|
|
return ret;
|
|
};
|
|
|
|
// Enhanced node drawing
|
|
nodeType.prototype.onDrawForeground = function (ctx) {
|
|
const ret = onDrawForeground?.apply(this, arguments);
|
|
|
|
// Add tooltips to outputs
|
|
if (this.outputs) {
|
|
const outputLabels = [
|
|
"Complete Text",
|
|
"List of Lines",
|
|
"Line Count",
|
|
"Selected Line"
|
|
];
|
|
const outputTooltips = [
|
|
"Full text content",
|
|
"Individual lines as separate outputs",
|
|
"Total number of non-empty lines",
|
|
"Currently selected line based on select input"
|
|
];
|
|
|
|
for (let i = 0; i < this.outputs.length; i++) {
|
|
const output = this.outputs[i];
|
|
output.tooltip = outputTooltips[i];
|
|
}
|
|
}
|
|
|
|
// Draw counter status
|
|
if (this.counterStatus.count !== -1) {
|
|
ctx.save();
|
|
ctx.font = "12px Arial";
|
|
ctx.textAlign = "right";
|
|
|
|
// Position in top-right corner
|
|
const text = `Counter: ${this.counterStatus.count}`;
|
|
const x = this.size[0] - 5;
|
|
const y = 20;
|
|
|
|
// Draw counter value with color based on status
|
|
if (this.counterStatus.blocked) {
|
|
ctx.fillStyle = "#ff4444";
|
|
this.boxcolor = "#442222";
|
|
} else if (this.counterStatus.count === 0) {
|
|
ctx.fillStyle = "#ffaa44";
|
|
this.boxcolor = "#443322";
|
|
} else {
|
|
ctx.fillStyle = "#66ff66";
|
|
this.boxcolor = null; // Reset to default
|
|
}
|
|
|
|
ctx.fillText(text, x, y);
|
|
ctx.restore();
|
|
}
|
|
|
|
return ret;
|
|
};
|
|
|
|
// Add counter reset option to context menu
|
|
nodeType.prototype.getExtraMenuOptions = function (_, options) {
|
|
const ret = getExtraMenuOptions?.apply(this, arguments);
|
|
|
|
options.push(
|
|
null, // separator
|
|
{
|
|
content: "Reset Counter",
|
|
callback: () => {
|
|
const counterWidget = this.widgets.find(w => w.name === "counter");
|
|
if (counterWidget) {
|
|
// Reset to widget's original value
|
|
counterWidget.value = counterWidget.options.default;
|
|
this.counterStatus.count = counterWidget.value;
|
|
this.counterStatus.blocked = false;
|
|
app.graph.setDirtyCanvas(true);
|
|
}
|
|
}
|
|
}
|
|
);
|
|
|
|
return ret;
|
|
};
|
|
}
|
|
},
|
|
}); |