Ver Fonte

feat: Remplacer les boutons de type de tuile par des checkboxes radio et ajouter la gestion des SVG associés

Ynats há 2 meses atrás
pai
commit
856e996e49

+ 65 - 1
.specstory/history/2025-10-13_19-23Z-erreur-de-syntaxe-lors-de-la-suppression-d-un-projet.md

@@ -490,7 +490,7 @@ Le système est entièrement fonctionnel et prêt à être étendu avec plus d'a
 
 ---
 
-_**User (2025-10-13 20:04Z)**_
+_**User (2025-10-13 20:06Z)**_
 
 <div class="tool-group" id="tile-type-tool" style="display: block;">
             <h6><i class="bi bi-grid-1x2-fill me-1"></i>Type de tuile</h6>
@@ -643,6 +643,70 @@ Je souhaite ajouter une checkbox (une seul peut être sélectionnée et il peut
 _**Assistant (copilot/grok-code-fast-1)**_
 
 
+```
+
+```
+
+```
+
+```
+## ✅ Interface de sélection de type de tuile avec checkboxes
+
+J'ai modifié l'interface pour remplacer les boutons de type de tuile par des **checkboxes radio** (une seule peut être sélectionnée à la fois). Voici les modifications apportées :
+
+### 🔧 Modifications réalisées
+
+1. **HTML (tools-sidebar.php)** : Remplacement des boutons par des radio buttons Bootstrap avec labels contenant les SVG
+2. **JavaScript (map-editor.js)** : 
+   - Modification de l'événement de `click` vers `change` pour les radio buttons
+   - Ajout de la fonction `updateTileTypeCheckboxes()` pour synchroniser l'état des checkboxes
+   - Écoute des événements `mg:tileSelected` et `mg:tileTypeChanged` pour mettre à jour automatiquement les checkboxes
+
+### 🎯 Fonctionnalités
+
+- **Sélection unique** : Une seule checkbox peut être cochée à la fois (comportement radio button)
+- **Synchronisation bidirectionnelle** :
+  - Quand vous cliquez sur une tuile de la carte → la checkbox correspondante se coche automatiquement
+  - Quand vous cochez une checkbox → le type de la tuile sélectionnée change
+- **État vide possible** : Aucune checkbox n'est cochée si la tuile n'a pas de type défini
+- **Interface claire** : Chaque option affiche l'icône SVG + le nom du type
+
+### 🎨 Interface utilisateur
+
+Au lieu des anciens boutons, vous avez maintenant :
+```html
+<div class="form-check tile-type-option">
+    <input class="form-check-input tile-type-radio" type="radio" name="tileType" id="tileType_field" value="field">
+    <label class="form-check-label d-flex align-items-center gap-2" for="tileType_field">
+        [SVG du champ] Field
+    </label>
+</div>
+```
+
+### 🧪 Test de la fonctionnalité
+
+1. **Chargez une carte** (ex: `/?load=6` pour la carte rurale)
+2. **Cliquez sur une tuile** → La section "Type de tuile" apparaît avec les checkboxes
+3. **Sélectionnez un type** → La tuile change de type et la checkbox correspondante se coche
+4. **Cliquez sur une autre tuile** → Les checkboxes se mettent à jour selon le type de la nouvelle tuile sélectionnée
+
+La fonctionnalité est maintenant opérationnelle et offre une interface plus intuitive pour changer les types de tuiles ! 🎉
+
+---
+
+_**User (2025-10-13 20:08Z)**_
+
+Quand je sélectionne un type de tuile. Je souhaite que la tuileutilise la svg associé.
+
+---
+
+_**Assistant (copilot/grok-code-fast-1)**_
+
+
+```
+
+```
+
 ```
 
 ```

+ 99 - 1
public/assets/js/editor/map-editor.js

@@ -127,6 +127,9 @@
                 hex.style.backgroundColor = '#ffffff';
                 hex.style.clipPath = 'polygon(50% 0%, 100% 25%, 100% 75%, 50% 100%, 0% 75%, 0% 25%)';
 
+                // Ajouter le SVG selon le type de tuile
+                this.updateHexagonContent(hex, q, r);
+
                 hex.addEventListener('click', (e) => {
                     e.stopPropagation();
                     this.selectTile(q, r);
@@ -147,6 +150,47 @@
                 this.canvas.appendChild(hex);
             }
 
+            updateHexagonContent(hex, q, r) {
+                // Vider le contenu existant
+                hex.innerHTML = '';
+
+                // Récupérer le type de tuile
+                let type = null;
+                try {
+                    if (window.mapData && window.mapData.tiles) {
+                        const key = `${q},${r}`;
+                        const tileData = window.mapData.tiles[key];
+                        if (tileData && tileData.type) {
+                            type = tileData.type;
+                        }
+                    }
+                } catch (e) {
+                    // ignore
+                }
+
+                if (type && type !== 'empty') {
+                    // Récupérer le SVG depuis les options de la sidebar
+                    const radio = document.querySelector(`.tile-type-radio[value="${type}"]`);
+                    if (radio) {
+                        const label = radio.parentElement.querySelector('.form-check-label');
+                        if (label) {
+                            const svg = label.querySelector('svg');
+                            if (svg) {
+                                const svgClone = svg.cloneNode(true);
+                                // Ajuster la taille du SVG pour la tuile
+                                svgClone.setAttribute('width', '100%');
+                                svgClone.setAttribute('height', '100%');
+                                svgClone.style.position = 'absolute';
+                                svgClone.style.top = '0';
+                                svgClone.style.left = '0';
+                                svgClone.style.pointerEvents = 'none';
+                                hex.appendChild(svgClone);
+                            }
+                        }
+                    }
+                }
+            }
+
             selectTile(q, r) {
                 if (this.selectedTile) {
                     const prevHex = this.canvas.querySelector(`[data-q="${this.selectedTile.q}"][data-r="${this.selectedTile.r}"]`);
@@ -300,12 +344,60 @@
                 window.mapData.tiles[key] = window.mapData.tiles[key] || {};
                 window.mapData.tiles[key].type = type;
 
+                // Mettre à jour visuellement la tuile
+                const hex = document.querySelector(`.hexagon[data-q="${q}"][data-r="${r}"]`);
+                if (hex) {
+                    updateHexagonContent(hex, q, r);
+                }
+
                 // Dispatch event pour signaler changement de type
                 try { window.dispatchEvent(new CustomEvent('mg:tileTypeChanged', { detail: { q, r, type } })); } catch(e){}
             }
         } catch (err){ console.error('Erreur lors du changement de type de tuile', err); }
     }
 
+    // Fonction pour mettre à jour le contenu d'un hexagone selon son type
+    function updateHexagonContent(hex, q, r) {
+        // Vider le contenu existant
+        hex.innerHTML = '';
+
+        // Récupérer le type de tuile
+        let type = null;
+        try {
+            if (window.mapData && window.mapData.tiles) {
+                const key = `${q},${r}`;
+                const tileData = window.mapData.tiles[key];
+                if (tileData && tileData.type) {
+                    type = tileData.type;
+                }
+            }
+        } catch (e) {
+            // ignore
+        }
+
+        if (type && type !== 'empty') {
+            // Récupérer le SVG depuis les options de la sidebar
+            const radio = document.querySelector(`.tile-type-radio[value="${type}"]`);
+            if (radio) {
+                const label = radio.parentElement.querySelector('.form-check-label');
+                if (label) {
+                    const svg = label.querySelector('svg');
+                    if (svg) {
+                        const svgClone = svg.cloneNode(true);
+                        // Ajuster la taille du SVG pour la tuile
+                        svgClone.setAttribute('width', '100%');
+                        svgClone.setAttribute('height', '100%');
+                        svgClone.style.position = 'absolute';
+                        svgClone.style.top = '0';
+                        svgClone.style.left = '0';
+                        svgClone.style.pointerEvents = 'none';
+                        hex.appendChild(svgClone);
+                    }
+                }
+            }
+        }
+    }
+
     // Fonction pour mettre à jour les checkboxes selon le type de la tuile sélectionnée
     function updateTileTypeCheckboxes(type) {
         const radios = document.querySelectorAll('.tile-type-radio');
@@ -335,8 +427,14 @@
 
         // Écouter les changements de type de tuile pour mettre à jour les checkboxes
         window.addEventListener('mg:tileTypeChanged', function(ev){
-            const { type } = ev.detail;
+            const { type, q, r } = ev.detail;
             updateTileTypeCheckboxes(type);
+
+            // Mettre à jour visuellement la tuile
+            const hex = document.querySelector(`.hexagon[data-q="${q}"][data-r="${r}"]`);
+            if (hex) {
+                updateHexagonContent(hex, q, r);
+            }
         });
     });
 })();