Add Master Visibility Toggle to Layers Panel

Introduce a three-state checkbox in CanvasLayersPanel header to control visibility of all layers at once. Supports automatic state updates and integrates with renderLayers() for seamless layer management.
This commit is contained in:
Dariusz L
2025-08-09 16:15:11 +02:00
parent 00cf74a3c2
commit c9860cac9e
4 changed files with 295 additions and 1 deletions

View File

@@ -121,6 +121,7 @@ export class CanvasLayersPanel {
this.container.tabIndex = 0; // Umożliwia fokus na panelu
this.container.innerHTML = `
<div class="layers-panel-header">
<div class="master-visibility-toggle" title="Toggle all layers visibility"></div>
<span class="layers-panel-title">Layers</span>
<div class="layers-panel-controls">
<button class="layers-btn" id="delete-layer-btn" title="Delete layer"></button>
@@ -135,6 +136,7 @@ export class CanvasLayersPanel {
// Setup event listeners dla przycisków
this.setupControlButtons();
this.setupMasterVisibilityToggle();
// Dodaj listener dla klawiatury, aby usuwanie działało z panelu
this.container.addEventListener('keydown', (e: KeyboardEvent) => {
@@ -169,6 +171,74 @@ export class CanvasLayersPanel {
this.updateButtonStates();
}
setupMasterVisibilityToggle(): void {
if (!this.container) return;
const toggleContainer = this.container.querySelector('.master-visibility-toggle') as HTMLElement;
if (!toggleContainer) return;
const updateToggleState = () => {
const total = this.canvas.layers.length;
const visibleCount = this.canvas.layers.filter(l => l.visible).length;
toggleContainer.innerHTML = '';
const checkboxContainer = document.createElement('div');
checkboxContainer.className = 'checkbox-container';
const checkbox = document.createElement('input');
checkbox.type = 'checkbox';
checkbox.id = 'master-visibility-checkbox';
const customCheckbox = document.createElement('span');
customCheckbox.className = 'custom-checkbox';
checkboxContainer.appendChild(checkbox);
checkboxContainer.appendChild(customCheckbox);
if (visibleCount === 0) {
checkbox.checked = false;
checkbox.indeterminate = false;
customCheckbox.classList.remove('checked', 'indeterminate');
} else if (visibleCount === total) {
checkbox.checked = true;
checkbox.indeterminate = false;
customCheckbox.classList.add('checked');
customCheckbox.classList.remove('indeterminate');
} else {
checkbox.checked = false;
checkbox.indeterminate = true;
customCheckbox.classList.add('indeterminate');
customCheckbox.classList.remove('checked');
}
checkboxContainer.addEventListener('click', (e) => {
e.stopPropagation();
let newVisible: boolean;
if (checkbox.indeterminate) {
newVisible = false; // hide all when mixed
} else if (checkbox.checked) {
newVisible = false; // toggle to hide all
} else {
newVisible = true; // toggle to show all
}
this.canvas.layers.forEach(layer => {
layer.visible = newVisible;
});
this.canvas.render();
this.canvas.requestSaveState();
updateToggleState();
this.renderLayers();
});
toggleContainer.appendChild(checkboxContainer);
};
updateToggleState();
this._updateMasterVisibilityToggle = updateToggleState;
}
private _updateMasterVisibilityToggle?: () => void;
renderLayers(): void {
if (!this.layersContainer) {
log.warn('Layers container not initialized');
@@ -186,10 +256,11 @@ export class CanvasLayersPanel {
sortedLayers.forEach((layer: Layer, index: number) => {
const layerElement = this.createLayerElement(layer, index);
if(this.layersContainer)
if (this.layersContainer)
this.layersContainer.appendChild(layerElement);
});
if (this._updateMasterVisibilityToggle) this._updateMasterVisibilityToggle();
log.debug(`Rendered ${sortedLayers.length} layers`);
}