tried stuff on code node. failed

This commit is contained in:
Fillip Isgro
2025-03-21 04:39:29 -05:00
parent 1c32bfbff3
commit ce7fffbb69
2 changed files with 28 additions and 206 deletions
+11 -12
View File
@@ -1,7 +1,7 @@
from pathlib import Path
from .sup import ROOT, AlwaysEqualProxy, parse_dynamic
class FL_CodeNode:
@classmethod
@@ -9,13 +9,12 @@ class FL_CodeNode:
return {
"required": {},
"optional": {
"code_input": ("STRING", {"default": "outputs[0] = 'hello, world!'", "multiline": True, "dynamicPrompts": False}),
"code_input": (
"STRING", {"default": "outputs[0] = 'hello, world!'", "multiline": True, "dynamicPrompts": False}),
"file": ("STRING", {"default": "./res/hello.py", "multiline": False, "dynamicPrompts": False}),
"use_file": ("BOOLEAN", {"default": False}),
"run_always": ("BOOLEAN", {"default": False}),
"editor_theme": (["dark", "light"], {"default": "dark"}),
"editor_mode": (["python", "javascript"], {"default": "python"}),
}}
"run_always": ("BOOLEAN", {"default": False})
}}
CATEGORY = "🏵️Fill Nodes/utility"
RETURN_TYPES = tuple(AlwaysEqualProxy("*") for _ in range(4))
@@ -30,7 +29,7 @@ FL_CodeNode is designed to execute custom user-provided Python code. The code ca
if run_always:
return float('nan')
hash = '$$' + str(kwargs) + '$$' + self.get_exec_string(self, code_input, file, use_file) + '$$'
#print(hash)
# print(hash)
return hash
def execute(self, code_input, file, use_file, run_always, **kwargs):
@@ -45,15 +44,15 @@ FL_CodeNode is designed to execute custom user-provided Python code. The code ca
raise RuntimeError(f"Error executing user code: {e}")
return tuple(outputs[i] for i in range(4))
def get_exec_string(self, code_input, file, use_file):
if use_file:
# load the referenced file
code_input = ""
if not (fname := Path(ROOT / file)).is_file():
#print(fname)
# print(fname)
if not (fname := Path(file)).is_file():
#print(fname)
# print(fname)
fname = None
if fname is not None:
try:
@@ -61,5 +60,5 @@ FL_CodeNode is designed to execute custom user-provided Python code. The code ca
code_input = f.read()
except Exception as e:
raise RuntimeError(f"[FL_CodeNode] error loading code file: {e}")
#print(code_input)
return code_input
# print(code_input)
return code_input
+17 -194
View File
@@ -1,198 +1,21 @@
import { app } from "../../../scripts/app.js";
/**
* File: fl_code_node.js
* Project: ComfyUI_Fill-Nodes
*
*/
import { app } from "../../../scripts/app.js"
import { node_add_dynamic } from "../widget.js"
const _id = "FL_CodeNode"
const _prefix = 'input'
app.registerExtension({
name: "Comfy.FL_CodeNode",
async nodeCreated(node) {
if (node.comfyClass === "FL_CodeNode") {
addCodeEditor(node);
name: 'fl.node.' + _id,
async beforeRegisterNodeDef(nodeType, nodeData, app) {
if (nodeData.name !== _id) {
return;
}
nodeType = node_add_dynamic(nodeType, _prefix);
}
});
function addCodeEditor(node) {
// Constants for UI layout
const PADDING = 10;
const LINE_HEIGHT = 20;
const CHAR_WIDTH = 8;
const GUTTER_WIDTH = 40;
// Editor state
let editorContent = "";
let cursorPos = 0;
let scrollOffset = 0;
let lines = [""];
let isEditing = false;
// Find and hide the default code input widget
const codeWidget = node.widgets.find(w => w.name === "code_input");
if (codeWidget) {
editorContent = codeWidget.value;
lines = editorContent.split('\n');
// Hide the original widget
codeWidget.origComputeSize = codeWidget.computeSize;
codeWidget.computeSize = () => [0, -4]; // Make it invisible
}
// Keywords for basic syntax highlighting
const keywords = [
"def", "class", "import", "from", "return", "if", "else", "elif",
"for", "while", "try", "except", "with", "as", "in", "is", "not",
"and", "or", "True", "False", "None"
];
function drawEditor(ctx) {
if (!node.flags.collapsed) {
const nodeWidth = node.size[0];
const width = nodeWidth - PADDING * 2;
const height = node.size[1] - 60; // Leave space for other widgets
// Draw editor background
ctx.fillStyle = "#1e1e1e";
ctx.fillRect(PADDING, 40, width, height);
// Draw gutter background
ctx.fillStyle = "#252526";
ctx.fillRect(PADDING, 40, GUTTER_WIDTH, height);
// Draw lines
ctx.font = "12px monospace";
const visibleLines = Math.floor(height / LINE_HEIGHT);
for (let i = 0; i < Math.min(lines.length, visibleLines); i++) {
const y = 40 + (i + 1) * LINE_HEIGHT;
// Draw line number
ctx.fillStyle = "#858585";
ctx.textAlign = "right";
ctx.fillText((i + 1).toString(), PADDING + GUTTER_WIDTH - 5, y);
// Draw line content with syntax highlighting
ctx.textAlign = "left";
const line = lines[i];
let x = PADDING + GUTTER_WIDTH + 5;
// Simple syntax highlighting
const words = line.split(/(\s+)/);
words.forEach(word => {
if (keywords.includes(word)) {
ctx.fillStyle = "#569cd6"; // Blue for keywords
} else if (/^["'].*["']$/.test(word)) {
ctx.fillStyle = "#ce9178"; // Brown for strings
} else if (/^\d+$/.test(word)) {
ctx.fillStyle = "#b5cea8"; // Green for numbers
} else {
ctx.fillStyle = "#d4d4d4"; // Default color
}
ctx.fillText(word, x, y);
x += ctx.measureText(word).width;
});
}
// Draw cursor if editing
if (isEditing) {
const cursorLine = Math.floor(cursorPos / (nodeWidth - GUTTER_WIDTH - PADDING * 2));
const cursorX = (cursorPos % (nodeWidth - GUTTER_WIDTH - PADDING * 2)) * CHAR_WIDTH + PADDING + GUTTER_WIDTH + 5;
const cursorY = 40 + cursorLine * LINE_HEIGHT;
ctx.strokeStyle = "#ffffff";
ctx.beginPath();
ctx.moveTo(cursorX, cursorY);
ctx.lineTo(cursorX, cursorY + LINE_HEIGHT);
ctx.stroke();
}
}
}
// Override node's drawing
const origDrawBackground = node.onDrawBackground;
node.onDrawBackground = function(ctx) {
if (origDrawBackground) {
origDrawBackground.call(this, ctx);
}
drawEditor(ctx);
};
// Handle mouse events
node.onMouseDown = function(evt) {
const localX = evt.canvasX - this.pos[0];
const localY = evt.canvasY - this.pos[1];
if (localY >= 40 && localX >= PADDING && localX <= this.size[0] - PADDING) {
isEditing = true;
// Calculate cursor position from click
const line = Math.floor((localY - 40) / LINE_HEIGHT);
const char = Math.floor((localX - PADDING - GUTTER_WIDTH - 5) / CHAR_WIDTH);
cursorPos = Math.max(0, Math.min(lines[line]?.length || 0, char));
this.setDirtyCanvas(true);
return true;
}
return false;
};
// Handle keyboard input
document.addEventListener('keydown', function(evt) {
if (isEditing && node.selected) {
const nodeWidth = node.size[0];
if (evt.key === 'Enter') {
const currentLine = Math.floor(cursorPos / (nodeWidth - GUTTER_WIDTH - PADDING * 2));
const currentLineContent = lines[currentLine] || "";
const cursorPosInLine = cursorPos % (nodeWidth - GUTTER_WIDTH - PADDING * 2);
// Split the current line at cursor position
const newLine = currentLineContent.substring(cursorPosInLine);
lines[currentLine] = currentLineContent.substring(0, cursorPosInLine);
lines.splice(currentLine + 1, 0, newLine);
cursorPos = (currentLine + 1) * (nodeWidth - GUTTER_WIDTH - PADDING * 2);
evt.preventDefault();
} else if (evt.key === 'Backspace') {
const currentLine = Math.floor(cursorPos / (nodeWidth - GUTTER_WIDTH - PADDING * 2));
if (cursorPos > 0 || currentLine > 0) {
if (cursorPos % (nodeWidth - GUTTER_WIDTH - PADDING * 2) === 0 && currentLine > 0) {
// At start of line, merge with previous line
const previousLine = lines[currentLine - 1];
lines[currentLine - 1] = previousLine + (lines[currentLine] || "");
lines.splice(currentLine, 1);
cursorPos = (currentLine - 1) * (nodeWidth - GUTTER_WIDTH - PADDING * 2) + previousLine.length;
} else {
// Normal backspace within line
const linePos = cursorPos % (nodeWidth - GUTTER_WIDTH - PADDING * 2);
lines[currentLine] = lines[currentLine].substring(0, linePos - 1) +
lines[currentLine].substring(linePos);
cursorPos--;
}
}
evt.preventDefault();
} else if (evt.key.length === 1 && !evt.ctrlKey && !evt.metaKey) {
const currentLine = Math.floor(cursorPos / (nodeWidth - GUTTER_WIDTH - PADDING * 2));
const linePos = cursorPos % (nodeWidth - GUTTER_WIDTH - PADDING * 2);
// Ensure the line exists
while (lines.length <= currentLine) {
lines.push("");
}
// Insert character at cursor position
lines[currentLine] = lines[currentLine].substring(0, linePos) +
evt.key +
lines[currentLine].substring(linePos);
cursorPos++;
evt.preventDefault();
}
// Update widget value
if (codeWidget) {
codeWidget.value = lines.join('\n');
}
node.setDirtyCanvas(true);
}
});
node.onMouseUp = function(evt) {
// Handle mouse up if needed
};
// Initial size
node.setSize([400, 300]);
}
})