/* Reversound is used to get the music sheet of a piece from a music file. Copyright (C) 2014 Gabriel AUGENDRE Copyright (C) 2014 Gabriel DIENY Copyright (C) 2014 Arthur GAUCHER Copyright (C) 2014 Gabriel LEPETIT-AIMON This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ package gui.graphs; import javafx.application.Platform; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; import javafx.event.EventHandler; import javafx.scene.effect.DropShadow; import javafx.scene.input.ContextMenuEvent; import javafx.scene.input.MouseEvent; import javafx.scene.layout.BorderPane; /** * Created by gaby on 11/05/14. * Classe permettant d'afficher un overlay au dessus du graphs principal dans une GraphicView */ public class OverlayGraph extends BorderPane implements ChangeListener, EventHandler { private AbstractGraph graph; private GraphicView graphicView; private AutoPosition autoPosition = AutoPosition.CUSTOM; private double xMousePos=0; private double yMousePos=0; private double xMouseOffset=0; private double yMouseOffset=0; public OverlayGraph() { super(); Platform.runLater(new Runnable() { @Override public void run() { getStyleClass().add("overlay"); getStylesheets().add(AmpliView.class.getResource("Overlay.css").toExternalForm()); DropShadow dS = new DropShadow(); dS.setRadius(10); dS.setOffsetY(2); dS.setOffsetX(2); setEffect(dS); } }); } public OverlayGraph(AbstractGraph graph){ this(); setGraph(graph); } public OverlayGraph(AbstractGraph graph, GraphicView graphicView){ this(graph); setGraphicView(graphicView); } public void setGraph(AbstractGraph graph){ if(graph==null) return; if(this.graph!=null) this.graph.setVisibility(false); graph.setVisibility(getVisibility()); this.graph = graph; Platform.runLater(new Runnable() { @Override public void run() { setCenter(graph.getMainNode()); } }); } static public OverlayGraph centeredOverlay(AbstractGraph graph, int height, int width){ OverlayGraph r = new OverlayGraph(graph); r.setOverlayHeight(height); r.setOverlayWidth(width); r.setAutoPosition(AutoPosition.CENTERED); return r; } static public OverlayGraph perfectCenteredOverlay(AbstractGraph graph){ OverlayGraph r = new OverlayGraph(graph); r.setAutoPosition(AutoPosition.PERFECT_CENTERED); return r; } static public OverlayGraph followMouseGraph(AbstractGraph graph, int height, int width){ OverlayGraph r = new OverlayGraph(graph); r.setAutoPosition(AutoPosition.MOUSE); r.setOverlayHeight(height); r.setOverlayWidth(width); return r; } public AbstractGraph getGraph() { return graph; } public boolean getVisibility(){return isVisible();} public void setVisibility(boolean visibility){ setVisible(visibility); graph.setVisibility(visibility); } public void viewVisibiliyChange(){ graph.setVisibility(getVisibility()||graphicView.getVisibility()); } /** * Fait apparaitre le graph à la position indiqué * Si le positionnement automatique est en mode MOUSE la position de l'overlay est forcé * Si il est en mode CENTERED ou PERFECT_CENTERED, le passe automatiquement en mode CUSTOM * @param x Position horizontale absolue dans la GraphicView * @param y Position verticale absolue dans la GraphicView */ public void popupAt(double x, double y){ if(autoPosition == AutoPosition.CENTERED || autoPosition==AutoPosition.PERFECT_CENTERED) setAutoPosition(AutoPosition.CUSTOM); if(autoPosition==AutoPosition.CUSTOM) { setTranslateX(x); setTranslateY(y); }else{ xMousePos = x; yMousePos = y; moveToMouse(); } } /** * Modifie la position horizontale de l'overlay. * Passe automatiquement le positionnement automatique en mode CUSTOM * @param x Position horizontale absolue dans la GraphicView */ public void setX(double x){ if(autoPosition!=AutoPosition.CUSTOM) setAutoPosition(AutoPosition.CUSTOM); setTranslateX(x); } /** * Modifie la position verticale de l'overlay. * Passe automatiquement le positionnement automatique en mode CUSTOM * @param y Position verticale absolue dans la GraphicView */ public void setY(double y){ if(autoPosition!=AutoPosition.CUSTOM) setAutoPosition(AutoPosition.CUSTOM); setTranslateX(y); } /** * Modifie la hauteur de l'overlay * Passe automatiquement le positionnement automatique en mose CENTERED si il était en mode PERFECT_CENTERED * @param height Hauteur de l'overlay */ public void setOverlayHeight(double height){ if(autoPosition==AutoPosition.PERFECT_CENTERED) setAutoPosition(AutoPosition.CENTERED); super.setPrefHeight(height); } /** * Modifie la largeur de l'overlay * Passe automatiquement le positionnement automatique en mose CENTERED si il était en mode PERFECT_CENTERED * @param width Largeur de l'overlay */ public void setOverlayWidth(double width){ if(autoPosition==AutoPosition.PERFECT_CENTERED) setAutoPosition(AutoPosition.CENTERED); super.setPrefWidth(width); } public double getxMouseOffset() { return xMouseOffset; } public void setxMouseOffset(double xMouseOffset) { this.xMouseOffset = xMouseOffset; } public double getyMouseOffset() { return yMouseOffset; } public void setyMouseOffset(double yMouseOffset) { this.yMouseOffset = yMouseOffset; } public void setGraphicView(GraphicView graphicView){ if(graphicView==this.graphicView) return; if(this.graphicView!=null) { if (autoPosition == AutoPosition.CENTERED || autoPosition == AutoPosition.PERFECT_CENTERED) { graphicView.getScene().widthProperty().removeListener(this); graphicView.getScene().heightProperty().removeListener(this); }else if (autoPosition == AutoPosition.MOUSE) { graphicView.getScene().removeEventHandler(MouseEvent.MOUSE_MOVED, this); } this.graphicView.removeOverlay(this); } setOnContextMenuRequested(new EventHandler() { @Override public void handle(ContextMenuEvent contextMenuEvent) { graphicView.popupOverlayContextMenu((int)contextMenuEvent.getSceneX(), (int)contextMenuEvent.getSceneY(), graph); contextMenuEvent.consume(); } }); this.graphicView = graphicView; applyConnection(); } /** * Modifie la propriété de placement automatique: * -CUSTOM: laisse le choix au programateur de placé ou il veut l'overlay * -CENTERED: centre la vue dans la fenetre (en tenant compte de la hauteur et largeur de l'overlay) * -MOUSE: positionne l'overlay sous la souris (en tenant compte du décalage mouseOffset) * @param autoPosition */ public void setAutoPosition(AutoPosition autoPosition){ if(this.autoPosition == autoPosition) return; if(graphicView!=null) { if (this.autoPosition == AutoPosition.CENTERED || autoPosition == AutoPosition.PERFECT_CENTERED) { graphicView.getScene().widthProperty().removeListener(this); graphicView.getScene().heightProperty().removeListener(this); } else if (this.autoPosition == AutoPosition.MOUSE) graphicView.getScene().removeEventHandler(MouseEvent.MOUSE_MOVED, this); } this.autoPosition = autoPosition; applyConnection(); } public AutoPosition getAutoPosition(){return autoPosition;} private void applyConnection(){ if(graphicView==null) return; if(autoPosition == AutoPosition.CENTERED || autoPosition==AutoPosition.PERFECT_CENTERED) { graphicView.getScene().widthProperty().addListener(this); graphicView.getScene().heightProperty().addListener(this); centerGeometry(); } if(autoPosition == AutoPosition.MOUSE) { graphicView.getScene().addEventHandler(MouseEvent.MOUSE_MOVED, this); moveToMouse(); } } private void centerGeometry(){ if(autoPosition==AutoPosition.PERFECT_CENTERED){ Platform.runLater(new Runnable() { @Override public void run() { double h = graphicView.getParent().getHeight(); double w = graphicView.getParent().getWidth(); setTranslateX(w/20.0); setTranslateY(h/ 20.0); OverlayGraph.super.setPrefHeight(h*18.0/20.0); OverlayGraph.super.setPrefWidth(w*18.0/20.0); } }); }else { Platform.runLater(new Runnable() { @Override public void run() { double h = graphicView.getParent().getHeight(); double w = graphicView.getParent().getWidth(); setTranslateX(w - getPrefWidth() / 2.0); setTranslateY(h - getPrefHeight() / 2.0); } }); } } private void moveToMouse(){ Platform.runLater(new Runnable() { @Override public void run() { setTranslateX(xMousePos - xMouseOffset); setTranslateY(yMousePos - yMouseOffset); } }); } public enum AutoPosition{ CUSTOM, CENTERED, PERFECT_CENTERED, MOUSE } @Override public void changed(ObservableValue observableValue, Number number, Number number2) { centerGeometry(); } @Override public void handle(MouseEvent mouseEvent) { xMousePos = mouseEvent.getX(); yMousePos = mouseEvent.getY(); moveToMouse(); } }