Files
2025-12-01 05:26:54 +00:00

220 lines
7.9 KiB
JavaScript

import { app } from '../../../scripts/app.js';
// == DEFAULTS ---
const DRIVEN_DEFAULTS = { driver: "", rotate: 0, d_scale: 1.0 };
const EASING_DEFAULTS = { path: "each", strength: 1.0, acceleration: 0.00 };
const SCALE_DEFAULT = 1.00;
const SELECTED_FOLDER_DEFAULT = null;
// == DRIVEN CONFIG PERSISTENCE ---
/**
* Initializes the DRIVEN configuration on a widget's value object.
* Handles migration and ensures the persistent `_drivenConfig` is the source of truth.
* @param {object} widgetValue The widget.value object to initialize.
* @param {object} loadedValue The raw `v` object from the widget's `set value(v)` setter.
*/
export function initializeDrivenConfig(widgetValue, loadedValue = null) {
// Handle migration from old format where `driven` was the config object
if (typeof widgetValue.driven === 'object' && widgetValue.driven !== null) {
widgetValue._drivenConfig = { ...DRIVEN_DEFAULTS, ...widgetValue.driven };
}
const loadedConfig = loadedValue?._drivenConfig;
widgetValue._drivenConfig = { ...DRIVEN_DEFAULTS, ...(loadedConfig || widgetValue._drivenConfig || {}) };
if (typeof widgetValue._drivenConfig.d_scale !== 'number' || isNaN(widgetValue._drivenConfig.d_scale)) {
widgetValue._drivenConfig.d_scale = DRIVEN_DEFAULTS.d_scale;
}
// Correct old 'smooth' property to 'd_scale'
if (widgetValue._drivenConfig.smooth !== undefined) {
if (widgetValue._drivenConfig.d_scale === 1.0) { // Only overwrite if d_scale is default
// Don't migrate old smooth=0 values to d_scale, since we want d_scale to default to 1.0
// Only migrate if the smooth value is not the old default of 0
if (widgetValue._drivenConfig.smooth !== 0) {
widgetValue._drivenConfig.d_scale = widgetValue._drivenConfig.smooth;
}
}
delete widgetValue._drivenConfig.smooth;
}
// Sync live `driven` object if it's active
if (widgetValue.driven) {
widgetValue.driven = { ...widgetValue._drivenConfig };
}
}
/**
* Updates a property in the DRIVEN configuration.
* @param {object} widget The widget instance.
* @param {string} property The property to update.
* @param {*} value The new value.
*/
export function updateDrivenConfigValue(widget, property, value) {
// Always update the persistent config
if (!widget.value._drivenConfig) {
widget.value._drivenConfig = { ...DRIVEN_DEFAULTS };
}
widget.value._drivenConfig[property] = value;
// If the driven toggle is on (i.e., `driven` is an object), update it too.
if (widget.value.driven && typeof widget.value.driven === 'object') {
widget.value.driven[property] = value;
}
if (app.graph) {
app.graph.setDirtyCanvas(true, true);
}
}
/**
* Toggles the driven state for a widget.
* When turning on, it copies the internal `_drivenConfig` to the live `driven` property.
* When turning off, it sets `driven` to false.
* @param {object} widget The widget instance.
*/
export function toggleDrivenState(widget) {
// Ensure the internal config is initialized before toggling.
if (!widget.value._drivenConfig) {
widget.value._drivenConfig = { ...DRIVEN_DEFAULTS };
}
if (widget.value.driven && typeof widget.value.driven === 'object') {
// State is ON -> Turn OFF
widget.value.driven = false;
} else {
// State is OFF -> Turn ON
// The live `driven` object becomes a copy of the persistent internal config.
widget.value.driven = { ...widget.value._drivenConfig };
}
if (app.graph) {
app.graph.setDirtyCanvas(true, true);
}
}
/**
* Prepares the driven config before its menu is displayed.
* Ensures the internal `_drivenConfig` is up-to-date with the live `driven` value if it's active.
* @param {object} widget The widget instance.
*/
export function prepareDrivenMenu(widget) {
if (!widget.value.driven) {
// If driven is off, ensure the internal config exists for the menu to read from.
if (!widget.value._drivenConfig || typeof widget.value._drivenConfig !== 'object') {
widget.value._drivenConfig = { ...DRIVEN_DEFAULTS };
}
} else if (typeof widget.value.driven === 'object') {
// If driven is on, sync the latest values from the live object to the internal one.
widget.value._drivenConfig = { ...widget.value.driven };
}
}
// == EASING CONFIG PERSISTENCE
/**
* @param {object} widgetValue The widget.value object to initialize.
*/
export function initializeEasingConfig(widgetValue, loadedValue = null) {
// Ensure the easingConfig object exists and apply defaults over the loaded data.
// Handle case where easingConfig might not exist at all (new layers)
if (!widgetValue.easingConfig || typeof widgetValue.easingConfig !== 'object') {
widgetValue.easingConfig = { path: "each", strength: 1.0, acceleration: 0.00 };
}
const loadedConfig = widgetValue.easingConfig;
// Apply defaults over the loaded data
widgetValue.easingConfig = { ...EASING_DEFAULTS, ...(loadedConfig || {}) };
}
/**
* Updates a property in the EASING configuration.
* @param {object} widget The widget instance.
* @param {string} property The property to update ('path' or 'strength').
* @param {*} value The new value.
*/
export function updateEasingConfigValue(widget, property, value) {
// Ensure the easingConfig object exists before updating.
if (!widget.value.easingConfig || typeof widget.value.easingConfig !== 'object') {
widget.value.easingConfig = { ...EASING_DEFAULTS };
}
// Update the property on the single source of truth.
widget.value.easingConfig[property] = value;
if (app.graph) {
app.graph.setDirtyCanvas(true, true);
}
}
// == SCALE CONFIG PERSISTENCE
/**
* Initializes the SCALE configuration on a widget's value object.
* @param {object} widgetValue The widget.value object to initialize.
* @param {object} loadedValue The raw `v` object from the widget's `set value(v)` setter.
*/
export function initializeScaleConfig(widgetValue, loadedValue = null) {
// Ensure scale exists and is a valid number, using loaded data or default
if (typeof widgetValue.scale !== 'number' || isNaN(widgetValue.scale)) {
widgetValue.scale = loadedValue?.scale !== undefined ? loadedValue.scale : SCALE_DEFAULT;
}
// Ensure scale is within valid bounds
widgetValue.scale = Math.max(0.01, Math.min(8.00, widgetValue.scale));
}
/**
* Updates the scale value for a widget.
* @param {object} widget The widget instance.
* @param {number} value The new scale value.
*/
export function updateScaleValue(widget, value) {
// Ensure the value is a valid number
if (typeof value !== 'number' || isNaN(value)) {
value = SCALE_DEFAULT;
}
// Clamp to valid range
value = Math.max(0.01, Math.min(8.00, value));
// Update the widget value
widget.value.scale = value;
if (app.graph) {
app.graph.setDirtyCanvas(true, true);
}
}
// == SELECTED FOLDER PERSISTENCE ==
/**
* Initializes the SELECTED FOLDER configuration on a widget's value object.
* @param {object} widgetValue The widget.value object to initialize.
* @param {object} loadedValue The raw `v` object from the widget's `set value(v)` setter.
*/
export function initializeSelectedFolderConfig(widgetValue, loadedValue = null) {
// Ensure selectedFolder exists, using loaded data or default
if (widgetValue.selectedFolder === undefined) {
widgetValue.selectedFolder = loadedValue?.selectedFolder !== undefined ? loadedValue.selectedFolder : SELECTED_FOLDER_DEFAULT;
}
}
/**
* Updates the selected folder value for a widget.
* @param {object} widget The widget instance.
* @param {string|null} value The new selected folder value.
*/
export function updateSelectedFolderValue(widget, value) {
// Update the widget value
widget.value.selectedFolder = value;
if (app.graph) {
app.graph.setDirtyCanvas(true, true);
}
}