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
This commit is contained in:
Dariusz L
2025-08-03 14:33:20 +02:00
parent d84b9385ad
commit ed9fdf5d60
4 changed files with 70 additions and 2 deletions

View File

@@ -139,6 +139,8 @@ export class CanvasLayersPanel {
log.info('Delete layer button clicked'); log.info('Delete layer button clicked');
this.deleteSelectedLayers(); this.deleteSelectedLayers();
}); });
// Initial button state update
this.updateButtonStates();
} }
renderLayers() { renderLayers() {
if (!this.layersContainer) { if (!this.layersContainer) {
@@ -228,6 +230,7 @@ export class CanvasLayersPanel {
const newSelection = this.canvas.canvasSelection.selectedLayers.filter((l) => l !== layer); const newSelection = this.canvas.canvasSelection.selectedLayers.filter((l) => l !== layer);
this.canvas.updateSelection(newSelection); this.canvas.updateSelection(newSelection);
this.updateSelectionAppearance(); this.updateSelectionAppearance();
this.updateButtonStates();
} }
}); });
layerRow.addEventListener('dblclick', (e) => { layerRow.addEventListener('dblclick', (e) => {
@@ -260,6 +263,7 @@ export class CanvasLayersPanel {
this.canvas.updateSelectionLogic(layer, isCtrlPressed, isShiftPressed, index); this.canvas.updateSelectionLogic(layer, isCtrlPressed, isShiftPressed, index);
// Aktualizuj tylko wygląd (klasy CSS), bez niszczenia DOM // 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}`); log.debug(`Layer clicked: ${layer.name}, selection count: ${this.canvas.canvasSelection.selectedLayers.length}`);
} }
startEditingLayerName(nameElement, layer) { 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). * Aktualizuje panel gdy zmieni się zaznaczenie (wywoływane z zewnątrz).
* Zamiast pełnego renderowania, tylko aktualizujemy wygląd. * Zamiast pełnego renderowania, tylko aktualizujemy wygląd.
*/ */
onSelectionChanged() { onSelectionChanged() {
this.updateSelectionAppearance(); this.updateSelectionAppearance();
this.updateButtonStates();
} }
destroy() { destroy() {
if (this.container && this.container.parentNode) { if (this.container && this.container.parentNode) {

View File

@@ -51,6 +51,17 @@
background: #5a5a5a; background: #5a5a5a;
} }
.layers-btn:disabled {
background: #2a2a2a;
color: #666666;
cursor: not-allowed;
opacity: 0.5;
}
.layers-btn:disabled:hover {
background: #2a2a2a;
}
.layers-container { .layers-container {
flex: 1; flex: 1;
overflow-y: auto; overflow-y: auto;

View File

@@ -152,7 +152,7 @@ export class CanvasLayersPanel {
setupControlButtons(): void { setupControlButtons(): void {
if (!this.container) return; 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 // Add delete icon to button
if (deleteBtn) { if (deleteBtn) {
@@ -164,6 +164,9 @@ export class CanvasLayersPanel {
log.info('Delete layer button clicked'); log.info('Delete layer button clicked');
this.deleteSelectedLayers(); this.deleteSelectedLayers();
}); });
// Initial button state update
this.updateButtonStates();
} }
renderLayers(): void { renderLayers(): void {
@@ -273,6 +276,7 @@ export class CanvasLayersPanel {
const newSelection = this.canvas.canvasSelection.selectedLayers.filter((l: Layer) => l !== layer); const newSelection = this.canvas.canvasSelection.selectedLayers.filter((l: Layer) => l !== layer);
this.canvas.updateSelection(newSelection); this.canvas.updateSelection(newSelection);
this.updateSelectionAppearance(); this.updateSelectionAppearance();
this.updateButtonStates();
} }
}); });
@@ -310,7 +314,8 @@ export class CanvasLayersPanel {
this.canvas.updateSelectionLogic(layer, isCtrlPressed, isShiftPressed, index); this.canvas.updateSelectionLogic(layer, isCtrlPressed, isShiftPressed, index);
// Aktualizuj tylko wygląd (klasy CSS), bez niszczenia DOM // 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}`); 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). * Aktualizuje panel gdy zmieni się zaznaczenie (wywoływane z zewnątrz).
* Zamiast pełnego renderowania, tylko aktualizujemy wygląd. * Zamiast pełnego renderowania, tylko aktualizujemy wygląd.
*/ */
onSelectionChanged(): void { onSelectionChanged(): void {
this.updateSelectionAppearance(); this.updateSelectionAppearance();
this.updateButtonStates();
} }
destroy(): void { destroy(): void {

View File

@@ -51,6 +51,17 @@
background: #5a5a5a; background: #5a5a5a;
} }
.layers-btn:disabled {
background: #2a2a2a;
color: #666666;
cursor: not-allowed;
opacity: 0.5;
}
.layers-btn:disabled:hover {
background: #2a2a2a;
}
.layers-container { .layers-container {
flex: 1; flex: 1;
overflow-y: auto; overflow-y: auto;