Refactor __init__.py to include ClickPopup; update TextCombiner for enhanced text processing with regex This commit adds the ClickPopup class to NODE_CLASS_MAPPINGS and NODE_DISPLAY_NAME_MAPPINGS in __init__.py. Additionally, the TextCombiner class has been refactored to improve its functionality, allowing for customizable separators and enhanced error handling for regex inputs. The changes aim to enhance the text processing capabilities of the application.
This commit is contained in:
+20
-1
@@ -2,12 +2,24 @@
|
||||
from .install import setup
|
||||
setup()
|
||||
|
||||
import os
|
||||
|
||||
NODE_CLASS_MAPPINGS = {}
|
||||
NODE_DISPLAY_NAME_MAPPINGS = {}
|
||||
|
||||
# 设置 web 目录
|
||||
WEB_DIRECTORY = os.path.join(os.path.dirname(os.path.realpath(__file__)), "web")
|
||||
|
||||
__all__ = ["NODE_CLASS_MAPPINGS", "NODE_DISPLAY_NAME_MAPPINGS", "WEB_DIRECTORY"]
|
||||
|
||||
try:
|
||||
from .image_resolution_adjuster import ImageResolutionAdjuster
|
||||
from .color_picker import ColorPicker
|
||||
from .remove_empty_lines import RemoveEmptyLinesAndLeadingSpaces
|
||||
from .text_combiner import TextCombiner
|
||||
from .multiline_text_input import MultilineTextInput
|
||||
from .click_popup import ClickPopup
|
||||
|
||||
|
||||
# 节点映射
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
@@ -16,6 +28,7 @@ try:
|
||||
"RemoveEmptyLinesAndLeadingSpaces": RemoveEmptyLinesAndLeadingSpaces,
|
||||
"TextCombiner": TextCombiner,
|
||||
"MultilineTextInput": MultilineTextInput,
|
||||
"ClickPopup": ClickPopup,
|
||||
}
|
||||
|
||||
NODE_DISPLAY_NAME_MAPPINGS = {
|
||||
@@ -23,10 +36,16 @@ try:
|
||||
"ColorPicker": "Color Picker",
|
||||
"RemoveEmptyLinesAndLeadingSpaces": "Remove Empty Lines And Leading Spaces",
|
||||
"TextCombiner": "Text Combiner",
|
||||
"MultilineTextInput": "Multiline Text Input"
|
||||
"MultilineTextInput": "Multiline Text Input",
|
||||
"ClickPopup": "Click Popup"
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
except ImportError as e:
|
||||
print(f"Error importing modules: {e}")
|
||||
print("Please restart ComfyUI after the installation is complete.")
|
||||
NODE_CLASS_MAPPINGS = {}
|
||||
NODE_DISPLAY_NAME_MAPPINGS = {}
|
||||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,26 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Filename: click_popup.py
|
||||
# Developer: jammyfu
|
||||
# Category: 🎨Painting👓Coder/🔧Utils
|
||||
|
||||
class ClickPopup:
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
return {
|
||||
"required": {
|
||||
"button": ("BOOLEAN", {"default": False}),
|
||||
},
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("STRING",)
|
||||
RETURN_NAMES = ("message",)
|
||||
FUNCTION = "show_popup"
|
||||
CATEGORY = "🎨Painting👓Coder/🔧Utils"
|
||||
|
||||
def show_popup(self, button):
|
||||
return ("Button clicked!",)
|
||||
|
||||
# 添加到 ComfyUI 节点注册
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
"ClickPopup": ClickPopup,
|
||||
}
|
||||
@@ -11,13 +11,6 @@ import folder_paths
|
||||
import json
|
||||
import os
|
||||
|
||||
# 尝试导入 gradio,如果失败则使用基础的颜色选择器
|
||||
try:
|
||||
import gradio as gr
|
||||
HAS_GRADIO = True
|
||||
except ImportError:
|
||||
HAS_GRADIO = False
|
||||
print("Gradio not found, using basic color picker")
|
||||
|
||||
def resize_image(image, target_width, target_height, method='contain', background_color='#000000'):
|
||||
"""Resize an image while maintaining aspect ratio.
|
||||
|
||||
+53
-41
@@ -3,22 +3,20 @@
|
||||
# Developer: jammyfu
|
||||
# Category: 🎨Painting👓Coder/📝Text
|
||||
|
||||
import comfy
|
||||
import re
|
||||
|
||||
class TextCombiner:
|
||||
def __init__(self):
|
||||
self.input_count = 1 # 初始输入节点数量
|
||||
|
||||
@classmethod
|
||||
def INPUT_TYPES(s):
|
||||
return {
|
||||
"required": {
|
||||
"text_1": ("STRING", {"multiline": True}),
|
||||
"refresh": ("BOOLEAN", {"default": False}),
|
||||
},
|
||||
"optional": {
|
||||
"text_2": ("STRING", {"multiline": True}), # 只保留一个可选输入
|
||||
"separator": ("STRING", {
|
||||
"default": ",",
|
||||
"multiline": False,
|
||||
"placeholder": "支持正则表达式和转义字符,如: ,|\\n,留空则用空格连接"
|
||||
}),
|
||||
},
|
||||
"optional": {}
|
||||
}
|
||||
|
||||
RETURN_TYPES = ("STRING",)
|
||||
@@ -26,38 +24,52 @@ class TextCombiner:
|
||||
FUNCTION = "combine_text"
|
||||
CATEGORY = "🎨Painting👓Coder/📝Text"
|
||||
|
||||
CONTEXT_MENU = {
|
||||
"refresh_node": ["Refresh Node", "refresh_node"],
|
||||
"add_input": ["Add Input", "add_input"],
|
||||
}
|
||||
|
||||
def combine_text(self, text_1, refresh=False, **kwargs):
|
||||
# 检查是否需要添加新的输入
|
||||
if kwargs.get(f"text_{self.input_count + 1}"):
|
||||
self.add_input()
|
||||
|
||||
# 组合所有非空文本
|
||||
texts = [text_1] + [v for k, v in kwargs.items() if v and v.strip()]
|
||||
combined_text = ", ".join(t.strip() for t in texts if t.strip())
|
||||
return (combined_text,)
|
||||
|
||||
def add_input(self):
|
||||
self.input_count += 1
|
||||
# 动态更新 INPUT_TYPES
|
||||
self.INPUT_TYPES = lambda s: {
|
||||
"required": {
|
||||
"text_1": ("STRING", {"multiline": True}),
|
||||
"refresh": ("BOOLEAN", {"default": False}),
|
||||
},
|
||||
"optional": {
|
||||
f"text_{i}": ("STRING", {"multiline": True})
|
||||
for i in range(2, self.input_count + 2) # +2 是为了总是多一个空输入
|
||||
},
|
||||
}
|
||||
return {"refresh": True}
|
||||
|
||||
def refresh_node(self):
|
||||
return {"refresh": True}
|
||||
def combine_text(self, separator=",", **kwargs):
|
||||
try:
|
||||
# 检查分隔符是否为空
|
||||
if not separator.strip():
|
||||
# 如果为空,使用空格作为分隔符
|
||||
actual_separator = " "
|
||||
is_newline_separator = False
|
||||
else:
|
||||
# 处理转义字符
|
||||
actual_separator = bytes(separator, "utf-8").decode("unicode_escape")
|
||||
# 检查分隔符是否包含换行相关字符
|
||||
is_newline_separator = bool(re.search(r'\\[rn]|[\r\n]', actual_separator))
|
||||
|
||||
# 收集所有非空文本
|
||||
texts = []
|
||||
for i in range(1, len(kwargs) + 1):
|
||||
key = f"text_{i}"
|
||||
if key in kwargs and kwargs[key] is not None:
|
||||
input_text = kwargs[key]
|
||||
# 标准化输入文本的换行符
|
||||
input_text = input_text.replace('\r\n', '\n').replace('\r', '\n')
|
||||
|
||||
# 使用正则表达式分割输入文本
|
||||
split_texts = re.split(actual_separator, input_text) if actual_separator != " " else [input_text]
|
||||
# 过滤空字符串并添加到结果列表,保留纯空格字符串
|
||||
texts.extend(t.rstrip('\n').rstrip('\r') for t in split_texts if t is not None)
|
||||
|
||||
# 根据分隔符类型选择拼接方式
|
||||
if is_newline_separator:
|
||||
# 如果分隔符包含换行,使用换行符拼接
|
||||
combined_text = '\n'.join(t if t.strip() else '""' for t in texts) if texts else "等待输入文本"
|
||||
elif not separator.strip():
|
||||
# 如果分隔符为空,使用单个空格拼接
|
||||
combined_text = ' '.join(t if t.strip() else '""' for t in texts) if texts else "等待输入文本"
|
||||
else:
|
||||
# 否则使用逗号和空格拼接
|
||||
combined_text = ", ".join(t if t.strip() else '""' for t in texts) if texts else "等待输入文本"
|
||||
|
||||
return (combined_text,)
|
||||
|
||||
except re.error as e:
|
||||
# 如果正则表达式无效,返回错误信息
|
||||
return (f"正则表达式错误: {str(e)}",)
|
||||
except Exception as e:
|
||||
# 处理其他可能的错误
|
||||
return (f"错误: {str(e)}",)
|
||||
|
||||
# 添加到 ComfyUI 节点注册
|
||||
NODE_CLASS_MAPPINGS = {
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
import { app } from "/scripts/app.js";
|
||||
|
||||
app.registerExtension({
|
||||
name: "Comfy.PaintingCoder.ClickPopup",
|
||||
async beforeRegisterNodeDef(nodeType, nodeData, app) {
|
||||
if (nodeData.name === "ClickPopup") {
|
||||
// 添加按钮点击事件处理
|
||||
const onNodeCreated = nodeType.prototype.onNodeCreated;
|
||||
nodeType.prototype.onNodeCreated = function () {
|
||||
const result = onNodeCreated ? onNodeCreated.apply(this, arguments) : undefined;
|
||||
|
||||
// 获取按钮部件
|
||||
const buttonWidget = this.widgets?.find(w => w.name === "button");
|
||||
if (buttonWidget) {
|
||||
buttonWidget.callback = () => {
|
||||
alert("Button clicked!");
|
||||
// 触发按钮点击后重置状态
|
||||
buttonWidget.value = false;
|
||||
};
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,57 @@
|
||||
import { app } from "/scripts/app.js";
|
||||
|
||||
app.registerExtension({
|
||||
name: "Comfy.PaintingCoder.TextCombiner",
|
||||
async beforeRegisterNodeDef(nodeType, nodeData, app) {
|
||||
if (nodeData.name === "TextCombiner") {
|
||||
const onNodeCreated = nodeType.prototype.onNodeCreated;
|
||||
nodeType.prototype.onNodeCreated = function() {
|
||||
const result = onNodeCreated ? onNodeCreated.apply(this, arguments) : undefined;
|
||||
|
||||
// 初始化状态
|
||||
this.lastConnectedCount = 0;
|
||||
|
||||
// 添加第一个输入点
|
||||
console.log("初始化:添加第一个输入点");
|
||||
this.addInput("text_1", "STRING");
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
nodeType.prototype.onConnectionsChange = function(connectionType, slot, isConnected) {
|
||||
if (connectionType === 1) { // 输入连接
|
||||
console.log(`连接变化 - 槽位: ${slot}, 已连接: ${isConnected}`);
|
||||
|
||||
const connectedCount = this.inputs.reduce((count, input) =>
|
||||
count + (input.link ? 1 : 0), 0);
|
||||
|
||||
console.log(`当前连接数量: ${connectedCount}, 上次连接数量: ${this.lastConnectedCount}`);
|
||||
|
||||
if (connectedCount !== this.lastConnectedCount) {
|
||||
this.lastConnectedCount = connectedCount;
|
||||
const targetCount = connectedCount + 1;
|
||||
console.log(`目标输入点数量: ${targetCount}`);
|
||||
|
||||
while (this.inputs.length < targetCount) {
|
||||
const newIndex = this.inputs.length + 1;
|
||||
console.log(`添加新输入点: text_${newIndex}`);
|
||||
this.addInput(`text_${newIndex}`, "STRING");
|
||||
}
|
||||
|
||||
while (this.inputs.length > Math.max(targetCount, 1)) {
|
||||
const lastInput = this.inputs[this.inputs.length - 1];
|
||||
if (!lastInput.link) {
|
||||
console.log(`移除输入点: ${this.inputs.length}`);
|
||||
this.removeInput(this.inputs.length - 1);
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`更新节点大小,当前输入点数量: ${this.inputs.length}`);
|
||||
this.setSize(this.computeSize());
|
||||
app.graph.setDirtyCanvas(true);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user