From ed9fdf5d60fa82e22db8b861ef9275b569a8a399 Mon Sep 17 00:00:00 2001 From: Dariusz L Date: Sun, 3 Aug 2025 14:33:20 +0200 Subject: [PATCH] disable delete button when no layers selected Added updateButtonStates() to enable/disable delete button based on selection Updated control setup and selection handlers to call this method Added CSS for disabled button state and tooltip Delete button now disables when no layers are selected; all other panel features unchanged --- js/CanvasLayersPanel.js | 21 +++++++++++++++++++++ js/css/layers_panel.css | 11 +++++++++++ src/CanvasLayersPanel.ts | 29 +++++++++++++++++++++++++++-- src/css/layers_panel.css | 11 +++++++++++ 4 files changed, 70 insertions(+), 2 deletions(-) diff --git a/js/CanvasLayersPanel.js b/js/CanvasLayersPanel.js index 720624e..dc46007 100644 --- a/js/CanvasLayersPanel.js +++ b/js/CanvasLayersPanel.js @@ -139,6 +139,8 @@ export class CanvasLayersPanel { log.info('Delete layer button clicked'); this.deleteSelectedLayers(); }); + // Initial button state update + this.updateButtonStates(); } renderLayers() { if (!this.layersContainer) { @@ -228,6 +230,7 @@ export class CanvasLayersPanel { const newSelection = this.canvas.canvasSelection.selectedLayers.filter((l) => l !== layer); this.canvas.updateSelection(newSelection); this.updateSelectionAppearance(); + this.updateButtonStates(); } }); layerRow.addEventListener('dblclick', (e) => { @@ -260,6 +263,7 @@ export class CanvasLayersPanel { this.canvas.updateSelectionLogic(layer, isCtrlPressed, isShiftPressed, index); // Aktualizuj tylko wygląd (klasy CSS), bez niszczenia DOM this.updateSelectionAppearance(); + this.updateButtonStates(); log.debug(`Layer clicked: ${layer.name}, selection count: ${this.canvas.canvasSelection.selectedLayers.length}`); } startEditingLayerName(nameElement, layer) { @@ -440,12 +444,29 @@ export class CanvasLayersPanel { } }); } + /** + * Aktualizuje stan przycisków w zależności od zaznaczenia warstw + */ + updateButtonStates() { + if (!this.container) + return; + const deleteBtn = this.container.querySelector('#delete-layer-btn'); + const hasSelectedLayers = this.canvas.canvasSelection.selectedLayers.length > 0; + if (deleteBtn) { + deleteBtn.disabled = !hasSelectedLayers; + deleteBtn.title = hasSelectedLayers + ? `Delete ${this.canvas.canvasSelection.selectedLayers.length} selected layer(s)` + : 'No layers selected'; + } + log.debug(`Button states updated - delete button ${hasSelectedLayers ? 'enabled' : 'disabled'}`); + } /** * Aktualizuje panel gdy zmieni się zaznaczenie (wywoływane z zewnątrz). * Zamiast pełnego renderowania, tylko aktualizujemy wygląd. */ onSelectionChanged() { this.updateSelectionAppearance(); + this.updateButtonStates(); } destroy() { if (this.container && this.container.parentNode) { diff --git a/js/css/layers_panel.css b/js/css/layers_panel.css index 22dacec..d98d211 100644 --- a/js/css/layers_panel.css +++ b/js/css/layers_panel.css @@ -51,6 +51,17 @@ background: #5a5a5a; } +.layers-btn:disabled { + background: #2a2a2a; + color: #666666; + cursor: not-allowed; + opacity: 0.5; +} + +.layers-btn:disabled:hover { + background: #2a2a2a; +} + .layers-container { flex: 1; overflow-y: auto; diff --git a/src/CanvasLayersPanel.ts b/src/CanvasLayersPanel.ts index 16fc598..219e836 100644 --- a/src/CanvasLayersPanel.ts +++ b/src/CanvasLayersPanel.ts @@ -152,7 +152,7 @@ export class CanvasLayersPanel { setupControlButtons(): void { if (!this.container) return; - const deleteBtn = this.container.querySelector('#delete-layer-btn'); + const deleteBtn = this.container.querySelector('#delete-layer-btn') as HTMLButtonElement; // Add delete icon to button if (deleteBtn) { @@ -164,6 +164,9 @@ export class CanvasLayersPanel { log.info('Delete layer button clicked'); this.deleteSelectedLayers(); }); + + // Initial button state update + this.updateButtonStates(); } renderLayers(): void { @@ -273,6 +276,7 @@ export class CanvasLayersPanel { const newSelection = this.canvas.canvasSelection.selectedLayers.filter((l: Layer) => l !== layer); this.canvas.updateSelection(newSelection); this.updateSelectionAppearance(); + this.updateButtonStates(); } }); @@ -310,7 +314,8 @@ export class CanvasLayersPanel { this.canvas.updateSelectionLogic(layer, isCtrlPressed, isShiftPressed, index); // Aktualizuj tylko wygląd (klasy CSS), bez niszczenia DOM - this.updateSelectionAppearance(); + this.updateSelectionAppearance(); + this.updateButtonStates(); log.debug(`Layer clicked: ${layer.name}, selection count: ${this.canvas.canvasSelection.selectedLayers.length}`); } @@ -529,12 +534,32 @@ export class CanvasLayersPanel { }); } + /** + * Aktualizuje stan przycisków w zależności od zaznaczenia warstw + */ + updateButtonStates(): void { + if (!this.container) return; + + const deleteBtn = this.container.querySelector('#delete-layer-btn') as HTMLButtonElement; + const hasSelectedLayers = this.canvas.canvasSelection.selectedLayers.length > 0; + + if (deleteBtn) { + deleteBtn.disabled = !hasSelectedLayers; + deleteBtn.title = hasSelectedLayers + ? `Delete ${this.canvas.canvasSelection.selectedLayers.length} selected layer(s)` + : 'No layers selected'; + } + + log.debug(`Button states updated - delete button ${hasSelectedLayers ? 'enabled' : 'disabled'}`); + } + /** * Aktualizuje panel gdy zmieni się zaznaczenie (wywoływane z zewnątrz). * Zamiast pełnego renderowania, tylko aktualizujemy wygląd. */ onSelectionChanged(): void { this.updateSelectionAppearance(); + this.updateButtonStates(); } destroy(): void { diff --git a/src/css/layers_panel.css b/src/css/layers_panel.css index 22dacec..d98d211 100644 --- a/src/css/layers_panel.css +++ b/src/css/layers_panel.css @@ -51,6 +51,17 @@ background: #5a5a5a; } +.layers-btn:disabled { + background: #2a2a2a; + color: #666666; + cursor: not-allowed; + opacity: 0.5; +} + +.layers-btn:disabled:hover { + background: #2a2a2a; +} + .layers-container { flex: 1; overflow-y: auto;