From ce7fffbb69ebfc40cbe7f50543bb868d8b28f7d9 Mon Sep 17 00:00:00 2001 From: Fillip Isgro Date: Fri, 21 Mar 2025 04:39:29 -0500 Subject: [PATCH] tried stuff on code node. failed --- nodes/FL_Code_Node.py | 23 ++--- web/nodes/fl_code_node.js | 211 +++----------------------------------- 2 files changed, 28 insertions(+), 206 deletions(-) diff --git a/nodes/FL_Code_Node.py b/nodes/FL_Code_Node.py index bd87de2..be9ef62 100644 --- a/nodes/FL_Code_Node.py +++ b/nodes/FL_Code_Node.py @@ -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 \ No newline at end of file + # print(code_input) + return code_input diff --git a/web/nodes/fl_code_node.js b/web/nodes/fl_code_node.js index 712bfef..2a0cfc9 100644 --- a/web/nodes/fl_code_node.js +++ b/web/nodes/fl_code_node.js @@ -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]); -} \ No newline at end of file +}) \ No newline at end of file