From ab680c99e3c2905ef29b9a72ea91e949d0d6de73 Mon Sep 17 00:00:00 2001
From: test <grave54122@gmail.com>
Date: Sun, 30 Mar 2025 15:31:42 +0000
Subject: [PATCH] TP3

---
 src/src/twisk/MainTwisk.java                  |  14 +-
 .../twisk/exceptions/ParametresException.java |  15 +
 src/src/twisk/modele/ActiviteIG.java          |  54 ++++
 src/src/twisk/modele/MondeIG.java             | 134 ++++++++-
 src/src/twisk/ressources/css/style-colore.css | 149 ++++++++++
 src/src/twisk/ressources/css/style-sombre.css | 144 +++++++++
 src/src/twisk/ressources/css/style.css        |  47 +++
 src/src/twisk/vues/VueActiviteIG.java         |  27 +-
 src/src/twisk/vues/VueMenu.java               | 274 ++++++++++++++----
 src/src/twisk/vues/VueMondeIG.java            |  17 +-
 src/src/twisk/vues/VueOutils.java             |   2 +
 11 files changed, 809 insertions(+), 68 deletions(-)
 create mode 100644 src/src/twisk/exceptions/ParametresException.java
 create mode 100644 src/src/twisk/ressources/css/style-colore.css
 create mode 100644 src/src/twisk/ressources/css/style-sombre.css

