Files
PozzettiAndrea-ComfyUI-Geom…/web/js/dynamic_widgets.js
T
2026-02-12 21:52:40 +01:00

120 lines
3.9 KiB
JavaScript

/**
* Dynamic Widget Visibility for Multi-Backend Nodes
*
* Shows/hides widgets based on selected backend.
* Mappings are loaded from backend_mappings.json (generated by prestartup_script.py).
*/
import { app } from "../../../scripts/app.js";
console.log("[GeomPack DynamicWidgets] Loading extension...");
// Will be populated from JSON
let BACKEND_MAPPINGS = {};
let BACKEND_WIDGET_NAME = {};
/**
* Fetch mappings from generated JSON (try both casing for manager installs)
*/
async function loadMappings() {
const paths = [
"/extensions/ComfyUI-GeometryPack/js/backend_mappings.json",
"/extensions/comfyui-geometrypack/js/backend_mappings.json",
];
for (const path of paths) {
try {
const response = await fetch(path);
if (response.ok) {
const data = await response.json();
BACKEND_MAPPINGS = data.mappings || {};
BACKEND_WIDGET_NAME = data.backend_widgets || {};
console.log("[GeomPack DynamicWidgets] Loaded mappings from", path);
return true;
}
} catch (e) {
// Try next path
}
}
console.warn("[GeomPack DynamicWidgets] Could not load backend_mappings.json");
return false;
}
// Load mappings on startup
loadMappings();
/**
* Update widget visibility based on selected backend
*/
function updateWidgetVisibility(node, selectedBackend) {
const nodeClass = node.comfyClass;
const mapping = BACKEND_MAPPINGS[nodeClass];
if (!mapping) return;
const visibleWidgets = mapping[selectedBackend] || [];
const backendWidgetName = BACKEND_WIDGET_NAME[nodeClass];
console.log(`[GeomPack DynamicWidgets] ${nodeClass}: backend="${selectedBackend}", visible=[${visibleWidgets.join(', ')}]`);
let visibilityChanged = false;
for (const widget of node.widgets || []) {
// Skip the backend/method selector itself and the mesh input
if (widget.name === backendWidgetName || widget.name === "trimesh" || widget.name === "mesh") continue;
// Check if this widget should be visible for the current backend
const allWidgets = Object.values(mapping).flat();
const isBackendWidget = allWidgets.includes(widget.name);
if (isBackendWidget) {
const shouldShow = visibleWidgets.includes(widget.name);
const wasHidden = widget.hidden;
widget.hidden = !shouldShow;
if (wasHidden !== widget.hidden) {
visibilityChanged = true;
console.log(`[GeomPack DynamicWidgets] Widget "${widget.name}": hidden=${widget.hidden}`);
}
}
}
if (visibilityChanged) {
node.setSize(node.computeSize());
app.graph.setDirtyCanvas(true, true);
}
}
app.registerExtension({
name: "GeomPack.DynamicWidgets",
nodeCreated(node) {
const nodeClass = node.comfyClass;
if (!BACKEND_MAPPINGS[nodeClass]) return;
console.log(`[GeomPack DynamicWidgets] Setting up node: ${nodeClass}`);
const backendWidgetName = BACKEND_WIDGET_NAME[nodeClass];
const backendWidget = node.widgets?.find(w => w.name === backendWidgetName);
if (!backendWidget) {
console.log(`[GeomPack DynamicWidgets] No ${backendWidgetName} widget found`);
return;
}
// Store original callback
const originalCallback = backendWidget.callback;
// Override callback to update visibility on change
backendWidget.callback = function(value) {
if (originalCallback) originalCallback.call(this, value);
updateWidgetVisibility(node, value);
};
// Initial visibility update (with delay to ensure widgets are created)
setTimeout(() => {
updateWidgetVisibility(node, backendWidget.value);
}, 50);
}
});
console.log("[GeomPack DynamicWidgets] Extension registered");