Single direction field (combo or optional input); unique list IDs per node instance

This commit is contained in:
2026-04-22 14:36:11 -07:00
parent f3d8c6c0f3
commit e5e19c4dbc
2 changed files with 28 additions and 72 deletions

View File

@@ -17,51 +17,19 @@ def _discover_directories():
candidates = set() candidates = set()
for root, dirs, files in os.walk(base_dir, followlinks=True): for root, dirs, _ in os.walk(base_dir, followlinks=True):
rel = os.path.relpath(root, base_dir) rel = os.path.relpath(root, base_dir)
if rel == ".": if rel == ".":
continue continue
dirs_lower = {d.lower() for d in dirs} dirs_lower = {d.lower() for d in dirs}
if VALID_DIRECTIONS & dirs_lower: if VALID_DIRECTIONS & dirs_lower or VALID_MODALITIES & dirs_lower:
candidates.add(rel)
elif VALID_MODALITIES & dirs_lower:
candidates.add(rel) candidates.add(rel)
return sorted(candidates) return sorted(candidates)
def _discover_children(parent_rel):
base_dir = folder_paths.get_input_directory()
if parent_rel:
parent_abs = os.path.join(base_dir, parent_rel)
else:
parent_abs = base_dir
if not os.path.isdir(parent_abs):
return []
children = set()
try:
for name in os.listdir(parent_abs):
full = os.path.join(parent_abs, name)
if os.path.isdir(full):
rel = os.path.relpath(full, base_dir)
children.add(rel)
except OSError:
pass
my_children = set()
for child in children:
child_parts = child.split("/")
parent_parts = parent_rel.split("/") if parent_rel else []
if len(child_parts) == len(parent_parts) + 1:
my_children.add(child_parts[-1])
return sorted(my_children)
def _resolve_target_dir(base_dir, directory, direction): def _resolve_target_dir(base_dir, directory, direction):
if not directory or not (isinstance(directory, str) and directory.strip()): if not directory or not (isinstance(directory, str) and directory.strip()):
raise ValueError("directory must be a non-empty string") raise ValueError("directory must be a non-empty string")
@@ -120,14 +88,17 @@ class CompassImageLoader:
return { return {
"required": { "required": {
"directory": (directories if directories else ["(none found)"],), "directory": (directories if directories else ["(none found)"],),
"direction": (["", "n", "ne", "e", "se", "s", "sw", "w", "nw"],), "direction": (
["", "n", "ne", "e", "se", "s", "sw", "w", "nw"],
{"default": ""},
),
"modality": (["image", "depth", "openpose"],), "modality": (["image", "depth", "openpose"],),
"frame": ("STRING", {"default": ""}), "frame": ("STRING", {"default": ""}),
"width": ("INT", {"default": 0, "min": 0, "max": 16384, "step": 1}), "width": ("INT", {"default": 0, "min": 0, "max": 16384, "step": 1}),
"height": ("INT", {"default": 0, "min": 0, "max": 16384, "step": 1}), "height": ("INT", {"default": 0, "min": 0, "max": 16384, "step": 1}),
}, },
"optional": { "optional": {
"direction_in": ("STRING", {"default": ""}), "direction_override": ("STRING", {"default": ""}),
}, },
} }
@@ -138,12 +109,12 @@ class CompassImageLoader:
def load_images( def load_images(
self, directory, direction, modality, frame=None, width=0, height=0, self, directory, direction, modality, frame=None, width=0, height=0,
direction_in=None direction_override=None
): ):
if direction_in and direction_in.strip(): if direction_override is not None and str(direction_override).strip():
resolved_direction = direction_in.strip() resolved_direction = str(direction_override).strip()
elif direction and direction.strip(): elif direction and direction.strip():
resolved_direction = direction.strip() resolved_direction = str(direction).strip()
else: else:
resolved_direction = "" resolved_direction = ""
@@ -198,14 +169,14 @@ class CompassImageLoader:
@classmethod @classmethod
def IS_CHANGED( def IS_CHANGED(
cls, directory, direction, modality, frame=None, width=0, height=0, cls, directory, direction, modality, frame=None, width=0, height=0,
direction_in=None direction_override=None
): ):
import hashlib import hashlib
if direction_in and direction_in.strip(): if direction_override is not None and str(direction_override).strip():
resolved_direction = direction_in.strip() resolved_direction = str(direction_override).strip()
elif direction and direction.strip(): elif direction and direction.strip():
resolved_direction = direction.strip() resolved_direction = str(direction).strip()
else: else:
resolved_direction = "" resolved_direction = ""

View File

@@ -84,9 +84,14 @@ app.registerExtension({
const inputEl = filterWidget?.inputEl; const inputEl = filterWidget?.inputEl;
if (!inputEl) return; if (!inputEl) return;
const listId = `compass_dir_list_${Date.now()}_${Math.random().toString(36).slice(2, 7)}`;
const listEl = document.createElement("ul"); const listEl = document.createElement("ul");
listEl.id = listId;
listEl.style.display = "none"; listEl.style.display = "none";
listEl.style.position = "absolute";
listEl.style.zIndex = "9999";
document.body.appendChild(listEl); document.body.appendChild(listEl);
inputEl._listId = listId;
inputEl._currentPrefix = directoryWidget.value || ""; inputEl._currentPrefix = directoryWidget.value || "";
@@ -147,8 +152,9 @@ app.registerExtension({
inputEl.addEventListener("blur", () => { inputEl.addEventListener("blur", () => {
setTimeout(() => { setTimeout(() => {
if (!listEl.contains(document.activeElement)) { const list = document.getElementById(inputEl._listId);
hideDropdown(listEl); if (list && !list.contains(document.activeElement)) {
hideDropdown(list);
} }
}, 150); }, 150);
}); });
@@ -171,7 +177,9 @@ app.registerExtension({
} }
}); });
const origSetValue = directoryWidget.callback ? directoryWidget.callback.bind(directoryWidget) : () => {}; const origSetValue = directoryWidget.callback
? directoryWidget.callback.bind(directoryWidget)
: () => {};
directoryWidget.callback = (value) => { directoryWidget.callback = (value) => {
origSetValue(value); origSetValue(value);
inputEl._currentPrefix = value || ""; inputEl._currentPrefix = value || "";
@@ -181,32 +189,9 @@ app.registerExtension({
const origOnRemoved = this.onRemoved ? this.onRemoved.bind(this) : () => {}; const origOnRemoved = this.onRemoved ? this.onRemoved.bind(this) : () => {};
this.onRemoved = () => { this.onRemoved = () => {
origOnRemoved(); origOnRemoved();
listEl.remove(); const list = document.getElementById(listId);
if (list) list.remove();
}; };
const imageWidget = this.widgets?.find((w) => w.name === "image");
if (imageWidget) {
const origCallback = imageWidget.callback ? imageWidget.callback.bind(imageWidget) : () => {};
imageWidget.callback = (value) => {
origCallback(value);
if (imageWidget.element) {
imageWidget.element.style.opacity = "1";
}
};
}
}; };
}, },
async loadedGraphNode(node) {
if (node.type !== "CompassImageLoader") return;
const directoryWidget = node.widgets?.find((w) => w.name === "directory");
const filterWidget = node.widgets?.find((w) => w.name === "directory_filter");
const inputEl = filterWidget?.inputEl;
const listEl = document.getElementById("compass_dir_list");
if (inputEl && listEl) {
inputEl._currentPrefix = directoryWidget?.value || "";
}
},
}); });