diff --git a/src/src/twisk/MainTwisk.java b/src/src/twisk/MainTwisk.java
index 4d1e3b3..f4695a3 100644
--- a/src/src/twisk/MainTwisk.java
+++ b/src/src/twisk/MainTwisk.java
@@ -20,22 +20,22 @@ public class MainTwisk extends Application {
             // Création du conteneur principal
             BorderPane root = new BorderPane();
 
-            // Création et placement de la barre de menu au nord
-            VueMenu vueMenu = new VueMenu(monde);
-            root.setTop(vueMenu);
+            // Création de la scène
+            Scene scene = new Scene(root, 800, 600);
 
             // Création et placement de la vue du monde au centre
             VueMondeIG vueMonde = new VueMondeIG(monde);
             root.setCenter(vueMonde);
 
+            // Création et placement du menu en haut
+            VueMenu vueMenu = new VueMenu(monde, scene);
+            root.setTop(vueMenu);
+
             // Création et placement de la vue des outils au sud
             VueOutils vueOutils = new VueOutils(monde);
             root.setBottom(vueOutils);
 
-            // Création de la scène
-            Scene scene = new Scene(root, 800, 600);
-
-            // Chargement du fichier CSS
+            // Chargement du fichier CSS par défaut
             String cssPath = getClass().getResource("/twisk/ressources/css/style.css").toExternalForm();
             scene.getStylesheets().add(cssPath);
 
diff --git a/src/src/twisk/exceptions/ParametresException.java b/src/src/twisk/exceptions/ParametresException.java
new file mode 100644
index 0000000..68812c8
--- /dev/null
+++ b/src/src/twisk/exceptions/ParametresException.java
@@ -0,0 +1,15 @@
+package twisk.exceptions;
+
+/**
+ * Exception levée lors d'un problème avec les paramètres d'une activité
+ */
+public class ParametresException extends TwiskException {
+
+    /**
+     * Constructeur
+     * @param message message d'erreur
+     */
+    public ParametresException(String message) {
+        super(message);
+    }
+}
diff --git a/src/src/twisk/modele/ActiviteIG.java b/src/src/twisk/modele/ActiviteIG.java
index bc4d491..7940cf9 100644
--- a/src/src/twisk/modele/ActiviteIG.java
+++ b/src/src/twisk/modele/ActiviteIG.java
@@ -1,12 +1,66 @@
 package twisk.modele;
 
+import twisk.exceptions.ParametresException;
 import twisk.outils.TailleComposants;
 
 public class ActiviteIG extends EtapeIG {
+    private int delai;
+    private int ecart;
 
+    /**
+     * Constructeur
+     * @param nom le nom de l'activité
+     */
     public ActiviteIG(String nom) {
         // Utilisation des tailles définies dans TailleComposants
         super(nom, TailleComposants.getInstance().getLargeurActivite(),
                 TailleComposants.getInstance().getHauteurActivite());
+
+        // Initialiser les paramètres avec des valeurs par défaut
+        this.delai = 4; // Valeur par défaut pour le délai
+        this.ecart = 2; // Valeur par défaut pour l'écart
+    }
+
+    /**
+     * Définit le délai de l'activité
+     * @param delai le délai en unités de temps
+     * @throws ParametresException si le délai est négatif ou nul
+     */
+    public void setDelai(int delai) throws ParametresException {
+        if (delai <= 0) {
+            throw new ParametresException("Le délai doit être un nombre positif");
+        }
+        this.delai = delai;
+    }
+
+    /**
+     * Définit l'écart de l'activité
+     * @param ecart l'écart en unités de temps
+     * @throws ParametresException si l'écart est négatif ou supérieur au délai
+     */
+    public void setEcart(int ecart) throws ParametresException {
+        if (ecart < 0) {
+            throw new ParametresException("L'écart doit être un nombre positif ou nul");
+        }
+        if (ecart >= delai) {
+            throw new ParametresException("L'écart doit être inférieur au délai");
+        }
+        this.ecart = ecart;
+    }
+
+    /**
+     * Retourne le délai de l'activité
+     * @return le délai
+     */
+    public int getDelai() {
+        return delai;
+    }
+
+    /**
+     * Retourne l'écart de l'activité
+     * @return l'écart
+     */
+    public int getEcart() {
+        return ecart;
     }
 }
diff --git a/src/src/twisk/modele/MondeIG.java b/src/src/twisk/modele/MondeIG.java
index a612c51..1ef1609 100644
--- a/src/src/twisk/modele/MondeIG.java
+++ b/src/src/twisk/modele/MondeIG.java
@@ -2,6 +2,7 @@ package twisk.modele;
 
 import javafx.util.Pair;
 import twisk.exceptions.ArcException;
+import twisk.exceptions.ParametresException;
 import twisk.outils.Observable;
 import twisk.outils.Observateur;
 
@@ -18,6 +19,9 @@ public class MondeIG implements Iterable<EtapeIG>, Observable {
     private static final int NB_POINTS_COURBE = 4;
     private Set<String> etapesSelectionnees;
     private Set<ArcIG> arcsSelectionnes;
+    private Set<String> entrees;
+    private Set<String> sorties;
+
 
 
     public MondeIG() {
@@ -28,7 +32,9 @@ public class MondeIG implements Iterable<EtapeIG>, Observable {
         compteurActivites = 1;
         observateurs = new ArrayList<>();
         etapesSelectionnees = new HashSet<>();
-        arcsSelectionnes = new HashSet<>();  // Initialiser l'ensemble des arcs sélectionnés
+        arcsSelectionnes = new HashSet<>();
+        entrees = new HashSet<>();
+        sorties = new HashSet<>();
 
         // Ajouter une activité par défaut à la construction
         ajouter("Activite");
@@ -570,5 +576,131 @@ public class MondeIG implements Iterable<EtapeIG>, Observable {
             return new Pair<>(false, e.getMessage());
         }
     }
+    /**
+     * Définit ou supprime les étapes sélectionnées comme entrées
+     */
+    public void definirEntrees() {
+        // Pour chaque étape sélectionnée
+        for (String idEtape : etapesSelectionnees) {
+            // Si l'étape est déjà une entrée, la supprimer
+            if (entrees.contains(idEtape)) {
+                entrees.remove(idEtape);
+            } else {
+                // Sinon, l'ajouter comme entrée et la retirer des sorties si elle y est
+                entrees.add(idEtape);
+                // Une entrée ne peut pas être une sortie
+                sorties.remove(idEtape);
+            }
+        }
+
+        // Notifier les observateurs pour mettre à jour l'affichage
+        notifierObservateurs();
+    }
+
+    /**
+     * Définit ou supprime les étapes sélectionnées comme sorties
+     */
+    public void definirSorties() {
+        // Pour chaque étape sélectionnée
+        for (String idEtape : etapesSelectionnees) {
+            // Si l'étape est déjà une sortie, la supprimer
+            if (sorties.contains(idEtape)) {
+                sorties.remove(idEtape);
+            } else {
+                // Sinon, l'ajouter comme sortie et la retirer des entrées si elle y est
+                sorties.add(idEtape);
+                // Une sortie ne peut pas être une entrée
+                entrees.remove(idEtape);
+            }
+        }
+
+        // Notifier les observateurs pour mettre à jour l'affichage
+        notifierObservateurs();
+    }
+
+    /**
+     * Vérifie si une étape est une entrée
+     * @param idEtape l'identifiant de l'étape
+     * @return true si l'étape est une entrée, false sinon
+     */
+    public boolean estUneEntree(String idEtape) {
+        return entrees.contains(idEtape);
+    }
+
+    /**
+     * Vérifie si une étape est une sortie
+     * @param idEtape l'identifiant de l'étape
+     * @return true si l'étape est une sortie, false sinon
+     */
+    public boolean estUneSortie(String idEtape) {
+        return sorties.contains(idEtape);
+    }
+
+    /**
+     * Définit les paramètres (délai et écart) de l'activité sélectionnée
+     * @param delai le délai en unités de temps
+     * @param ecart l'écart en unités de temps
+     * @throws ParametresException si les paramètres sont incorrects
+     * @throws IllegalStateException si aucune activité n'est sélectionnée ou si plusieurs étapes sont sélectionnées
+     */
+    public void definirParametres(int delai, int ecart) throws ParametresException, IllegalStateException {
+        // Vérifier qu'une seule étape est sélectionnée
+        if (etapesSelectionnees.size() != 1) {
+            throw new IllegalStateException("Il faut sélectionner une seule activité pour définir ses paramètres");
+        }
+
+        // Récupérer l'étape sélectionnée
+        String idEtape = etapesSelectionnees.iterator().next();
+        EtapeIG etape = etapes.get(idEtape);
+
+        // Vérifier que l'étape est bien une activité
+        if (!(etape instanceof ActiviteIG)) {
+            throw new IllegalStateException("Seules les activités peuvent avoir des paramètres de délai et d'écart");
+        }
+
+        // Définir les paramètres
+        ActiviteIG activite = (ActiviteIG) etape;
+        activite.setDelai(delai);
+        activite.setEcart(ecart);
+
+        // Notifier les observateurs
+        notifierObservateurs();
+    }
+
+    /**
+     * Vérifie si une seule activité est sélectionnée
+     * @return true si une seule activité est sélectionnée, false sinon
+     */
+    public boolean uneSeuleActiviteSelectionnee() {
+        if (etapesSelectionnees.size() != 1) {
+            return false;
+        }
+
+        String idEtape = etapesSelectionnees.iterator().next();
+        EtapeIG etape = etapes.get(idEtape);
+
+        return etape instanceof ActiviteIG;
+    }
+
+    /**
+     * Retourne l'activité sélectionnée si une seule activité est sélectionnée
+     * @return l'activité sélectionnée
+     * @throws IllegalStateException si aucune activité n'est sélectionnée ou si plusieurs étapes sont sélectionnées
+     */
+    public ActiviteIG getActiviteSelectionnee() throws IllegalStateException {
+        if (etapesSelectionnees.size() != 1) {
+            throw new IllegalStateException("Il faut sélectionner une seule activité");
+        }
+
+        String idEtape = etapesSelectionnees.iterator().next();
+        EtapeIG etape = etapes.get(idEtape);
+
+        if (!(etape instanceof ActiviteIG)) {
+            throw new IllegalStateException("L'étape sélectionnée n'est pas une activité");
+        }
+
+        return (ActiviteIG) etape;
+    }
+
 
 }
diff --git a/src/src/twisk/ressources/css/style-colore.css b/src/src/twisk/ressources/css/style-colore.css
new file mode 100644
index 0000000..b5f5201
--- /dev/null
+++ b/src/src/twisk/ressources/css/style-colore.css
@@ -0,0 +1,149 @@
+/* Styles généraux */
+.root {
+    -fx-font-family: 'Comic Sans MS', cursive;
+    -fx-background-color: #f0f8ff;
+}
+
+/* Style pour VueMondeIG */
+.monde {
+    -fx-background-color: linear-gradient(to bottom right, #e6f7ff, #f0e6ff);
+    -fx-padding: 10px;
+}
+
+/* Style pour VueActiviteIG */
+.activite {
+    -fx-background-color: transparent;
+}
+
+.activite-rectangle {
+    -fx-fill: linear-gradient(to bottom, #ffffff, #f0f0ff);
+    -fx-stroke: #9966cc;
+    -fx-stroke-width: 3;
+    -fx-arc-width: 20;
+    -fx-arc-height: 20;
+    -fx-effect: dropshadow(three-pass-box, rgba(153,102,204,0.5), 10, 0, 0, 5);
+}
+
+/* Style pour le titre de l'activité */
+.titre-activite {
+    -fx-font-size: 16px;
+    -fx-font-weight: bold;
+    -fx-text-fill: #6600cc;
+    -fx-padding: 8px;
+    -fx-background-color: linear-gradient(to right, #e6ccff, #ccccff);
+    -fx-background-radius: 15 15 0 0;
+}
+
+/* Modifications pour la zone des clients */
+.zone-clients {
+    -fx-background-color: #ffffff;
+    -fx-border-color: #cc99ff;
+    -fx-border-width: 2px;
+    -fx-border-radius: 0 0 15 15;
+    -fx-background-radius: 0 0 15 15;
+    -fx-padding: 8px;
+    -fx-min-height: 30px;
+    -fx-font-size: 12px;
+}
+
+/* Modifications pour la zone des paramètres */
+.zone-parametres {
+    -fx-background-color: #f5f0ff;
+    -fx-border-color: #cc99ff;
+    -fx-border-width: 2px;
+    -fx-border-radius: 0 0 15 15;
+    -fx-background-radius: 0 0 15 15;
+    -fx-padding: 8px;
+    -fx-font-size: 10px;
+    -fx-text-fill: #6600cc;
+}
+
+
+/* Style pour la barre d'outils */
+.outils {
+    -fx-background-color: linear-gradient(to right, #cc99ff, #9966cc);
+    -fx-padding: 12px;
+    -fx-spacing: 15px;
+}
+
+/* Style pour les boutons */
+.bouton {
+    -fx-background-color: #ff66cc;
+    -fx-text-fill: white;
+    -fx-font-weight: bold;
+    -fx-padding: 10px 20px;
+    -fx-background-radius: 20px;
+    -fx-cursor: hand;
+    -fx-effect: dropshadow(three-pass-box, rgba(255,102,204,0.5), 5, 0, 0, 2);
+}
+
+.bouton:hover {
+    -fx-background-color: #ff33cc;
+    -fx-effect: dropshadow(three-pass-box, rgba(255,102,204,0.8), 8, 0, 0, 3);
+}
+
+.bouton:pressed {
+    -fx-background-color: #cc0099;
+    -fx-effect: dropshadow(three-pass-box, rgba(255,102,204,0.3), 3, 0, 0, 1);
+}
+
+/* Style pour les points de contrôle */
+.point-controle {
+    -fx-fill: #ff99cc;
+    -fx-stroke: #cc0099;
+    -fx-stroke-width: 2;
+    -fx-cursor: hand;
+}
+
+.point-controle:hover {
+    -fx-fill: #ff66cc;
+    -fx-effect: dropshadow(three-pass-box, rgba(255,102,204,0.8), 5, 0, 0, 0);
+    -fx-scale-x: 1.2;
+    -fx-scale-y: 1.2;
+}
+
+/* Style pour les arcs */
+.arc-ligne {
+    -fx-stroke: #9966cc;
+    -fx-stroke-width: 3;
+    -fx-stroke-dash-array: 10 5;
+    -fx-effect: dropshadow(three-pass-box, rgba(153,102,204,0.5), 3, 0, 0, 0);
+}
+
+.arc-fleche {
+    -fx-fill: #9966cc;
+    -fx-stroke: #6600cc;
+    -fx-stroke-width: 2;
+}
+
+/* Style pour les étapes sélectionnées */
+.etape-selectionnee {
+    -fx-effect: dropshadow(three-pass-box, #ff33cc, 15, 0, 0, 0);
+}
+
+.etape-selectionnee .activite-rectangle {
+    -fx-stroke: #ff33cc;
+    -fx-stroke-width: 4;
+}
+
+/* Style pour les entrées */
+.etape-entree .activite-rectangle {
+    -fx-fill: linear-gradient(to bottom, #ffffff, #e6ffe6);
+    -fx-stroke: #66cc66;
+}
+
+.etape-entree .titre-activite {
+    -fx-text-fill: #006600;
+    -fx-background-color: linear-gradient(to right, #ccffcc, #99ff99);
+}
+
+/* Style pour les sorties */
+.etape-sortie .activite-rectangle {
+    -fx-fill: linear-gradient(to bottom, #ffffff, #ffe6e6);
+    -fx-stroke: #cc6666;
+}
+
+.etape-sortie .titre-activite {
+    -fx-text-fill: #660000;
+    -fx-background-color: linear-gradient(to right, #ffcccc, #ff9999);
+}
diff --git a/src/src/twisk/ressources/css/style-sombre.css b/src/src/twisk/ressources/css/style-sombre.css
new file mode 100644
index 0000000..d1e20af
--- /dev/null
+++ b/src/src/twisk/ressources/css/style-sombre.css
@@ -0,0 +1,144 @@
+/* Styles généraux */
+.root {
+    -fx-font-family: 'Segoe UI', Arial, sans-serif;
+    -fx-background-color: #2d2d2d;
+}
+
+/* Style pour VueMondeIG */
+.monde {
+    -fx-background-color: #1e1e1e;
+    -fx-padding: 10px;
+}
+
+/* Style pour VueActiviteIG */
+.activite {
+    -fx-background-color: transparent;
+}
+
+.activite-rectangle {
+    -fx-fill: #3c3c3c;
+    -fx-stroke: #6c6c6c;
+    -fx-stroke-width: 2;
+    -fx-arc-width: 10;
+    -fx-arc-height: 10;
+}
+
+/* Style pour le titre de l'activité */
+.titre-activite {
+    -fx-font-size: 14px;
+    -fx-font-weight: bold;
+    -fx-text-fill: #e0e0e0;
+    -fx-padding: 5px;
+    -fx-background-color: #4c4c4c;
+    -fx-background-radius: 5px 5px 0 0;
+}
+
+/* Style pour la zone des clients */
+.zone-clients {
+    -fx-background-color: #2d2d2d;
+    -fx-border-color: #6c6c6c;
+    -fx-border-width: 1px;
+    -fx-border-radius: 0 0 5px 5px;
+    -fx-background-radius: 0 0 5px 5px;
+    -fx-padding: 5px;
+    -fx-min-height: 30px;
+    -fx-text-fill: #e0e0e0;
+}
+
+/* Style pour la zone des paramètres */
+.zone-parametres {
+    -fx-background-color: #2d2d2d;
+    -fx-border-color: #6c6c6c;
+    -fx-border-width: 1px;
+    -fx-border-radius: 0 0 5px 5px;
+    -fx-background-radius: 0 0 5px 5px;
+    -fx-padding: 5px;
+    -fx-font-size: 10px;
+    -fx-text-fill: #b0b0b0;
+}
+
+/* Style pour la barre d'outils */
+.outils {
+    -fx-background-color: #333333;
+    -fx-padding: 10px;
+    -fx-spacing: 10px;
+}
+
+/* Style pour les boutons */
+.bouton {
+    -fx-background-color: #4c4c4c;
+    -fx-text-fill: white;
+    -fx-font-weight: bold;
+    -fx-padding: 8px 15px;
+    -fx-background-radius: 5px;
+    -fx-cursor: hand;
+}
+
+.bouton:hover {
+    -fx-background-color: #5c5c5c;
+}
+
+.bouton:pressed {
+    -fx-background-color: #3c3c3c;
+}
+
+/* Style pour les points de contrôle */
+.point-controle {
+    -fx-fill: #6c6c6c;
+    -fx-stroke: #b0b0b0;
+    -fx-cursor: hand;
+}
+
+.point-controle:hover {
+    -fx-fill: #b0b0b0;
+    -fx-effect: dropshadow(three-pass-box, rgba(255,255,255,0.3), 3, 0, 0, 0);
+}
+
+/* Style pour les arcs */
+.arc-ligne {
+    -fx-stroke: #b0b0b0;
+    -fx-stroke-width: 2;
+}
+
+.arc-fleche {
+    -fx-fill: #b0b0b0;
+    -fx-stroke: #b0b0b0;
+    -fx-stroke-width: 1;
+}
+
+/* Style pour les étapes sélectionnées */
+.etape-selectionnee {
+    -fx-effect: dropshadow(three-pass-box, #ff9900, 10, 0, 0, 0);
+    -fx-border-color: #ff9900;
+    -fx-border-width: 3;
+}
+
+/* Style pour les entrées */
+.etape-entree .activite-rectangle {
+    -fx-fill: #2d4d2d;
+    -fx-stroke: #4c8c4c;
+}
+
+.etape-entree .titre-activite {
+    -fx-text-fill: #a0d0a0;
+    -fx-background-color: #3c5c3c;
+}
+
+.etape-entree .zone-clients {
+    -fx-border-color: #4c8c4c;
+}
+
+/* Style pour les sorties */
+.etape-sortie .activite-rectangle {
+    -fx-fill: #4d2d2d;
+    -fx-stroke: #8c4c4c;
+}
+
+.etape-sortie .titre-activite {
+    -fx-text-fill: #d0a0a0;
+    -fx-background-color: #5c3c3c;
+}
+
+.etape-sortie .zone-clients {
+    -fx-border-color: #8c4c4c;
+}
diff --git a/src/src/twisk/ressources/css/style.css b/src/src/twisk/ressources/css/style.css
index a15023e..5f93165 100644
--- a/src/src/twisk/ressources/css/style.css
+++ b/src/src/twisk/ressources/css/style.css
@@ -134,4 +134,51 @@
     -fx-cursor: hand;
 }
 
+/* Style pour les entrées */
+.etape-entree .activite-rectangle {
+    -fx-fill: #e6ffe6; /* Fond légèrement vert */
+    -fx-stroke: #28a745; /* Bordure verte */
+}
+
+.etape-entree .titre-activite {
+    -fx-text-fill: #28a745;
+    -fx-background-color: #d4edda;
+}
+
+.etape-entree .zone-clients {
+    -fx-border-color: #28a745;
+}
+
+/* Style pour les sorties */
+.etape-sortie .activite-rectangle {
+    -fx-fill: #ffe6e6; /* Fond légèrement rouge */
+    -fx-stroke: #dc3545; /* Bordure rouge */
+}
+
+.etape-sortie .titre-activite {
+    -fx-text-fill: #dc3545;
+    -fx-background-color: #f8d7da;
+}
+
+.etape-sortie .zone-clients {
+    -fx-border-color: #dc3545;
+}
+
+/* Style pour les étapes sélectionnées */
+.etape-selectionnee {
+    -fx-effect: dropshadow(three-pass-box, #ff6600, 10, 0, 0, 0);
+}
+
+/* Style pour la zone des paramètres */
+.zone-parametres {
+    -fx-background-color: #f8f9fa;
+    -fx-border-color: #dee2e6;
+    -fx-border-width: 1px;
+    -fx-border-radius: 0 0 5px 5px;
+    -fx-background-radius: 0 0 5px 5px;
+    -fx-padding: 5px;
+    -fx-font-size: 10px;
+    -fx-text-fill: #6c757d;
+}
+
 
diff --git a/src/src/twisk/vues/VueActiviteIG.java b/src/src/twisk/vues/VueActiviteIG.java
index 0c97e21..a9b7b31 100644
--- a/src/src/twisk/vues/VueActiviteIG.java
+++ b/src/src/twisk/vues/VueActiviteIG.java
@@ -2,7 +2,12 @@ package twisk.vues;
 
 import javafx.scene.control.Label;
 import javafx.scene.layout.VBox;
+import javafx.scene.paint.Color;
+import javafx.scene.shape.Circle;
 import javafx.scene.shape.Rectangle;
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.Pane;
+import twisk.modele.ActiviteIG;
 import twisk.modele.EtapeIG;
 import twisk.modele.MondeIG;
 
@@ -32,9 +37,14 @@ public class VueActiviteIG extends VueEtapeIG {
         zoneClients.getStyleClass().add("zone-clients");
         zoneClients.setPrefWidth(etape.getLargeur());
 
+        ActiviteIG activite = (ActiviteIG) etape;
+        Label zoneParametres = new Label("Délai: " + activite.getDelai() + ", Écart: " + activite.getEcart());
+        zoneParametres.getStyleClass().add("zone-parametres");
+        zoneParametres.setPrefWidth(etape.getLargeur());
+
         // Créer un conteneur pour organiser les éléments
         conteneur = new VBox();
-        conteneur.getChildren().addAll(titre, zoneClients);
+        conteneur.getChildren().addAll(titre, zoneClients, zoneParametres);
         conteneur.setPrefWidth(etape.getLargeur());
         conteneur.setPrefHeight(etape.getHauteur());
 
@@ -65,5 +75,18 @@ public class VueActiviteIG extends VueEtapeIG {
             // Style pour une étape non sélectionnée
             this.getStyleClass().remove("etape-selectionnee");
         }
+
+        // Vérifier si l'étape est une entrée ou une sortie
+        if (monde.estUneEntree(etape.getIdentifiant())) {
+            this.getStyleClass().add("etape-entree");
+        } else {
+            this.getStyleClass().remove("etape-entree");
+        }
+
+        if (monde.estUneSortie(etape.getIdentifiant())) {
+            this.getStyleClass().add("etape-sortie");
+        } else {
+            this.getStyleClass().remove("etape-sortie");
+        }
     }
-}
+}
\ No newline at end of file
diff --git a/src/src/twisk/vues/VueMenu.java b/src/src/twisk/vues/VueMenu.java
index d96f196..df60605 100644
--- a/src/src/twisk/vues/VueMenu.java
+++ b/src/src/twisk/vues/VueMenu.java
@@ -1,33 +1,42 @@
 package twisk.vues;
 
 import javafx.application.Platform;
-import javafx.scene.control.Menu;
-import javafx.scene.control.MenuBar;
-import javafx.scene.control.MenuItem;
-import javafx.scene.control.TextInputDialog;
+import javafx.beans.binding.Bindings;
+import javafx.beans.property.BooleanProperty;
+import javafx.beans.property.SimpleBooleanProperty;
+import javafx.geometry.Insets;
+import javafx.scene.Scene;
+import javafx.scene.control.*;
 import javafx.scene.input.KeyCombination;
-import twisk.modele.EtapeIG;
+import javafx.scene.layout.GridPane;
+import javafx.util.Pair;
+import twisk.exceptions.ParametresException;
+import twisk.modele.ActiviteIG;
 import twisk.modele.MondeIG;
-import twisk.outils.Observateur;
-
-import java.util.Optional;
 
 /**
  * Vue représentant la barre de menu de l'application
  */
-public class VueMenu extends MenuBar implements Observateur {
+public class VueMenu extends MenuBar {
     private final MondeIG monde;
-    private MenuItem itemRenommer;
+    private final Scene scene;
+    private final BooleanProperty uneEtapeSelectionnee;
+    private final BooleanProperty plusieursEtapesSelectionnees;
+    private final BooleanProperty uneActiviteSelectionnee;
 
     /**
      * Constructeur
      * @param monde le monde à manipuler
+     * @param scene la scène principale de l'application
      */
-    public VueMenu(MondeIG monde) {
+    public VueMenu(MondeIG monde, Scene scene) {
         this.monde = monde;
+        this.scene = scene;
 
-        // S'enregistrer comme observateur du monde
-        monde.ajouterObservateur(this);
+        // Propriétés pour le binding
+        uneEtapeSelectionnee = new SimpleBooleanProperty(false);
+        plusieursEtapesSelectionnees = new SimpleBooleanProperty(false);
+        uneActiviteSelectionnee = new SimpleBooleanProperty(false);
 
         // Création du menu Fichier
         Menu menuFichier = new Menu("Fichier");
@@ -44,68 +53,231 @@ public class VueMenu extends MenuBar implements Observateur {
         Menu menuEdition = new Menu("Édition");
 
         // Création de l'item Supprimer
-        MenuItem itemSupprimer = new MenuItem("Supprimer la sélection");
+        MenuItem itemSupprimer = new MenuItem("Supprimer");
         itemSupprimer.setAccelerator(KeyCombination.keyCombination("Delete"));
-        itemSupprimer.setOnAction(event -> monde.supprimerSelection());
-
-        // Création de l'item Effacer la sélection
-        MenuItem itemEffacerSelection = new MenuItem("Effacer la sélection");
-        itemEffacerSelection.setAccelerator(KeyCombination.keyCombination("F1"));
-        itemEffacerSelection.setOnAction(event -> monde.deselectionnerTout());
+        itemSupprimer.setOnAction(event -> monde.supprimerEtapesSelectionnees());
+        // Activer seulement si au moins une étape est sélectionnée
+        itemSupprimer.disableProperty().bind(
+                uneEtapeSelectionnee.not().and(plusieursEtapesSelectionnees.not())
+        );
 
         // Création de l'item Renommer
-        itemRenommer = new MenuItem("Renommer la sélection");
-        itemRenommer.setAccelerator(KeyCombination.keyCombination("F2"));
-        itemRenommer.setOnAction(event -> renommerSelection());
+        MenuItem itemRenommer = new MenuItem("Renommer");
+        itemRenommer.setAccelerator(KeyCombination.keyCombination("Ctrl+R"));
+        itemRenommer.setOnAction(event -> afficherDialogueRenommer());
+        // Activer seulement si une seule étape est sélectionnée
+        itemRenommer.disableProperty().bind(uneEtapeSelectionnee.not());
 
-        // Désactiver l'item Renommer par défaut (sera activé si une seule étape est sélectionnée)
-        itemRenommer.setDisable(true);
+        // Création de l'item Désélectionner
+        MenuItem itemDeselectionner = new MenuItem("Désélectionner tout");
+        itemDeselectionner.setAccelerator(KeyCombination.keyCombination("Escape"));
+        itemDeselectionner.setOnAction(event -> monde.deselectionnerTout());
+        // Activer seulement si au moins une étape est sélectionnée
+        itemDeselectionner.disableProperty().bind(
+                uneEtapeSelectionnee.not().and(plusieursEtapesSelectionnees.not())
+        );
 
         // Ajout des items au menu Édition
-        menuEdition.getItems().addAll(itemEffacerSelection, itemRenommer,itemSupprimer);
+        menuEdition.getItems().addAll(itemSupprimer, itemRenommer, new SeparatorMenuItem(), itemDeselectionner);
+
+        // Création du menu Paramètres
+        Menu menuParametres = new Menu("Paramètres");
+
+        // Création de l'item Paramètres
+        MenuItem itemParametres = new MenuItem("Définir délai et écart");
+        itemParametres.setOnAction(event -> afficherDialogueParametres());
+        // Activer seulement si une seule activité est sélectionnée
+        itemParametres.disableProperty().bind(uneActiviteSelectionnee.not());
+
+        // Ajout de l'item au menu Paramètres
+        menuParametres.getItems().add(itemParametres);
+
+        // Création du menu Monde
+        Menu menuMonde = new Menu("Monde");
+
+        // Création de l'item Entrée
+        MenuItem itemEntree = new MenuItem("Entrée");
+        itemEntree.setOnAction(event -> monde.definirEntrees());
+        // Activer seulement si au moins une étape est sélectionnée
+        itemEntree.disableProperty().bind(
+                uneEtapeSelectionnee.not().and(plusieursEtapesSelectionnees.not())
+        );
+
+        // Création de l'item Sortie
+        MenuItem itemSortie = new MenuItem("Sortie");
+        itemSortie.setOnAction(event -> monde.definirSorties());
+        // Activer seulement si au moins une étape est sélectionnée
+        itemSortie.disableProperty().bind(
+                uneEtapeSelectionnee.not().and(plusieursEtapesSelectionnees.not())
+        );
+
+        // Ajout des items au menu Monde
+        menuMonde.getItems().addAll(itemEntree, itemSortie);
+
+        // Création du menu Style
+        Menu menuStyle = new Menu("Style");
+
+        // Créer un groupe pour les styles (pour que seul un style soit actif à la fois)
+        ToggleGroup groupeStyles = new ToggleGroup();
+
+        // Créer les items de style
+        RadioMenuItem styleClassique = new RadioMenuItem("Classique");
+        styleClassique.setToggleGroup(groupeStyles);
+        styleClassique.setSelected(true); // Style par défaut
+        styleClassique.setOnAction(event -> changerStyle("style"));
+
+        RadioMenuItem styleSombre = new RadioMenuItem("Sombre");
+        styleSombre.setToggleGroup(groupeStyles);
+        styleSombre.setOnAction(event -> changerStyle("style-sombre"));
+
+        RadioMenuItem styleColoré = new RadioMenuItem("Coloré");
+        styleColoré.setToggleGroup(groupeStyles);
+        styleColoré.setOnAction(event -> changerStyle("style-colore"));
+
+        RadioMenuItem styleMinimaliste = new RadioMenuItem("Minimaliste");
+        styleMinimaliste.setToggleGroup(groupeStyles);
+        styleMinimaliste.setOnAction(event -> changerStyle("style-minimaliste"));
+
+        // Ajouter les items au menu Style
+        menuStyle.getItems().addAll(styleClassique, styleSombre, styleColoré, styleMinimaliste);
 
         // Ajout des menus à la barre de menu
-        this.getMenus().addAll(menuFichier, menuEdition);
+        this.getMenus().addAll(menuFichier, menuEdition, menuParametres, menuMonde, menuStyle);
 
-        // Mettre à jour l'état des items
-        reagir();
+        // S'enregistrer comme observateur du monde pour mettre à jour l'état du menu
+        monde.ajouterObservateur(() -> mettreAJourMenu());
     }
 
     /**
-     * Ouvre une boîte de dialogue pour renommer l'étape sélectionnée
+     * Met à jour l'état du menu en fonction de l'état du monde
      */
-    private void renommerSelection() {
-        // Vérifier qu'une seule étape est sélectionnée
-        if (monde.getNbEtapesSelectionnees() != 1) {
-            return;
-        }
+    private void mettreAJourMenu() {
+        int nbEtapesSelectionnees = monde.getNbEtapesSelectionnees();
+        uneEtapeSelectionnee.set(nbEtapesSelectionnees == 1);
+        plusieursEtapesSelectionnees.set(nbEtapesSelectionnees > 1);
+        uneActiviteSelectionnee.set(monde.uneSeuleActiviteSelectionnee());
+    }
 
+    /**
+     * Affiche une boîte de dialogue pour renommer l'étape sélectionnée
+     */
+    private void afficherDialogueRenommer() {
         // Récupérer l'étape sélectionnée
-        EtapeIG etape = monde.getEtapeSelectionnee();
+        if (monde.getNbEtapesSelectionnees() != 1) return;
 
-        // Créer une boîte de dialogue pour saisir le nouveau nom
-        TextInputDialog dialog = new TextInputDialog(etape.getNom());
+        // Créer une boîte de dialogue
+        TextInputDialog dialog = new TextInputDialog(monde.getEtapeSelectionnee().getNom());
         dialog.setTitle("Renommer l'activité");
-        dialog.setHeaderText("Renommer l'activité " + etape.getNom());
-        dialog.setContentText("Nouveau nom:");
-
-        // Afficher la boîte de dialogue et attendre la saisie
-        Optional<String> result = dialog.showAndWait();
+        dialog.setHeaderText("Entrez le nouveau nom de l'activité");
+        dialog.setContentText("Nom:");
 
-        // Si l'utilisateur a saisi un nouveau nom, renommer l'étape
-        result.ifPresent(nouveauNom -> {
+        // Récupérer le résultat
+        dialog.showAndWait().ifPresent(nouveauNom -> {
             if (!nouveauNom.isEmpty()) {
-                monde.renommerEtape(etape, nouveauNom);
+                monde.renommerEtape(monde.getEtapeSelectionnee(), nouveauNom);
             }
         });
     }
 
     /**
-     * Met à jour l'état des items du menu en fonction de l'état du monde
+     * Affiche une boîte de dialogue pour saisir les paramètres de l'activité sélectionnée
+     */
+    private void afficherDialogueParametres() {
+        // Vérifier qu'une seule activité est sélectionnée
+        if (!monde.uneSeuleActiviteSelectionnee()) return;
+
+        try {
+            // Récupérer l'activité sélectionnée
+            ActiviteIG activite = monde.getActiviteSelectionnee();
+
+            // Créer une boîte de dialogue personnalisée
+            Dialog<Pair<Integer, Integer>> dialog = new Dialog<>();
+            dialog.setTitle("Paramètres de l'activité");
+            dialog.setHeaderText("Définir le délai et l'écart");
+
+            // Ajouter les boutons
+            ButtonType boutonValider = new ButtonType("Valider", ButtonBar.ButtonData.OK_DONE);
+            dialog.getDialogPane().getButtonTypes().addAll(boutonValider, ButtonType.CANCEL);
+
+            // Créer la grille pour les champs
+            GridPane grid = new GridPane();
+            grid.setHgap(10);
+            grid.setVgap(10);
+            grid.setPadding(new Insets(20, 150, 10, 10));
+
+            // Créer les champs
+            TextField champDelai = new TextField();
+            champDelai.setPromptText("Délai");
+            TextField champEcart = new TextField();
+            champEcart.setPromptText("Écart");
+
+            // Récupérer les valeurs actuelles
+            champDelai.setText(String.valueOf(activite.getDelai()));
+            champEcart.setText(String.valueOf(activite.getEcart()));
+
+            // Ajouter les champs à la grille
+            grid.add(new Label("Délai:"), 0, 0);
+            grid.add(champDelai, 1, 0);
+            grid.add(new Label("Écart:"), 0, 1);
+            grid.add(champEcart, 1, 1);
+
+            // Ajouter la grille à la boîte de dialogue
+            dialog.getDialogPane().setContent(grid);
+
+            // Convertir le résultat
+            dialog.setResultConverter(dialogButton -> {
+                if (dialogButton == boutonValider) {
+                    try {
+                        int delai = Integer.parseInt(champDelai.getText());
+                        int ecart = Integer.parseInt(champEcart.getText());
+                        return new Pair<>(delai, ecart);
+                    } catch (NumberFormatException e) {
+                        return null;
+                    }
+                }
+                return null;
+            });
+
+            // Afficher la boîte de dialogue et traiter le résultat
+            dialog.showAndWait().ifPresent(parametres -> {
+                try {
+                    monde.definirParametres(parametres.getKey(), parametres.getValue());
+                } catch (ParametresException e) {
+                    // Afficher un message d'erreur
+                    Alert alert = new Alert(Alert.AlertType.ERROR);
+                    alert.setTitle("Erreur");
+                    alert.setHeaderText("Paramètres invalides");
+                    alert.setContentText(e.getMessage());
+                    alert.showAndWait();
+                } catch (IllegalStateException e) {
+                    // Afficher un message d'erreur
+                    Alert alert = new Alert(Alert.AlertType.ERROR);
+                    alert.setTitle("Erreur");
+                    alert.setHeaderText("Sélection invalide");
+                    alert.setContentText(e.getMessage());
+                    alert.showAndWait();
+                }
+            });
+        } catch (IllegalStateException e) {
+            // Afficher un message d'erreur
+            Alert alert = new Alert(Alert.AlertType.ERROR);
+            alert.setTitle("Erreur");
+            alert.setHeaderText("Sélection invalide");
+            alert.setContentText(e.getMessage());
+            alert.showAndWait();
+        }
+    }
+
+    /**
+     * Change le style de l'application
+     * @param nomStyle le nom du fichier CSS de style (sans l'extension)
      */
-    @Override
-    public void reagir() {
-        // Activer l'item Renommer uniquement si une seule étape est sélectionnée
-        itemRenommer.setDisable(monde.getNbEtapesSelectionnees() != 1);
+    private void changerStyle(String nomStyle) {
+        // Supprimer tous les styles existants
+        scene.getStylesheets().clear();
+
+        // Ajouter le nouveau style
+        String cssPath = getClass().getResource("/twisk/ressources/css/" + nomStyle + ".css").toExternalForm();
+        scene.getStylesheets().add(cssPath);
     }
 }
diff --git a/src/src/twisk/vues/VueMondeIG.java b/src/src/twisk/vues/VueMondeIG.java
index 1373997..821ff27 100644
--- a/src/src/twisk/vues/VueMondeIG.java
+++ b/src/src/twisk/vues/VueMondeIG.java
@@ -100,7 +100,14 @@ public class VueMondeIG extends Pane implements Observateur {
         // Effacer tous les composants existants
         this.getChildren().clear();
 
-        // IMPORTANT: Afficher d'abord les arcs
+        // D'abord, afficher les étapes
+        for (EtapeIG etape : monde) {
+            // Créer et ajouter la vue de l'étape
+            VueEtapeIG vueEtape = new VueActiviteIG(etape, monde);
+            this.getChildren().add(vueEtape);
+        }
+
+        // Ensuite, afficher les arcs (pour qu'ils soient au-dessus des étapes)
         Iterator<ArcIG> itArcs = monde.iteratorArcs();
         while (itArcs.hasNext()) {
             ArcIG arc = itArcs.next();
@@ -122,13 +129,8 @@ public class VueMondeIG extends Pane implements Observateur {
             this.getChildren().add(vueArc);
         }
 
-        // Ensuite, afficher les étapes et leurs points de contrôle
+        // Enfin, afficher les points de contrôle (pour qu'ils soient tout en haut)
         for (EtapeIG etape : monde) {
-            // Créer et ajouter la vue de l'étape
-            VueEtapeIG vueEtape = new VueActiviteIG(etape, monde);
-            this.getChildren().add(vueEtape);
-
-            // Ajouter les vues des points de contrôle de l'étape
             for (PointDeControleIG pt : etape) {
                 VuePointDeControleIG vuePt = new VuePointDeControleIG(pt, monde);
                 this.getChildren().add(vuePt);
@@ -137,6 +139,7 @@ public class VueMondeIG extends Pane implements Observateur {
     }
 
 
+
     /**
      * Affiche un message d'erreur dans une boîte de dialogue
      * @param message le message à afficher
diff --git a/src/src/twisk/vues/VueOutils.java b/src/src/twisk/vues/VueOutils.java
index 013711d..997baa8 100644
--- a/src/src/twisk/vues/VueOutils.java
+++ b/src/src/twisk/vues/VueOutils.java
@@ -18,6 +18,8 @@ public class VueOutils extends HBox {
         Button btnAjouterActivite = new Button("+ Activité");
         btnAjouterActivite.getStyleClass().add("bouton");
 
+
+
         // Ajout d'un tooltip
         Tooltip tooltip = new Tooltip("Ajouter une nouvelle activité");
         btnAjouterActivite.setTooltip(tooltip);
-- 
GitLab