diff --git a/VRGNYMusicLights/Sources/AnimationPlayer.java b/VRGNYMusicLights/Sources/AnimationPlayer.java
deleted file mode 100644
index 3356186..0000000
--- a/VRGNYMusicLights/Sources/AnimationPlayer.java
+++ /dev/null
@@ -1,108 +0,0 @@
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-
-import javax.swing.Box;
-import javax.swing.BoxLayout;
-import javax.swing.ImageIcon;
-import javax.swing.JButton;
-import javax.swing.JPanel;
-
-public class AnimationPlayer extends JPanel implements ActionListener {
- private static final long serialVersionUID = 1L;
-
- private Interface interf;
-
- private JButton backward;
- private JButton stop;
- private JButton play;
- private JButton pause;
- private JButton forward;
-
- private boolean go = false;
- private boolean stopClock = false;
- private static final int TICK_JUMP = 10;
- private Thread tickClock = new Thread(new Runnable() {
- @Override
- public void run() {
- while(!stopClock) {
- if(!go) { // pause
- try { Thread.sleep(100); }
- catch (InterruptedException ignored) {}
- continue;
- }
-
- long before = System.currentTimeMillis();
- interf.computeTick();
- interf.tick += TICK_JUMP;
- long after = System.currentTimeMillis();
-
- if(after - before < TICK_JUMP) {
- try { Thread.sleep(TICK_JUMP - after + before);}
- catch (InterruptedException ignored) {}
- } else if(after - before > TICK_JUMP) {
- System.err.println("Animation were slowed down by " + String.valueOf(after - before - TICK_JUMP) + " ticks !");
- }
- }
- }
- });
- public void stopTickClock() {stopClock = true;}
-
- public AnimationPlayer(Interface interf) { this(interf, BoxLayout.LINE_AXIS); }
- public AnimationPlayer(Interface interf, int direction) {
- this.interf = interf;
-
- setLayout(new BoxLayout(this, direction));
-
- add(Box.createHorizontalGlue());
-
- // backward button
- backward = new JButton(new ImageIcon(getClass().getResource("/icons/backward.png")));
- backward.addActionListener(this);
- add(backward);
-
- // stop button
- stop = new JButton(new ImageIcon(getClass().getResource("/icons/stop.png")));
- stop.addActionListener(this);
- add(stop);
-
- // play button
- play = new JButton(new ImageIcon(getClass().getResource("/icons/play.png")));
- play.addActionListener(this);
- add(play);
-
- // pause button
- pause = new JButton(new ImageIcon(getClass().getResource("/icons/pause.png")));
- pause.addActionListener(this);
- add(pause);
-
- // forward button
- forward = new JButton(new ImageIcon(getClass().getResource("/icons/forward.png")));
- forward.addActionListener(this);
- add(forward);
-
- add(Box.createHorizontalGlue());
-
- tickClock.start();
- }
-
- @Override
- public void actionPerformed(ActionEvent e) {
- if(e.getSource() == backward) {
- interf.tick -= 100;
- if(interf.tick < 0)
- interf.tick = 0;
- interf.computeTick();
- }else if(e.getSource() == stop) {
- go = false;
- interf.tick = 0;
- interf.computeTick();
- }else if(e.getSource() == play) {
- go = true;
- }else if(e.getSource() == pause) {
- go = false;
- }else if(e.getSource() == forward) {
- interf.tick += 100;
- interf.computeTick();
- }
- }
-}
diff --git a/VRGNYMusicLights/Sources/ApplicationJava/AnimationPlayer.java b/VRGNYMusicLights/Sources/ApplicationJava/AnimationPlayer.java
new file mode 100644
index 0000000..3356186
--- /dev/null
+++ b/VRGNYMusicLights/Sources/ApplicationJava/AnimationPlayer.java
@@ -0,0 +1,108 @@
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.Box;
+import javax.swing.BoxLayout;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JPanel;
+
+public class AnimationPlayer extends JPanel implements ActionListener {
+ private static final long serialVersionUID = 1L;
+
+ private Interface interf;
+
+ private JButton backward;
+ private JButton stop;
+ private JButton play;
+ private JButton pause;
+ private JButton forward;
+
+ private boolean go = false;
+ private boolean stopClock = false;
+ private static final int TICK_JUMP = 10;
+ private Thread tickClock = new Thread(new Runnable() {
+ @Override
+ public void run() {
+ while(!stopClock) {
+ if(!go) { // pause
+ try { Thread.sleep(100); }
+ catch (InterruptedException ignored) {}
+ continue;
+ }
+
+ long before = System.currentTimeMillis();
+ interf.computeTick();
+ interf.tick += TICK_JUMP;
+ long after = System.currentTimeMillis();
+
+ if(after - before < TICK_JUMP) {
+ try { Thread.sleep(TICK_JUMP - after + before);}
+ catch (InterruptedException ignored) {}
+ } else if(after - before > TICK_JUMP) {
+ System.err.println("Animation were slowed down by " + String.valueOf(after - before - TICK_JUMP) + " ticks !");
+ }
+ }
+ }
+ });
+ public void stopTickClock() {stopClock = true;}
+
+ public AnimationPlayer(Interface interf) { this(interf, BoxLayout.LINE_AXIS); }
+ public AnimationPlayer(Interface interf, int direction) {
+ this.interf = interf;
+
+ setLayout(new BoxLayout(this, direction));
+
+ add(Box.createHorizontalGlue());
+
+ // backward button
+ backward = new JButton(new ImageIcon(getClass().getResource("/icons/backward.png")));
+ backward.addActionListener(this);
+ add(backward);
+
+ // stop button
+ stop = new JButton(new ImageIcon(getClass().getResource("/icons/stop.png")));
+ stop.addActionListener(this);
+ add(stop);
+
+ // play button
+ play = new JButton(new ImageIcon(getClass().getResource("/icons/play.png")));
+ play.addActionListener(this);
+ add(play);
+
+ // pause button
+ pause = new JButton(new ImageIcon(getClass().getResource("/icons/pause.png")));
+ pause.addActionListener(this);
+ add(pause);
+
+ // forward button
+ forward = new JButton(new ImageIcon(getClass().getResource("/icons/forward.png")));
+ forward.addActionListener(this);
+ add(forward);
+
+ add(Box.createHorizontalGlue());
+
+ tickClock.start();
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if(e.getSource() == backward) {
+ interf.tick -= 100;
+ if(interf.tick < 0)
+ interf.tick = 0;
+ interf.computeTick();
+ }else if(e.getSource() == stop) {
+ go = false;
+ interf.tick = 0;
+ interf.computeTick();
+ }else if(e.getSource() == play) {
+ go = true;
+ }else if(e.getSource() == pause) {
+ go = false;
+ }else if(e.getSource() == forward) {
+ interf.tick += 100;
+ interf.computeTick();
+ }
+ }
+}
diff --git a/VRGNYMusicLights/Sources/ApplicationJava/CommandJPanel.java b/VRGNYMusicLights/Sources/ApplicationJava/CommandJPanel.java
new file mode 100644
index 0000000..072bd3f
--- /dev/null
+++ b/VRGNYMusicLights/Sources/ApplicationJava/CommandJPanel.java
@@ -0,0 +1,95 @@
+import java.awt.Color;
+import java.awt.Font;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+import javax.swing.BorderFactory;
+import javax.swing.BoxLayout;
+import javax.swing.JButton;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+
+public class CommandJPanel extends JPanel implements ActionListener {
+ private static final long serialVersionUID = 1L;
+ private static final Font titleFont = new Font(new JLabel().getFont().getName(), Font.BOLD, 14);
+
+ private JButton addPattern;
+ private JButton editPattern;
+ private JButton removePattern;
+ private JButton exports;
+ private JButton imports;
+
+ private Interface interf;
+
+ public CommandJPanel(Interface interf) {
+ this.interf = interf;
+ setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
+ setBorder(BorderFactory.createMatteBorder(0, 4, 0, 0, Color.LIGHT_GRAY));
+
+ // Title
+
+ JLabel title = new JLabel("Commands :");
+ title.setFont(titleFont);
+ add(title);
+
+ // Buttons
+
+ addPattern = new JButton("Add pattern");
+ editPattern = new JButton("Edit pattern");
+ removePattern = new JButton("Remove pattern");
+ exports = new JButton("Export");
+ imports = new JButton("Import");
+
+ addPattern.setMaximumSize(removePattern.getMaximumSize());
+ editPattern.setMaximumSize(removePattern.getMaximumSize());
+ exports.setMaximumSize(removePattern.getMaximumSize());
+ imports.setMaximumSize(removePattern.getMaximumSize());
+
+ addPattern.addActionListener(this);
+ editPattern.addActionListener(this);
+ removePattern.addActionListener(this);
+ exports.addActionListener(this);
+ imports.addActionListener(this);
+
+ add(addPattern);
+ add(editPattern);
+ add(removePattern);
+ add(exports);
+ add(imports);
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if(e.getSource() == addPattern) {
+ PatternEditorJDialog dialog = new PatternEditorJDialog(interf);
+ Music music = dialog.showDialog();
+ if(music == null)
+ return;
+ interf.musicList.addMusic(music);
+ interf.timeLinePanel.updateList();
+ } else if(e.getSource() == editPattern) {
+ int index = interf.timeLineList.getSelectedIndex();
+ if(index == -1)
+ return;
+ PatternEditorJDialog dialog = new PatternEditorJDialog(interf, interf.musicList.getList().get(index));
+ Music music = dialog.showDialog();
+ if(music == null)
+ return;
+ interf.musicList.setMusicAt(index, music);
+ interf.timeLinePanel.updateList();
+ } else if(e.getSource() == removePattern) {
+ int index = interf.timeLineList.getSelectedIndex();
+ if(index == -1)
+ return;
+ interf.musicList.deleteMusic(index);
+ interf.timeLinePanel.updateList();
+ } else if(e.getSource() == exports) {
+ ImportExport.exportWithDialog(interf.musicList);
+ } else if(e.getSource() == imports) {
+ MusicList newActionList = ImportExport.importsWithDialog();
+ if(newActionList != null)
+ interf.musicList = newActionList;
+ interf.timeLinePanel.updateList();
+ }
+ }
+}
diff --git a/VRGNYMusicLights/Sources/ApplicationJava/CustomSliderUI.java b/VRGNYMusicLights/Sources/ApplicationJava/CustomSliderUI.java
new file mode 100644
index 0000000..ca64c57
--- /dev/null
+++ b/VRGNYMusicLights/Sources/ApplicationJava/CustomSliderUI.java
@@ -0,0 +1,151 @@
+import java.awt.BasicStroke;
+import java.awt.Color;
+import java.awt.Dimension;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Rectangle;
+import java.awt.RenderingHints;
+import java.awt.Shape;
+import java.awt.Stroke;
+import java.awt.geom.Ellipse2D;
+
+import javax.swing.JComponent;
+import javax.swing.JSlider;
+import javax.swing.SwingConstants;
+import javax.swing.plaf.ComponentUI;
+import javax.swing.plaf.basic.BasicSliderUI;
+
+public class CustomSliderUI extends BasicSliderUI {
+ private final BasicStroke stroke = new BasicStroke(2f);
+ private JSlider slider;
+
+ public CustomSliderUI(JSlider b) {
+ super(b);
+ this.slider = b;
+ }
+
+ public static ComponentUI createUI(JComponent c) {
+ return new CustomSliderUI((JSlider)c);
+ }
+
+
+ @Override
+ protected void calculateThumbSize() {
+ super.calculateThumbSize();
+ thumbRect.setSize(thumbRect.width, thumbRect.height);
+ }
+
+ /** Creates a listener to handle track events in the specified slider.*/
+ @Override
+ protected TrackListener createTrackListener(JSlider slider) {
+ return new TrackListener();
+ }
+
+
+ @Override
+ protected void calculateThumbLocation() {
+ // Call superclass method for lower thumb location.
+ super.calculateThumbLocation();
+
+ // Adjust upper value to snap to ticks if necessary.
+ if (slider.getSnapToTicks()) {
+ int upperValue = slider.getValue() + slider.getExtent();
+ int snappedValue = upperValue;
+ int majorTickSpacing = slider.getMajorTickSpacing();
+ int minorTickSpacing = slider.getMinorTickSpacing();
+ int tickSpacing = 0;
+
+ if (minorTickSpacing > 0) {
+ tickSpacing = minorTickSpacing;
+ } else if (majorTickSpacing > 0) {
+ tickSpacing = majorTickSpacing;
+ }
+
+ if (tickSpacing != 0) {
+ // If it's not on a tick, change the value
+ if ((upperValue - slider.getMinimum()) % tickSpacing != 0) {
+ float temp = (float)(upperValue - slider.getMinimum()) / (float)tickSpacing;
+ int whichTick = Math.round(temp);
+ snappedValue = slider.getMinimum() + (whichTick * tickSpacing);
+ }
+
+ if (snappedValue != upperValue) {
+ slider.setExtent(snappedValue - slider.getValue());
+ }
+ }
+ }
+
+ // Calculate upper thumb location. The thumb is centered over its
+ // value on the track.
+ if (slider.getOrientation() == JSlider.HORIZONTAL) {
+ int upperPosition = xPositionForValue(slider.getValue() + slider.getExtent());
+ thumbRect.x = upperPosition - (thumbRect.width / 2);
+ thumbRect.y = trackRect.y;
+
+ } else {
+ int upperPosition = yPositionForValue(slider.getValue() + slider.getExtent());
+ thumbRect.x = trackRect.x;
+ thumbRect.y = upperPosition - (thumbRect.height / 2);
+ }
+ slider.repaint();
+ }
+
+ /** Returns the size of a thumb.
+ * Parent method not use size from LaF
+ * @return size of trumb */
+ @Override
+ protected Dimension getThumbSize() {
+ return new Dimension(5, 10);
+ }
+
+
+ private Shape createThumbShape(int width, int height) {
+ Ellipse2D shape = new Ellipse2D.Double(0, 0, width, height);
+ return shape;
+ }
+
+ @Override
+ public void paintTrack(Graphics g) {
+ Graphics2D g2d = (Graphics2D) g;
+ Stroke old = g2d.getStroke();
+ g2d.setStroke(stroke);
+ g2d.setPaint(slider.isEnabled() ? Color.LIGHT_GRAY : Color.WHITE);
+ Color oldColor = slider.isEnabled() ? Color.LIGHT_GRAY : Color.WHITE;
+ Rectangle trackBounds = trackRect;
+ if (slider.getOrientation() == SwingConstants.HORIZONTAL) {
+ g2d.drawLine(trackRect.x, trackRect.y + trackRect.height / 2,
+ trackRect.x + trackRect.width, trackRect.y + trackRect.height / 2);
+ int lowerX = thumbRect.width / 2;
+ int upperX = thumbRect.x + (thumbRect.width / 2);
+ int cy = (trackBounds.height / 2) - 2;
+ g2d.translate(trackBounds.x, trackBounds.y + cy);
+ g2d.setColor(slider.isEnabled() ? Color.BLACK : Color.LIGHT_GRAY);
+ g2d.drawLine(lowerX - trackBounds.x, 2, upperX - trackBounds.x, 2);
+ g2d.translate(-trackBounds.x, -(trackBounds.y + cy));
+ g2d.setColor(oldColor);
+ }
+ g2d.setStroke(old);
+ }
+
+
+
+ /** Overrides superclass method to do nothing. Thumb painting is handled
+ * within the paint()
method.*/
+ @Override
+ public void paintThumb(Graphics g) {
+ Rectangle knobBounds = thumbRect;
+ int w = knobBounds.width;
+ int h = knobBounds.height;
+ Graphics2D g2d = (Graphics2D) g.create();
+ Shape thumbShape = createThumbShape(w - 1, h - 1);
+ g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+ RenderingHints.VALUE_ANTIALIAS_ON);
+ g2d.translate(knobBounds.x, knobBounds.y);
+ g2d.setColor(slider.isEnabled() ? Color.LIGHT_GRAY : Color.WHITE);
+ g2d.fill(thumbShape);
+
+ g2d.setColor(slider.isEnabled() ? Color.BLACK : Color.LIGHT_GRAY);
+ g2d.draw(thumbShape);
+ g2d.dispose();
+ }
+}
\ No newline at end of file
diff --git a/VRGNYMusicLights/Sources/ApplicationJava/ImportExport.java b/VRGNYMusicLights/Sources/ApplicationJava/ImportExport.java
new file mode 100644
index 0000000..15dfeac
--- /dev/null
+++ b/VRGNYMusicLights/Sources/ApplicationJava/ImportExport.java
@@ -0,0 +1,73 @@
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+
+import javax.swing.JFileChooser;
+import javax.swing.JOptionPane;
+import javax.swing.filechooser.FileNameExtensionFilter;
+
+public class ImportExport {
+ public static void exportWithDialog(MusicList list) {
+ JFileChooser chooser = new JFileChooser();
+ FileNameExtensionFilter filter = new FileNameExtensionFilter("Array data", "adata");
+ chooser.setFileFilter(filter);
+ chooser.setApproveButtonText("Exporter");
+ int returnVal = chooser.showOpenDialog(null);
+ if(returnVal == JFileChooser.APPROVE_OPTION)
+ export(list, chooser.getSelectedFile().getPath());
+ }
+ private static void export(MusicList list, String path) {
+ String str = "";//list.getLeftDeltaArray() + "\n" + list.getRightDeltaArray() + "\n" + list.getLeftDelaiArray() + "\n" + list.getRightDelaiArray();
+
+ if(!path.endsWith(".adata"))
+ path += ".adata";
+ BufferedWriter bufferedWriter = null;
+ try {
+ File file = new File(path);
+ if (!file.exists())
+ file.createNewFile();
+ bufferedWriter = new BufferedWriter(new FileWriter(file));
+ bufferedWriter.write(str);
+ bufferedWriter.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static MusicList importsWithDialog() {
+ JFileChooser chooser = new JFileChooser();
+ FileNameExtensionFilter filter = new FileNameExtensionFilter("Array data", "adata");
+ chooser.setFileFilter(filter);
+ chooser.setMultiSelectionEnabled(false);
+ chooser.setApproveButtonText("Importer");
+ int returnVal = chooser.showOpenDialog(null);
+ if(returnVal == JFileChooser.APPROVE_OPTION && chooser.getSelectedFile().exists() && chooser.getSelectedFile().isFile())
+ return imports(chooser.getSelectedFile().getPath());
+ if(returnVal == JFileChooser.APPROVE_OPTION)
+ JOptionPane.showMessageDialog(null, "You have to choose an exisiting file", "Import error", JOptionPane.ERROR_MESSAGE);
+ return null;
+ }
+ private static MusicList imports(String path) {
+ try {
+ byte[] encoded = Files.readAllBytes(Paths.get(path));
+ String str = new String(encoded, Charset.defaultCharset());
+
+ //long[][] longList = Util.getArraysFromImport(str);
+ /*if(longList == null) {
+ JOptionPane.showMessageDialog(null, "The choosen file is invalid or currupted", "Import error", JOptionPane.ERROR_MESSAGE);
+ return null;
+ }
+ int[][] intList = new int[2][longList[0].length];
+ for(int i=0; i<2; i++)
+ for(int j=0; j musics;
+ private SerialCom serialCom;
+
+ public MusicList(SerialCom serialCom) {
+ this.serialCom = serialCom;
+ musics = new ArrayList<>();
+ }
+
+ public ArrayList getList() { return musics; }
+ public void addMusic(Music music) { musics.add(music); }
+ public void setMusicAt(int index, Music music) { musics.set(index, music); }
+ public void deleteMusic(int index) { musics.remove(index); }
+
+ public double[] render(long tick) {
+ if(musics.size() == 0)
+ return null;
+ double[] lights = musics.get(0).render(tick);
+ for(int i=1; i 1)
+ lights[j] = 1;
+ }
+ }
+ return lights;
+ }
+}
diff --git a/VRGNYMusicLights/Sources/ApplicationJava/MusicPath.java b/VRGNYMusicLights/Sources/ApplicationJava/MusicPath.java
new file mode 100644
index 0000000..f8ba122
--- /dev/null
+++ b/VRGNYMusicLights/Sources/ApplicationJava/MusicPath.java
@@ -0,0 +1,144 @@
+
+public class MusicPath {
+ public static final double[][] LIGHT_COORDS = new double[][] {
+ // Planche 1
+ {0.0383, 0}, {0.0766, 0}, {0.115, 0}, {0.1533, 0}, {0.1916, 0}, {0.23, 0}, //M1L1
+ {0.2683, 0}, {0.306, 0}, {0.345, 0}, {0.383, 0}, {0.4216, 0}, {0.46, 0}, {0.4983, 0}, //M1L2
+ {0.0333, 0.25}, {0.0666, 0.25}, {0.0999, 0.25}, {0.1333, 0.25}, //P1-1
+ {0.3016, 0.25}, {0.3366, 0.25}, {0.3733, 0.25}, {0.4099, 0.25}, {0.4466, 0.25}, {0.4833, 0.25}, {0.5199, 0.25}, //P1-2
+ {0.3366, 0.3}, {0.3366, 0.35}, //P1-3
+ {0, 0.3075}, {0, 0.365}, {0, 0.4225}, //M1l1
+
+ // Planche 2
+ {0.5366, 0}, {0.575, 0}, {0.6133, 0}, {0.6516, 0}, {0.69, 0}, {0.7283, 0}, {0.7666, 0}, //M2L1
+ {0.805, 0}, {0.8433, 0}, {0.8816, 0}, {0.92, 0}, {0.9583, 0}, //M2L2
+ {0.5566, 0.25}, {0.5933, 0.25}, {0.6299, 0.25}, {0.6666, 0.25}, //P2-1
+ {0.8366, 0.25}, {0.8699, 0.25}, {0.9032, 0.25}, {0.9366, 0.25}, {0.9699, 0.25}, //P2-2
+ {1, 0.06}, {1, 0.115}, {1, 0.17}, {1, 0.225}, {1, 0.28}, {1, 0.335}, {1, 0.39}, //M2l1
+
+ // Planche 3
+ {0.3366, 0.4}, {0.3366, 0.45}, {0.3366, 0.5}, //P3-1
+ {0.3366, 0.75}, {0.3366, 0.8}, //P3-2
+ {0, 0.48}, {0, 0.5375}, {0, 0.595}, {0, 0.6525}, {0, 0.71}, {0, 0.7675}, //M3l1
+
+ // Planche 4
+ {1, 0.445}, {1, 0.5}, {1, 0.555}, {1, 0.61}, {1, 0.665}, {1, 0.72}, {1, 0.775}, //M4l1
+
+ // Planche 5
+ {0.0383, 1}, {0.0766, 1}, {0.115, 1}, {0.1533, 1}, {0.1916, 1}, {0.23, 1}, //M5L1
+ {0.2683, 1}, {0.306, 1}, {0.345, 1}, {0.383, 1}, {0.4216, 1}, {0.46, 1}, {0.4983, 1}, //M5L2
+ {0.3366, 0.85}, {0.3366, 0.9}, {0.3366, 0.95}, //P5-1
+ {0, 0.8255}, {0, 0.8835}, {0, 0.9415}, //M5l1
+
+ // Planche 6
+ {0.5366, 1}, {0.575, 1}, {0.6133, 1}, {0.6516, 1}, {0.69, 1}, {0.7283, 1}, {0.7666, 1}, //M6L1
+ {0.805, 1}, {0.8433, 1}, {0.8816, 1}, {0.92, 1}, {0.9583, 1}, //M6L2
+ {1, 0.83}, {1, 0.885}, {1, 0.94} //M6l1
+ };
+
+ public static final String[] pathNames = new String[] {
+ "Vertical down",
+ "Vertical up",
+ "Horizontal right to left",
+ "Horizontal left to right",
+ "Diagonal up right to down left",
+ "Diagonal down left to up right",
+ "Diagonal up left to down right",
+ "Diagonal down right to up left",
+ "Center out",
+ "Center in",
+ "Flashing",
+ };
+ public static final int VERTICAL_DOWN = 0;
+ public static final int VERTICAL_UP = 1;
+ public static final int HORIZONTAL_TO_LEFT = 2;
+ public static final int HORIZONTAL_TO_RIGHT = 3;
+ public static final int DIAGONAL_TOP_RIGHT_DOWN_LEFT = 4;
+ public static final int DIAGONAL_DOWN_LEFT_TOP_RIGHT = 5;
+ public static final int DIAGONAL_TOP_LEFT_DOWN_RIGHT = 6;
+ public static final int DIAGONAL_DOWN_RIGHT_TOP_LEFT = 7;
+ public static final int CENTER_OUT = 8;
+ public static final int CENTER_IN = 9;
+ public static final int ALL = 10;
+
+ private int animation;
+ private int effectDuration;
+ private double[][] lightsCoords;
+
+ public MusicPath(int animation, int effectDuration) { this(animation, effectDuration, LIGHT_COORDS); }
+ public MusicPath(int animation, int effectDuration, double[][] lightsCoords) {
+ this.animation = animation;
+ this.effectDuration = effectDuration;
+ this.lightsCoords = lightsCoords;
+ }
+
+ public int getAnimation() { return animation; }
+ public int getEffectDuration() { return effectDuration; }
+
+ public int[] calculateTickDelais() { // tick in ms
+ int[] ticksDelais = new int[lightsCoords.length];
+ for(int i=0; i= stop)
+ return 0;
+ int tickMod = (int) (tick % totalLength);
+ if(tickMod < patternTiming[0])
+ return 0;
+ if(tickMod < patternTiming[1])
+ return (double) (tickMod - patternTiming[0]) / (double) (pattern[1]);
+ if(tickMod < patternTiming[2])
+ return 1;
+ if(tickMod < patternTiming[3])
+ return 1 - ((double) (tickMod - patternTiming[2]) / (double) (pattern[3]));
+ return 0;
+ }
+}
diff --git a/VRGNYMusicLights/Sources/ApplicationJava/MusicRenderer.java b/VRGNYMusicLights/Sources/ApplicationJava/MusicRenderer.java
new file mode 100644
index 0000000..ea1d528
--- /dev/null
+++ b/VRGNYMusicLights/Sources/ApplicationJava/MusicRenderer.java
@@ -0,0 +1,68 @@
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.Font;
+import java.util.ArrayList;
+
+import javax.swing.Box;
+import javax.swing.BoxLayout;
+import javax.swing.JLabel;
+import javax.swing.JList;
+import javax.swing.JPanel;
+import javax.swing.ListCellRenderer;
+
+public class MusicRenderer extends JPanel implements ListCellRenderer {
+ private static final long serialVersionUID = 1L;
+ private static final Color DEFAULT_BACKGROUND = new JPanel().getBackground();
+ private static final Font defaultFont = new Font(new JLabel().getFont().getName(), Font.PLAIN, new JLabel().getFont().getSize());
+
+ private TimeLineJPanel timeLine;
+ private int infoPadding = 0;
+
+ public ArrayList patterns;
+
+ public MusicRenderer(TimeLineJPanel timeLine) {
+ this.timeLine = timeLine;
+ this.patterns = new ArrayList<>();
+ }
+
+ public void setInfoPadding(int infoPadding) { this.infoPadding = infoPadding; }
+
+ @Override
+ public Component getListCellRendererComponent(JList extends Music> list, Music music, int index,
+ boolean isSelected, boolean cellHasFocus) {
+ removeAll();
+ if(music == null)
+ return this;
+
+ setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
+
+ JPanel infoPanel = new JPanel();
+ infoPanel.setLayout(new BoxLayout(infoPanel, BoxLayout.LINE_AXIS));
+ infoPanel.add(Box.createRigidArea(new Dimension(infoPadding, 0)));
+ JLabel infoLabel = new JLabel("Pattern " + String.valueOf(index) + " : "
+ + "(vol : " + String.valueOf(music.getVolume()) + ", "
+ + "effect : " + MusicPath.pathNames[music.getMusicPath().getAnimation()] + ", "
+ + "effect duration : " + Util.tickToText(music.getMusicPath().getEffectDuration()) + ")");
+ infoLabel.setFont(defaultFont);
+ infoPanel.add(infoLabel);
+ infoPanel.add(Box.createHorizontalGlue());
+
+ if(isSelected) {
+ infoPanel.setBackground(Color.LIGHT_GRAY);
+ } else {
+ infoPanel.setBackground(DEFAULT_BACKGROUND);
+ }
+
+ add(infoPanel);
+
+ PatternJPanel pattern = new PatternJPanel(music, timeLine);
+ if(patterns.size() > index)
+ patterns.set(index, pattern);
+ else
+ patterns.add(pattern);
+ add(pattern);
+
+ return this;
+ }
+}
diff --git a/VRGNYMusicLights/Sources/ApplicationJava/NoSerialPortException.java b/VRGNYMusicLights/Sources/ApplicationJava/NoSerialPortException.java
new file mode 100644
index 0000000..c29ea0c
--- /dev/null
+++ b/VRGNYMusicLights/Sources/ApplicationJava/NoSerialPortException.java
@@ -0,0 +1,8 @@
+
+public class NoSerialPortException extends Exception {
+ private static final long serialVersionUID = 1L;
+
+ public NoSerialPortException() {
+ super("No serial port available !");
+ }
+}
diff --git a/VRGNYMusicLights/Sources/ApplicationJava/PatternEditorJDialog.java b/VRGNYMusicLights/Sources/ApplicationJava/PatternEditorJDialog.java
new file mode 100644
index 0000000..1dad6c4
--- /dev/null
+++ b/VRGNYMusicLights/Sources/ApplicationJava/PatternEditorJDialog.java
@@ -0,0 +1,253 @@
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.Font;
+import java.awt.Frame;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+
+import javax.swing.Box;
+import javax.swing.BoxLayout;
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JDialog;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JSlider;
+import javax.swing.JTextField;
+
+public class PatternEditorJDialog extends JDialog implements ActionListener, FocusListener {
+ private static final long serialVersionUID = 1L;
+ private static final Font titleFont = new Font(new JLabel().getFont().getName(), Font.BOLD, 14);
+ private static final String[] fieldsNames = new String[] {
+ "Low time : ", //0
+ "Rise time : ", //1
+ "High time : ", //2
+ "Fall time : ", //3
+ "Low time : ", //4
+ "Repeat : ", //5
+ "Begin time : ", //6
+ "Volume : ", //7
+ "Path : ", //8
+ "Duration : ", //9
+ "Pattern time : ", //10
+ "Total time : " //11
+ };
+ private void generateComponents() {
+ fields = new Component[fieldsNames.length];
+
+ // 7 textfields
+ for(int i=0; i<7; i++) {
+ fields[i] = new JTextField(10);
+ fields[i].addFocusListener(this);
+ }
+
+ // 1 slider
+ fields[7] = new JSlider(0, 10, 8);
+ ((JSlider) fields[7]).setMajorTickSpacing(2);
+ ((JSlider) fields[7]).setMinorTickSpacing(1);
+ ((JSlider) fields[7]).setPaintTicks(true);
+
+ // 1 combobox
+ fields[8] = new JComboBox(MusicPath.pathNames);
+
+
+ // 1 textfields
+ fields[9] = new JTextField(10);
+ fields[9].addFocusListener(this);
+
+ // 2 textfields disabled
+ for(int i=10; i<12; i++) {
+ fields[i] = new JTextField(10);
+ fields[i].setEnabled(false);
+ fields[i].addFocusListener(this);
+ fields[i].setForeground(Color.DARK_GRAY);
+ }
+ }
+
+ private Component[] fields;
+ private JButton ok;
+ private JButton cancel;
+ private Music music = null;
+
+ public PatternEditorJDialog(Frame parent) { this(parent, null); }
+ public PatternEditorJDialog(Frame parent, Music musicPrev) {
+ super(parent, "Pattern editor", true);
+ generateComponents();
+
+ // main panel
+
+ JPanel mainPanel = new JPanel(new BorderLayout());
+ getContentPane().add(mainPanel);
+
+ // title
+
+ JPanel titlePanel = new JPanel(new FlowLayout());
+ JLabel title = new JLabel("Pattern parameters : ");
+ title.setFont(titleFont);
+ titlePanel.add(title);
+ mainPanel.add(titlePanel, BorderLayout.NORTH);
+
+ // center panel
+ JPanel centerPanel = new JPanel();
+ centerPanel.setLayout(new BoxLayout(centerPanel, BoxLayout.LINE_AXIS));
+ mainPanel.add(centerPanel, BorderLayout.CENTER);
+ //padding
+ centerPanel.add(Box.createRigidArea(new Dimension(5, 0)));
+
+ // labels panel
+ JPanel labelsPanel = new JPanel();
+ labelsPanel.setLayout(new BoxLayout(labelsPanel, BoxLayout.PAGE_AXIS));
+ centerPanel.add(labelsPanel);
+
+ // fields panel
+ JPanel fieldsPanel = new JPanel();
+ fieldsPanel.setLayout(new BoxLayout(fieldsPanel, BoxLayout.PAGE_AXIS));
+ centerPanel.add(fieldsPanel);
+ //padding
+ centerPanel.add(Box.createRigidArea(new Dimension(5, 0)));
+
+ JLabel[] fieldsLabels = new JLabel[fieldsNames.length];
+ for(int i=0; i) fields[8]).setSelectedIndex(path.getAnimation());
+
+ ((JTextField) fields[9]).setText(String.valueOf(path.getEffectDuration()));
+ }
+
+ public Music showDialog() {
+ setVisible(true);
+ return music;
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if(e.getSource() == ok) {
+ updateFields();
+
+ int lowTime = (int) Util.textToTick(((JTextField) fields[0]).getText());
+ int raiseTime = (int) Util.textToTick(((JTextField) fields[1]).getText());
+ int highTime = (int) Util.textToTick(((JTextField) fields[2]).getText());
+ int fallTime = (int) Util.textToTick(((JTextField) fields[3]).getText());
+ int pauseTime = (int) Util.textToTick(((JTextField) fields[4]).getText());
+ int repeats = Integer.parseInt(((JTextField) fields[5]).getText());
+ long beginTime = Util.textToTick(((JTextField) fields[6]).getText());
+
+ int animationId = ((JComboBox>) fields[8]).getSelectedIndex();
+ int effectDuration = (int) Util.textToTick(((JTextField) fields[9]).getText());
+
+ MusicPattern musicPattern = new MusicPattern(new int[] {lowTime, raiseTime, highTime, fallTime, pauseTime}, repeats, beginTime);
+ MusicPath musicPath = new MusicPath(animationId, effectDuration);
+ double volume = (double) ((JSlider) fields[7]).getValue() / (double) ((JSlider) fields[7]).getMaximum();
+
+ //invalid params
+ if((lowTime == 0 && raiseTime == 0 && highTime == 0 && fallTime == 0 && pauseTime == 0)
+ || (repeats <= 0)
+ || (beginTime < 0)
+ || (effectDuration < 0)) {
+ music = null;
+ dispose();
+ return;
+ }
+
+ music = new Music(musicPattern, musicPath, volume);
+
+ dispose();
+ } else if(e.getSource() == cancel) {
+ music = null;
+ dispose();
+ }
+ }
+
+ public void updateFields() {
+ // format textfields
+ for(int i=0; i portEnum = CommPortIdentifier.getPortIdentifiers();
+
+ // Search for serial port
+ while (portEnum.hasMoreElements()) {
+ CommPortIdentifier currPortId = (CommPortIdentifier) portEnum.nextElement();
+ if (currPortId.getName().equals(portName)) {
+ portId = currPortId;
+ break;
+ }
+ }
+ if (portId == null)
+ throw new SerialComPortException(portName);
+
+ // open connection
+ try {
+ serialPort = (SerialPort) portId.open(this.getClass().getName(), TIME_OUT);
+ serialPort.setSerialPortParams(DATA_RATE, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
+
+ input = serialPort.getInputStream();
+ output = serialPort.getOutputStream();
+ } catch (IOException
+ | UnsupportedCommOperationException
+ | PortInUseException e) {
+ throw new SerialComPortException(portName);
+ }
+ }
+
+ public void close() {
+ try {
+ input.close();
+ output.close();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ serialPort.removeEventListener();
+ serialPort.close();
+ }
+ public void send(byte[] bytes) {
+ try {
+ this.output.write(bytes);
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ public byte[] recieve() {
+ byte[] buffer = new byte[BUFFER_SIZE];
+ int len = -1;
+
+ try { len = this.input.read(buffer); }
+ catch (IOException e) { return null; }
+
+ if(len == -1 || len == 0)
+ return null;
+ byte[] data = new byte[len];
+ for(int i=0; i portNames;
+ private String choosedPort = null;
+
+ private JList list;
+ private JButton ok;
+ private JButton cancel;
+
+ private SerialPortChooserDialog() {
+ Enumeration> portEnum = CommPortIdentifier.getPortIdentifiers();
+ portNames = new ArrayList<>();
+
+ while (portEnum.hasMoreElements()) {
+ CommPortIdentifier currPortId = (CommPortIdentifier) portEnum.nextElement();
+ portNames.add(currPortId.getName());
+ }
+
+ onlyOneChoice = portNames.size() <= 1;
+ emptyChoice = portNames.size() == 0;
+ if(onlyOneChoice || emptyChoice)
+ return;
+
+ // JDialog creation
+ JPanel mainPanel = new JPanel(new BorderLayout());
+ setModal(true);
+ setTitle("Serial port chooser");
+
+ // title
+ mainPanel.add(new JLabel("Choose a serial port : "), BorderLayout.NORTH);
+
+ // list ports
+ DefaultListModel listModel = new DefaultListModel<>();
+ for(String str : portNames)
+ listModel.addElement(str);
+ list = new JList<>(listModel);
+ list.addListSelectionListener(this);
+ list.setVisibleRowCount(3);
+ list.setLayoutOrientation(JList.VERTICAL);
+ list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+
+ JScrollPane scrollPane = new JScrollPane(list, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
+ scrollPane.setPreferredSize(new Dimension(200, 100));
+ mainPanel.add(scrollPane, BorderLayout.CENTER);
+
+ // buttons ok / cancel
+ JPanel borderLayoutPanel = new JPanel(new BorderLayout());
+ JPanel buttonsLayout = new JPanel(new FlowLayout(FlowLayout.LEADING, 5, 3));
+ ok = new JButton("Ok");
+ cancel = new JButton("Cancel");
+ ok.addActionListener(this);
+ cancel.addActionListener(this);
+ ok.setEnabled(false);
+ buttonsLayout.add(cancel);
+ buttonsLayout.add(ok);
+ borderLayoutPanel.add(buttonsLayout, BorderLayout.EAST);
+ mainPanel.add(borderLayoutPanel, BorderLayout.SOUTH);
+
+ // padding
+ JPanel padding = new JPanel(new FlowLayout(FlowLayout.LEADING, 5, 5));
+ padding.add(mainPanel);
+ add(padding);
+
+ setResizable(false);
+ pack();
+ setLocationRelativeTo(null);
+ setVisible(true);
+ }
+
+ public static String showSerialPortChooserDialog() throws NoSerialPortException {
+ SerialPortChooserDialog dialog = new SerialPortChooserDialog();
+ if(dialog.emptyChoice)
+ throw new NoSerialPortException();
+ if(dialog.onlyOneChoice)
+ return dialog.portNames.get(0);
+ return dialog.choosedPort;
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if(e.getSource() == ok) {
+ choosedPort = list.getSelectedValue();
+ dispose();
+ } else if(e.getSource() == cancel) {
+ dispose();
+ }
+ }
+
+ @Override
+ public void valueChanged(ListSelectionEvent e) {
+ if(e.getSource() == list) {
+ ok.setEnabled(list.getSelectedIndex() != -1);
+ }
+ }
+}
diff --git a/VRGNYMusicLights/Sources/ApplicationJava/TimeLineJList.java b/VRGNYMusicLights/Sources/ApplicationJava/TimeLineJList.java
new file mode 100644
index 0000000..0989a5f
--- /dev/null
+++ b/VRGNYMusicLights/Sources/ApplicationJava/TimeLineJList.java
@@ -0,0 +1,29 @@
+import java.awt.Color;
+import java.awt.Graphics;
+
+import javax.swing.JList;
+import javax.swing.ListModel;
+
+public class TimeLineJList extends JList {
+ private static final long serialVersionUID = 1L;
+ private static final int MARK_WIDTH = 2;
+
+ private Interface interf;
+
+ public TimeLineJList(ListModel dataModel, Interface interf) {
+ super(dataModel);
+ this.interf = interf;
+ }
+
+ @Override
+ protected void paintComponent(Graphics g) {
+ super.paintComponent(g);
+ g.setColor(Color.BLACK);
+
+ int maxHeight = getPreferredSize().height;
+
+ int mark = Util.transformZoom(interf.tick, interf.timeLinePanel.getZoomLevel());
+
+ g.fillRect(mark, 0, MARK_WIDTH, maxHeight);
+ }
+}
diff --git a/VRGNYMusicLights/Sources/ApplicationJava/TimeLineJPanel.java b/VRGNYMusicLights/Sources/ApplicationJava/TimeLineJPanel.java
new file mode 100644
index 0000000..0d22290
--- /dev/null
+++ b/VRGNYMusicLights/Sources/ApplicationJava/TimeLineJPanel.java
@@ -0,0 +1,228 @@
+import java.awt.Dimension;
+import java.awt.Font;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.AdjustmentEvent;
+import java.awt.event.AdjustmentListener;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import java.awt.event.MouseWheelEvent;
+import java.awt.event.MouseWheelListener;
+
+import javax.swing.Box;
+import javax.swing.BoxLayout;
+import javax.swing.DefaultListModel;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JScrollBar;
+import javax.swing.JScrollPane;
+import javax.swing.JSlider;
+import javax.swing.JTextField;
+import javax.swing.ListSelectionModel;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+
+public class TimeLineJPanel extends JPanel implements MouseWheelListener, FocusListener, ActionListener, ChangeListener, AdjustmentListener {
+ private static final long serialVersionUID = 1L;
+ private static final Font titleFont = new Font(new JLabel().getFont().getName(), Font.BOLD, 14);
+
+ private static final int SCROLL_SPEED_HORIZONTAL = 30;
+ private static final int SCROLL_SPEED_VERTICAL = 30;
+
+ private DefaultListModel listModel;
+ private double zoomLevel = 1;
+
+ private JScrollPane scrollPane;
+ private MusicRenderer musicRenderer;
+ private Interface interf;
+ private JTextField currentTick;
+ private JLabel maxTicks;
+ private JPanel scrollPanel;
+
+ public TimeLineJPanel(Interface interf) {
+ this.interf = interf;
+ setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
+
+ // timing infos
+ JPanel timingPanel = new JPanel();
+ timingPanel.setLayout(new BoxLayout(timingPanel, BoxLayout.LINE_AXIS));
+
+ JLabel title = new JLabel("Timeline : ");
+ title.setFont(titleFont);
+ timingPanel.add(title);
+
+ currentTick = new JTextField("00:00.000", 8);
+ currentTick.setMaximumSize( currentTick.getPreferredSize() );
+ currentTick.addFocusListener(this);
+ currentTick.addActionListener(this);
+ timingPanel.add(currentTick);
+
+ maxTicks = new JLabel(" / 00:00.0000 (MM:ss:ms)");
+ timingPanel.add(maxTicks);
+
+ timingPanel.add(Box.createHorizontalGlue());
+
+ add(timingPanel);
+
+ // scroll pane
+
+ scrollPanel = new JPanel();
+ scrollPanel.setLayout(new BoxLayout(scrollPanel, BoxLayout.PAGE_AXIS));
+ scrollPane = new JScrollPane(scrollPanel, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
+ scrollPane.addMouseWheelListener(this);
+ scrollPane.setWheelScrollingEnabled(false);
+ scrollPane.getHorizontalScrollBar().addAdjustmentListener(this);
+ scrollPane.setPreferredSize(new Dimension(800, 400));
+ add(scrollPane);
+
+ // slider
+
+ interf.timeSlider = new JSlider(JSlider.HORIZONTAL, 0, 0, 0);
+ interf.timeSlider.setMajorTickSpacing(1000);
+ interf.timeSlider.setMinorTickSpacing(500);
+ interf.timeSlider.setPaintTicks(true);
+ interf.timeSlider.setAlignmentX(LEFT_ALIGNMENT);
+ interf.timeSlider.setEnabled(false);
+ interf.timeSlider.setUI(new CustomSliderUI(interf.timeSlider));
+ interf.timeSlider.addChangeListener(this);
+ scrollPanel.add(interf.timeSlider);
+
+ // timeline
+
+ listModel = new DefaultListModel<>();
+ for(Music music : interf.musicList.getList())
+ listModel.addElement(music);
+ interf.timeLineList = new TimeLineJList(listModel, interf);
+ musicRenderer = new MusicRenderer(this);
+ interf.timeLineList.setCellRenderer(musicRenderer);
+ interf.timeLineList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+ interf.timeLineList.setAlignmentX(LEFT_ALIGNMENT);
+ scrollPanel.add(interf.timeLineList);
+ }
+
+ public double getZoomLevel() { return zoomLevel; }
+
+ public void updateList() {
+ final MusicList musicList = interf.musicList;
+
+ listModel.clear();
+ for(Music music : musicList.getList())
+ listModel.addElement(music);
+
+ // compute max slider
+ long maxTick = 0;
+ for(Music music : musicList.getList()) {
+ if(music.getMusicPattern().getStop() > maxTick)
+ maxTick = music.getMusicPattern().getStop();
+ }
+ interf.timeSlider.setMaximum((int) maxTick);
+
+ // update need a delay and have to be call with another thread (note sure why...)
+ new Thread(new Runnable() {
+ @Override
+ public void run() {
+ try {
+ Thread.sleep(10);
+ } catch (InterruptedException e) {
+ e.printStackTrace();
+ }
+ if(musicList.getList().size() != 0)
+ updateTimeLine(0);
+ }
+ }).start();
+ }
+
+ public void updateTick() {
+ currentTick.setText(Util.tickToText(interf.tick));
+ long maxTick = 0;
+ for(PatternJPanel pattern : musicRenderer.patterns) {
+ pattern.refreshPreferedSize();
+ long tick = pattern.getMusic().getMusicPattern().getStop();
+ if(tick > maxTick)
+ maxTick = tick;
+ }
+ maxTicks.setText(Util.tickToText(maxTick) + " (mm:ss:ms)");
+ }
+
+ public void mouseWheelMoved(MouseWheelEvent e) {
+ if(e.getSource() == scrollPane) {
+ if (e.isControlDown()) {
+ if(interf.musicList.getList().size() != 0)
+ updateTimeLine(e.getWheelRotation());
+ } else if(e.isShiftDown()) {
+ JScrollBar sb = scrollPane.getHorizontalScrollBar();
+ sb.setValue(sb.getValue() + e.getWheelRotation() * SCROLL_SPEED_HORIZONTAL);
+ } else {
+ JScrollBar sb = scrollPane.getVerticalScrollBar();
+ sb.setValue(sb.getValue() + e.getWheelRotation() * SCROLL_SPEED_VERTICAL);
+ }
+ }
+ }
+
+ public void updateTimeLine(int wheelRot) {
+ if(wheelRot < 0)
+ zoomLevel *= (double) wheelRot * -1.1;
+ else if (wheelRot > 0)
+ zoomLevel *= (double) wheelRot / 1.1;
+
+ interf.timeSlider.setEnabled(musicRenderer.patterns.size() != 0);
+ int maxWidth = 0;
+ if(musicRenderer.patterns.size() == 0) {
+ interf.timeSlider.setValue(0);
+ maxWidth = (int) (scrollPane.getPreferredSize().width - new JScrollBar().getPreferredSize().getWidth()) - 1;
+ } else {
+ for(PatternJPanel pattern : musicRenderer.patterns) {
+ pattern.refreshPreferedSize();
+ int width = pattern.getEnd();
+ if(width > maxWidth)
+ maxWidth = width;
+ }
+ }
+
+ interf.timeSlider.setMaximumSize(new Dimension(maxWidth, interf.timeSlider.getPreferredSize().height));
+ interf.timeLineList.setMaximumSize(new Dimension(maxWidth, PatternJPanel.PATTERN_HEIGHT * musicRenderer.patterns.size()));
+ interf.timeLineList.setPreferredSize(new Dimension(maxWidth, PatternJPanel.PATTERN_HEIGHT * musicRenderer.patterns.size()));
+ scrollPanel.setPreferredSize(new Dimension(maxWidth, PatternJPanel.PATTERN_HEIGHT * musicRenderer.patterns.size()));
+ scrollPane.repaint();
+ scrollPane.getViewport().revalidate();
+ scrollPanel.revalidate();
+ }
+
+ @Override
+ public void focusLost(FocusEvent e) {
+ if(e.getSource() == currentTick) {
+ interf.tick = Util.textToTick(currentTick.getText());
+ currentTick.setText(Util.tickToText(interf.tick));
+ interf.computeTick();
+ }
+ }
+ @Override
+ public void focusGained(FocusEvent e) {
+ if(e.getSource() == currentTick)
+ currentTick.setCaretPosition(currentTick.getDocument().getLength());
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ if(e.getSource() == currentTick)
+ interf.getContentPane().requestFocus();
+ }
+
+ @Override
+ public void stateChanged(ChangeEvent e) {
+ if(e.getSource() == interf.timeSlider) {
+ interf.tick = interf.timeSlider.getValue();
+ interf.computeTick();
+ }
+ }
+
+ @Override
+ public void adjustmentValueChanged(AdjustmentEvent e) {
+ if(e.getSource() == scrollPane.getHorizontalScrollBar()) {
+ musicRenderer.setInfoPadding(scrollPane.getHorizontalScrollBar().getValue());
+ scrollPane.repaint();
+ scrollPane.getViewport().revalidate();
+ scrollPanel.revalidate();
+ }
+ }
+}
diff --git a/VRGNYMusicLights/Sources/ApplicationJava/Util.java b/VRGNYMusicLights/Sources/ApplicationJava/Util.java
new file mode 100644
index 0000000..4de6b0d
--- /dev/null
+++ b/VRGNYMusicLights/Sources/ApplicationJava/Util.java
@@ -0,0 +1,54 @@
+
+public class Util {
+ public static long textToTick(String str) {
+ if(str == null || str.equals(""))
+ return 0;
+ String[] strs = str.split(":|\\.");
+ long ticks = 0;
+
+ try {
+ switch (strs.length) {
+ case 1:
+ ticks += Integer.parseInt(strs[0]);
+ break;
+ case 2:
+ ticks += Integer.parseInt(strs[1]);
+ ticks += Integer.parseInt(strs[0]) * 1000;
+ break;
+ case 3:
+ ticks += Integer.parseInt(strs[2]);
+ ticks += Integer.parseInt(strs[1]) * 1000;
+ ticks += Integer.parseInt(strs[0]) * 60000;
+ break;
+ }
+ } catch (NumberFormatException e) {
+ return 0;
+ }
+ return ticks;
+ }
+
+ public static String tickToText(long tick) {
+ String str = "";
+
+ if(tick > 5900000)
+ str += "99:";
+ else
+ str += String.format("%02d", (int) ((double) tick / 60000d)) + ":";
+
+ tick -= (int) ((double) tick / 60000d) * 60000;
+ str += String.format("%02d", (int) ((double) tick / 1000d)) + ".";
+
+ tick -= (int) ((double) tick / 1000d) * 1000;
+ str += String.format("%03d", tick);
+
+ return str;
+ }
+
+ public static String formatTime(String str) {
+ return tickToText(textToTick(str));
+ }
+
+ public static int transformZoom(long n, double zoom) {
+ return (int) ((double) n / (double) PatternJPanel.ZOOM_MULTIPLIER * zoom);
+ }
+}
diff --git a/VRGNYMusicLights/Sources/ApplicationJava/icons/Thumbs.db b/VRGNYMusicLights/Sources/ApplicationJava/icons/Thumbs.db
new file mode 100644
index 0000000..312f2e0
Binary files /dev/null and b/VRGNYMusicLights/Sources/ApplicationJava/icons/Thumbs.db differ
diff --git a/VRGNYMusicLights/Sources/ApplicationJava/icons/backward.png b/VRGNYMusicLights/Sources/ApplicationJava/icons/backward.png
new file mode 100644
index 0000000..afe80fa
Binary files /dev/null and b/VRGNYMusicLights/Sources/ApplicationJava/icons/backward.png differ
diff --git a/VRGNYMusicLights/Sources/ApplicationJava/icons/forward.png b/VRGNYMusicLights/Sources/ApplicationJava/icons/forward.png
new file mode 100644
index 0000000..d5a9a81
Binary files /dev/null and b/VRGNYMusicLights/Sources/ApplicationJava/icons/forward.png differ
diff --git a/VRGNYMusicLights/Sources/ApplicationJava/icons/pause.png b/VRGNYMusicLights/Sources/ApplicationJava/icons/pause.png
new file mode 100644
index 0000000..5cdd300
Binary files /dev/null and b/VRGNYMusicLights/Sources/ApplicationJava/icons/pause.png differ
diff --git a/VRGNYMusicLights/Sources/ApplicationJava/icons/play.png b/VRGNYMusicLights/Sources/ApplicationJava/icons/play.png
new file mode 100644
index 0000000..38c4f20
Binary files /dev/null and b/VRGNYMusicLights/Sources/ApplicationJava/icons/play.png differ
diff --git a/VRGNYMusicLights/Sources/ApplicationJava/icons/stop.png b/VRGNYMusicLights/Sources/ApplicationJava/icons/stop.png
new file mode 100644
index 0000000..9e5f9a2
Binary files /dev/null and b/VRGNYMusicLights/Sources/ApplicationJava/icons/stop.png differ
diff --git a/VRGNYMusicLights/Sources/Interface.java b/VRGNYMusicLights/Sources/Interface.java
deleted file mode 100644
index d3320b5..0000000
--- a/VRGNYMusicLights/Sources/Interface.java
+++ /dev/null
@@ -1,55 +0,0 @@
-import java.awt.BorderLayout;
-import java.awt.event.WindowAdapter;
-import java.awt.event.WindowEvent;
-
-import javax.swing.JFrame;
-import javax.swing.JPanel;
-
-public class Interface extends JFrame{
- private static final long serialVersionUID = 1L;
- //private static final Font titleFont = new Font(new JLabel().getFont().getName(), Font.BOLD, 14);
- //private static final Font defaultFont = new Font(new JLabel().getFont().getName(), Font.PLAIN, new JLabel().getFont().getSize());
-
- protected MusicList musicList;
- protected AnimationPlayer animPlayer;
- protected TimeLineJPanel timeLinePanel;
- protected TimeLineJList timeLineList;
- protected LightCanvasJPanel lightCanvas;
- protected long tick = 0;
-
- public Interface(MusicList musicList, final Runnable executeOnClose) {
- super("VRGNYMusicLights");
- this.musicList = musicList;
- setResizable(false);
- populateWindow();
- pack();
- setLocationRelativeTo(null); // center window
- getContentPane().requestFocus();
-
- addWindowListener(new WindowAdapter() {
- @Override
- public void windowClosing(WindowEvent e) {
- if(animPlayer != null)
- animPlayer.stopTickClock();
- if(executeOnClose != null)
- executeOnClose.run();
- dispose();
- }
- });
- }
-
- protected void computeTick() {
- lightCanvas.paintLights(musicList.render(tick));
- timeLineList.repaint();
- timeLinePanel.updateTick();
- }
-
- private void populateWindow() {
- JPanel mainPanel = new JPanel(new BorderLayout());
- timeLinePanel = new TimeLineJPanel(this, musicList);
- mainPanel.add(timeLinePanel, BorderLayout.CENTER);
- lightCanvas = new LightCanvasJPanel();
- mainPanel.add(new PlayJPanel(this, lightCanvas), BorderLayout.SOUTH);
- add(mainPanel);
- }
-}
diff --git a/VRGNYMusicLights/Sources/InvalidPatternException.java b/VRGNYMusicLights/Sources/InvalidPatternException.java
deleted file mode 100644
index 9668ca1..0000000
--- a/VRGNYMusicLights/Sources/InvalidPatternException.java
+++ /dev/null
@@ -1,8 +0,0 @@
-
-public class InvalidPatternException extends RuntimeException {
- private static final long serialVersionUID = 1L;
-
- public InvalidPatternException() {
- super("Invalid pattern given. Length must be equal to 5.");
- }
-}
diff --git a/VRGNYMusicLights/Sources/LightCanvasJPanel.java b/VRGNYMusicLights/Sources/LightCanvasJPanel.java
deleted file mode 100644
index 3debfbb..0000000
--- a/VRGNYMusicLights/Sources/LightCanvasJPanel.java
+++ /dev/null
@@ -1,63 +0,0 @@
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.Graphics;
-
-import javax.swing.JPanel;
-
-public class LightCanvasJPanel extends JPanel {
- private static final long serialVersionUID = 1L;
- private static final int WIDTH = 320; // = 300 + padding * 2
- private static final int HEIGHT = 220; // = 200 + padding * 2
- private static final int LIGHT_RADIUS = 4;
- private static final int PADDING = 10;
- private double[][] lightsCoords;
- private double[] lights = null;
-
- public LightCanvasJPanel() { this(MusicPath.LIGHT_COORDS); }
- public LightCanvasJPanel(double[][] lightsCoords) {
- this.lightsCoords = lightsCoords;
- setPreferredSize(new Dimension(WIDTH, HEIGHT));
- }
-
- public void paintLights(double[] lights) {
- this.lights = lights;
- repaint();
- }
-
- @Override
- protected void paintComponent(Graphics g) {
- super.paintComponent(g);
-
- // background
- g.setColor(Color.WHITE);
- g.fillRect(0, 0, WIDTH, HEIGHT);
-
- // lights
- if(lightsCoords == null) return;
- g.setColor(Color.BLACK);
- for(double[] light : lightsCoords) {
- if(light.length != 2)
- throw new MalformedCoordinates();
- int centerX = (int) (light[0] * (WIDTH - PADDING * 2)) + PADDING;
- int centerY = (int) (light[1] * (HEIGHT - PADDING * 2)) + PADDING;
-
- g.fillOval(centerX - LIGHT_RADIUS, centerY - LIGHT_RADIUS, LIGHT_RADIUS * 2, LIGHT_RADIUS * 2);
- }
-
- // lights values
- if(lights == null || lights.length != lightsCoords.length)
- return;
- g.setColor(Color.YELLOW);
- for(int i=0; i musics;
- private SerialCom serialCom;
-
- public MusicList(SerialCom serialCom) {
- this.serialCom = serialCom;
- musics = new ArrayList<>();
- }
-
- public ArrayList getList() { return musics; }
- public void addMusic(Music music) { musics.add(music); }
- public void deleteMusic(int index) { musics.remove(index); }
-
- public double[] render(long tick) {
- if(musics.size() == 0)
- return null;
- double[] lights = musics.get(0).render(tick);
- for(int i=1; i 1)
- lights[j] = 1;
- }
- }
- return lights;
- }
-}
diff --git a/VRGNYMusicLights/Sources/MusicPath.java b/VRGNYMusicLights/Sources/MusicPath.java
deleted file mode 100644
index 6c1c903..0000000
--- a/VRGNYMusicLights/Sources/MusicPath.java
+++ /dev/null
@@ -1,128 +0,0 @@
-
-public class MusicPath {
- public static final double[][] LIGHT_COORDS = new double[][] {
- // Planche 1
- {0.0383, 0}, {0.0766, 0}, {0.115, 0}, {0.1533, 0}, {0.1916, 0}, {0.23, 0}, //M1L1
- {0.2683, 0}, {0.306, 0}, {0.345, 0}, {0.383, 0}, {0.4216, 0}, {0.46, 0}, {0.4983, 0}, //M1L2
- {0.0333, 0.25}, {0.0666, 0.25}, {0.0999, 0.25}, {0.1333, 0.25}, //P1-1
- {0.3016, 0.25}, {0.3366, 0.25}, {0.3733, 0.25}, {0.4099, 0.25}, {0.4466, 0.25}, {0.4833, 0.25}, {0.5199, 0.25}, //P1-2
- {0.3366, 0.3}, {0.3366, 0.35}, //P1-3
- {0, 0.3075}, {0, 0.365}, {0, 0.4225}, //M1l1
-
- // Planche 2
- {0.5366, 0}, {0.575, 0}, {0.6133, 0}, {0.6516, 0}, {0.69, 0}, {0.7283, 0}, {0.7666, 0}, //M2L1
- {0.805, 0}, {0.8433, 0}, {0.8816, 0}, {0.92, 0}, {0.9583, 0}, //M2L2
- {0.5566, 0.25}, {0.5933, 0.25}, {0.6299, 0.25}, {0.6666, 0.25}, //P2-1
- {0.8366, 0.25}, {0.8699, 0.25}, {0.9032, 0.25}, {0.9366, 0.25}, {0.9699, 0.25}, //P2-2
- {1, 0.06}, {1, 0.115}, {1, 0.17}, {1, 0.225}, {1, 0.28}, {1, 0.335}, {1, 0.39}, //M2l1
-
- // Planche 3
- {0.3366, 0.4}, {0.3366, 0.45}, {0.3366, 0.5}, //P3-1
- {0.3366, 0.75}, {0.3366, 0.8}, //P3-2
- {0, 0.48}, {0, 0.5375}, {0, 0.595}, {0, 0.6525}, {0, 0.71}, {0, 0.7675}, //M3l1
-
- // Planche 4
- {1, 0.445}, {1, 0.5}, {1, 0.555}, {1, 0.61}, {1, 0.665}, {1, 0.72}, {1, 0.775}, //M4l1
-
- // Planche 5
- {0.0383, 1}, {0.0766, 1}, {0.115, 1}, {0.1533, 1}, {0.1916, 1}, {0.23, 1}, //M5L1
- {0.2683, 1}, {0.306, 1}, {0.345, 1}, {0.383, 1}, {0.4216, 1}, {0.46, 1}, {0.4983, 1}, //M5L2
- {0.3366, 0.85}, {0.3366, 0.9}, {0.3366, 0.95}, //P5-1
- {0, 0.8255}, {0, 0.8835}, {0, 0.9415}, //M5l1
-
- // Planche 6
- {0.5366, 1}, {0.575, 1}, {0.6133, 1}, {0.6516, 1}, {0.69, 1}, {0.7283, 1}, {0.7666, 1}, //M6L1
- {0.805, 1}, {0.8433, 1}, {0.8816, 1}, {0.92, 1}, {0.9583, 1}, //M6L2
- {1, 0.83}, {1, 0.885}, {1, 0.94} //M6l1
- };
-
- public static final int VERTICAL_DOWN = 0;
- public static final int VERTICAL_UP = 1;
- public static final int HORIZONTAL_TO_LEFT = 2;
- public static final int HORIZONTAL_TO_RIGHT = 3;
- public static final int DIAGONAL_TOP_RIGHT_DOWN_LEFT = 4;
- public static final int DIAGONAL_DOWN_LEFT_TOP_RIGHT = 5;
- public static final int DIAGONAL_TOP_LEFT_DOWN_RIGHT = 6;
- public static final int DIAGONAL_DOWN_RIGHT_TOP_LEFT = 7;
- public static final int CENTER_OUT = 8;
- public static final int CENTER_IN = 9;
- public static final int ALL = 10;
-
- private int animation;
- private int effectDuration;
- private double[][] lightsCoords;
-
- public MusicPath(int animation, int effectDuration) { this(animation, effectDuration, LIGHT_COORDS); }
- public MusicPath(int animation, int effectDuration, double[][] lightsCoords) {
- this.animation = animation;
- this.effectDuration = effectDuration;
- this.lightsCoords = lightsCoords;
- }
-
- public int[] calculateTickDelais() { // tick in ms
- int[] ticksDelais = new int[lightsCoords.length];
- for(int i=0; i= stop)
- return 0;
- int tickMod = (int) (tick % totalLength);
- if(tickMod < patternTiming[0])
- return 0;
- if(tickMod < patternTiming[1])
- return (double) (tickMod - patternTiming[0]) / (double) (pattern[1]);
- if(tickMod < patternTiming[2])
- return 1;
- if(tickMod < patternTiming[3])
- return 1 - ((double) (tickMod - patternTiming[2]) / (double) (pattern[3]));
- return 0;
- }
-}
diff --git a/VRGNYMusicLights/Sources/MusicRenderer.java b/VRGNYMusicLights/Sources/MusicRenderer.java
deleted file mode 100644
index d56e039..0000000
--- a/VRGNYMusicLights/Sources/MusicRenderer.java
+++ /dev/null
@@ -1,54 +0,0 @@
-import java.awt.Color;
-import java.awt.Component;
-import java.util.ArrayList;
-
-import javax.swing.Box;
-import javax.swing.BoxLayout;
-import javax.swing.JLabel;
-import javax.swing.JList;
-import javax.swing.JPanel;
-import javax.swing.ListCellRenderer;
-
-public class MusicRenderer extends JPanel implements ListCellRenderer {
- private static final long serialVersionUID = 1L;
- private static final Color DEFAULT_BACKGROUND = new JPanel().getBackground();
-
- private TimeLineJPanel timeLine;
-
- public ArrayList patterns;
-
- public MusicRenderer(TimeLineJPanel timeLine) {
- this.timeLine = timeLine;
- this.patterns = new ArrayList<>();
- }
-
- @Override
- public Component getListCellRendererComponent(JList extends Music> list, Music music, int index,
- boolean isSelected, boolean cellHasFocus) {
- removeAll();
-
- if(isSelected) {
- setBackground(Color.LIGHT_GRAY);
- } else {
- setBackground(DEFAULT_BACKGROUND);
- }
-
- setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
-
- JPanel infoPanel = new JPanel();
- infoPanel.setLayout(new BoxLayout(infoPanel, BoxLayout.LINE_AXIS));
- infoPanel.add(new JLabel("Pattern " + String.valueOf(index) + " :"));
- //TODO rigid area to follow scroll ?
- infoPanel.add(Box.createHorizontalGlue());
- add(infoPanel);
-
- PatternJPanel pattern = new PatternJPanel(music, timeLine);
- if(patterns.size() > index)
- patterns.set(index, pattern);
- else
- patterns.add(pattern);
- add(pattern);
-
- return this;
- }
-}
diff --git a/VRGNYMusicLights/Sources/NoSerialPortException.java b/VRGNYMusicLights/Sources/NoSerialPortException.java
deleted file mode 100644
index c29ea0c..0000000
--- a/VRGNYMusicLights/Sources/NoSerialPortException.java
+++ /dev/null
@@ -1,8 +0,0 @@
-
-public class NoSerialPortException extends Exception {
- private static final long serialVersionUID = 1L;
-
- public NoSerialPortException() {
- super("No serial port available !");
- }
-}
diff --git a/VRGNYMusicLights/Sources/PatternJPanel.java b/VRGNYMusicLights/Sources/PatternJPanel.java
deleted file mode 100644
index 52ae221..0000000
--- a/VRGNYMusicLights/Sources/PatternJPanel.java
+++ /dev/null
@@ -1,63 +0,0 @@
-import java.awt.Color;
-import java.awt.Dimension;
-import java.awt.Graphics;
-
-import javax.swing.JPanel;
-
-public class PatternJPanel extends JPanel {
- private static final long serialVersionUID = 1L;
- private static final int HEIGHT = 50;
- private static final int PADDING = 2;
- public static final int ZOOM_MULTIPLIER = 10;
-
- private Music music;
- private TimeLineJPanel timeLine;
- private int end;
-
- public PatternJPanel(Music music, TimeLineJPanel timeLine) {
- this.music = music;
- this.timeLine = timeLine;
- end = transformZoon(music.getMusicPattern().getStop());
- setPreferredSize(new Dimension((int) end, HEIGHT));
- }
-
- public void refreshPreferedSize() {
- end = transformZoon(music.getMusicPattern().getStop());
- setPreferredSize(new Dimension((int) end, HEIGHT));
- }
-
- public int getEnd() { return end; }
- public Music getMusic() { return music; }
-
- @Override
- protected void paintComponent(Graphics g) {
- super.paintComponent(g);
-
- g.setColor(Color.WHITE);
- int begin = transformZoon(music.getMusicPattern().getBegin());
- g.fillRect(begin, 0, end, HEIGHT);
-
- MusicPattern pattern = music.getMusicPattern();
- g.setColor(Color.BLACK);
- for(int i=0; i portEnum = CommPortIdentifier.getPortIdentifiers();
-
- // Search for serial port
- while (portEnum.hasMoreElements()) {
- CommPortIdentifier currPortId = (CommPortIdentifier) portEnum.nextElement();
- if (currPortId.getName().equals(portName)) {
- portId = currPortId;
- break;
- }
- }
- if (portId == null)
- throw new SerialComPortException(portName);
-
- // open connection
- try {
- serialPort = (SerialPort) portId.open(this.getClass().getName(), TIME_OUT);
- serialPort.setSerialPortParams(DATA_RATE, SerialPort.DATABITS_8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
-
- input = serialPort.getInputStream();
- output = serialPort.getOutputStream();
- } catch (IOException
- | UnsupportedCommOperationException
- | PortInUseException e) {
- throw new SerialComPortException(portName);
- }
- }
-
- public void close() {
- try {
- input.close();
- output.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- serialPort.removeEventListener();
- serialPort.close();
- }
- public void send(byte[] bytes) {
- try {
- this.output.write(bytes);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
-
- public byte[] recieve() {
- byte[] buffer = new byte[BUFFER_SIZE];
- int len = -1;
-
- try { len = this.input.read(buffer); }
- catch (IOException e) { return null; }
-
- if(len == -1 || len == 0)
- return null;
- byte[] data = new byte[len];
- for(int i=0; i portNames;
- private String choosedPort = null;
-
- private JList list;
- private JButton ok;
- private JButton cancel;
-
- private SerialPortChooserDialog() {
- Enumeration> portEnum = CommPortIdentifier.getPortIdentifiers();
- portNames = new ArrayList<>();
-
- while (portEnum.hasMoreElements()) {
- CommPortIdentifier currPortId = (CommPortIdentifier) portEnum.nextElement();
- portNames.add(currPortId.getName());
- }
-
- onlyOneChoice = portNames.size() <= 1;
- emptyChoice = portNames.size() == 0;
- if(onlyOneChoice || emptyChoice)
- return;
-
- // JDialog creation
- JPanel mainPanel = new JPanel(new BorderLayout());
- setModal(true);
- setTitle("Serial port chooser");
-
- // title
- mainPanel.add(new JLabel("Choose a serial port : "), BorderLayout.NORTH);
-
- // list ports
- DefaultListModel listModel = new DefaultListModel<>();
- for(String str : portNames)
- listModel.addElement(str);
- list = new JList<>(listModel);
- list.addListSelectionListener(this);
- list.setVisibleRowCount(3);
- list.setLayoutOrientation(JList.VERTICAL);
- list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
-
- JScrollPane scrollPane = new JScrollPane(list, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
- scrollPane.setPreferredSize(new Dimension(200, 100));
- mainPanel.add(scrollPane, BorderLayout.CENTER);
-
- // buttons ok / cancel
- JPanel borderLayoutPanel = new JPanel(new BorderLayout());
- JPanel buttonsLayout = new JPanel(new FlowLayout(FlowLayout.LEADING, 5, 3));
- ok = new JButton("Ok");
- cancel = new JButton("Cancel");
- ok.addActionListener(this);
- cancel.addActionListener(this);
- ok.setEnabled(false);
- buttonsLayout.add(cancel);
- buttonsLayout.add(ok);
- borderLayoutPanel.add(buttonsLayout, BorderLayout.EAST);
- mainPanel.add(borderLayoutPanel, BorderLayout.SOUTH);
-
- // padding
- JPanel padding = new JPanel(new FlowLayout(FlowLayout.LEADING, 5, 5));
- padding.add(mainPanel);
- add(padding);
-
- setResizable(false);
- pack();
- setLocationRelativeTo(null);
- setVisible(true);
- }
-
- public static String showSerialPortChooserDialog() throws NoSerialPortException {
- SerialPortChooserDialog dialog = new SerialPortChooserDialog();
- if(dialog.emptyChoice)
- throw new NoSerialPortException();
- if(dialog.onlyOneChoice)
- return dialog.portNames.get(0);
- return dialog.choosedPort;
- }
-
- @Override
- public void actionPerformed(ActionEvent e) {
- if(e.getSource() == ok) {
- choosedPort = list.getSelectedValue();
- dispose();
- } else if(e.getSource() == cancel) {
- dispose();
- }
- }
-
- @Override
- public void valueChanged(ListSelectionEvent e) {
- if(e.getSource() == list) {
- ok.setEnabled(list.getSelectedIndex() != -1);
- }
- }
-}
diff --git a/VRGNYMusicLights/Sources/TimeLineJList.java b/VRGNYMusicLights/Sources/TimeLineJList.java
deleted file mode 100644
index e9d05bd..0000000
--- a/VRGNYMusicLights/Sources/TimeLineJList.java
+++ /dev/null
@@ -1,36 +0,0 @@
-import java.awt.Color;
-import java.awt.Graphics;
-
-import javax.swing.JList;
-import javax.swing.ListModel;
-
-public class TimeLineJList extends JList {
- private static final long serialVersionUID = 1L;
- private static final int MARK_WIDTH = 2;
-
- private Interface interf;
-
- public TimeLineJList(ListModel dataModel, Interface interf) {
- super(dataModel);
- this.interf = interf;
- }
-
- @Override
- protected void paintComponent(Graphics g) {
- super.paintComponent(g);
- g.setColor(Color.BLACK);
-
- int maxHeight = getPreferredSize().height;
- int maxWidth = getPreferredSize().width;
-
- int mark = transformZoon(interf.tick);
- if(mark > maxWidth)
- mark = maxWidth;
-
- g.fillRect(mark, 0, MARK_WIDTH, maxHeight);
- }
-
- private int transformZoon(long n) {
- return (int) ((double) n / (double) PatternJPanel.ZOOM_MULTIPLIER * interf.timeLinePanel.getZoomLevel());
- }
-}
diff --git a/VRGNYMusicLights/Sources/TimeLineJPanel.java b/VRGNYMusicLights/Sources/TimeLineJPanel.java
deleted file mode 100644
index dbb0f13..0000000
--- a/VRGNYMusicLights/Sources/TimeLineJPanel.java
+++ /dev/null
@@ -1,146 +0,0 @@
-import java.awt.Dimension;
-import java.awt.Font;
-import java.awt.event.ActionEvent;
-import java.awt.event.ActionListener;
-import java.awt.event.FocusEvent;
-import java.awt.event.FocusListener;
-import java.awt.event.MouseWheelEvent;
-import java.awt.event.MouseWheelListener;
-
-import javax.swing.Box;
-import javax.swing.BoxLayout;
-import javax.swing.DefaultListModel;
-import javax.swing.JLabel;
-import javax.swing.JPanel;
-import javax.swing.JScrollBar;
-import javax.swing.JScrollPane;
-import javax.swing.JTextField;
-import javax.swing.ListSelectionModel;
-
-public class TimeLineJPanel extends JPanel implements MouseWheelListener, FocusListener, ActionListener {
- private static final long serialVersionUID = 1L;
- private static final Font titleFont = new Font(new JLabel().getFont().getName(), Font.BOLD, 14);
-
- private static final int SCROLL_SPEED_HORIZONTAL = 30;
- private static final int SCROLL_SPEED_VERTICAL = 30;
-
- private DefaultListModel listModel;
- private double zoomLevel = 1;
-
- private JScrollPane scrollPane;
- private MusicRenderer musicRenderer;
- private Interface interf;
- private JTextField currentTick;
- private JLabel maxTicks;
-
- public TimeLineJPanel(Interface interf, MusicList list) {
- this.interf = interf;
- setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
-
- // timing infos
- JPanel timingPanel = new JPanel();
- timingPanel.setLayout(new BoxLayout(timingPanel, BoxLayout.LINE_AXIS));
-
- JLabel title = new JLabel("Timeline : ");
- title.setFont(titleFont);
- timingPanel.add(title);
-
- currentTick = new JTextField("00:00.000", 8);
- currentTick.setMaximumSize( currentTick.getPreferredSize() );
- currentTick.addFocusListener(this);
- currentTick.addActionListener(this);
- timingPanel.add(currentTick);
-
- maxTicks = new JLabel(" / 00:00.0000 (MM:ss:ms)");
- timingPanel.add(maxTicks);
-
- timingPanel.add(Box.createHorizontalGlue());
-
- add(timingPanel);
-
- // timeline
-
- listModel = new DefaultListModel<>();
- for(Music music : list.getList())
- listModel.addElement(music);
-
- interf.timeLineList = new TimeLineJList(listModel, interf);
- musicRenderer = new MusicRenderer(this);
- interf.timeLineList.setCellRenderer(musicRenderer);
- interf.timeLineList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
- scrollPane = new JScrollPane(interf.timeLineList, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
- scrollPane.addMouseWheelListener(this);
- scrollPane.setWheelScrollingEnabled(false);
- scrollPane.setPreferredSize(new Dimension(800, 400));
- add(scrollPane);
- }
-
- public double getZoomLevel() { return zoomLevel; }
-
- public void updateList(MusicList list) {
- listModel.clear();
- for(Music music : list.getList())
- listModel.addElement(music);
- }
-
- public void updateTick() {
- currentTick.setText(Util.tickToText(interf.tick));
- long maxTick = 0;
- for(PatternJPanel pattern : musicRenderer.patterns) {
- pattern.refreshPreferedSize();
- long tick = pattern.getMusic().getMusicPattern().getStop();
- if(tick > maxTick)
- maxTick = tick;
- }
- maxTicks.setText(Util.tickToText(maxTick) + " (MM:ss:ms)");
- }
-
- public void mouseWheelMoved(MouseWheelEvent e) {
- if(e.getSource() == scrollPane) {
- if (e.isControlDown()) {
- if(e.getWheelRotation() < 0)
- zoomLevel *= (double) e.getWheelRotation() * -1.1;
- else
- zoomLevel *= (double) e.getWheelRotation() / 1.1;
-
- int maxWidth = 0;
- for(PatternJPanel pattern : musicRenderer.patterns) {
- pattern.refreshPreferedSize();
- int width = pattern.getEnd();
- if(width > maxWidth)
- maxWidth = width;
- }
-
- interf.timeLineList.setPreferredSize(new Dimension(maxWidth, interf.getPreferredSize().height));
- scrollPane.repaint();
- scrollPane.getViewport().revalidate();
- } else if(e.isShiftDown()) {
- JScrollBar sb = scrollPane.getHorizontalScrollBar();
- sb.setValue(sb.getValue() + e.getWheelRotation() * SCROLL_SPEED_HORIZONTAL);
- } else {
- JScrollBar sb = scrollPane.getVerticalScrollBar();
- sb.setValue(sb.getValue() + e.getWheelRotation() * SCROLL_SPEED_VERTICAL);
- }
- }
- }
-
- @Override
- public void focusLost(FocusEvent e) {
- if(e.getSource() == currentTick) {
- interf.tick = Util.textToTick(currentTick.getText());
- currentTick.setText(Util.tickToText(interf.tick));
- interf.computeTick();
- }
- }
- @Override
- public void focusGained(FocusEvent e) {
- if(e.getSource() == currentTick)
- currentTick.setCaretPosition(currentTick.getDocument().getLength());
- }
-
- @Override
- public void actionPerformed(ActionEvent e) {
- if(e.getSource() == currentTick)
- interf.getContentPane().requestFocus();
- }
-}
diff --git a/VRGNYMusicLights/Sources/Util.java b/VRGNYMusicLights/Sources/Util.java
deleted file mode 100644
index a687340..0000000
--- a/VRGNYMusicLights/Sources/Util.java
+++ /dev/null
@@ -1,46 +0,0 @@
-
-public class Util {
- public static long textToTick(String str) {
- if(str == null || str.equals(""))
- return 0;
- String[] strs = str.split(":|\\.");
- long ticks = 0;
-
- try {
- switch (strs.length) {
- case 1:
- ticks += Integer.parseInt(strs[0]);
- break;
- case 2:
- ticks += Integer.parseInt(strs[1]);
- ticks += Integer.parseInt(strs[0]) * 1000;
- break;
- case 3:
- ticks += Integer.parseInt(strs[2]);
- ticks += Integer.parseInt(strs[1]) * 1000;
- ticks += Integer.parseInt(strs[0]) * 60000;
- break;
- }
- } catch (NumberFormatException e) {
- return 0;
- }
- return ticks;
- }
-
- public static String tickToText(long tick) {
- String str = "";
-
- if(tick > 5900000)
- str += "99:";
- else
- str += String.format("%02d", (int) ((double) tick / 60000d)) + ":";
-
- tick -= (int) ((double) tick / 60000d) * 60000;
- str += String.format("%02d", (int) ((double) tick / 1000d)) + ".";
-
- tick -= (int) ((double) tick / 1000d) * 1000;
- str += String.format("%03d", tick);
-
- return str;
- }
-}
diff --git a/VRGNYMusicLights/Sources/icons/backward.png b/VRGNYMusicLights/Sources/icons/backward.png
deleted file mode 100644
index afe80fa..0000000
Binary files a/VRGNYMusicLights/Sources/icons/backward.png and /dev/null differ
diff --git a/VRGNYMusicLights/Sources/icons/forward.png b/VRGNYMusicLights/Sources/icons/forward.png
deleted file mode 100644
index d5a9a81..0000000
Binary files a/VRGNYMusicLights/Sources/icons/forward.png and /dev/null differ
diff --git a/VRGNYMusicLights/Sources/icons/pause.png b/VRGNYMusicLights/Sources/icons/pause.png
deleted file mode 100644
index 5cdd300..0000000
Binary files a/VRGNYMusicLights/Sources/icons/pause.png and /dev/null differ
diff --git a/VRGNYMusicLights/Sources/icons/play.png b/VRGNYMusicLights/Sources/icons/play.png
deleted file mode 100644
index 38c4f20..0000000
Binary files a/VRGNYMusicLights/Sources/icons/play.png and /dev/null differ
diff --git a/VRGNYMusicLights/Sources/icons/stop.png b/VRGNYMusicLights/Sources/icons/stop.png
deleted file mode 100644
index 9e5f9a2..0000000
Binary files a/VRGNYMusicLights/Sources/icons/stop.png and /dev/null differ
--
libgit2 0.21.2