Files
CraftopiaStudio-ComfyUI-Cra…/smart_prompt_controller.py
T
rubz c0609cfc85 add Smart Profile Switch, fix folder picker, README overhaul, v1.0.2
- rename Smart Category Config → Smart Profile Switch 🧩 (code, JS, locales, demo workflow)
- add banner.svg and embed it at the top of README
- replace fragile OpenFileDialog folder-browse hack with native IFileDialog/FOS_PICKFOLDERS picker — fixes wrong-folder bug on single-click select
- flip Smart Resize's upscale_if_smaller default to true — node now resizes to target by default, as the name implies
- add width/height source tooltip to Smart Resolution Multiplier's image input
- fix stale widgets_values in smart_batch_resize_demo.json (10 fields → 13 after prefix/counter fields were added)
- full README rewrite: correct inputs/defaults/outputs for all 5 nodes, new Smart Profile Switch section, Example workflows section, expanded "Why these nodes?"
- add new example workflow (seedvr2_smartresize_demo.json), updated screenshots
- add assets/*.ai to .gitignore
- bump version to 1.0.2
2026-07-01 12:33:32 +02:00

99 lines
3.3 KiB
Python

class SmartPromptController:
"""
Craftopia — Smart Prompt Controller 📋
Cycles through up to 4 prompt lists using a single incrementing counter.
Counts lines automatically and outputs the selected prompt + list number.
"""
@classmethod
def INPUT_TYPES(cls):
return {
"required": {
"index": ("INT", {
"default": 1,
"min": 1,
"max": 99999,
"step": 1,
"display": "number",
"control_after_generate": "increment",
"tooltip": "Current position across all lists.",
}),
},
"optional": {
"prompt_list_1": ("STRING", {"forceInput": True, "tooltip": "Prompt list, one prompt per line."}),
"prompt_list_2": ("STRING", {"forceInput": True, "tooltip": "Optional second prompt list."}),
"prompt_list_3": ("STRING", {"forceInput": True, "tooltip": "Optional third prompt list."}),
"prompt_list_4": ("STRING", {"forceInput": True, "tooltip": "Optional fourth prompt list."}),
}
}
RETURN_TYPES = ("STRING", "INT")
RETURN_NAMES = ("prompt", "active_list")
FUNCTION = "control"
CATEGORY = "CraftKit"
OUTPUT_NODE = True
def _get_lines(self, text):
"""Return list of non-empty lines from a text block."""
if not text:
return []
if isinstance(text, list):
text = text[0] if text else ""
return [l for l in str(text).splitlines() if l.strip()]
def control(self, index, prompt_list_1="", prompt_list_2="",
prompt_list_3="", prompt_list_4=""):
raw = [prompt_list_1, prompt_list_2, prompt_list_3, prompt_list_4]
# Collect active lists: (list_index, [lines])
active = []
for i, text in enumerate(raw):
lines = self._get_lines(text)
if lines:
active.append((i, lines))
total_all = sum(len(lines) for _, lines in active)
if total_all == 0:
return {"ui": {"text": ["no prompts connected"]},
"result": ("", 0)}
# Map counter position to list + line
idx = (index - 1) % total_all
cumulative = 0
selected_list_index = 0
selected_line_index = 0
selected_prompt = ""
for list_idx, lines in active:
if idx < cumulative + len(lines):
selected_list_index = list_idx
selected_line_index = idx - cumulative
selected_prompt = lines[selected_line_index]
break
cumulative += len(lines)
# Label: "List 1 — 4/5 | total: 8"
list_number = selected_list_index + 1
list_total = len(self._get_lines(raw[selected_list_index]))
prompt_display = selected_line_index + 1
label = f"List {list_number} \u2014 {prompt_display}/{list_total} | total: {total_all}"
return {
"ui": {"text": [label]},
"result": (
selected_prompt,
list_number,
)
}
NODE_CLASS_MAPPINGS = {
"SmartPromptController": SmartPromptController,
}
NODE_DISPLAY_NAME_MAPPINGS = {
"SmartPromptController": "Smart Prompt Controller \ud83d\udccb",
}