diff --git a/src/src/twisk/MainTwisk.java b/src/src/twisk/MainTwisk.java index 785b687216f9e785fe6b112e162a7deac187e3ae..4d1e3b3913cce916dce41ee654d97f4b91c6cc14 100644 --- a/src/src/twisk/MainTwisk.java +++ b/src/src/twisk/MainTwisk.java @@ -5,6 +5,7 @@ import javafx.scene.Scene; import javafx.scene.layout.BorderPane; import javafx.stage.Stage; import twisk.modele.MondeIG; +import twisk.vues.VueMenu; import twisk.vues.VueMondeIG; import twisk.vues.VueOutils; @@ -19,6 +20,10 @@ 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 et placement de la vue du monde au centre VueMondeIG vueMonde = new VueMondeIG(monde); root.setCenter(vueMonde); diff --git a/src/src/twisk/modele/EtapeIG.java b/src/src/twisk/modele/EtapeIG.java index 66514b09dc91ba161921959f32bb6ec0e504701b..e38fc8043d35fcb7bef2a3ef9b3314519258ae24 100644 --- a/src/src/twisk/modele/EtapeIG.java +++ b/src/src/twisk/modele/EtapeIG.java @@ -35,37 +35,32 @@ public abstract class EtapeIG implements Iterable<PointDeControleIG> { private void creerPointsDeControle() { // Point sur le côté supérieur (milieu) pointsDeControle.add(new PointDeControleIG( - posX + largeur / 2, - posY, "p" + identifiant + "N", // N pour Nord - this + this, + "N" )); // Point sur le côté droit (milieu) pointsDeControle.add(new PointDeControleIG( - posX + largeur, - posY + hauteur / 2, "p" + identifiant + "E", // E pour Est - this + this, + "E" )); // Point sur le côté inférieur (milieu) pointsDeControle.add(new PointDeControleIG( - posX + largeur / 2, - posY + hauteur, "p" + identifiant + "S", // S pour Sud - this + this, + "S" )); // Point sur le côté gauche (milieu) pointsDeControle.add(new PointDeControleIG( - posX, - posY + hauteur / 2, "p" + identifiant + "O", // O pour Ouest - this + this, + "O" )); } - /** * Met à jour la position des points de contrôle quand l'étape est déplacée */ diff --git a/src/src/twisk/modele/MondeIG.java b/src/src/twisk/modele/MondeIG.java index 55e3ead3510a2f0b0311e8a538aa8674b94be5f1..a612c51f200264258953ba63f37c21867dad21b1 100644 --- a/src/src/twisk/modele/MondeIG.java +++ b/src/src/twisk/modele/MondeIG.java @@ -1,5 +1,6 @@ package twisk.modele; +import javafx.util.Pair; import twisk.exceptions.ArcException; import twisk.outils.Observable; import twisk.outils.Observateur; @@ -15,6 +16,9 @@ public class MondeIG implements Iterable<EtapeIG>, Observable { private PointDeControleIG pointSelectionne; private List<Point2D> pointsCliques; private static final int NB_POINTS_COURBE = 4; + private Set<String> etapesSelectionnees; + private Set<ArcIG> arcsSelectionnes; + public MondeIG() { etapes = new HashMap<>(); @@ -23,11 +27,14 @@ public class MondeIG implements Iterable<EtapeIG>, Observable { pointsCliques = new ArrayList<>(); compteurActivites = 1; observateurs = new ArrayList<>(); + etapesSelectionnees = new HashSet<>(); + arcsSelectionnes = new HashSet<>(); // Initialiser l'ensemble des arcs sélectionnés // Ajouter une activité par défaut à la construction ajouter("Activite"); } + /** * Ajoute une étape du type spécifié * @param type le type d'étape à ajouter @@ -285,5 +292,283 @@ public class MondeIG implements Iterable<EtapeIG>, Observable { pointsCliques.add(new Point2D(x, y)); } } + /** + * Gère la sélection/désélection d'une étape + * @param etape l'étape à sélectionner/désélectionner + */ + public void selectionnerEtape(EtapeIG etape) { + String id = etape.getIdentifiant(); + + // Si l'étape est déjà sélectionnée, la désélectionner + if (etapesSelectionnees.contains(id)) { + etapesSelectionnees.remove(id); + } else { + // Sinon, la sélectionner + etapesSelectionnees.add(id); + } + + // Notifier les observateurs pour mettre à jour l'affichage + notifierObservateurs(); + } + + /** + * Vérifie si une étape est sélectionnée + * @param etape l'étape à vérifier + * @return true si l'étape est sélectionnée, false sinon + */ + public boolean estSelectionnee(EtapeIG etape) { + return etapesSelectionnees.contains(etape.getIdentifiant()); + } + + /** + * Retourne l'ensemble des identifiants des étapes sélectionnées + * @return ensemble des identifiants + */ + public Set<String> getEtapesSelectionnees() { + return Collections.unmodifiableSet(etapesSelectionnees); + } + + /** + * Supprime toutes les étapes sélectionnées et les arcs qui leur sont attachés + */ + public void supprimerEtapesSelectionnees() { + // Créer une liste temporaire pour éviter les problèmes de concurrence + List<String> aSupprimer = new ArrayList<>(etapesSelectionnees); + + // Supprimer les arcs attachés aux étapes sélectionnées + Iterator<ArcIG> itArc = arcs.iterator(); + while (itArc.hasNext()) { + ArcIG arc = itArc.next(); + // Si l'arc est attaché à une étape sélectionnée, le supprimer + if (etapesSelectionnees.contains(arc.getP1().getEtape().getIdentifiant()) || + etapesSelectionnees.contains(arc.getP2().getEtape().getIdentifiant())) { + itArc.remove(); + } + } + + // Supprimer les étapes sélectionnées + for (String id : aSupprimer) { + etapes.remove(id); + } + + // Vider la liste des étapes sélectionnées + etapesSelectionnees.clear(); + + // Notifier les observateurs + notifierObservateurs(); + } + /** + * Retourne le nombre d'étapes sélectionnées + * @return nombre d'étapes sélectionnées + */ + public int getNbEtapesSelectionnees() { + return etapesSelectionnees.size(); + } + + /** + * Retourne l'étape sélectionnée (si une seule est sélectionnée) + * @return l'étape sélectionnée ou null si aucune ou plusieurs sont sélectionnées + */ + public EtapeIG getEtapeSelectionnee() { + if (etapesSelectionnees.size() != 1) { + return null; + } + + // Récupérer l'identifiant de l'étape sélectionnée + String id = etapesSelectionnees.iterator().next(); + + // Retourner l'étape correspondante + return etapes.get(id); + } + + /** + * Renomme une étape + * @param etape l'étape à renommer + * @param nouveauNom le nouveau nom de l'étape + */ + public void renommerEtape(EtapeIG etape, String nouveauNom) { + // Vérifier que l'étape existe + if (etapes.containsKey(etape.getIdentifiant())) { + // Renommer l'étape + etape.setNom(nouveauNom); + + // Notifier les observateurs + notifierObservateurs(); + } + } + + /** + * Déplace une étape aux coordonnées spécifiées + * @param idEtape l'identifiant de l'étape à déplacer + * @param x la nouvelle coordonnée x + * @param y la nouvelle coordonnée y + */ + public void deplacerEtape(String idEtape, int x, int y) { + // Vérifier que l'étape existe + if (etapes.containsKey(idEtape)) { + EtapeIG etape = etapes.get(idEtape); + + // Calculer les nouvelles coordonnées en tenant compte du centre de l'étape + int newX = x - etape.getLargeur() / 2; + int newY = y - etape.getHauteur() / 2; + + // Éviter les coordonnées négatives + newX = Math.max(0, newX); + newY = Math.max(0, newY); + + // Mettre à jour les coordonnées de l'étape + etape.setPosX(newX); + etape.setPosY(newY); + + // Notifier les observateurs + notifierObservateurs(); + } + } + /** + * Sélectionne ou désélectionne un arc + * @param arc l'arc à sélectionner/désélectionner + */ + public void selectionnerArc(ArcIG arc) { + if (arcsSelectionnes.contains(arc)) { + // Si l'arc est déjà sélectionné, le désélectionner + arcsSelectionnes.remove(arc); + } else { + // Sinon, le sélectionner + arcsSelectionnes.add(arc); + } + + // Notifier les observateurs pour mettre à jour l'affichage + notifierObservateurs(); + } + + + /** + * Vérifie si un arc est sélectionné + * @param arc l'arc à vérifier + * @return true si l'arc est sélectionné, false sinon + */ + public boolean estSelectionne(ArcIG arc) { + return arcsSelectionnes.contains(arc); + } + + /** + * Supprime toutes les étapes sélectionnées et les arcs sélectionnés + */ + public void supprimerSelection() { + // Créer une liste temporaire pour éviter les ConcurrentModificationException + List<ArcIG> arcsASupprimer = new ArrayList<>(); + + // Supprimer les arcs attachés aux étapes sélectionnées + for (ArcIG arc : arcs) { + if (etapesSelectionnees.contains(arc.getP1().getEtape().getIdentifiant()) || + etapesSelectionnees.contains(arc.getP2().getEtape().getIdentifiant())) { + arcsASupprimer.add(arc); + } + } + + // Supprimer les arcs sélectionnés + for (ArcIG arc : arcsSelectionnes) { + if (!arcsASupprimer.contains(arc)) { + arcsASupprimer.add(arc); + } + } + + // Supprimer les arcs de la liste principale + arcs.removeAll(arcsASupprimer); + + // Supprimer les étapes sélectionnées + for (String id : new ArrayList<>(etapesSelectionnees)) { + etapes.remove(id); + } + + // Vider les listes de sélection + etapesSelectionnees.clear(); + arcsSelectionnes.clear(); + + // Notifier les observateurs + notifierObservateurs(); + } + /** + * Désélectionne tous les éléments sélectionnés (étapes et arcs) + */ + public void deselectionnerTout() { + // Vider les ensembles de sélection + etapesSelectionnees.clear(); + arcsSelectionnes.clear(); + + // Notifier les observateurs + notifierObservateurs(); + } + /** + * Retourne un point de contrôle à partir de son ID + * @param id l'ID du point de contrôle + * @return le point de contrôle ou null s'il n'existe pas + */ + public PointDeControleIG getPointDeControleById(String id) { + // Parcourir toutes les étapes + for (EtapeIG etape : etapes.values()) { + // Parcourir tous les points de contrôle de l'étape + for (PointDeControleIG pt : etape) { + if (pt.getId().equals(id)) { + return pt; + } + } + } + return null; + } + /** + * Gère le drag and drop entre deux points de contrôle + * @param pointSource le point de contrôle source + * @param pointCible le point de contrôle cible + * @return true si l'opération a réussi, false sinon avec un message d'erreur + */ + public Pair<Boolean, String> gererDragAndDropPoints(PointDeControleIG pointSource, PointDeControleIG pointCible) { + try { + // Vérifier que les points sont différents + if (pointSource == pointCible) { + return new Pair<>(false, "Impossible de créer un arc: les deux points sont identiques"); + } + + // Vérifier que les points ne sont pas sur la même étape + if (pointSource.getEtape().equals(pointCible.getEtape())) { + return new Pair<>(false, "Impossible de créer un arc: les deux points appartiennent à la même étape"); + } + + // Vérifier qu'il n'existe pas déjà un arc entre ces deux points + for (ArcIG arc : arcs) { + if ((arc.getP1().equals(pointSource) && arc.getP2().equals(pointCible))) { + return new Pair<>(false, "Impossible de créer un arc: un arc existe déjà entre ces deux points"); + } + } + + // Vérifier qu'il n'existe pas déjà un arc dans le sens inverse + for (ArcIG arc : arcs) { + if ((arc.getP1().equals(pointCible) && arc.getP2().equals(pointSource)) || + (arc.getP1().getEtape().equals(pointCible.getEtape()) && arc.getP2().getEtape().equals(pointSource.getEtape()))) { + return new Pair<>(false, "Impossible de créer un arc: un arc existe déjà dans le sens inverse"); + } + } + + // Vérifier que le point de départ n'est pas déjà utilisé comme source d'un autre arc + for (ArcIG arc : arcs) { + if (arc.getP1().equals(pointSource)) { + return new Pair<>(false, "Impossible de créer un arc: le point de départ est déjà utilisé comme source d'un autre arc"); + } + } + + // Vérifier que le point d'arrivée n'est pas déjà utilisé comme destination d'un autre arc + for (ArcIG arc : arcs) { + if (arc.getP2().equals(pointCible)) { + return new Pair<>(false, "Impossible de créer un arc: le point d'arrivée est déjà utilisé comme destination d'un autre arc"); + } + } + + // Toutes les contraintes sont satisfaites, on peut ajouter l'arc + ajouter(pointSource, pointCible); + return new Pair<>(true, ""); + } catch (ArcException e) { + return new Pair<>(false, e.getMessage()); + } + } } diff --git a/src/src/twisk/modele/PointDeControleIG.java b/src/src/twisk/modele/PointDeControleIG.java index 30fc1791d379a8e3ff868a4f254f181b55a0f9bf..8ab7af38d2dba7c99b1d66d5475010aaf1d73301 100644 --- a/src/src/twisk/modele/PointDeControleIG.java +++ b/src/src/twisk/modele/PointDeControleIG.java @@ -4,39 +4,56 @@ package twisk.modele; * Classe représentant un point de contrôle sur une étape */ public class PointDeControleIG { - private final int posX; - private final int posY; private final String id; private final EtapeIG etape; + private final String position; // "N", "E", "S", "O" /** * Constructeur - * @param posX position X du centre du point - * @param posY position Y du centre du point - * @param id identifiant unique - * @param etape étape à laquelle le point est rattaché + * @param id identifiant du point + * @param etape étape à laquelle appartient le point + * @param position position du point ("N", "E", "S", "O") */ - public PointDeControleIG(int posX, int posY, String id, EtapeIG etape) { - this.posX = posX; - this.posY = posY; + public PointDeControleIG(String id, EtapeIG etape, String position) { this.id = id; this.etape = etape; + this.position = position; } /** - * Retourne la position X du point - * @return position X + * Retourne la coordonnée X du point + * @return coordonnée X */ public int getPosX() { - return posX; + switch (position) { + case "N": // Nord + case "S": // Sud + return etape.getPosX() + etape.getLargeur() / 2; + case "E": // Est + return etape.getPosX() + etape.getLargeur(); + case "O": // Ouest + return etape.getPosX(); + default: + return 0; + } } /** - * Retourne la position Y du point - * @return position Y + * Retourne la coordonnée Y du point + * @return coordonnée Y */ public int getPosY() { - return posY; + switch (position) { + case "N": // Nord + return etape.getPosY(); + case "E": // Est + case "O": // Ouest + return etape.getPosY() + etape.getHauteur() / 2; + case "S": // Sud + return etape.getPosY() + etape.getHauteur(); + default: + return 0; + } } /** diff --git a/src/src/twisk/ressources/css/style.css b/src/src/twisk/ressources/css/style.css index 96183686d10907d5e99ac40b6e22e36ddcc34a85..a15023e2c80977dfd1163181fdf95b3a0f4788fa 100644 --- a/src/src/twisk/ressources/css/style.css +++ b/src/src/twisk/ressources/css/style.css @@ -20,6 +20,15 @@ -fx-effect: dropshadow(three-pass-box, rgba(0,0,0,0.2), 5, 0, 0, 2); } +/* Style pour le rectangle de l'activité */ +.activite-rectangle { + -fx-fill: #e6f2ff; + -fx-stroke: #0066cc; + -fx-stroke-width: 2px; + -fx-arc-height: 10; + -fx-arc-width: 10; +} + /* Style pour le titre de l'activité */ .titre-activite { -fx-font-size: 14px; @@ -28,6 +37,7 @@ -fx-padding: 5px; -fx-background-color: #cce0ff; -fx-background-radius: 5px 5px 0 0; + -fx-alignment: center; } /* Style pour la zone des clients */ @@ -39,6 +49,15 @@ -fx-background-radius: 0 0 5px 5px; -fx-padding: 5px; -fx-min-height: 30px; + -fx-alignment: center; + -fx-text-fill: #0066cc; +} + +/* Style pour les étapes sélectionnées */ +.etape-selectionnee { + -fx-effect: dropshadow(three-pass-box, #ff6600, 10, 0, 0, 0); + -fx-border-color: #ff6600; + -fx-border-width: 3; } /* Style pour la barre d'outils */ @@ -97,3 +116,22 @@ -fx-fill: #66b3ff; -fx-effect: dropshadow(three-pass-box, rgba(0,0,0,0.3), 3, 0, 0, 0); } + +/* Style pour les arcs sélectionnés */ +.arc-selectionne .arc-ligne { + -fx-stroke: #ff6600; + -fx-stroke-width: 3; + -fx-effect: dropshadow(three-pass-box, #ff6600, 5, 0, 0, 0); +} + +.arc-selectionne .arc-fleche { + -fx-fill: #ff6600; + -fx-stroke: #ff6600; +} + +/* Style pour les arcs */ +.arc { + -fx-cursor: hand; +} + + diff --git a/src/src/twisk/vues/VueActiviteIG.java b/src/src/twisk/vues/VueActiviteIG.java index 787d348e847357bdd71c6cc242d2659ba6c4238d..0c97e219141c0254dba5511ebb9b84e9e9f584db 100644 --- a/src/src/twisk/vues/VueActiviteIG.java +++ b/src/src/twisk/vues/VueActiviteIG.java @@ -1,36 +1,69 @@ package twisk.vues; -import javafx.scene.layout.HBox; +import javafx.scene.control.Label; import javafx.scene.layout.VBox; +import javafx.scene.shape.Rectangle; import twisk.modele.EtapeIG; +import twisk.modele.MondeIG; public class VueActiviteIG extends VueEtapeIG { - private HBox zoneClients; + private Label titre; + private Rectangle rectangle; + private VBox conteneur; - public VueActiviteIG(EtapeIG etape) { - super(etape); + /** + * Constructeur + * @param etape l'étape à représenter + * @param monde le monde auquel appartient l'étape + */ + public VueActiviteIG(EtapeIG etape, MondeIG monde) { + super(etape, monde); - // Appliquer la classe CSS à l'activité - this.getStyleClass().add("activite"); + // Créer le rectangle représentant l'activité + rectangle = new Rectangle(etape.getLargeur(), etape.getHauteur()); - // Appliquer la classe CSS au titre + // Créer le titre de l'activité + titre = new Label(etape.getNom()); titre.getStyleClass().add("titre-activite"); + titre.setPrefWidth(etape.getLargeur()); - // Création de la zone pour les clients - zoneClients = new HBox(); - zoneClients.setPrefSize(etape.getLargeur(), etape.getHauteur() - 30); // Réserver de l'espace pour le titre + // Créer la zone des clients + Label zoneClients = new Label("Clients: 0"); zoneClients.getStyleClass().add("zone-clients"); + zoneClients.setPrefWidth(etape.getLargeur()); + + // Créer un conteneur pour organiser les éléments + conteneur = new VBox(); + conteneur.getChildren().addAll(titre, zoneClients); + conteneur.setPrefWidth(etape.getLargeur()); + conteneur.setPrefHeight(etape.getHauteur()); + + // Ajouter les éléments à la vue + this.getChildren().addAll(rectangle, conteneur); - // Organisation verticale: titre en haut, zone clients en dessous - VBox contenu = new VBox(); - contenu.getChildren().addAll(titre, zoneClients); - contenu.setPrefSize(etape.getLargeur(), etape.getHauteur()); + // Positionner la vue aux coordonnées de l'étape + this.setLayoutX(etape.getPosX()); + this.setLayoutY(etape.getPosY()); - // Ajout du contenu au composant - this.getChildren().clear(); - this.getChildren().add(contenu); + // Ajouter les classes CSS pour le styling + this.getStyleClass().add("activite"); + rectangle.getStyleClass().add("activite-rectangle"); + + // Mettre à jour le style en fonction de l'état de sélection + mettreAJourStyle(); + } - // Positionnement du composant - relocate(etape.getPosX(), etape.getPosY()); + /** + * Met à jour le style de l'étape en fonction de son état de sélection + */ + @Override + public void mettreAJourStyle() { + if (monde.estSelectionnee(etape)) { + // Style pour une étape sélectionnée + this.getStyleClass().add("etape-selectionnee"); + } else { + // Style pour une étape non sélectionnée + this.getStyleClass().remove("etape-selectionnee"); + } } } diff --git a/src/src/twisk/vues/VueArcIG.java b/src/src/twisk/vues/VueArcIG.java index 94adb204708567fc15e1395697c2ad7b3b00ec4c..8d318c7b0642999d3dce2359faab1939a6860a66 100644 --- a/src/src/twisk/vues/VueArcIG.java +++ b/src/src/twisk/vues/VueArcIG.java @@ -1,23 +1,38 @@ package twisk.vues; -import javafx.scene.layout.Pane; +import javafx.scene.Group; import javafx.scene.paint.Color; import twisk.modele.ArcIG; +import twisk.modele.MondeIG; /** - * Vue abstraite d'un arc + * Vue abstraite représentant un arc */ -public abstract class VueArcIG extends Pane { - protected final ArcIG arc; +public abstract class VueArcIG extends Group { + protected ArcIG arc; + protected MondeIG monde; /** * Constructeur * @param arc l'arc à représenter + * @param monde le monde auquel appartient l'arc */ - public VueArcIG(ArcIG arc) { + public VueArcIG(ArcIG arc, MondeIG monde) { this.arc = arc; + this.monde = monde; + + // Ajouter un écouteur de clic pour la sélection + this.setOnMouseClicked(event -> { + monde.selectionnerArc(arc); + event.consume(); // Empêcher la propagation de l'événement + }); // Ajouter une classe CSS pour le styling this.getStyleClass().add("arc"); } + + /** + * Met à jour le style de l'arc en fonction de son état de sélection + */ + public abstract void mettreAJourStyle(); } diff --git a/src/src/twisk/vues/VueCourbeIG.java b/src/src/twisk/vues/VueCourbeIG.java index a1c973db5f873caf18331c82092cf33f08d3098d..a0692076d3926ac411669694280c1b46bf2f8b86 100644 --- a/src/src/twisk/vues/VueCourbeIG.java +++ b/src/src/twisk/vues/VueCourbeIG.java @@ -2,92 +2,112 @@ package twisk.vues; import javafx.scene.paint.Color; import javafx.scene.shape.CubicCurve; -import javafx.scene.shape.Polyline; +import javafx.scene.shape.Polygon; import twisk.modele.ArcIG; import twisk.modele.CourbeIG; +import twisk.modele.MondeIG; import twisk.modele.PointDeControleIG; /** - * Vue d'une courbe + * Vue représentant une courbe */ public class VueCourbeIG extends VueArcIG { - private final CubicCurve courbe; - private final Polyline fleche; + private CubicCurve courbe; + private Polygon fleche; /** * Constructeur * @param arc l'arc à représenter + * @param monde le monde auquel appartient l'arc */ - public VueCourbeIG(ArcIG arc) { - super(arc); + public VueCourbeIG(ArcIG arc, MondeIG monde) { + super(arc, monde); + + // Vérifier que l'arc est bien une courbe + if (!(arc instanceof CourbeIG)) { + throw new IllegalArgumentException("L'arc n'est pas une courbe"); + } CourbeIG courbeIG = (CourbeIG) arc; - // Récupérer les coordonnées des points de contrôle + // Récupérer les points de contrôle PointDeControleIG p1 = arc.getP1(); PointDeControleIG p2 = arc.getP2(); // Créer la courbe courbe = new CubicCurve( - p1.getPosX(), p1.getPosY(), // Point de départ - courbeIG.getControlX1(), courbeIG.getControlY1(), // Premier point de contrôle - courbeIG.getControlX2(), courbeIG.getControlY2(), // Deuxième point de contrôle - p2.getPosX(), p2.getPosY() // Point d'arrivée - ); - courbe.setFill(null); // Pas de remplissage - courbe.setStroke(Color.valueOf("#0066cc")); - courbe.setStrokeWidth(2); - courbe.getStyleClass().add("arc-courbe"); - - // Calculer les coordonnées de la flèche - // Pour une courbe, on utilise la tangente au point d'arrivée - double[] coordsFleche = calculerCoordonneesTrianglePourCourbe( + p1.getPosX(), p1.getPosY(), + courbeIG.getControlX1(), courbeIG.getControlY1(), courbeIG.getControlX2(), courbeIG.getControlY2(), p2.getPosX(), p2.getPosY() ); + courbe.setFill(null); // Pas de remplissage + courbe.getStyleClass().add("arc-ligne"); + + // Calculer l'angle de la tangente à la courbe au point d'arrivée + double dx = p2.getPosX() - courbeIG.getControlX2(); + double dy = p2.getPosY() - courbeIG.getControlY2(); + double angle = Math.atan2(dy, dx); + + // Créer la flèche + fleche = new Polygon(); + double size = 10; // Taille de la flèche + + // Calculer les points de la flèche + double x1 = p2.getPosX() - size * Math.cos(angle); + double y1 = p2.getPosY() - size * Math.sin(angle); + double x2 = x1 - size * Math.cos(angle + Math.PI/6); + double y2 = y1 - size * Math.sin(angle + Math.PI/6); + double x3 = x1 - size * Math.cos(angle - Math.PI/6); + double y3 = y1 - size * Math.sin(angle - Math.PI/6); - // Créer la flèche (triangle) - fleche = new Polyline(coordsFleche); - fleche.setFill(Color.valueOf("#0066cc")); - fleche.setStroke(Color.valueOf("#0066cc")); + // Définir les points de la flèche + fleche.getPoints().add((double) p2.getPosX()); + fleche.getPoints().add((double) p2.getPosY()); + fleche.getPoints().add(x2); + fleche.getPoints().add(y2); + fleche.getPoints().add(x3); + fleche.getPoints().add(y3); fleche.getStyleClass().add("arc-fleche"); - // Ajouter les composants au Pane + // Ajouter les éléments à la vue this.getChildren().addAll(courbe, fleche); + + // Maintenant que tout est initialisé, mettre à jour le style + mettreAJourStyle(); } /** - * Calcule les coordonnées des trois points du triangle formant la flèche - * en utilisant la tangente à la courbe au point d'arrivée - * @param controlX coordonnée x du point de contrôle précédant le point d'arrivée - * @param controlY coordonnée y du point de contrôle précédant le point d'arrivée - * @param x2 coordonnée x du point d'arrivée - * @param y2 coordonnée y du point d'arrivée - * @return tableau des coordonnées des trois points du triangle + * Met à jour le style de l'arc en fonction de son état de sélection + */ + /** + * Met à jour le style de l'arc en fonction de son état de sélection */ - private double[] calculerCoordonneesTrianglePourCourbe(double controlX, double controlY, double x2, double y2) { - // Longueur de la flèche - double longueurFleche = 15; + @Override + public void mettreAJourStyle() { + if (monde.estSelectionne(arc)) { + // Style pour un arc sélectionné + courbe.setStroke(Color.valueOf("#ff6600")); + courbe.setStrokeWidth(3); + fleche.setFill(Color.valueOf("#ff6600")); + fleche.setStroke(Color.valueOf("#ff6600")); + this.getStyleClass().add("arc-selectionne"); - // Angle de la flèche (en radians) - double angleFleche = Math.PI / 6; // 30 degrés + // Ajouter un effet de surbrillance + courbe.setEffect(new javafx.scene.effect.DropShadow(5, Color.valueOf("#ff6600"))); + fleche.setEffect(new javafx.scene.effect.DropShadow(5, Color.valueOf("#ff6600"))); + } else { + // Style pour un arc non sélectionné + courbe.setStroke(Color.valueOf("#0066cc")); + courbe.setStrokeWidth(2); + fleche.setFill(Color.valueOf("#0066cc")); + fleche.setStroke(Color.valueOf("#0066cc")); + this.getStyleClass().remove("arc-selectionne"); - // Calculer l'angle de la tangente à la courbe au point d'arrivée - double angle = Math.atan2(y2 - controlY, x2 - controlX); - - // Calculer les coordonnées des trois points du triangle - double x3 = x2 - longueurFleche * Math.cos(angle - angleFleche); - double y3 = y2 - longueurFleche * Math.sin(angle - angleFleche); - - double x4 = x2 - longueurFleche * Math.cos(angle + angleFleche); - double y4 = y2 - longueurFleche * Math.sin(angle + angleFleche); - - // Retourner les coordonnées sous forme de tableau pour la Polyline - return new double[] { - x2, y2, // Sommet de la flèche - x3, y3, // Premier point de la base - x4, y4, // Deuxième point de la base - x2, y2 // Retour au sommet pour fermer le triangle - }; + // Supprimer l'effet + courbe.setEffect(null); + fleche.setEffect(null); + } } + } diff --git a/src/src/twisk/vues/VueEtapeIG.java b/src/src/twisk/vues/VueEtapeIG.java index a1bc4ee46eabb854d63cb8f6e70422317074fd86..75146ed58ca4b65e5f95b278f48aea047f4b9bde 100644 --- a/src/src/twisk/vues/VueEtapeIG.java +++ b/src/src/twisk/vues/VueEtapeIG.java @@ -1,24 +1,71 @@ package twisk.vues; -import javafx.scene.control.Label; +import javafx.scene.SnapshotParameters; +import javafx.scene.image.WritableImage; +import javafx.scene.input.ClipboardContent; +import javafx.scene.input.Dragboard; +import javafx.scene.input.MouseEvent; +import javafx.scene.input.TransferMode; import javafx.scene.layout.Pane; import twisk.modele.EtapeIG; +import twisk.modele.MondeIG; public abstract class VueEtapeIG extends Pane { - protected EtapeIG etape; - protected Label titre; + protected final EtapeIG etape; + protected final MondeIG monde; - public VueEtapeIG(EtapeIG etape) { + /** + * Constructeur + * @param etape l'étape à représenter + * @param monde le monde auquel appartient l'étape + */ + public VueEtapeIG(EtapeIG etape, MondeIG monde) { this.etape = etape; + this.monde = monde; - // Création du titre - this.titre = new Label(etape.getNom()); - titre.setStyle("-fx-font-weight: bold;"); + // Définir l'ID du composant avec l'identifiant de l'étape + this.setId(etape.getIdentifiant()); - // Ajout du titre au composant - this.getChildren().add(titre); + // Ajouter l'écouteur de clic pour la sélection + this.setOnMouseClicked(event -> { + monde.selectionnerEtape(etape); + event.consume(); // Empêcher la propagation de l'événement + }); - // Positionnement du composant selon les coordonnées de l'étape - relocate(etape.getPosX(), etape.getPosY()); + // Ajouter l'écouteur pour le début du drag + this.setOnDragDetected(this::gererDebutDrag); } + + /** + * Gère le début du drag d'une étape + * @param event l'événement de souris + */ + private void gererDebutDrag(MouseEvent event) { + // Démarrer le drag and drop + Dragboard db = this.startDragAndDrop(TransferMode.MOVE); + + // Créer le contenu du clipboard + ClipboardContent content = new ClipboardContent(); + + // Ajouter l'identifiant de l'étape au clipboard + content.putString(etape.getIdentifiant()); + + // Créer une image de l'étape pour visualiser le déplacement + WritableImage snapshot = this.snapshot(new SnapshotParameters(), null); + content.putImage(snapshot); + + // Définir le contenu du dragboard + db.setContent(content); + + // Afficher l'identifiant pour vérification + System.out.println("Début du drag de l'étape0: " + etape.getIdentifiant()); + + // Consommer l'événement + event.consume(); + } + + /** + * Met à jour le style de l'étape en fonction de son état de sélection + */ + public abstract void mettreAJourStyle(); } diff --git a/src/src/twisk/vues/VueLigneDroiteIG.java b/src/src/twisk/vues/VueLigneDroiteIG.java index 0fe42a15a4fe002b1fa3cd7a5d1dd585c003c5eb..6c5da8338b0962076a5aeb7cc6656884f104dff4 100644 --- a/src/src/twisk/vues/VueLigneDroiteIG.java +++ b/src/src/twisk/vues/VueLigneDroiteIG.java @@ -2,79 +2,97 @@ package twisk.vues; import javafx.scene.paint.Color; import javafx.scene.shape.Line; -import javafx.scene.shape.Polyline; +import javafx.scene.shape.Polygon; import twisk.modele.ArcIG; import twisk.modele.LigneDroiteIG; +import twisk.modele.MondeIG; import twisk.modele.PointDeControleIG; /** - * Vue d'une ligne droite + * Vue représentant une ligne droite */ public class VueLigneDroiteIG extends VueArcIG { - private final Line ligne; - private final Polyline fleche; + private Line ligne; + private Polygon fleche; /** * Constructeur * @param arc l'arc à représenter + * @param monde le monde auquel appartient l'arc */ - public VueLigneDroiteIG(ArcIG arc) { - super(arc); + public VueLigneDroiteIG(ArcIG arc, MondeIG monde) { + super(arc, monde); - // Récupérer les coordonnées des points de contrôle + // Récupérer les points de contrôle PointDeControleIG p1 = arc.getP1(); PointDeControleIG p2 = arc.getP2(); // Créer la ligne ligne = new Line(p1.getPosX(), p1.getPosY(), p2.getPosX(), p2.getPosY()); - ligne.setStroke(Color.valueOf("#0066cc")); - ligne.setStrokeWidth(2); ligne.getStyleClass().add("arc-ligne"); - // Calculer les coordonnées de la flèche - double[] coordsFleche = calculerCoordonneesTriangle(p1.getPosX(), p1.getPosY(), p2.getPosX(), p2.getPosY()); + // Calculer l'angle de la ligne pour orienter la flèche + double angle = Math.atan2(p2.getPosY() - p1.getPosY(), p2.getPosX() - p1.getPosX()); - // Créer la flèche (triangle) - fleche = new Polyline(coordsFleche); - fleche.setFill(Color.valueOf("#0066cc")); - fleche.setStroke(Color.valueOf("#0066cc")); + // Créer la flèche + fleche = new Polygon(); + double size = 10; // Taille de la flèche + + // Calculer les points de la flèche + double x1 = p2.getPosX() - size * Math.cos(angle); + double y1 = p2.getPosY() - size * Math.sin(angle); + double x2 = x1 - size * Math.cos(angle + Math.PI/6); + double y2 = y1 - size * Math.sin(angle + Math.PI/6); + double x3 = x1 - size * Math.cos(angle - Math.PI/6); + double y3 = y1 - size * Math.sin(angle - Math.PI/6); + + // Définir les points de la flèche + fleche.getPoints().add((double) p2.getPosX()); + fleche.getPoints().add((double) p2.getPosY()); + fleche.getPoints().add(x2); + fleche.getPoints().add(y2); + fleche.getPoints().add(x3); + fleche.getPoints().add(y3); fleche.getStyleClass().add("arc-fleche"); - // Ajouter les composants au Pane + // Ajouter les éléments à la vue this.getChildren().addAll(ligne, fleche); + + // Maintenant que tout est initialisé, mettre à jour le style + mettreAJourStyle(); } /** - * Calcule les coordonnées des trois points du triangle formant la flèche - * @param x1 coordonnée x du premier point - * @param y1 coordonnée y du premier point - * @param x2 coordonnée x du deuxième point - * @param y2 coordonnée y du deuxième point - * @return tableau des coordonnées des trois points du triangle + * Met à jour le style de l'arc en fonction de son état de sélection */ - private double[] calculerCoordonneesTriangle(double x1, double y1, double x2, double y2) { - // Longueur de la flèche - double longueurFleche = 15; - - // Angle de la flèche (en radians) - double angleFleche = Math.PI / 6; // 30 degrés - - // Calculer l'angle de la ligne - double angle = Math.atan2(y2 - y1, x2 - x1); - - // Calculer les coordonnées des trois points du triangle - double x3 = x2 - longueurFleche * Math.cos(angle - angleFleche); - double y3 = y2 - longueurFleche * Math.sin(angle - angleFleche); + /** + * Met à jour le style de l'arc en fonction de son état de sélection + */ + @Override + public void mettreAJourStyle() { + if (monde.estSelectionne(arc)) { + // Style pour un arc sélectionné + ligne.setStroke(Color.valueOf("#ff6600")); + ligne.setStrokeWidth(3); + fleche.setFill(Color.valueOf("#ff6600")); + fleche.setStroke(Color.valueOf("#ff6600")); + this.getStyleClass().add("arc-selectionne"); - double x4 = x2 - longueurFleche * Math.cos(angle + angleFleche); - double y4 = y2 - longueurFleche * Math.sin(angle + angleFleche); + // Ajouter un effet de surbrillance + ligne.setEffect(new javafx.scene.effect.DropShadow(5, Color.valueOf("#ff6600"))); + fleche.setEffect(new javafx.scene.effect.DropShadow(5, Color.valueOf("#ff6600"))); + } else { + // Style pour un arc non sélectionné + ligne.setStroke(Color.valueOf("#0066cc")); + ligne.setStrokeWidth(2); + fleche.setFill(Color.valueOf("#0066cc")); + fleche.setStroke(Color.valueOf("#0066cc")); + this.getStyleClass().remove("arc-selectionne"); - // Retourner les coordonnées sous forme de tableau pour la Polyline - return new double[] { - x2, y2, // Sommet de la flèche - x3, y3, // Premier point de la base - x4, y4, // Deuxième point de la base - x2, y2 // Retour au sommet pour fermer le triangle - }; + // Supprimer l'effet + ligne.setEffect(null); + fleche.setEffect(null); + } } + } diff --git a/src/src/twisk/vues/VueMenu.java b/src/src/twisk/vues/VueMenu.java new file mode 100644 index 0000000000000000000000000000000000000000..d96f19624821647898b43ec10d4def9ab287ae01 --- /dev/null +++ b/src/src/twisk/vues/VueMenu.java @@ -0,0 +1,111 @@ +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.scene.input.KeyCombination; +import twisk.modele.EtapeIG; +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 { + private final MondeIG monde; + private MenuItem itemRenommer; + + /** + * Constructeur + * @param monde le monde à manipuler + */ + public VueMenu(MondeIG monde) { + this.monde = monde; + + // S'enregistrer comme observateur du monde + monde.ajouterObservateur(this); + + // Création du menu Fichier + Menu menuFichier = new Menu("Fichier"); + + // Création de l'item Quitter + MenuItem itemQuitter = new MenuItem("Quitter"); + itemQuitter.setAccelerator(KeyCombination.keyCombination("Ctrl+Q")); + itemQuitter.setOnAction(event -> Platform.exit()); + + // Ajout de l'item au menu Fichier + menuFichier.getItems().add(itemQuitter); + + // Création du menu Édition + Menu menuEdition = new Menu("Édition"); + + // Création de l'item Supprimer + MenuItem itemSupprimer = new MenuItem("Supprimer la sélection"); + 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()); + + // Création de l'item Renommer + itemRenommer = new MenuItem("Renommer la sélection"); + itemRenommer.setAccelerator(KeyCombination.keyCombination("F2")); + itemRenommer.setOnAction(event -> renommerSelection()); + + // Désactiver l'item Renommer par défaut (sera activé si une seule étape est sélectionnée) + itemRenommer.setDisable(true); + + // Ajout des items au menu Édition + menuEdition.getItems().addAll(itemEffacerSelection, itemRenommer,itemSupprimer); + + // Ajout des menus à la barre de menu + this.getMenus().addAll(menuFichier, menuEdition); + + // Mettre à jour l'état des items + reagir(); + } + + /** + * Ouvre une boîte de dialogue pour renommer l'étape sélectionnée + */ + private void renommerSelection() { + // Vérifier qu'une seule étape est sélectionnée + if (monde.getNbEtapesSelectionnees() != 1) { + return; + } + + // Récupérer l'étape sélectionnée + EtapeIG etape = monde.getEtapeSelectionnee(); + + // Créer une boîte de dialogue pour saisir le nouveau nom + TextInputDialog dialog = new TextInputDialog(etape.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(); + + // Si l'utilisateur a saisi un nouveau nom, renommer l'étape + result.ifPresent(nouveauNom -> { + if (!nouveauNom.isEmpty()) { + monde.renommerEtape(etape, nouveauNom); + } + }); + } + + /** + * Met à jour l'état des items du menu en fonction de l'état du monde + */ + @Override + public void reagir() { + // Activer l'item Renommer uniquement si une seule étape est sélectionnée + itemRenommer.setDisable(monde.getNbEtapesSelectionnees() != 1); + } +} diff --git a/src/src/twisk/vues/VueMondeIG.java b/src/src/twisk/vues/VueMondeIG.java index 0db916a3ac4b3bab8633b27a9a3c0faa827a6de1..1373997a2508becbb295516650851c842d3497af 100644 --- a/src/src/twisk/vues/VueMondeIG.java +++ b/src/src/twisk/vues/VueMondeIG.java @@ -2,6 +2,9 @@ package twisk.vues; import javafx.animation.PauseTransition; import javafx.scene.control.Alert; +import javafx.scene.input.DragEvent; +import javafx.scene.input.Dragboard; +import javafx.scene.input.TransferMode; import javafx.scene.layout.Pane; import javafx.util.Duration; import twisk.exceptions.ArcException; @@ -31,10 +34,67 @@ public class VueMondeIG extends Pane implements Observateur { } }); + // Ajouter les écouteurs pour le drag and drop + this.setOnDragOver(this::gererDragOver); + this.setOnDragDropped(this::gererDragDropped); + // Initialiser la vue reagir(); } + /** + * Gère l'événement de survol pendant le drag + * @param event l'événement de drag + */ + private void gererDragOver(DragEvent event) { + // Accepter uniquement si c'est un drag de type MOVE et s'il contient une chaîne + if (event.getGestureSource() != this && + event.getDragboard().hasString() && + event.getDragboard().hasImage()) { + + // Accepter le transfert + event.acceptTransferModes(TransferMode.MOVE); + } + + // Consommer l'événement + event.consume(); + } + + /** + * Gère l'événement de drop + * @param event l'événement de drag + */ + private void gererDragDropped(DragEvent event) { + // Récupérer le dragboard + Dragboard db = event.getDragboard(); + boolean success = false; + + // Vérifier s'il contient une chaîne (identifiant de l'étape) + if (db.hasString()) { + // Récupérer l'identifiant de l'étape + String idEtape = db.getString(); + + // Récupérer les coordonnées de la souris + double x = event.getX(); + double y = event.getY(); + + // Afficher les informations pour vérification + System.out.println("Drop de l'étape: " + idEtape + " aux coordonnées: " + x + ", " + y); + + // Déplacer l'étape dans le modèle + monde.deplacerEtape(idEtape, (int) x, (int) y); + + // Indiquer que le transfert a réussi + success = true; + } + + // Indiquer si le transfert a réussi ou échoué + event.setDropCompleted(success); + + // Consommer l'événement + event.consume(); + } + @Override public void reagir() { // Effacer tous les composants existants @@ -48,21 +108,24 @@ public class VueMondeIG extends Pane implements Observateur { // Créer la vue appropriée selon le type d'arc if (arc instanceof LigneDroiteIG) { - vueArc = new VueLigneDroiteIG(arc); + vueArc = new VueLigneDroiteIG(arc, monde); } else if (arc instanceof CourbeIG) { - vueArc = new VueCourbeIG(arc); + vueArc = new VueCourbeIG(arc, monde); } else { // Ne devrait jamais arriver, mais au cas où continue; } + // Mettre à jour le style en fonction de l'état de sélection + vueArc.mettreAJourStyle(); + this.getChildren().add(vueArc); } // Ensuite, afficher les étapes et leurs points de contrôle for (EtapeIG etape : monde) { // Créer et ajouter la vue de l'étape - VueEtapeIG vueEtape = new VueActiviteIG(etape); + VueEtapeIG vueEtape = new VueActiviteIG(etape, monde); this.getChildren().add(vueEtape); // Ajouter les vues des points de contrôle de l'étape @@ -72,6 +135,8 @@ public class VueMondeIG extends Pane implements Observateur { } } } + + /** * Affiche un message d'erreur dans une boîte de dialogue * @param message le message à afficher @@ -91,5 +156,4 @@ public class VueMondeIG extends Pane implements Observateur { // Afficher la boîte de dialogue alert.show(); } - } diff --git a/src/src/twisk/vues/VuePointDeControleIG.java b/src/src/twisk/vues/VuePointDeControleIG.java index 638957607b11a431b233e4c3fefcc0909d310a14..1c7ae502c9d4faab0eec9154b36f811062afa51c 100644 --- a/src/src/twisk/vues/VuePointDeControleIG.java +++ b/src/src/twisk/vues/VuePointDeControleIG.java @@ -2,10 +2,13 @@ package twisk.vues; import javafx.animation.PauseTransition; import javafx.scene.control.Alert; -import javafx.scene.control.Alert.AlertType; +import javafx.scene.input.*; import javafx.scene.paint.Color; import javafx.scene.shape.Circle; +import javafx.scene.SnapshotParameters; +import javafx.scene.image.WritableImage; import javafx.util.Duration; +import javafx.util.Pair; import twisk.exceptions.ArcException; import twisk.modele.MondeIG; import twisk.modele.PointDeControleIG; @@ -20,7 +23,7 @@ public class VuePointDeControleIG extends Circle { /** * Constructeur * @param pointDeControle le point de contrôle à représenter - * @param monde le monde + * @param monde le monde auquel appartient le point de contrôle */ public VuePointDeControleIG(PointDeControleIG pointDeControle, MondeIG monde) { super(pointDeControle.getPosX(), pointDeControle.getPosY(), 5); // Rayon de 5 pixels @@ -35,16 +38,103 @@ public class VuePointDeControleIG extends Circle { // Ajouter une classe CSS pour le styling this.getStyleClass().add("point-controle"); + // Configurer les interactions + configurerInteractions(); } + /** + * Configure les interactions du point de contrôle + */ + private void configurerInteractions() { + // Configurer le point comme source de drag + this.setOnDragDetected(this::gererDebutDrag); + + // Configurer le point comme cible de drop + this.setOnDragOver(this::gererDragOver); + this.setOnDragDropped(this::gererDrop); + + // Ajouter un écouteur de clic + this.setOnMouseClicked(event -> { + try { + monde.selectionnerPointDeControle(pointDeControle); + } catch (ArcException e) { + afficherMessageErreur(e.getMessage()); + } + event.consume(); + }); + + } + + /** + * Gère le début du drag + * @param event l'événement de début de drag + */ + private void gererDebutDrag(MouseEvent event) { + // Démarrer le drag + Dragboard db = this.startDragAndDrop(TransferMode.ANY); + + // Créer un contenu pour le drag avec l'ID du point de contrôle + ClipboardContent content = new ClipboardContent(); + content.putString(pointDeControle.getId()); + db.setContent(content); + + // Créer une image pour le drag (aspect visuel uniquement) + SnapshotParameters params = new SnapshotParameters(); + params.setFill(Color.TRANSPARENT); + WritableImage image = this.snapshot(params, null); + db.setDragView(image); + + event.consume(); + } + + /** + * Gère le survol du drag + * @param event l'événement de survol + */ + private void gererDragOver(DragEvent event) { + // Vérifier que la source du drag est un autre point de contrôle + if (event.getGestureSource() instanceof VuePointDeControleIG && + event.getGestureSource() != this) { + // Accepter le transfert + event.acceptTransferModes(TransferMode.LINK); + } + + event.consume(); + } /** - * Affiche un message d'erreur dans une boîte de dialogue + * Gère le drop + * @param event l'événement de drop + */ + private void gererDrop(DragEvent event) { + // Récupérer l'ID du point de contrôle source + String idPointSource = event.getDragboard().getString(); + + // Récupérer le point de contrôle source à partir de son ID + PointDeControleIG pointSource = monde.getPointDeControleById(idPointSource); + + if (pointSource != null) { + // Déléguer la logique de création d'arc au modèle + Pair<Boolean, String> resultat = monde.gererDragAndDropPoints(pointSource, this.pointDeControle); + + // Si l'opération a échoué, afficher un message d'erreur + if (!resultat.getKey()) { + afficherMessageErreur(resultat.getValue()); + } + } + + // Indiquer que le drop est terminé + event.setDropCompleted(true); + event.consume(); + } + + /** + * Affiche un message d'erreur (aspect UI uniquement) * @param message le message à afficher */ private void afficherMessageErreur(String message) { // Créer une boîte de dialogue d'alerte - Alert alert = new Alert(AlertType.ERROR); + Alert alert = new Alert(Alert.AlertType.ERROR); alert.setTitle("Erreur"); alert.setHeaderText("Impossible de créer l'arc"); alert.setContentText(message); @@ -57,12 +147,4 @@ public class VuePointDeControleIG extends Circle { // Afficher la boîte de dialogue alert.show(); } - - /** - * Retourne le point de contrôle associé à cette vue - * @return le point de contrôle - */ - public PointDeControleIG getPointDeControle() { - return pointDeControle; - } }