From 615c58f7993fb48ceef330e2d27cc0b2810642b0 Mon Sep 17 00:00:00 2001
From: test <grave54122@gmail.com>
Date: Sun, 30 Mar 2025 12:10:10 +0000
Subject: [PATCH] TP1 debut

---
 src/src/twisk/MainTwisk.java                  | 45 ++++++++++++
 src/src/twisk/modele/ActiviteIG.java          |  8 +++
 src/src/twisk/modele/EtapeIG.java             | 64 +++++++++++++++++
 src/src/twisk/modele/FabriqueIdentifiant.java | 23 ++++++
 src/src/twisk/modele/MondeIG.java             | 60 ++++++++++++++++
 src/src/twisk/outils/Observable.java          |  6 ++
 src/src/twisk/outils/Observateur.java         |  5 ++
 src/src/twisk/test/modele/ActiviteIGTest.java | 50 +++++++++++++
 .../test/modele/FabriqueIdentifiantTest.java  | 33 +++++++++
 src/src/twisk/test/modele/MondeIGTest.java    | 72 +++++++++++++++++++
 src/src/twisk/vues/VueActiviteIG.java         | 33 +++++++++
 src/src/twisk/vues/VueEtapeIG.java            | 24 +++++++
 src/src/twisk/vues/VueMondeIG.java            | 32 +++++++++
 src/src/twisk/vues/VueOutils.java             | 27 +++++++
 14 files changed, 482 insertions(+)
 create mode 100644 src/src/twisk/MainTwisk.java
 create mode 100644 src/src/twisk/modele/ActiviteIG.java
 create mode 100644 src/src/twisk/modele/EtapeIG.java
 create mode 100644 src/src/twisk/modele/FabriqueIdentifiant.java
 create mode 100644 src/src/twisk/modele/MondeIG.java
 create mode 100644 src/src/twisk/outils/Observable.java
 create mode 100644 src/src/twisk/outils/Observateur.java
 create mode 100644 src/src/twisk/test/modele/ActiviteIGTest.java
 create mode 100644 src/src/twisk/test/modele/FabriqueIdentifiantTest.java
 create mode 100644 src/src/twisk/test/modele/MondeIGTest.java
 create mode 100644 src/src/twisk/vues/VueActiviteIG.java
 create mode 100644 src/src/twisk/vues/VueEtapeIG.java
 create mode 100644 src/src/twisk/vues/VueMondeIG.java
 create mode 100644 src/src/twisk/vues/VueOutils.java

