updated to v2.0.0
added new features such as dynamic sum adjustment and sum-lock dynamics
This commit is contained in:
+73
-48
@@ -1,6 +1,6 @@
|
||||
import { app } from "../../scripts/app.js";
|
||||
|
||||
console.log("Loading context.js for Slider Stacker");
|
||||
// Removed console log
|
||||
|
||||
// --- Helper Functions (Copied from Dynamic.js for self-containment) ---
|
||||
|
||||
@@ -14,9 +14,28 @@ const getWidgetValue = (widget) => {
|
||||
return isNaN(num) ? 0 : num;
|
||||
};
|
||||
|
||||
// Function to check if node is our Slider Stacker using multiple identification methods
|
||||
function isSliderStackerNode(node) {
|
||||
// Check the display title
|
||||
const nodeTitle = node.getTitle ? node.getTitle() : node.title;
|
||||
if (nodeTitle === "Slider Stacker") return true;
|
||||
|
||||
// Check internal type name
|
||||
if (node.type === "Slider Stacker (DSS)") return true;
|
||||
|
||||
// Check properties that are unique to our node
|
||||
if (findWidgetByName(node, "sliders_count") &&
|
||||
findWidgetByName(node, "sliders_max") &&
|
||||
findWidgetByName(node, "slider_name_1")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// Gets the actual max strength based on current slider values and activity
|
||||
function recalculateCurrentMaxStrength(node) {
|
||||
const sliderCountWidget = findWidgetByName(node, "slider_count");
|
||||
const sliderCountWidget = findWidgetByName(node, "sliders_count");
|
||||
const count = getWidgetValue(sliderCountWidget);
|
||||
let currentMaxValue = 0;
|
||||
for (let i = 1; i <= count; i++) {
|
||||
@@ -25,7 +44,7 @@ function recalculateCurrentMaxStrength(node) {
|
||||
currentMaxValue = Math.max(currentMaxValue, getWidgetValue(wtWidget));
|
||||
}
|
||||
}
|
||||
const maxStrengthWidget = findWidgetByName(node, "slider_max_strength");
|
||||
const maxStrengthWidget = findWidgetByName(node, "sliders_max");
|
||||
const overallMax = maxStrengthWidget?.options?.max ?? 2.0;
|
||||
const overallMin = maxStrengthWidget?.options?.min ?? 0.0;
|
||||
return Math.max(overallMin, Math.min(currentMaxValue, overallMax));
|
||||
@@ -34,7 +53,7 @@ function recalculateCurrentMaxStrength(node) {
|
||||
// Updates the stored normalized weights based on current displayed values and max strength
|
||||
function updateNormalization(node, currentMaxStrength) {
|
||||
if (!node.normalizedSliderWeights) node.normalizedSliderWeights = {}; // Ensure it exists
|
||||
const sliderCountWidget = findWidgetByName(node, "slider_count");
|
||||
const sliderCountWidget = findWidgetByName(node, "sliders_count");
|
||||
const maxSliders = sliderCountWidget?.options?.max || 50;
|
||||
for (let i = 1; i <= maxSliders; i++) {
|
||||
const wtWidget = findWidgetByName(node, `(${i})`);
|
||||
@@ -50,9 +69,9 @@ function updateNormalization(node, currentMaxStrength) {
|
||||
// Updates the displayed values of individual sliders based on normalized weights and new max strength
|
||||
// Note: Needs access to node._isUpdatingInternally if called directly, but here it's used post-operation
|
||||
function updateAllSliderDisplaysFromContext(node, newMaxStrength) {
|
||||
if (!node.normalizedSliderWeights) return;
|
||||
if (!node.normalizedSliderWeights) return;
|
||||
node._isUpdatingInternally = true; // Set flag for this operation
|
||||
const count = getWidgetValue(findWidgetByName(node, "slider_count"));
|
||||
const count = getWidgetValue(findWidgetByName(node, "sliders_count"));
|
||||
for (let i = 1; i <= count; i++) {
|
||||
const wtWidget = findWidgetByName(node, `(${i})`);
|
||||
if (wtWidget) {
|
||||
@@ -60,17 +79,19 @@ function updateAllSliderDisplaysFromContext(node, newMaxStrength) {
|
||||
let newDisplayValue = normalizedValue * newMaxStrength;
|
||||
const widgetMax = wtWidget.options?.max ?? 2.0;
|
||||
const widgetMin = wtWidget.options?.min ?? 0.0;
|
||||
newDisplayValue = Math.max(widgetMin, Math.min(newDisplayValue, widgetMax, newMaxStrength));
|
||||
newDisplayValue = Math.max(widgetMin, Math.min(newDisplayValue, widgetMax, newMaxStrength));
|
||||
if (Math.abs(getWidgetValue(wtWidget) - newDisplayValue) > 0.001) {
|
||||
wtWidget.value = newDisplayValue; // This should use the intercepted setter
|
||||
}
|
||||
}
|
||||
}
|
||||
node.graph.setDirtyCanvas(true, true);
|
||||
if (node.graph) {
|
||||
node.graph.setDirtyCanvas(true, true);
|
||||
}
|
||||
node._isUpdatingInternally = false;
|
||||
}
|
||||
|
||||
// --- Function to add menu options ---
|
||||
// --- Function to add menu options ---
|
||||
|
||||
function addContextMenuOptions(node) {
|
||||
const originalGetExtraMenuOptions = node.getExtraMenuOptions;
|
||||
@@ -83,7 +104,7 @@ function addContextMenuOptions(node) {
|
||||
options.push({
|
||||
content: "Average Slider Values",
|
||||
callback: () => {
|
||||
const count = getWidgetValue(findWidgetByName(this, "slider_count"));
|
||||
const count = getWidgetValue(findWidgetByName(this, "sliders_count"));
|
||||
let sum = 0;
|
||||
let activeCount = 0;
|
||||
for (let i = 1; i <= count; i++) {
|
||||
@@ -94,27 +115,29 @@ function addContextMenuOptions(node) {
|
||||
}
|
||||
}
|
||||
const average = activeCount > 0 ? sum / activeCount : 0;
|
||||
|
||||
this._isUpdatingInternally = true;
|
||||
|
||||
this._isUpdatingInternally = true;
|
||||
for (let i = 1; i <= count; i++) {
|
||||
const wtWidget = findWidgetByName(this, `(${i})`);
|
||||
if (wtWidget) { wtWidget.value = average; }
|
||||
}
|
||||
this._isUpdatingInternally = false;
|
||||
|
||||
|
||||
// Recalculate max and update normalization *after* loop
|
||||
const newMax = recalculateCurrentMaxStrength(this);
|
||||
updateNormalization(this, newMax);
|
||||
|
||||
|
||||
// Trigger update on master slider to sync everything
|
||||
const masterWidget = findWidgetByName(this, "slider_max_strength");
|
||||
const masterWidget = findWidgetByName(this, "sliders_max");
|
||||
if (masterWidget && Math.abs(getWidgetValue(masterWidget) - newMax) > 0.001) {
|
||||
masterWidget.value = newMax; // This uses the setter from Dynamic.js
|
||||
} else {
|
||||
// If max didn't change, still redraw displays based on new average
|
||||
updateAllSliderDisplaysFromContext(this, newMax);
|
||||
}
|
||||
this.graph.setDirtyCanvas(true, true);
|
||||
if (this.graph) {
|
||||
this.graph.setDirtyCanvas(true, true);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -122,25 +145,27 @@ function addContextMenuOptions(node) {
|
||||
options.push({
|
||||
content: "Reset Slider Values",
|
||||
callback: () => {
|
||||
const count = getWidgetValue(findWidgetByName(this, "slider_count"));
|
||||
const defaultValue = 1.0;
|
||||
|
||||
const count = getWidgetValue(findWidgetByName(this, "sliders_count"));
|
||||
const defaultValue = 1.0;
|
||||
|
||||
this._isUpdatingInternally = true;
|
||||
for (let i = 1; i <= count; i++) {
|
||||
const wtWidget = findWidgetByName(this, `(${i})`);
|
||||
if (wtWidget) { wtWidget.value = defaultValue; }
|
||||
}
|
||||
this._isUpdatingInternally = false;
|
||||
|
||||
|
||||
const newMax = recalculateCurrentMaxStrength(this);
|
||||
updateNormalization(this, newMax);
|
||||
const masterWidget = findWidgetByName(this, "slider_max_strength");
|
||||
updateNormalization(this, newMax);
|
||||
const masterWidget = findWidgetByName(this, "sliders_max");
|
||||
if (masterWidget && Math.abs(getWidgetValue(masterWidget) - newMax) > 0.001) {
|
||||
masterWidget.value = newMax;
|
||||
} else {
|
||||
updateAllSliderDisplaysFromContext(this, newMax);
|
||||
}
|
||||
this.graph.setDirtyCanvas(true, true);
|
||||
if (this.graph) {
|
||||
this.graph.setDirtyCanvas(true, true);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -148,7 +173,7 @@ function addContextMenuOptions(node) {
|
||||
options.push({
|
||||
content: "Set All to Max Value",
|
||||
callback: () => {
|
||||
const count = getWidgetValue(findWidgetByName(this, "slider_count"));
|
||||
const count = getWidgetValue(findWidgetByName(this, "sliders_count"));
|
||||
let maxValue = -Infinity; // Start low
|
||||
|
||||
// First pass: Find the maximum value among visible sliders
|
||||
@@ -158,37 +183,36 @@ function addContextMenuOptions(node) {
|
||||
maxValue = Math.max(maxValue, getWidgetValue(wtWidget));
|
||||
}
|
||||
}
|
||||
// Ensure maxValue is within widget bounds if needed (though setters handle clamping)
|
||||
// const widgetMaxBound = findWidgetByName(this, `(1)`)?.options?.max ?? 2.0;
|
||||
// maxValue = Math.min(maxValue, widgetMaxBound);
|
||||
|
||||
|
||||
// Second pass: Set all visible sliders to the found maximum value
|
||||
this._isUpdatingInternally = true;
|
||||
this._isUpdatingInternally = true;
|
||||
for (let i = 1; i <= count; i++) {
|
||||
const wtWidget = findWidgetByName(this, `(${i})`);
|
||||
if (wtWidget) { wtWidget.value = maxValue; } // Use setter
|
||||
}
|
||||
this._isUpdatingInternally = false;
|
||||
|
||||
|
||||
// Recalculate max (should be == maxValue), normalize, and update master slider
|
||||
const newMax = recalculateCurrentMaxStrength(this); // Will be maxValue
|
||||
updateNormalization(this, newMax);
|
||||
const masterWidget = findWidgetByName(this, "slider_max_strength");
|
||||
const masterWidget = findWidgetByName(this, "sliders_max");
|
||||
// Update master slider directly - its setter handles updating displays
|
||||
if (masterWidget && Math.abs(getWidgetValue(masterWidget) - newMax) > 0.001) {
|
||||
masterWidget.value = newMax;
|
||||
masterWidget.value = newMax;
|
||||
}
|
||||
if (this.graph) {
|
||||
this.graph.setDirtyCanvas(true, true);
|
||||
}
|
||||
this.graph.setDirtyCanvas(true, true);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
// Option 4: Set All to Min Value
|
||||
options.push({
|
||||
content: "Set All to Min Value",
|
||||
callback: () => {
|
||||
const count = getWidgetValue(findWidgetByName(this, "slider_count"));
|
||||
const count = getWidgetValue(findWidgetByName(this, "sliders_count"));
|
||||
let minValue = Infinity; // Start high
|
||||
|
||||
|
||||
// First pass: Find the minimum value among visible sliders
|
||||
for (let i = 1; i <= count; i++) {
|
||||
const wtWidget = findWidgetByName(this, `(${i})`);
|
||||
@@ -196,40 +220,41 @@ function addContextMenuOptions(node) {
|
||||
minValue = Math.min(minValue, getWidgetValue(wtWidget));
|
||||
}
|
||||
}
|
||||
// Ensure minValue isn't below widget bounds
|
||||
// const widgetMinBound = findWidgetByName(this, `(1)`)?.options?.min ?? 0.0;
|
||||
// minValue = Math.max(minValue, widgetMinBound);
|
||||
|
||||
// Second pass: Set all visible sliders to the found minimum value
|
||||
this._isUpdatingInternally = true;
|
||||
this._isUpdatingInternally = true;
|
||||
for (let i = 1; i <= count; i++) {
|
||||
const wtWidget = findWidgetByName(this, `(${i})`);
|
||||
if (wtWidget) { wtWidget.value = minValue; } // Use setter
|
||||
}
|
||||
this._isUpdatingInternally = false;
|
||||
|
||||
|
||||
// Recalculate max (will be == minValue), normalize, and update master slider
|
||||
const newMax = recalculateCurrentMaxStrength(this); // Will be minValue
|
||||
updateNormalization(this, newMax);
|
||||
const masterWidget = findWidgetByName(this, "slider_max_strength");
|
||||
updateNormalization(this, newMax);
|
||||
const masterWidget = findWidgetByName(this, "sliders_max");
|
||||
// Update master slider directly
|
||||
if (masterWidget && Math.abs(getWidgetValue(masterWidget) - newMax) > 0.001) {
|
||||
masterWidget.value = newMax;
|
||||
}
|
||||
this.graph.setDirtyCanvas(true, true);
|
||||
if (this.graph) {
|
||||
this.graph.setDirtyCanvas(true, true);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
// --- ComfyUI Extension ---
|
||||
// --- ComfyUI Extension ---
|
||||
|
||||
app.registerExtension({
|
||||
name: "Comfy.DynamicSlidersStack.ContextMenu",
|
||||
nodeCreated(node) {
|
||||
const nodeTitle = node.getTitle ? node.getTitle() : node.title;
|
||||
if (nodeTitle === "Slider Stacker") {
|
||||
// Use our robust identification instead of title
|
||||
if (isSliderStackerNode(node)) {
|
||||
addContextMenuOptions(node);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// console.log("Loaded Dynamic Sliders Stack Context Menu Script");
|
||||
|
||||
Reference in New Issue
Block a user