Removed Prompt Editor and rolled into Prompt Builder

This commit is contained in:
Joel Trauger
2023-12-26 23:06:25 -06:00
parent 66cc05f069
commit 8519e28da2
3 changed files with 160 additions and 186 deletions
+1 -3
View File
@@ -6,17 +6,15 @@
"""
from .harronode import Harronode,PromptEditor
from .harronode import Harronode
from .harroserver import HarroServer
NODE_CLASS_MAPPINGS = {
"Harronode": Harronode,
"PromptEditor": PromptEditor
}
NODE_DISPLAY_NAME_MAPPINGS = {
"Harronode": "Harronode - Prompt Builder",
"PromptEditor": "Harronode - Prompt Editor"
}
WEB_DIRECTORY = "js"
+1 -126
View File
@@ -20,6 +20,7 @@ class Harronode:
"required": {
"prompt": ("STRING", {"default": "", "multiline": True}),
"text_on_image": ("STRING", {"default": "", "multiline": True}),
"mode": ("BOOLEAN", {"default": True, "label_on": "Editable", "label_off": "Fixed"}),
"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}),
@@ -49,129 +50,3 @@ class Harronode:
def doTheThing(self, *args, **kwargs):
output = kwargs['prompt']
return(output,) # comma outputs a tuple with a single record instead of a bunch of records all containing the prompt
class PromptEditor:
@classmethod
def INPUT_TYPES(cls):
inputs = {
"optional": {
"prompt": ("STRING", {"forceInput": True}) # forceInput makes it an input node
},
"required": {
"mode": (["Edit", "Bypass"],{}),
"promptEditor": ("STRING", {"default": "", "multiline": True})
},
"hidden": {
"unique_id": "UNIQUE_ID",
"extra_pnginfo": "EXTRA_PNGINFO"
},
}
return inputs
RETURN_TYPES = ("STRING",)
FUNCTION = "EditPrompt"
CATEGORY = "Harronode/PromptBuilder"
def EditPrompt(self, *args, **kwargs):
print("EditPrompt")
output = ''
prompt = ''
unique_id = kwargs["unique_id"]
extra_pnginfo = kwargs["extra_pnginfo"]
mode = kwargs["mode"]
promptEditor = kwargs["promptEditor"]
if "prompt" in kwargs:
prompt = kwargs["prompt"]
if unique_id and extra_pnginfo and "workflow" in extra_pnginfo:
workflow = extra_pnginfo["workflow"]
target_id = unique_id
node = None
# try to find the node in the workflow so we can get all the values of it
for node in workflow["nodes"]:
if str(node["id"]) == target_id:
break
# if the node is found, set the value of the textbox (3rd input, 0-indexed) to the prompt
if node:
print(node)
if mode == "Edit":
server.PromptServer.instance.send_sync("harronode-populate-promptEditor", {"node_id": unique_id, "value": prompt,})
output = promptEditor,
else:
# just set the output to the string we input
output = prompt,
return (output,)
def onprompt_populate_prompt(json_data):
try:
prompt = json_data['prompt']
updated_widget_values = {}
for k, v in prompt.items():
if 'class_type' in v and (v['class_type'] == 'Harronode'):
inputs = v['inputs']
if isinstance(inputs['prompt'], str):
inputs['prompt'] = prompt_builder.build_prompt(inputs)
server.PromptServer.instance.send_sync("harronode-node-feedback", {"node_id": k, "widget_name": "prompt", "type": "STRING", "value": inputs['prompt']})
updated_widget_values[k] = inputs['prompt']
except Exception as e:
print(f"[WARN] ComfyUI-Harronode: Error on prompt\n{e}")
def harroonprompt(json_data):
try:
onprompt_populate_prompt(json_data)
except Exception as e:
print(f"[WARN] ComfyUI-Harronode: Error on prompt - autopopulation of prompt will not work.\n{e}")
return json_data
class prompt_builder:
def build_prompt(inputs):
# Initialize the prompt builder string
text = ""
text = text + "('"
text = text + inputs["text_on_image"]
text_weight = inputs["text_weight"]
text = text + f"':{text_weight:.2f}) text logo, "
color_count = inputs["color_count"]
# gather colors
if color_count > 0:
color1 = inputs["color_1"]
color2 = inputs["color_2"]
color3 = inputs["color_3"]
for i in range(1, color_count + 1):
variable_name = f"color{i}"
color_value = locals()[variable_name]
text = text + color_value + ", "
style_count = inputs["style_count"]
# gather styles
if style_count > 0:
style1 = inputs["style_1"]
style2 = inputs["style_2"]
for i in range(1, style_count + 1):
variable_name = f"style{i}"
style_value = locals()[variable_name]
text = text + style_value + ", "
accent_count = inputs["accent_count"]
# gather accents
if accent_count > 0:
accent1 = inputs["accent_1"]
accent2 = inputs["accent_2"]
accent3 = inputs["accent_3"]
for i in range(1, accent_count + 1):
variable_name = f"accent{i}"
accent_value = locals()[variable_name]
text = text + accent_value + ", "
content_count = inputs["content_count"]
# gather contents
if content_count > 0:
content1 = inputs["content_1"]
content2 = inputs["content_2"]
content3 = inputs["content_3"]
for i in range(1, content_count + 1):
variable_name = f"content{i}"
content_value = locals()[variable_name]
text = text + content_value + ", "
return text
server.PromptServer.instance.add_on_prompt_handler(harroonprompt)
+158 -57
View File
@@ -1,23 +1,88 @@
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": []
}
const harroWidgetHandlers = {
"Harronode": {
'color_count': handleColorCount,
'style_count': handleStyleCount,
'accent_count': handleAccentCount,
'content_count': handleContentCount
},
"PromptEditor": {
'mode': handleMode
'content_count': handleContentCount,
'color_1': handlePromptChange,
'color_2': handlePromptChange,
'color_3': handlePromptChange,
'style_1': handlePromptChange,
'style_2': handlePromptChange,
'accent_1': handlePromptChange,
'accent_2': handlePromptChange,
'accent_3': handlePromptChange,
'content_1': handlePromptChange,
'content_2': handlePromptChange,
'content_3': handlePromptChange,
'text_weight': handlePromptChange,
},
};
// ------------------ HANDLERS
function handlePromptChange(node, widget) {
rebuildPrompt(node);
}
function handleColorCount(node, widget) {
updateColorWidgets(node, widget.value);
@@ -35,19 +100,6 @@ function handleContentCount(node, widget) {
updateContentWidgets(node, widget.value);
}
function handleMode (node, widget) {
//const goButton = findWidgetByName(node, "Prompt looks good (GO)");
const promptEditor = findWidgetByName(node, "promptEditor");
if (widget.value == "Bypass"){
//goButton.disabled = 1==1;
promptEditor.inputEl.disabled = 1==1;
}
else {
//goButton.disabled = 1==0;
promptEditor.inputEl.disabled = 1==0;
}
}
//----------------------END HANDLERS
//-------function credit to efficiency nodes for comfyUI---------//
@@ -88,7 +140,6 @@ function harrToggleWidget(node, widget, show = false, suffix = "") {
// -- BASE CODE NEEDED BY PROMPT BUILDER
function updateColorWidgets(node, color_count){
console.log("colors", color_count)
for (let i = 1; i <= 3; i++) {
//find widget
const color_picker = findWidgetByName(node, `color_${i}`)
@@ -101,6 +152,7 @@ function updateColorWidgets(node, color_count){
harrToggleWidget(node, color_picker, false)
}
}
rebuildPrompt(node);
}
function updateStyleWidgets(node, color_count){
@@ -116,6 +168,7 @@ function updateStyleWidgets(node, color_count){
harrToggleWidget(node, style_picker, false)
}
}
rebuildPrompt(node);
}
function updateAccentWidgets(node, color_count){
for (let i = 1; i <= 3; i++) {
@@ -130,6 +183,7 @@ function updateAccentWidgets(node, color_count){
harrToggleWidget(node, accent_picker, false)
}
}
rebuildPrompt(node);
}
function updateContentWidgets(node, color_count){
for (let i = 1; i <= 3; i++) {
@@ -144,6 +198,56 @@ function updateContentWidgets(node, color_count){
harrToggleWidget(node, content_picker, false)
}
}
rebuildPrompt(node);
}
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, "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
var promptOutput = "";
promptOutput = buildPrompt(node);
node.widgets[0].inputEl.value = promptOutput;
}
// -- END BASE CODE NEEDED BY PROMPT BUILDER
@@ -155,39 +259,21 @@ function startupLogic (node, widget) //change name
if (handler) {
handler(node, widget);
}
prompt = findWidgetByName(node, 'prompt');
}
function progressButtonPressed (){
}
app.registerExtension({
name: "harronode.harronode",
setup(){
function harronode_populate_promptEditor(event)
{
const node = app.graph._nodes_by_id[event.detail.node_id];
if (node) {
if(node.comfyClass == "PromptEditor") {
let prompt = event.detail.value;
if (prompt != previousPrompt){
previousPrompt = prompt;
node.widgets[1].inputEl.value = event.detail.value;
}
}
} else {
console.log(`Harronode Prompt Editor - failed to find ${event.detail.node_id}`)
}
}
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 prompt = event.detail.value;
node.widgets[0].inputEl.value = prompt;
let widgets = event.detail.value;
console.log(widgets);
rebuildPrompt(node);
}
}
else {
@@ -195,10 +281,10 @@ app.registerExtension({
}
}
api.addEventListener("harronode-populate-promptEditor", harronode_populate_promptEditor);
api.addEventListener("harronode-node-feedback", harronode_node_feedback);
},
async nodeCreated(node) {
async nodeCreated(node)
{
for (const w of node.widgets || []) {
let widgetValue = w.value;
@@ -225,22 +311,37 @@ app.registerExtension({
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;
}
});
}
}
//do this if we're messing with the prompt builder
if(node.comfyClass == "Harronode"){
node.widgets[0].inputEl.placeholder = "Populated Prompt (Will be generated automatically)";
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";
const prompt = node.widgets.find((w) => w.name == 'prompt');
prompt.inputEl.disabled = 1 == 1;
}
//do this if we're messing with the prompt editor
if(node.comfyClass == "PromptEditor") {
const mode = node.widgets.find((w) => w.name === "mode");
node.widgets[1].inputEl.placeholder = "Populated Prompt (Will be generated automatically)";
console.log("setting size");
const newHeight = node.computeSize()[1];
node.setSize([node.size[0], newHeight]);
//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);
}
}
setTimeout(() => { initialized = true; }, 500);
}
});
});