Files
animate/docs/js/controls/ControlManager.js
Sam 14ec23237f V1.1
Giant refactor. added layers. ui overhaul. added save/load and we now got presets
2025-12-28 03:21:25 +13:00

117 lines
3.2 KiB
JavaScript

/**
* ControlManager - Manages UI controls for shapes
*
* Handles creation, updates, and cleanup of control panels
* Ready for Phase 2 multi-shape support (panels per shape)
*/
class ControlManager {
constructor(containerId) {
this.container = document.getElementById(containerId);
this.filterManager = filterManager; // Use global FilterManager
this.factory = new ControlFactory(this);
// Track all active controls (for future multi-shape, keyed by shape id)
this.activeControls = new Map();
}
/**
* Add a filter to a control
*/
addFilter(controlData, controlConfig, filterType) {
const filterInstance = this.filterManager.createFilterInstance(filterType, controlConfig);
const filterDef = this.filterManager.getFilter(filterType);
if (!controlData.filters) {
controlData.filters = [];
}
// Create filter UI
const filterUI = this.factory.createFilterUI(
filterInstance,
filterDef,
controlData,
controlConfig
);
controlData.filtersContainer.appendChild(filterUI);
controlData.filters.push(filterInstance);
}
/**
* Remove a filter from a control
*/
removeFilter(controlData, filterInstance) {
const index = controlData.filters.indexOf(filterInstance);
if (index > -1) {
controlData.filters.splice(index, 1);
if (filterInstance.element && filterInstance.element.parentNode) {
filterInstance.element.parentNode.removeChild(filterInstance.element);
}
}
}
/**
* Add a control for a shape
* @param {object} config - Control configuration
* @param {BaseShape} instance - Shape instance
* @returns {object} Control data
*/
addControl(config, instance) {
return this.factory.create(config, instance, this.container);
}
/**
* Remove a control
* @param {object} controlData - Control data from addControl
*/
removeControl(controlData) {
if (!controlData) return;
// Remove event listeners
if (controlData.element && controlData.listener) {
const eventType = controlData.type === 'checkbox' ? 'change' :
controlData.type === 'dropdown' ? 'change' : 'input';
controlData.element.removeEventListener(eventType, controlData.listener);
}
// Remove filters
if (controlData.filters) {
for (const filter of controlData.filters) {
if (filter.element && filter.element.parentNode) {
filter.element.parentNode.removeChild(filter.element);
}
}
}
// Remove wrapper element
if (controlData.wrapper && controlData.wrapper.parentNode) {
controlData.wrapper.parentNode.removeChild(controlData.wrapper);
}
}
/**
* Clear all controls
*/
clearAll() {
while (this.container.firstChild) {
this.container.removeChild(this.container.firstChild);
}
this.activeControls.clear();
}
/**
* Update a control's displayed value programmatically
*/
updateControlValue(property, value) {
const element = document.getElementById(`el${property}`);
const label = document.getElementById(`elText${property}`);
if (element) {
element.value = value;
}
if (label) {
label.textContent = Math.round(value * 100) / 100;
}
}
}