reversound/src/gui/graphs/GraphicView.java
2014-06-16 16:48:34 +02:00

372 lines
9.6 KiB
Java

/*
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 <http://www.gnu.org/licenses/>.
*/
package gui.graphs;
import conteneurs.ObservableObject;
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.event.EventHandler;
import javafx.scene.Scene;
import javafx.scene.input.ContextMenuEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.layout.StackPane;
import processing.buffer.Buffer;
import javax.swing.*;
import javax.swing.event.AncestorEvent;
import javax.swing.event.AncestorListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.ArrayList;
/**
* Created by Gabriel on 12/03/14.
* Classe gérant l'adaptation entre JavaFX et swing et chargée d'afficher les graphs et leurs overlays
*/
public class GraphicView extends JFXPanel{
static private ArrayList<Class> typeSupported = new ArrayList<>();
static private ArrayList<ArrayList<AbstractGraph>> genericGraphes = new ArrayList<>();
static public void initGraph(){
registerGraph(new AmpliView());
registerGraph(new Spectrogram());
registerGraph(new SpectreView());
registerGraph(new EventViewer());
registerGraph(new ProfilView());
registerGraph(new NoteViewer());
}
static public void registerGraph(AbstractGraph graph){
int idType = typeSupported.indexOf(graph.getType());;
if(idType==-1){
typeSupported.add(graph.getType());
genericGraphes.add(new ArrayList<>());
idType = typeSupported.size()-1;
}
genericGraphes.get(idType).add(graph);
}
private final String name;
private JMenu switchMenu = null;
private BorderPane layout = new BorderPane();
private ArrayList<AbstractGraph> graphs = new ArrayList<>();
private Pane overlayLayout = new Pane();
private ArrayList<OverlayGraph> overlays = new ArrayList<>();
private int idCurrentGraph=-1;
private boolean visibility = false;
protected GraphicView( String name) {
super();
this.name = name;
this.addAncestorListener(new AncestorListener() {
@Override
public void ancestorAdded(AncestorEvent event) {
visibilityChange(true);
}
@Override
public void ancestorRemoved(AncestorEvent event) {
visibilityChange(false);
}
@Override
public void ancestorMoved(AncestorEvent event) {
}
});
}
public void visibilityChange(boolean isVisible){
if(visibility == isVisible)
return;
visibility = isVisible;
for (int i = 0; i < graphs.size(); i++) {
graphs.get(i).visibilityChange(isVisible&&i==idCurrentGraph);
}
for(OverlayGraph o: overlays)
o.viewVisibiliyChange();
}
public boolean getVisibility(){
return visibility;
}
private void setMainGraph(int idGraph){
if(idGraph<0 || idGraph>graphs.size())
return;
if(getGraph(idCurrentGraph)!=null)
getGraph(idCurrentGraph).setVisibility(false);
for(OverlayGraph o: overlays)
o.setVisibility(false);
Platform.runLater(new Runnable() {
@Override
public void run() {
layout.setCenter(graphs.get(idGraph).getMainNode());
idCurrentGraph = idGraph;
graphs.get(idGraph).setVisibility(true);
}
});
}
public static GraphicView createGraphicView(Buffer buffer, boolean syncWithPlayer){
GraphicView g = new GraphicView(buffer.getName());
ArrayList<AbstractGraph> graphs = createGraphs(buffer, g, syncWithPlayer);
if(graphs.size()==0)
return null;
for(AbstractGraph graph: graphs)
g.addGraph(graph);
if(!finishSetup(g))
return null;
return g;
}
public static GraphicView createGraphicView(ObservableObject o) {
GraphicView g = new GraphicView(o.toString());
ArrayList<AbstractGraph> graphs = createGraphs(o, g);
if(graphs.size()==0)
return null;
for(AbstractGraph graph: graphs)
g.addGraph(graph);
if(!finishSetup(g))
return null;
return g;
}
public static ArrayList<AbstractGraph> createGraphs(Buffer buffer, GraphicView graphicView, boolean syncWithPlayer){
if(typeSupported.isEmpty()) {
initGraph();
if(typeSupported.isEmpty())
return new ArrayList<>();
}
int idType = typeSupported.indexOf(buffer.getType());
if(idType==-1)
return new ArrayList<>();
ArrayList<AbstractGraph> r = new ArrayList<>(genericGraphes.get(idType).size());
for (int i = 0; i < genericGraphes.get(idType).size(); i++)
r.add(genericGraphes.get(idType).get(i).setupGraph(buffer, graphicView, syncWithPlayer));
return r;
}
public ArrayList<AbstractGraph> createGraphs(Buffer buffer, boolean syncWithPlayer){
return createGraphs(buffer, this, syncWithPlayer);
}
public static ArrayList<AbstractGraph> createGraphs(ObservableObject observableObject, GraphicView graphicView){
if (typeSupported.isEmpty()) {
initGraph();
if (typeSupported.isEmpty())
return new ArrayList<>();
}
int idType = typeSupported.indexOf(observableObject.getType());
if(idType==-1)
return new ArrayList<>();
ArrayList<AbstractGraph> r = new ArrayList<>(genericGraphes.get(idType).size());
for (int i = 0; i < genericGraphes.get(idType).size(); i++) {
AbstractGraph abstractGraph = genericGraphes.get(idType).get(i).setupGraph(observableObject,graphicView);
if(abstractGraph!=null)
r.add(abstractGraph);
}
return r;
}
public ArrayList<AbstractGraph> createGraphs(ObservableObject observableObject){
return createGraphs(observableObject, this);
}
public OverlayGraph createOverlay(AbstractGraph graph, OverlayGraph.AutoPosition position, boolean showByDefault){
OverlayGraph o = null;
switch(position){
case CUSTOM:
o = new OverlayGraph(graph, this);
break;
case CENTERED:
o = OverlayGraph.centeredOverlay(graph, 300,450);
break;
case PERFECT_CENTERED:
o = OverlayGraph.perfectCenteredOverlay(graph);
break;
case MOUSE:
o = OverlayGraph.followMouseGraph(graph, 200, 250);
break;
}
o.setVisibility(showByDefault);
addOverlay(o);
return o;
}
public void addOverlay(OverlayGraph overlayGraph){
if(overlays.contains(overlayGraph))
return;
overlays.add(overlayGraph);
overlayLayout.getChildren().add(overlayGraph);
}
public void removeOverlay(OverlayGraph overlayGraph){
int id = overlays.indexOf(overlayGraph);
if(id==-1)
return;
overlays.remove(id);
overlayLayout.getChildren().remove(id);
}
public ArrayList<OverlayGraph> getOverlays() {
return overlays;
}
private static boolean finishSetup(GraphicView g){
if(g.getNbrGraph()==0)
return false;
if(g.getNbrGraph()>1) {
JMenu menu = new JMenu("Type de graphe");
ButtonGroup radioGroup = new ButtonGroup();
for (int i = 0; i < g.getNbrGraph(); i++) {
AbstractGraph graph = g.getGraph(i);
JRadioButtonMenuItem graphItem = new JRadioButtonMenuItem(graph.getName(), i == 0);
final int idGraph = i;
graphItem.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
if (e.getStateChange() == ItemEvent.SELECTED)
g.setMainGraph(idGraph);
}
});
radioGroup.add(graphItem);
menu.add(graphItem);
}
g.setSwitchMenu(menu);
}
g.initGraphicView();
g.setMainGraph(0);
return true;
}
private void initGraphicView(){
Platform.runLater(new Runnable() {
@Override
public void run() {
setScene(new Scene(new StackPane(layout, overlayLayout)));
layout.setOnContextMenuRequested(new EventHandler<ContextMenuEvent>() {
@Override
public void handle(ContextMenuEvent contextMenuEvent) {
popupContextMenu((int)contextMenuEvent.getX(), (int)contextMenuEvent.getY());
contextMenuEvent.consume();
}
});
overlayLayout.setMouseTransparent(true);
for(OverlayGraph o: overlays)
o.setGraphicView(GraphicView.this);
}
});
}
private void setSwitchMenu(JMenu menu){switchMenu = menu;}
private int addGraph(AbstractGraph graph){graphs.add(graph); return graphs.size()-1;}
public int getNbrGraph(){return graphs.size();}
public AbstractGraph getGraph(int id){
if(id<0|| id>graphs.size())
return null;
return graphs.get(id);
}
public int getIdMainGraph(){return idCurrentGraph;}
public AbstractGraph getMainGraph(){return graphs.get(idCurrentGraph);}
public void popupContextMenu(int x, int y){
JPopupMenu contextMenu = new JPopupMenu();
if(switchMenu!=null) {
contextMenu.add(switchMenu);
contextMenu.addSeparator();
}
getMainGraph().createContextMenu(contextMenu);
contextMenu.show(this, x, y);
}
public void popupOverlayContextMenu(int x, int y, AbstractGraph graph){
JPopupMenu contextMenu = new JPopupMenu();
graph.createContextMenu(contextMenu);
contextMenu.show(this, x, y);
}
public String getName() {
return name;
}
private BorderPane getBorderPane(){return layout;}
}