diff --git a/src/src/twisk/MainTwisk.java b/src/src/twisk/MainTwisk.java
new file mode 100644
index 0000000..3044754
--- /dev/null
+++ b/src/src/twisk/MainTwisk.java
@@ -0,0 +1,45 @@
+package twisk;
+
+import javafx.application.Application;
+import javafx.scene.Scene;
+import javafx.scene.layout.BorderPane;
+import javafx.stage.Stage;
+import twisk.modele.MondeIG;
+import twisk.vues.VueMondeIG;
+import twisk.vues.VueOutils;
+
+public class MainTwisk extends Application {
+
+    @Override
+    public void start(Stage primaryStage) {
+        try {
+            // Création du modèle
+            MondeIG monde = new MondeIG();
+
+            // Création du conteneur principal
+            BorderPane root = new BorderPane();
+
+            // Création et placement de la vue du monde au centre
+            VueMondeIG vueMonde = new VueMondeIG(monde);
+            root.setCenter(vueMonde);
+
+            // 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);
+
+            // Configuration de la fenêtre principale
+            primaryStage.setTitle("TwiskIG");
+            primaryStage.setScene(scene);
+            primaryStage.show();
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    public static void main(String[] args) {
+        launch(args);
+    }
+}
diff --git a/src/src/twisk/modele/ActiviteIG.java b/src/src/twisk/modele/ActiviteIG.java
new file mode 100644
index 0000000..3ddd57b
--- /dev/null
+++ b/src/src/twisk/modele/ActiviteIG.java
@@ -0,0 +1,8 @@
+package twisk.modele;
+
+public class ActiviteIG extends EtapeIG {
+
+    public ActiviteIG(String nom) {
+        super(nom, 100, 60); // Dimensions par défaut pour une activité
+    }
+}
diff --git a/src/src/twisk/modele/EtapeIG.java b/src/src/twisk/modele/EtapeIG.java
new file mode 100644
index 0000000..fc57098
--- /dev/null
+++ b/src/src/twisk/modele/EtapeIG.java
@@ -0,0 +1,64 @@
+package twisk.modele;
+
+public abstract class EtapeIG {
+    private String nom;
+    private final String identifiant;
+    private int posX;
+    private int posY;
+    private int largeur;
+    private int hauteur;
+
+    public EtapeIG(String nom, int largeur, int hauteur) {
+        this.nom = nom;
+        this.identifiant = FabriqueIdentifiant.getInstance().getIdentifiantUnique();
+        // Position aléatoire entre 0 et 500 (à ajuster selon vos besoins)
+        this.posX = (int) (Math.random() * 500);
+        this.posY = (int) (Math.random() * 500);
+        this.largeur = largeur;
+        this.hauteur = hauteur;
+    }
+
+    public String getNom() {
+        return nom;
+    }
+
+    public void setNom(String nom) {
+        this.nom = nom;
+    }
+
+    public String getIdentifiant() {
+        return identifiant;
+    }
+
+    public int getPosX() {
+        return posX;
+    }
+
+    public void setPosX(int posX) {
+        this.posX = posX;
+    }
+
+    public int getPosY() {
+        return posY;
+    }
+
+    public void setPosY(int posY) {
+        this.posY = posY;
+    }
+
+    public int getLargeur() {
+        return largeur;
+    }
+
+    public void setLargeur(int largeur) {
+        this.largeur = largeur;
+    }
+
+    public int getHauteur() {
+        return hauteur;
+    }
+
+    public void setHauteur(int hauteur) {
+        this.hauteur = hauteur;
+    }
+}
diff --git a/src/src/twisk/modele/FabriqueIdentifiant.java b/src/src/twisk/modele/FabriqueIdentifiant.java
new file mode 100644
index 0000000..18d4f08
--- /dev/null
+++ b/src/src/twisk/modele/FabriqueIdentifiant.java
@@ -0,0 +1,23 @@
+package twisk.modele;
+
+public class FabriqueIdentifiant {
+    private static FabriqueIdentifiant instance = new FabriqueIdentifiant();
+    private int compteur;
+
+    private FabriqueIdentifiant() {
+        compteur = 0;
+    }
+
+    public static FabriqueIdentifiant getInstance() {
+        return instance;
+    }
+
+    public String getIdentifiantUnique() {
+        return String.valueOf(compteur++);
+    }
+
+    // For testing purposes
+    public void reset() {
+        compteur = 0;
+    }
+}
diff --git a/src/src/twisk/modele/MondeIG.java b/src/src/twisk/modele/MondeIG.java
new file mode 100644
index 0000000..edc5540
--- /dev/null
+++ b/src/src/twisk/modele/MondeIG.java
@@ -0,0 +1,60 @@
+package twisk.modele;
+
+import twisk.outils.Observable;
+import twisk.outils.Observateur;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Map;
+
+public class MondeIG implements Iterable<EtapeIG>, Observable {
+    private final Map<String, EtapeIG> etapes;
+    private int compteurActivites;
+    private ArrayList<Observateur> observateurs;
+
+    public MondeIG() {
+        etapes = new HashMap<>();
+        compteurActivites = 1;
+        observateurs = new ArrayList<>();
+
+        // Ajouter une activité par défaut à la construction
+        ajouter("Activite");
+    }
+
+    public void ajouter(String type) {
+        if ("Activite".equals(type)) {
+            String nom = "Activite " + compteurActivites++;
+            ActiviteIG activite = new ActiviteIG(nom);
+            etapes.put(activite.getIdentifiant(), activite);
+
+            // Trace temporaire pour vérifier l'effet du clic
+            System.out.println("Ajout d'une activité : " + nom + " (id: " + activite.getIdentifiant() + ")");
+
+            // Notifier les observateurs
+            notifierObservateurs();
+        }
+        // Autres types d'étapes pourront être ajoutés ici dans le futur
+    }
+
+    public EtapeIG getEtape(String identifiant) {
+        return etapes.get(identifiant);
+    }
+
+    @Override
+    public Iterator<EtapeIG> iterator() {
+        return etapes.values().iterator();
+    }
+
+    @Override
+    public void ajouterObservateur(Observateur o) {
+        observateurs.add(o);
+    }
+
+    @Override
+    public void notifierObservateurs() {
+        for (Observateur o : observateurs) {
+            o.reagir();
+        }
+    }
+}
diff --git a/src/src/twisk/outils/Observable.java b/src/src/twisk/outils/Observable.java
new file mode 100644
index 0000000..ea648b7
--- /dev/null
+++ b/src/src/twisk/outils/Observable.java
@@ -0,0 +1,6 @@
+package twisk.outils;
+
+public interface Observable {
+    void ajouterObservateur(Observateur o);
+    void notifierObservateurs();
+}
diff --git a/src/src/twisk/outils/Observateur.java b/src/src/twisk/outils/Observateur.java
new file mode 100644
index 0000000..6eece88
--- /dev/null
+++ b/src/src/twisk/outils/Observateur.java
@@ -0,0 +1,5 @@
+package twisk.outils;
+
+public interface Observateur {
+    void reagir();
+}
diff --git a/src/src/twisk/test/modele/ActiviteIGTest.java b/src/src/twisk/test/modele/ActiviteIGTest.java
new file mode 100644
index 0000000..57019ba
--- /dev/null
+++ b/src/src/twisk/test/modele/ActiviteIGTest.java
@@ -0,0 +1,50 @@
+package twisk.test.modele;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import twisk.modele.ActiviteIG;
+import twisk.modele.FabriqueIdentifiant;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class ActiviteIGTest {
+
+    @BeforeEach
+    void setUp() {
+        FabriqueIdentifiant.getInstance().reset();
+    }
+
+    @Test
+    void testConstructeur() {
+        ActiviteIG activite = new ActiviteIG("Activite Test");
+
+        assertEquals("Activite Test", activite.getNom(), "Le nom devrait être correctement initialisé");
+        assertEquals("0", activite.getIdentifiant(), "L'identifiant devrait être 0");
+        assertEquals(100, activite.getLargeur(), "La largeur par défaut devrait être 100");
+        assertEquals(60, activite.getHauteur(), "La hauteur par défaut devrait être 60");
+
+        // Vérifier que la position est dans les limites attendues
+        assertTrue(activite.getPosX() >= 0 && activite.getPosX() <= 500, "La position X devrait être entre 0 et 500");
+        assertTrue(activite.getPosY() >= 0 && activite.getPosY() <= 500, "La position Y devrait être entre 0 et 500");
+    }
+
+    @Test
+    void testSetters() {
+        ActiviteIG activite = new ActiviteIG("Activite Test");
+
+        activite.setNom("Nouveau Nom");
+        assertEquals("Nouveau Nom", activite.getNom(), "Le nom devrait être modifié");
+
+        activite.setPosX(200);
+        assertEquals(200, activite.getPosX(), "La position X devrait être modifiée");
+
+        activite.setPosY(300);
+        assertEquals(300, activite.getPosY(), "La position Y devrait être modifiée");
+
+        activite.setLargeur(150);
+        assertEquals(150, activite.getLargeur(), "La largeur devrait être modifiée");
+
+        activite.setHauteur(80);
+        assertEquals(80, activite.getHauteur(), "La hauteur devrait être modifiée");
+    }
+}
diff --git a/src/src/twisk/test/modele/FabriqueIdentifiantTest.java b/src/src/twisk/test/modele/FabriqueIdentifiantTest.java
new file mode 100644
index 0000000..a318fd8
--- /dev/null
+++ b/src/src/twisk/test/modele/FabriqueIdentifiantTest.java
@@ -0,0 +1,33 @@
+package twisk.test.modele;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import twisk.modele.FabriqueIdentifiant;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class FabriqueIdentifiantTest {
+
+    @BeforeEach
+    void setUp() {
+        FabriqueIdentifiant.getInstance().reset();
+    }
+
+    @Test
+    void testGetInstance() {
+        FabriqueIdentifiant instance1 = FabriqueIdentifiant.getInstance();
+        FabriqueIdentifiant instance2 = FabriqueIdentifiant.getInstance();
+        assertSame(instance1, instance2, "Les instances devraient être identiques (singleton)");
+    }
+
+    @Test
+    void testGetIdentifiantUnique() {
+        FabriqueIdentifiant fabrique = FabriqueIdentifiant.getInstance();
+        String id1 = fabrique.getIdentifiantUnique();
+        String id2 = fabrique.getIdentifiantUnique();
+
+        assertNotEquals(id1, id2, "Les identifiants devraient être uniques");
+        assertEquals("0", id1, "Premier identifiant devrait être 0");
+        assertEquals("1", id2, "Deuxième identifiant devrait être 1");
+    }
+}
diff --git a/src/src/twisk/test/modele/MondeIGTest.java b/src/src/twisk/test/modele/MondeIGTest.java
new file mode 100644
index 0000000..09129b8
--- /dev/null
+++ b/src/src/twisk/test/modele/MondeIGTest.java
@@ -0,0 +1,72 @@
+package twisk.test.modele;
+
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import twisk.modele.ActiviteIG;
+import twisk.modele.EtapeIG;
+import twisk.modele.FabriqueIdentifiant;
+import twisk.modele.MondeIG;
+
+import java.util.Iterator;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+class MondeIGTest {
+
+    @BeforeEach
+    void setUp() {
+        FabriqueIdentifiant.getInstance().reset();
+    }
+
+    @Test
+    void testConstructeur() {
+        MondeIG monde = new MondeIG();
+
+        // Vérifier qu'il y a une activité par défaut
+        Iterator<EtapeIG> it = monde.iterator();
+        assertTrue(it.hasNext(), "Le monde devrait contenir au moins une étape");
+
+        EtapeIG etape = it.next();
+        assertTrue(etape instanceof ActiviteIG, "L'étape devrait être une ActiviteIG");
+        assertEquals("Activite 1", etape.getNom(), "Le nom par défaut devrait être 'Activite 1'");
+        assertFalse(it.hasNext(), "Le monde ne devrait contenir qu'une seule étape à l'initialisation");
+    }
+
+    @Test
+    void testAjouter() {
+        MondeIG monde = new MondeIG();
+
+        // Ajouter une nouvelle activité
+        monde.ajouter("Activite");
+
+        // Vérifier qu'il y a maintenant deux activités
+        Iterator<EtapeIG> it = monde.iterator();
+        assertTrue(it.hasNext());
+        EtapeIG etape1 = it.next();
+        assertTrue(it.hasNext());
+        EtapeIG etape2 = it.next();
+        assertFalse(it.hasNext());
+
+        // Vérifier que les noms sont différents
+        assertNotEquals(etape1.getNom(), etape2.getNom(), "Les noms des activités devraient être différents");
+
+        // Vérifier que les identifiants sont différents
+        assertNotEquals(etape1.getIdentifiant(), etape2.getIdentifiant(), "Les identifiants devraient être différents");
+    }
+
+    @Test
+    void testIterator() {
+        MondeIG monde = new MondeIG();
+        monde.ajouter("Activite");
+        monde.ajouter("Activite");
+
+        int count = 0;
+        for (EtapeIG etape : monde) {
+            assertNotNull(etape, "L'étape ne devrait pas être null");
+            assertTrue(etape instanceof ActiviteIG, "L'étape devrait être une ActiviteIG");
+            count++;
+        }
+
+        assertEquals(3, count, "Le monde devrait contenir 3 étapes");
+    }
+}
diff --git a/src/src/twisk/vues/VueActiviteIG.java b/src/src/twisk/vues/VueActiviteIG.java
new file mode 100644
index 0000000..7d4a70a
--- /dev/null
+++ b/src/src/twisk/vues/VueActiviteIG.java
@@ -0,0 +1,33 @@
+package twisk.vues;
+
+import javafx.scene.layout.HBox;
+import javafx.scene.layout.VBox;
+import twisk.modele.ActiviteIG;
+import twisk.modele.EtapeIG;
+
+public class VueActiviteIG extends VueEtapeIG {
+    private HBox zoneClients;
+
+    public VueActiviteIG(EtapeIG etape) {
+        super(etape);
+
+        // Création de la zone pour les clients
+        zoneClients = new HBox();
+        zoneClients.setPrefSize(etape.getLargeur(), etape.getHauteur() - 20); // Réserver de l'espace pour le titre
+        zoneClients.setStyle("-fx-border-color: #0059FF; -fx-background-insets: 0 0 -1 0, 0, 1, 2; -fx-background-radius: 3px, 3px, 2px, 1px;");
+
+        // Organisation verticale: titre en haut, zone clients en dessous
+        VBox contenu = new VBox();
+        contenu.getChildren().addAll(titre, zoneClients);
+
+        // Définir la taille du composant
+        this.setPrefSize(etape.getLargeur(), etape.getHauteur());
+
+        // Ajout du contenu au composant
+        this.getChildren().clear();
+        this.getChildren().add(contenu);
+
+        // Ajout d'un style pour la boîte
+        this.setStyle("-fx-border-color: black; -fx-border-width: 1px;");
+    }
+}
diff --git a/src/src/twisk/vues/VueEtapeIG.java b/src/src/twisk/vues/VueEtapeIG.java
new file mode 100644
index 0000000..a1bc4ee
--- /dev/null
+++ b/src/src/twisk/vues/VueEtapeIG.java
@@ -0,0 +1,24 @@
+package twisk.vues;
+
+import javafx.scene.control.Label;
+import javafx.scene.layout.Pane;
+import twisk.modele.EtapeIG;
+
+public abstract class VueEtapeIG extends Pane {
+    protected EtapeIG etape;
+    protected Label titre;
+
+    public VueEtapeIG(EtapeIG etape) {
+        this.etape = etape;
+
+        // Création du titre
+        this.titre = new Label(etape.getNom());
+        titre.setStyle("-fx-font-weight: bold;");
+
+        // Ajout du titre au composant
+        this.getChildren().add(titre);
+
+        // Positionnement du composant selon les coordonnées de l'étape
+        relocate(etape.getPosX(), etape.getPosY());
+    }
+}
diff --git a/src/src/twisk/vues/VueMondeIG.java b/src/src/twisk/vues/VueMondeIG.java
new file mode 100644
index 0000000..8b1b5fc
--- /dev/null
+++ b/src/src/twisk/vues/VueMondeIG.java
@@ -0,0 +1,32 @@
+package twisk.vues;
+
+import javafx.scene.layout.Pane;
+import twisk.modele.EtapeIG;
+import twisk.modele.MondeIG;
+import twisk.outils.Observateur;
+
+public class VueMondeIG extends Pane implements Observateur {
+    private MondeIG monde;
+
+    public VueMondeIG(MondeIG monde) {
+        this.monde = monde;
+
+        // S'enregistrer comme observateur du monde
+        monde.ajouterObservateur(this);
+
+        // Initialiser la vue
+        reagir();
+    }
+
+    @Override
+    public void reagir() {
+        // Effacer tous les composants existants
+        this.getChildren().clear();
+
+        // Ajouter une vue pour chaque étape du monde
+        for (EtapeIG etape : monde) {
+            VueEtapeIG vueEtape = new VueActiviteIG(etape);
+            this.getChildren().add(vueEtape);
+        }
+    }
+}
diff --git a/src/src/twisk/vues/VueOutils.java b/src/src/twisk/vues/VueOutils.java
new file mode 100644
index 0000000..50e50d5
--- /dev/null
+++ b/src/src/twisk/vues/VueOutils.java
@@ -0,0 +1,27 @@
+package twisk.vues;
+
+import javafx.scene.control.Button;
+import javafx.scene.control.Tooltip;
+import javafx.scene.layout.HBox;
+import twisk.modele.MondeIG;
+
+public class VueOutils extends HBox {
+    private final MondeIG monde;
+
+    public VueOutils(MondeIG monde) {
+        this.monde = monde;
+
+        // Création du bouton pour ajouter une activité
+        Button btnAjouterActivite = new Button("+ Activité");
+
+        // Ajout d'un tooltip
+        Tooltip tooltip = new Tooltip("Ajouter une nouvelle activité");
+        btnAjouterActivite.setTooltip(tooltip);
+
+        // Ajout de l'écouteur d'événement
+        btnAjouterActivite.setOnAction(event -> monde.ajouter("Activite"));
+
+        // Ajout du bouton à la vue
+        this.getChildren().add(btnAjouterActivite);
+    }
+}
-- 
GitLab