diff --git a/harronode.py b/harronode.py index 72d5236..b46c412 100644 --- a/harronode.py +++ b/harronode.py @@ -18,9 +18,7 @@ class Harronode: # setup inputs for the node inputs = { "required": { - "prompt": ("STRING", {"default": "", "multiline": True}), - "text_on_image": ("STRING", {"default": "", "multiline": True}), - "mode": ("BOOLEAN", {"default": True, "label_on": "Editable", "label_off": "Fixed"}), + "desired_image_text": ("STRING", {"default": "", "multiline": False}), "text_weight": ("FLOAT", {"default": 1.0, "min":0.5, "max":1.5, "step": 0.01}), "color_count": ("INT", {"default": 1, "min": 0, "max": 3, "step": 1}), "style_count": ("INT", {"default": 1, "min": 1, "max": 2, "step": 1}), @@ -41,6 +39,8 @@ class Harronode: for i in range (1, 4): inputs["required"][f"content_{i}"] = (content, {"default": content[0] if content else None}) + inputs["required"]["prompt"] = ("STRING", {"default": "", "multiline": True}) + return inputs RETURN_TYPES = ("STRING",) diff --git a/js/harronode.js b/js/harronode.js index 4c15b52..4315a9a 100644 --- a/js/harronode.js +++ b/js/harronode.js @@ -1,62 +1,10 @@ import { app } from "../../scripts/app.js"; import { api } from "../../scripts/api.js"; import "../../scripts/widgets.js"; -import { ComfyWidgets } from "../../scripts/widgets.js"; let origProps = {}; let initialized = false; -let previousPrompt = ""; -let tokenDict = { - "text": { - "location": 0, - "currentValue":"" - }, - "color_1":{ - "location": 0, - "currentValue":"" - }, - "color_2":{ - "location": 0, - "currentValue":"" - }, - "color_3":{ - "location": 0, - "currentValue":"" - }, - "style_1":{ - "location": 0, - "currentValue":"" - }, - "style_2":{ - "location": 0, - "currentValue":"" - }, - "accent_1":{ - "location": 0, - "currentValue":"" - }, - "accent_2":{ - "location": 0, - "currentValue":"" - }, - "accent_3":{ - "location": 0, - "currentValue":"" - }, - "content_1":{ - "location": 0, - "currentValue":"" - }, - "content_2":{ - "location": 0, - "currentValue":"" - }, - "content_3":{ - "location": 0, - "currentValue":"" - }, - "tokens": [] -} +let oldTTI = ""; const harroWidgetHandlers = { "Harronode": { @@ -76,12 +24,12 @@ const harroWidgetHandlers = { 'content_2': handlePromptChange, 'content_3': handlePromptChange, 'text_weight': handlePromptChange, + 'desired_image_text': handlePromptChange, }, }; -// ------------------ HANDLERS function handlePromptChange(node, widget) { - rebuildPrompt(node); + rebuildPrompt(node, widget); } function handleColorCount(node, widget) { @@ -100,248 +48,134 @@ function handleContentCount(node, widget) { updateContentWidgets(node, widget.value); } -//----------------------END HANDLERS +const findWidgetByName = (node, name) => node.widgets ? node.widgets.find((w) => w.name === name) : null; -//-------function credit to efficiency nodes for comfyUI---------// - -const findWidgetByName = (node, name) => { - return node.widgets ? node.widgets.find((w) => w.name === name) : null; -}; - -const doesInputWithNameExist = (node, name) => { - return node.inputs ? node.inputs.some((input) => input.name === name) : false; -}; +const doesInputWithNameExist = (node, name) => node.inputs ? node.inputs.some((input) => input.name === name) : false; const HIDDEN_TAG = "harrohide"; -// function to hide a widget from view function harrToggleWidget(node, widget, show = false, suffix = "") { if (!widget || doesInputWithNameExist(node, widget.name)) return; - // Store the original properties of the widget if not already stored if (!origProps[widget.name]) { origProps[widget.name] = { origType: widget.type, origComputeSize: widget.computeSize }; } - const origSize = node.size; - - // Set the widget type and computeSize based on the show flag widget.type = show ? origProps[widget.name].origType : HIDDEN_TAG + suffix; widget.computeSize = show ? origProps[widget.name].origComputeSize : () => [0, -4]; - // Recursively handle linked widgets if they exist widget.linkedWidgets?.forEach(w => harrToggleWidget(node, w, ":" + widget.name, show)); - // Calculate the new height for the node based on its computeSize method const newHeight = node.computeSize()[1]; node.setSize([node.size[0], newHeight]); } -//--------------------------END CREDIT---------------------------// -// -- BASE CODE NEEDED BY PROMPT BUILDER -function updateColorWidgets(node, color_count){ +function updateColorWidgets(node, count) { + updateWidgetsByCount(node, "color", count); +} + +function updateStyleWidgets(node, count) { + updateWidgetsByCount(node, "style", count); +} + +function updateAccentWidgets(node, count) { + updateWidgetsByCount(node, "accent", count); +} + +function updateContentWidgets(node, count) { + updateWidgetsByCount(node, "content", count); +} + +function updateWidgetsByCount(node, type, count) { for (let i = 1; i <= 3; i++) { - //find widget - const color_picker = findWidgetByName(node, `color_${i}`) - if(i <= color_count){ - //set visible and required - harrToggleWidget(node, color_picker, true) - } - else { - //hide and set not required - harrToggleWidget(node, color_picker, false) - } + const widget = findWidgetByName(node, `${type}_${i}`); + harrToggleWidget(node, widget, i <= count); } rebuildPrompt(node); } -function updateStyleWidgets(node, color_count){ - for (let i = 1; i <= 3; i++) { - //find widget - const style_picker = findWidgetByName(node, `style_${i}`) - if(i <= color_count){ - //set visible and required - harrToggleWidget(node, style_picker, true) - } - else { - //hide and set not required - harrToggleWidget(node, style_picker, false) - } - } - rebuildPrompt(node); -} -function updateAccentWidgets(node, color_count){ - for (let i = 1; i <= 3; i++) { - //find widget - const accent_picker = findWidgetByName(node, `accent_${i}`) - if(i <= color_count){ - //set visible and required - harrToggleWidget(node, accent_picker, true) - } - else { - //hide and set not required - harrToggleWidget(node, accent_picker, false) - } - } - rebuildPrompt(node); -} -function updateContentWidgets(node, color_count){ - for (let i = 1; i <= 3; i++) { - //find widget - const content_picker = findWidgetByName(node, `content_${i}`) - if(i <= color_count){ - //set visible and required - harrToggleWidget(node, content_picker, true) - } - else { - //hide and set not required - harrToggleWidget(node, content_picker, false) - } - } - rebuildPrompt(node); -} +function buildPrompt(node, widgets = null) { + let prompt = ''; + const widgetArray = widgets || node.widgets; -function buildPrompt(node, widgets = null, event = null){ - var prompt = ""; - var _widgets; - if(widgets != null) - { - _widgets = widgets; - - } - //get widget values from node - else { - if(node.comfyClass == "Harronode"){ - _widgets = node.widgets; + prompt += `("${findWidgetByName(node, "desired_image_text").value}":${parseFloat(findWidgetByName(node, "text_weight").value).toFixed(2)}) text logo, `; + + //TY ChatGPT <3 ;) + ['color', 'style', 'accent', 'content'].forEach((type) => { + const count = findWidgetByName(node, `${type}_count`).value; + for (let i = 1; i <= count; i++) { + const value = findWidgetByName(node, `${type}_${i}`).value; + prompt += `${value}, `; } - } - prompt += '("' + findWidgetByName(node, "text_on_image").value+ '":' + parseFloat(findWidgetByName(node, "text_weight").value).toFixed(2) + ") text logo, "; - //foreach color - var colors = findWidgetByName(node, "color_count").value; - for(var i = 1; i <= colors; i++){ - var color = findWidgetByName(node, `color_${i}`).value; - prompt += color + ", "; - } - //foreach style - var styles = findWidgetByName(node, "style_count").value; - for(var i = 1; i <= styles; i++){ - var style = findWidgetByName(node, `style_${i}`).value; - prompt += style + ", "; - } - //foreach accent - var accents = findWidgetByName(node, "accent_count").value; - for(var i = 1; i <= accents; i++){ - var accent = findWidgetByName(node, `accent_${i}`).value; - prompt += accent + ", "; - } - //foreach content - var contents = findWidgetByName(node, "content_count").value; - for(var i = 1; i <= contents; i++){ - var content = findWidgetByName(node, `content_${i}`).value; - prompt += content + ", "; - } + }); + return prompt; } -function rebuildPrompt(node){ - // build prompt +function rebuildPrompt(node, widget) { var promptOutput = ""; - promptOutput = buildPrompt(node); - node.widgets[0].inputEl.value = promptOutput; + if (widget){ + console.log(widget.name); + if (widget.name == "desired_image_text"){ + if(widget.value != oldTTI) { + console.log("Old TTI =", oldTTI); + console.log("widget.value =", widget.value); + oldTTI = widget.value; + promptOutput = buildPrompt(node); + node.widgets[17].inputEl.value = promptOutput; + } + } + else { + promptOutput = buildPrompt(node); + node.widgets[17].inputEl.value = promptOutput; + } + } } -// -- END BASE CODE NEEDED BY PROMPT BUILDER - -function startupLogic (node, widget) //change name -{ - // Retrieve the handler for the current node title and widget name +function startupLogic(node, widget) { const handler = harroWidgetHandlers[node.comfyClass]?.[widget.name]; if (handler) { handler(node, widget); } } +function harronode_node_feedback(event) { + const node = app.graph._nodes_by_id[event.detail.node_id]; + if (node && node.comfyClass === "Harronode") { + rebuildPrompt(node); + } else { + console.log(`Harronode Prompt Builder - failed to find ${event.detail.node_id}`); + } +} + app.registerExtension({ name: "harronode.harronode", - setup() - { - function harronode_node_feedback(event){ - const node = app.graph._nodes_by_id[event.detail.node_id]; - let promptOutput = ""; - let editedPrompt = node.widgets[0].inputEl.value; - if (node) { - if(node.comfyClass == "Harronode"){ - let widgets = event.detail.value; - console.log(widgets); - rebuildPrompt(node); - } - } - else { - console.log(`Harronode Prompt Builder - failed to find ${event.detail.node_id}`); - } - } - - api.addEventListener("harronode-node-feedback", harronode_node_feedback); - }, - async nodeCreated(node) - { - for (const w of node.widgets || []) { - let widgetValue = w.value; - - // Store the original descriptor if it exists - let originalDescriptor = Object.getOwnPropertyDescriptor(w, 'value'); - startupLogic(node, w); - Object.defineProperty(w, 'value', { - get() { - // If there's an original getter, use it. Otherwise, return widgetValue. - let valueToReturn = originalDescriptor && originalDescriptor.get - ? originalDescriptor.get.call(w) - : widgetValue; - - return valueToReturn; - }, - set(newVal) { - // If there's an original setter, use it. Otherwise, set widgetValue. - if (originalDescriptor && originalDescriptor.set) { - originalDescriptor.set.call(w, newVal); - } else { - widgetValue = newVal; - } - - startupLogic(node, w); - } - }); - if(node.comfyClass == "Harronode"){ - const editablePrompt = node.widgets.find((w) => w.name == 'prompt'); - const mode_widget = node.widgets.find((w) => w.name == 'mode'); - Object.defineProperty(mode_widget, "value", { - set: (value) => { - node._mode_value = value == true || value == "Editable"; - editablePrompt.inputEl.disabled = value == false || value == "Editable"; - }, - get: () => { - if(node._mode_value != undefined) - return node._mode_value; - else - return true; + nodeCreated(node) { + if (node.comfyClass === "Harronode") { + for (const w of node.widgets || []) { + let widgetValue = w.value; + let originalDescriptor = Object.getOwnPropertyDescriptor(w, 'value'); + startupLogic(node, w); + Object.defineProperty(w, 'value', { + get() { + let valueToReturn = originalDescriptor && originalDescriptor.get + ? originalDescriptor.get.call(w) + : widgetValue; + return valueToReturn; + }, + set(newVal) { + if (originalDescriptor && originalDescriptor.set) { + originalDescriptor.set.call(w, newVal); + } else { + widgetValue = newVal; } + startupLogic(node, w); + } }); } - } - //do this if we're messing with the prompt builder - if(node.comfyClass == "Harronode"){ - node.widgets[0].inputEl.placeholder = "Generated Prompt - Changing a parameter may overwrite what is in this box."; - node.widgets[1].inputEl.placeholder = "Input Text to Display on Image"; - //janky af but I don't care at this point - if(!initialized) { - console.log(node.widgets); - const thebutton = node.addWidget("button", "CLICK to Rebuild Prompt (Erases edits)", "", () => { - rebuildPrompt(node); - }); - initialized = true; - console.log(node.widgets); - } + node.widgets[17].inputEl.placeholder = "Generated Prompt - Changing a parameter may overwrite what is in this box."; + api.addEventListener("harronode-node-feedback", harronode_node_feedback); } setTimeout(() => { initialized = true; }, 500); } -}); \ No newline at end of file +});