Commit d175ba5513176028c75d5a51711a9394e811a89b

Authored by pfrison
1 parent bd56dbdb

VRGNYMusicLight application java presque finie

Showing 32 changed files with 791 additions and 92 deletions   Show diff stats
VRGNYMusicLights/Sources/AnimationPlayer.java renamed to VRGNYMusicLights/Sources/ApplicationJava/AnimationPlayer.java
VRGNYMusicLights/Sources/ApplicationJava/CommandJPanel.java 0 → 100644
@@ -0,0 +1,95 @@ @@ -0,0 +1,95 @@
  1 +import java.awt.Color;
  2 +import java.awt.Font;
  3 +import java.awt.event.ActionEvent;
  4 +import java.awt.event.ActionListener;
  5 +
  6 +import javax.swing.BorderFactory;
  7 +import javax.swing.BoxLayout;
  8 +import javax.swing.JButton;
  9 +import javax.swing.JLabel;
  10 +import javax.swing.JPanel;
  11 +
  12 +public class CommandJPanel extends JPanel implements ActionListener {
  13 + private static final long serialVersionUID = 1L;
  14 + private static final Font titleFont = new Font(new JLabel().getFont().getName(), Font.BOLD, 14);
  15 +
  16 + private JButton addPattern;
  17 + private JButton editPattern;
  18 + private JButton removePattern;
  19 + private JButton exports;
  20 + private JButton imports;
  21 +
  22 + private Interface interf;
  23 +
  24 + public CommandJPanel(Interface interf) {
  25 + this.interf = interf;
  26 + setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
  27 + setBorder(BorderFactory.createMatteBorder(0, 4, 0, 0, Color.LIGHT_GRAY));
  28 +
  29 + // Title
  30 +
  31 + JLabel title = new JLabel("Commands :");
  32 + title.setFont(titleFont);
  33 + add(title);
  34 +
  35 + // Buttons
  36 +
  37 + addPattern = new JButton("Add pattern");
  38 + editPattern = new JButton("Edit pattern");
  39 + removePattern = new JButton("Remove pattern");
  40 + exports = new JButton("Export");
  41 + imports = new JButton("Import");
  42 +
  43 + addPattern.setMaximumSize(removePattern.getMaximumSize());
  44 + editPattern.setMaximumSize(removePattern.getMaximumSize());
  45 + exports.setMaximumSize(removePattern.getMaximumSize());
  46 + imports.setMaximumSize(removePattern.getMaximumSize());
  47 +
  48 + addPattern.addActionListener(this);
  49 + editPattern.addActionListener(this);
  50 + removePattern.addActionListener(this);
  51 + exports.addActionListener(this);
  52 + imports.addActionListener(this);
  53 +
  54 + add(addPattern);
  55 + add(editPattern);
  56 + add(removePattern);
  57 + add(exports);
  58 + add(imports);
  59 + }
  60 +
  61 + @Override
  62 + public void actionPerformed(ActionEvent e) {
  63 + if(e.getSource() == addPattern) {
  64 + PatternEditorJDialog dialog = new PatternEditorJDialog(interf);
  65 + Music music = dialog.showDialog();
  66 + if(music == null)
  67 + return;
  68 + interf.musicList.addMusic(music);
  69 + interf.timeLinePanel.updateList();
  70 + } else if(e.getSource() == editPattern) {
  71 + int index = interf.timeLineList.getSelectedIndex();
  72 + if(index == -1)
  73 + return;
  74 + PatternEditorJDialog dialog = new PatternEditorJDialog(interf, interf.musicList.getList().get(index));
  75 + Music music = dialog.showDialog();
  76 + if(music == null)
  77 + return;
  78 + interf.musicList.setMusicAt(index, music);
  79 + interf.timeLinePanel.updateList();
  80 + } else if(e.getSource() == removePattern) {
  81 + int index = interf.timeLineList.getSelectedIndex();
  82 + if(index == -1)
  83 + return;
  84 + interf.musicList.deleteMusic(index);
  85 + interf.timeLinePanel.updateList();
  86 + } else if(e.getSource() == exports) {
  87 + ImportExport.exportWithDialog(interf.musicList);
  88 + } else if(e.getSource() == imports) {
  89 + MusicList newActionList = ImportExport.importsWithDialog();
  90 + if(newActionList != null)
  91 + interf.musicList = newActionList;
  92 + interf.timeLinePanel.updateList();
  93 + }
  94 + }
  95 +}
VRGNYMusicLights/Sources/ApplicationJava/CustomSliderUI.java 0 → 100644
@@ -0,0 +1,151 @@ @@ -0,0 +1,151 @@
  1 +import java.awt.BasicStroke;
  2 +import java.awt.Color;
  3 +import java.awt.Dimension;
  4 +import java.awt.Graphics;
  5 +import java.awt.Graphics2D;
  6 +import java.awt.Rectangle;
  7 +import java.awt.RenderingHints;
  8 +import java.awt.Shape;
  9 +import java.awt.Stroke;
  10 +import java.awt.geom.Ellipse2D;
  11 +
  12 +import javax.swing.JComponent;
  13 +import javax.swing.JSlider;
  14 +import javax.swing.SwingConstants;
  15 +import javax.swing.plaf.ComponentUI;
  16 +import javax.swing.plaf.basic.BasicSliderUI;
  17 +
  18 +public class CustomSliderUI extends BasicSliderUI {
  19 + private final BasicStroke stroke = new BasicStroke(2f);
  20 + private JSlider slider;
  21 +
  22 + public CustomSliderUI(JSlider b) {
  23 + super(b);
  24 + this.slider = b;
  25 + }
  26 +
  27 + public static ComponentUI createUI(JComponent c) {
  28 + return new CustomSliderUI((JSlider)c);
  29 + }
  30 +
  31 +
  32 + @Override
  33 + protected void calculateThumbSize() {
  34 + super.calculateThumbSize();
  35 + thumbRect.setSize(thumbRect.width, thumbRect.height);
  36 + }
  37 +
  38 + /** Creates a listener to handle track events in the specified slider.*/
  39 + @Override
  40 + protected TrackListener createTrackListener(JSlider slider) {
  41 + return new TrackListener();
  42 + }
  43 +
  44 +
  45 + @Override
  46 + protected void calculateThumbLocation() {
  47 + // Call superclass method for lower thumb location.
  48 + super.calculateThumbLocation();
  49 +
  50 + // Adjust upper value to snap to ticks if necessary.
  51 + if (slider.getSnapToTicks()) {
  52 + int upperValue = slider.getValue() + slider.getExtent();
  53 + int snappedValue = upperValue;
  54 + int majorTickSpacing = slider.getMajorTickSpacing();
  55 + int minorTickSpacing = slider.getMinorTickSpacing();
  56 + int tickSpacing = 0;
  57 +
  58 + if (minorTickSpacing > 0) {
  59 + tickSpacing = minorTickSpacing;
  60 + } else if (majorTickSpacing > 0) {
  61 + tickSpacing = majorTickSpacing;
  62 + }
  63 +
  64 + if (tickSpacing != 0) {
  65 + // If it's not on a tick, change the value
  66 + if ((upperValue - slider.getMinimum()) % tickSpacing != 0) {
  67 + float temp = (float)(upperValue - slider.getMinimum()) / (float)tickSpacing;
  68 + int whichTick = Math.round(temp);
  69 + snappedValue = slider.getMinimum() + (whichTick * tickSpacing);
  70 + }
  71 +
  72 + if (snappedValue != upperValue) {
  73 + slider.setExtent(snappedValue - slider.getValue());
  74 + }
  75 + }
  76 + }
  77 +
  78 + // Calculate upper thumb location. The thumb is centered over its
  79 + // value on the track.
  80 + if (slider.getOrientation() == JSlider.HORIZONTAL) {
  81 + int upperPosition = xPositionForValue(slider.getValue() + slider.getExtent());
  82 + thumbRect.x = upperPosition - (thumbRect.width / 2);
  83 + thumbRect.y = trackRect.y;
  84 +
  85 + } else {
  86 + int upperPosition = yPositionForValue(slider.getValue() + slider.getExtent());
  87 + thumbRect.x = trackRect.x;
  88 + thumbRect.y = upperPosition - (thumbRect.height / 2);
  89 + }
  90 + slider.repaint();
  91 + }
  92 +
  93 + /** Returns the size of a thumb.
  94 + * Parent method not use size from LaF
  95 + * @return size of trumb */
  96 + @Override
  97 + protected Dimension getThumbSize() {
  98 + return new Dimension(5, 10);
  99 + }
  100 +
  101 +
  102 + private Shape createThumbShape(int width, int height) {
  103 + Ellipse2D shape = new Ellipse2D.Double(0, 0, width, height);
  104 + return shape;
  105 + }
  106 +
  107 + @Override
  108 + public void paintTrack(Graphics g) {
  109 + Graphics2D g2d = (Graphics2D) g;
  110 + Stroke old = g2d.getStroke();
  111 + g2d.setStroke(stroke);
  112 + g2d.setPaint(slider.isEnabled() ? Color.LIGHT_GRAY : Color.WHITE);
  113 + Color oldColor = slider.isEnabled() ? Color.LIGHT_GRAY : Color.WHITE;
  114 + Rectangle trackBounds = trackRect;
  115 + if (slider.getOrientation() == SwingConstants.HORIZONTAL) {
  116 + g2d.drawLine(trackRect.x, trackRect.y + trackRect.height / 2,
  117 + trackRect.x + trackRect.width, trackRect.y + trackRect.height / 2);
  118 + int lowerX = thumbRect.width / 2;
  119 + int upperX = thumbRect.x + (thumbRect.width / 2);
  120 + int cy = (trackBounds.height / 2) - 2;
  121 + g2d.translate(trackBounds.x, trackBounds.y + cy);
  122 + g2d.setColor(slider.isEnabled() ? Color.BLACK : Color.LIGHT_GRAY);
  123 + g2d.drawLine(lowerX - trackBounds.x, 2, upperX - trackBounds.x, 2);
  124 + g2d.translate(-trackBounds.x, -(trackBounds.y + cy));
  125 + g2d.setColor(oldColor);
  126 + }
  127 + g2d.setStroke(old);
  128 + }
  129 +
  130 +
  131 +
  132 + /** Overrides superclass method to do nothing. Thumb painting is handled
  133 + * within the <code>paint()</code> method.*/
  134 + @Override
  135 + public void paintThumb(Graphics g) {
  136 + Rectangle knobBounds = thumbRect;
  137 + int w = knobBounds.width;
  138 + int h = knobBounds.height;
  139 + Graphics2D g2d = (Graphics2D) g.create();
  140 + Shape thumbShape = createThumbShape(w - 1, h - 1);
  141 + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
  142 + RenderingHints.VALUE_ANTIALIAS_ON);
  143 + g2d.translate(knobBounds.x, knobBounds.y);
  144 + g2d.setColor(slider.isEnabled() ? Color.LIGHT_GRAY : Color.WHITE);
  145 + g2d.fill(thumbShape);
  146 +
  147 + g2d.setColor(slider.isEnabled() ? Color.BLACK : Color.LIGHT_GRAY);
  148 + g2d.draw(thumbShape);
  149 + g2d.dispose();
  150 + }
  151 +}
0 \ No newline at end of file 152 \ No newline at end of file
VRGNYMusicLights/Sources/ApplicationJava/ImportExport.java 0 → 100644
@@ -0,0 +1,73 @@ @@ -0,0 +1,73 @@
  1 +import java.io.BufferedWriter;
  2 +import java.io.File;
  3 +import java.io.FileWriter;
  4 +import java.io.IOException;
  5 +import java.nio.charset.Charset;
  6 +import java.nio.file.Files;
  7 +import java.nio.file.Paths;
  8 +
  9 +import javax.swing.JFileChooser;
  10 +import javax.swing.JOptionPane;
  11 +import javax.swing.filechooser.FileNameExtensionFilter;
  12 +
  13 +public class ImportExport {
  14 + public static void exportWithDialog(MusicList list) {
  15 + JFileChooser chooser = new JFileChooser();
  16 + FileNameExtensionFilter filter = new FileNameExtensionFilter("Array data", "adata");
  17 + chooser.setFileFilter(filter);
  18 + chooser.setApproveButtonText("Exporter");
  19 + int returnVal = chooser.showOpenDialog(null);
  20 + if(returnVal == JFileChooser.APPROVE_OPTION)
  21 + export(list, chooser.getSelectedFile().getPath());
  22 + }
  23 + private static void export(MusicList list, String path) {
  24 + String str = "";//list.getLeftDeltaArray() + "\n" + list.getRightDeltaArray() + "\n" + list.getLeftDelaiArray() + "\n" + list.getRightDelaiArray();
  25 +
  26 + if(!path.endsWith(".adata"))
  27 + path += ".adata";
  28 + BufferedWriter bufferedWriter = null;
  29 + try {
  30 + File file = new File(path);
  31 + if (!file.exists())
  32 + file.createNewFile();
  33 + bufferedWriter = new BufferedWriter(new FileWriter(file));
  34 + bufferedWriter.write(str);
  35 + bufferedWriter.close();
  36 + } catch (IOException e) {
  37 + e.printStackTrace();
  38 + }
  39 + }
  40 +
  41 + public static MusicList importsWithDialog() {
  42 + JFileChooser chooser = new JFileChooser();
  43 + FileNameExtensionFilter filter = new FileNameExtensionFilter("Array data", "adata");
  44 + chooser.setFileFilter(filter);
  45 + chooser.setMultiSelectionEnabled(false);
  46 + chooser.setApproveButtonText("Importer");
  47 + int returnVal = chooser.showOpenDialog(null);
  48 + if(returnVal == JFileChooser.APPROVE_OPTION && chooser.getSelectedFile().exists() && chooser.getSelectedFile().isFile())
  49 + return imports(chooser.getSelectedFile().getPath());
  50 + if(returnVal == JFileChooser.APPROVE_OPTION)
  51 + JOptionPane.showMessageDialog(null, "You have to choose an exisiting file", "Import error", JOptionPane.ERROR_MESSAGE);
  52 + return null;
  53 + }
  54 + private static MusicList imports(String path) {
  55 + try {
  56 + byte[] encoded = Files.readAllBytes(Paths.get(path));
  57 + String str = new String(encoded, Charset.defaultCharset());
  58 +
  59 + //long[][] longList = Util.getArraysFromImport(str);
  60 + /*if(longList == null) {
  61 + JOptionPane.showMessageDialog(null, "The choosen file is invalid or currupted", "Import error", JOptionPane.ERROR_MESSAGE);
  62 + return null;
  63 + }
  64 + int[][] intList = new int[2][longList[0].length];
  65 + for(int i=0; i<2; i++)
  66 + for(int j=0; j<longList[0].length; j++)
  67 + intList[i][j] = (int) longList[i][j];
  68 +
  69 + return new MusicList(intList[0], intList[1], longList[2], longList[3]);*/
  70 + } catch (IOException ignored) {}
  71 + return null;
  72 + }
  73 +}
VRGNYMusicLights/Sources/Interface.java renamed to VRGNYMusicLights/Sources/ApplicationJava/Interface.java
1 import java.awt.BorderLayout; 1 import java.awt.BorderLayout;
  2 +import java.awt.Dimension;
2 import java.awt.event.WindowAdapter; 3 import java.awt.event.WindowAdapter;
3 import java.awt.event.WindowEvent; 4 import java.awt.event.WindowEvent;
4 5
5 import javax.swing.JFrame; 6 import javax.swing.JFrame;
6 import javax.swing.JPanel; 7 import javax.swing.JPanel;
  8 +import javax.swing.JSlider;
7 9
8 public class Interface extends JFrame{ 10 public class Interface extends JFrame{
9 private static final long serialVersionUID = 1L; 11 private static final long serialVersionUID = 1L;
@@ -15,14 +17,16 @@ public class Interface extends JFrame{ @@ -15,14 +17,16 @@ public class Interface extends JFrame{
15 protected TimeLineJPanel timeLinePanel; 17 protected TimeLineJPanel timeLinePanel;
16 protected TimeLineJList timeLineList; 18 protected TimeLineJList timeLineList;
17 protected LightCanvasJPanel lightCanvas; 19 protected LightCanvasJPanel lightCanvas;
  20 + protected JSlider timeSlider;
18 protected long tick = 0; 21 protected long tick = 0;
19 22
20 public Interface(MusicList musicList, final Runnable executeOnClose) { 23 public Interface(MusicList musicList, final Runnable executeOnClose) {
21 super("VRGNYMusicLights"); 24 super("VRGNYMusicLights");
22 this.musicList = musicList; 25 this.musicList = musicList;
23 - setResizable(false);  
24 populateWindow(); 26 populateWindow();
25 pack(); 27 pack();
  28 + setMinimumSize(new Dimension(600, 500));
  29 + setSize(new Dimension(800, 600));
26 setLocationRelativeTo(null); // center window 30 setLocationRelativeTo(null); // center window
27 getContentPane().requestFocus(); 31 getContentPane().requestFocus();
28 32
@@ -39,6 +43,7 @@ public class Interface extends JFrame{ @@ -39,6 +43,7 @@ public class Interface extends JFrame{
39 } 43 }
40 44
41 protected void computeTick() { 45 protected void computeTick() {
  46 + timeSlider.setValue((int) tick);
42 lightCanvas.paintLights(musicList.render(tick)); 47 lightCanvas.paintLights(musicList.render(tick));
43 timeLineList.repaint(); 48 timeLineList.repaint();
44 timeLinePanel.updateTick(); 49 timeLinePanel.updateTick();
@@ -46,10 +51,11 @@ public class Interface extends JFrame{ @@ -46,10 +51,11 @@ public class Interface extends JFrame{
46 51
47 private void populateWindow() { 52 private void populateWindow() {
48 JPanel mainPanel = new JPanel(new BorderLayout()); 53 JPanel mainPanel = new JPanel(new BorderLayout());
49 - timeLinePanel = new TimeLineJPanel(this, musicList); 54 + timeLinePanel = new TimeLineJPanel(this);
50 mainPanel.add(timeLinePanel, BorderLayout.CENTER); 55 mainPanel.add(timeLinePanel, BorderLayout.CENTER);
51 lightCanvas = new LightCanvasJPanel(); 56 lightCanvas = new LightCanvasJPanel();
52 mainPanel.add(new PlayJPanel(this, lightCanvas), BorderLayout.SOUTH); 57 mainPanel.add(new PlayJPanel(this, lightCanvas), BorderLayout.SOUTH);
  58 + mainPanel.add(new CommandJPanel(this), BorderLayout.EAST);
53 add(mainPanel); 59 add(mainPanel);
54 } 60 }
55 } 61 }
VRGNYMusicLights/Sources/InvalidPatternException.java renamed to VRGNYMusicLights/Sources/ApplicationJava/InvalidPatternException.java
VRGNYMusicLights/Sources/LightCanvasJPanel.java renamed to VRGNYMusicLights/Sources/ApplicationJava/LightCanvasJPanel.java
VRGNYMusicLights/Sources/Main.java renamed to VRGNYMusicLights/Sources/ApplicationJava/Main.java
@@ -3,6 +3,10 @@ import javax.swing.JOptionPane; @@ -3,6 +3,10 @@ import javax.swing.JOptionPane;
3 /* TODO list : 3 /* TODO list :
4 * - keyboard listener for animation player (play / pause = space, forward = semicolon, backward = comma, stop = backspace) 4 * - keyboard listener for animation player (play / pause = space, forward = semicolon, backward = comma, stop = backspace)
5 * - pattern timeline info to follow scroll horizontal ? 5 * - pattern timeline info to follow scroll horizontal ?
  6 + * - export / import
  7 + * - play on arduino button
  8 + * - slider update on edit / add / delete music
  9 + * - checkbox option to follow the tick mark when playing
6 */ 10 */
7 public class Main { 11 public class Main {
8 public static void main(String[] args) throws InterruptedException { 12 public static void main(String[] args) throws InterruptedException {
@@ -21,16 +25,16 @@ public class Main { @@ -21,16 +25,16 @@ public class Main {
21 Thread.sleep(1000);*/ 25 Thread.sleep(1000);*/
22 26
23 MusicList musicList = new MusicList(null); 27 MusicList musicList = new MusicList(null);
24 - musicList.addMusic( 28 + /*musicList.addMusic(
25 new Music( 29 new Music(
26 - new MusicPattern(new int[] {0, 10, 100, 10, 100}, 100, 1000),  
27 - new MusicPath(MusicPath.CENTER_OUT, 1000), 30 + new MusicPattern(new int[] {0, 10, 100, 10, 100}, 10, 1000),
  31 + new MusicPath(MusicPath.CENTER_IN, 1000),
28 1)); 32 1));
29 musicList.addMusic( 33 musicList.addMusic(
30 new Music( 34 new Music(
31 new MusicPattern(new int[] {0, 10, 100, 10, 100}, 1, 0), 35 new MusicPattern(new int[] {0, 10, 100, 10, 100}, 1, 0),
32 new MusicPath(MusicPath.CENTER_OUT, 1000), 36 new MusicPath(MusicPath.CENTER_OUT, 1000),
33 - 1)); 37 + 1));*/
34 38
35 Interface i = new Interface(musicList, new Runnable() { 39 Interface i = new Interface(musicList, new Runnable() {
36 @Override 40 @Override
VRGNYMusicLights/Sources/MalformedCoordinates.java renamed to VRGNYMusicLights/Sources/ApplicationJava/MalformedCoordinates.java
VRGNYMusicLights/Sources/Music.java renamed to VRGNYMusicLights/Sources/ApplicationJava/Music.java
1 1
2 public class Music { 2 public class Music {
3 private MusicPattern pattern; 3 private MusicPattern pattern;
  4 + public MusicPath path;
4 private int[] lightTickDelais; 5 private int[] lightTickDelais;
5 private double volume; 6 private double volume;
6 7
7 public Music(MusicPattern pattern, MusicPath path, double volume) { 8 public Music(MusicPattern pattern, MusicPath path, double volume) {
8 this.pattern = pattern; 9 this.pattern = pattern;
  10 + this.path = path;
9 this.lightTickDelais = path.calculateTickDelais(); 11 this.lightTickDelais = path.calculateTickDelais();
10 this.volume = volume; 12 this.volume = volume;
11 } 13 }
12 - 14 +
13 public MusicPattern getMusicPattern() { return pattern; } 15 public MusicPattern getMusicPattern() { return pattern; }
  16 + public MusicPath getMusicPath() { return path; }
  17 + public double getVolume() { return volume; }
14 18
15 public double[] render(long tick) { 19 public double[] render(long tick) {
16 double[] lights = new double[lightTickDelais.length]; 20 double[] lights = new double[lightTickDelais.length];
VRGNYMusicLights/Sources/MusicList.java renamed to VRGNYMusicLights/Sources/ApplicationJava/MusicList.java
@@ -11,6 +11,7 @@ public class MusicList { @@ -11,6 +11,7 @@ public class MusicList {
11 11
12 public ArrayList<Music> getList() { return musics; } 12 public ArrayList<Music> getList() { return musics; }
13 public void addMusic(Music music) { musics.add(music); } 13 public void addMusic(Music music) { musics.add(music); }
  14 + public void setMusicAt(int index, Music music) { musics.set(index, music); }
14 public void deleteMusic(int index) { musics.remove(index); } 15 public void deleteMusic(int index) { musics.remove(index); }
15 16
16 public double[] render(long tick) { 17 public double[] render(long tick) {
VRGNYMusicLights/Sources/MusicPath.java renamed to VRGNYMusicLights/Sources/ApplicationJava/MusicPath.java
@@ -36,6 +36,19 @@ public class MusicPath { @@ -36,6 +36,19 @@ public class MusicPath {
36 {1, 0.83}, {1, 0.885}, {1, 0.94} //M6l1 36 {1, 0.83}, {1, 0.885}, {1, 0.94} //M6l1
37 }; 37 };
38 38
  39 + public static final String[] pathNames = new String[] {
  40 + "Vertical down",
  41 + "Vertical up",
  42 + "Horizontal right to left",
  43 + "Horizontal left to right",
  44 + "Diagonal up right to down left",
  45 + "Diagonal down left to up right",
  46 + "Diagonal up left to down right",
  47 + "Diagonal down right to up left",
  48 + "Center out",
  49 + "Center in",
  50 + "Flashing",
  51 + };
39 public static final int VERTICAL_DOWN = 0; 52 public static final int VERTICAL_DOWN = 0;
40 public static final int VERTICAL_UP = 1; 53 public static final int VERTICAL_UP = 1;
41 public static final int HORIZONTAL_TO_LEFT = 2; 54 public static final int HORIZONTAL_TO_LEFT = 2;
@@ -58,6 +71,9 @@ public class MusicPath { @@ -58,6 +71,9 @@ public class MusicPath {
58 this.effectDuration = effectDuration; 71 this.effectDuration = effectDuration;
59 this.lightsCoords = lightsCoords; 72 this.lightsCoords = lightsCoords;
60 } 73 }
  74 +
  75 + public int getAnimation() { return animation; }
  76 + public int getEffectDuration() { return effectDuration; }
61 77
62 public int[] calculateTickDelais() { // tick in ms 78 public int[] calculateTickDelais() { // tick in ms
63 int[] ticksDelais = new int[lightsCoords.length]; 79 int[] ticksDelais = new int[lightsCoords.length];
VRGNYMusicLights/Sources/MusicPattern.java renamed to VRGNYMusicLights/Sources/ApplicationJava/MusicPattern.java
@@ -23,10 +23,11 @@ public class MusicPattern { @@ -23,10 +23,11 @@ public class MusicPattern {
23 for(int i=1; i<5; i++) 23 for(int i=1; i<5; i++)
24 this.patternTiming[i] = this.patternTiming[i-1] + pattern[i]; 24 this.patternTiming[i] = this.patternTiming[i-1] + pattern[i];
25 this.begin = begin; 25 this.begin = begin;
26 - this.stop = repeat * totalLength; 26 + this.stop = repeat * totalLength + begin;
27 this.repeat = repeat; 27 this.repeat = repeat;
28 } 28 }
29 29
  30 + public int[] getPattern() { return pattern; }
30 public int[] getPatternTiming() { return patternTiming; } 31 public int[] getPatternTiming() { return patternTiming; }
31 public long getStop() { return stop; } 32 public long getStop() { return stop; }
32 public long getBegin() { return begin; } 33 public long getBegin() { return begin; }
VRGNYMusicLights/Sources/MusicRenderer.java renamed to VRGNYMusicLights/Sources/ApplicationJava/MusicRenderer.java
1 import java.awt.Color; 1 import java.awt.Color;
2 import java.awt.Component; 2 import java.awt.Component;
  3 +import java.awt.Dimension;
  4 +import java.awt.Font;
3 import java.util.ArrayList; 5 import java.util.ArrayList;
4 6
5 import javax.swing.Box; 7 import javax.swing.Box;
@@ -12,8 +14,10 @@ import javax.swing.ListCellRenderer; @@ -12,8 +14,10 @@ import javax.swing.ListCellRenderer;
12 public class MusicRenderer extends JPanel implements ListCellRenderer<Music> { 14 public class MusicRenderer extends JPanel implements ListCellRenderer<Music> {
13 private static final long serialVersionUID = 1L; 15 private static final long serialVersionUID = 1L;
14 private static final Color DEFAULT_BACKGROUND = new JPanel().getBackground(); 16 private static final Color DEFAULT_BACKGROUND = new JPanel().getBackground();
  17 + private static final Font defaultFont = new Font(new JLabel().getFont().getName(), Font.PLAIN, new JLabel().getFont().getSize());
15 18
16 private TimeLineJPanel timeLine; 19 private TimeLineJPanel timeLine;
  20 + private int infoPadding = 0;
17 21
18 public ArrayList<PatternJPanel> patterns; 22 public ArrayList<PatternJPanel> patterns;
19 23
@@ -22,24 +26,34 @@ public class MusicRenderer extends JPanel implements ListCellRenderer&lt;Music&gt; { @@ -22,24 +26,34 @@ public class MusicRenderer extends JPanel implements ListCellRenderer&lt;Music&gt; {
22 this.patterns = new ArrayList<>(); 26 this.patterns = new ArrayList<>();
23 } 27 }
24 28
  29 + public void setInfoPadding(int infoPadding) { this.infoPadding = infoPadding; }
  30 +
25 @Override 31 @Override
26 public Component getListCellRendererComponent(JList<? extends Music> list, Music music, int index, 32 public Component getListCellRendererComponent(JList<? extends Music> list, Music music, int index,
27 boolean isSelected, boolean cellHasFocus) { 33 boolean isSelected, boolean cellHasFocus) {
28 removeAll(); 34 removeAll();
29 -  
30 - if(isSelected) {  
31 - setBackground(Color.LIGHT_GRAY);  
32 - } else {  
33 - setBackground(DEFAULT_BACKGROUND);  
34 - } 35 + if(music == null)
  36 + return this;
35 37
36 setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS)); 38 setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
37 39
38 JPanel infoPanel = new JPanel(); 40 JPanel infoPanel = new JPanel();
39 infoPanel.setLayout(new BoxLayout(infoPanel, BoxLayout.LINE_AXIS)); 41 infoPanel.setLayout(new BoxLayout(infoPanel, BoxLayout.LINE_AXIS));
40 - infoPanel.add(new JLabel("Pattern " + String.valueOf(index) + " :"));  
41 - //TODO rigid area to follow scroll ? 42 + infoPanel.add(Box.createRigidArea(new Dimension(infoPadding, 0)));
  43 + JLabel infoLabel = new JLabel("Pattern " + String.valueOf(index) + " : "
  44 + + "(vol : " + String.valueOf(music.getVolume()) + ", "
  45 + + "effect : " + MusicPath.pathNames[music.getMusicPath().getAnimation()] + ", "
  46 + + "effect duration : " + Util.tickToText(music.getMusicPath().getEffectDuration()) + ")");
  47 + infoLabel.setFont(defaultFont);
  48 + infoPanel.add(infoLabel);
42 infoPanel.add(Box.createHorizontalGlue()); 49 infoPanel.add(Box.createHorizontalGlue());
  50 +
  51 + if(isSelected) {
  52 + infoPanel.setBackground(Color.LIGHT_GRAY);
  53 + } else {
  54 + infoPanel.setBackground(DEFAULT_BACKGROUND);
  55 + }
  56 +
43 add(infoPanel); 57 add(infoPanel);
44 58
45 PatternJPanel pattern = new PatternJPanel(music, timeLine); 59 PatternJPanel pattern = new PatternJPanel(music, timeLine);
VRGNYMusicLights/Sources/NoSerialPortException.java renamed to VRGNYMusicLights/Sources/ApplicationJava/NoSerialPortException.java
VRGNYMusicLights/Sources/ApplicationJava/PatternEditorJDialog.java 0 → 100644
@@ -0,0 +1,253 @@ @@ -0,0 +1,253 @@
  1 +import java.awt.BorderLayout;
  2 +import java.awt.Color;
  3 +import java.awt.Component;
  4 +import java.awt.Dimension;
  5 +import java.awt.FlowLayout;
  6 +import java.awt.Font;
  7 +import java.awt.Frame;
  8 +import java.awt.event.ActionEvent;
  9 +import java.awt.event.ActionListener;
  10 +import java.awt.event.FocusEvent;
  11 +import java.awt.event.FocusListener;
  12 +
  13 +import javax.swing.Box;
  14 +import javax.swing.BoxLayout;
  15 +import javax.swing.JButton;
  16 +import javax.swing.JComboBox;
  17 +import javax.swing.JDialog;
  18 +import javax.swing.JFrame;
  19 +import javax.swing.JLabel;
  20 +import javax.swing.JPanel;
  21 +import javax.swing.JSlider;
  22 +import javax.swing.JTextField;
  23 +
  24 +public class PatternEditorJDialog extends JDialog implements ActionListener, FocusListener {
  25 + private static final long serialVersionUID = 1L;
  26 + private static final Font titleFont = new Font(new JLabel().getFont().getName(), Font.BOLD, 14);
  27 + private static final String[] fieldsNames = new String[] {
  28 + "Low time : ", //0
  29 + "Rise time : ", //1
  30 + "High time : ", //2
  31 + "Fall time : ", //3
  32 + "Low time : ", //4
  33 + "Repeat : ", //5
  34 + "Begin time : ", //6
  35 + "Volume : ", //7
  36 + "Path : ", //8
  37 + "Duration : ", //9
  38 + "Pattern time : ", //10
  39 + "Total time : " //11
  40 + };
  41 + private void generateComponents() {
  42 + fields = new Component[fieldsNames.length];
  43 +
  44 + // 7 textfields
  45 + for(int i=0; i<7; i++) {
  46 + fields[i] = new JTextField(10);
  47 + fields[i].addFocusListener(this);
  48 + }
  49 +
  50 + // 1 slider
  51 + fields[7] = new JSlider(0, 10, 8);
  52 + ((JSlider) fields[7]).setMajorTickSpacing(2);
  53 + ((JSlider) fields[7]).setMinorTickSpacing(1);
  54 + ((JSlider) fields[7]).setPaintTicks(true);
  55 +
  56 + // 1 combobox
  57 + fields[8] = new JComboBox<String>(MusicPath.pathNames);
  58 +
  59 +
  60 + // 1 textfields
  61 + fields[9] = new JTextField(10);
  62 + fields[9].addFocusListener(this);
  63 +
  64 + // 2 textfields disabled
  65 + for(int i=10; i<12; i++) {
  66 + fields[i] = new JTextField(10);
  67 + fields[i].setEnabled(false);
  68 + fields[i].addFocusListener(this);
  69 + fields[i].setForeground(Color.DARK_GRAY);
  70 + }
  71 + }
  72 +
  73 + private Component[] fields;
  74 + private JButton ok;
  75 + private JButton cancel;
  76 + private Music music = null;
  77 +
  78 + public PatternEditorJDialog(Frame parent) { this(parent, null); }
  79 + public PatternEditorJDialog(Frame parent, Music musicPrev) {
  80 + super(parent, "Pattern editor", true);
  81 + generateComponents();
  82 +
  83 + // main panel
  84 +
  85 + JPanel mainPanel = new JPanel(new BorderLayout());
  86 + getContentPane().add(mainPanel);
  87 +
  88 + // title
  89 +
  90 + JPanel titlePanel = new JPanel(new FlowLayout());
  91 + JLabel title = new JLabel("Pattern parameters : ");
  92 + title.setFont(titleFont);
  93 + titlePanel.add(title);
  94 + mainPanel.add(titlePanel, BorderLayout.NORTH);
  95 +
  96 + // center panel
  97 + JPanel centerPanel = new JPanel();
  98 + centerPanel.setLayout(new BoxLayout(centerPanel, BoxLayout.LINE_AXIS));
  99 + mainPanel.add(centerPanel, BorderLayout.CENTER);
  100 + //padding
  101 + centerPanel.add(Box.createRigidArea(new Dimension(5, 0)));
  102 +
  103 + // labels panel
  104 + JPanel labelsPanel = new JPanel();
  105 + labelsPanel.setLayout(new BoxLayout(labelsPanel, BoxLayout.PAGE_AXIS));
  106 + centerPanel.add(labelsPanel);
  107 +
  108 + // fields panel
  109 + JPanel fieldsPanel = new JPanel();
  110 + fieldsPanel.setLayout(new BoxLayout(fieldsPanel, BoxLayout.PAGE_AXIS));
  111 + centerPanel.add(fieldsPanel);
  112 + //padding
  113 + centerPanel.add(Box.createRigidArea(new Dimension(5, 0)));
  114 +
  115 + JLabel[] fieldsLabels = new JLabel[fieldsNames.length];
  116 + for(int i=0; i<fields.length; i++) {
  117 + fieldsPanel.add(fields[i]);
  118 +
  119 + fieldsLabels[i] = new JLabel(fieldsNames[i]);
  120 + fieldsLabels[i].setAlignmentX(Component.RIGHT_ALIGNMENT);
  121 + fieldsLabels[i].setMaximumSize(new Dimension(fieldsLabels[i].getPreferredSize().width, fields[i].getPreferredSize().height));
  122 + labelsPanel.add(fieldsLabels[i]);
  123 + }
  124 +
  125 + // buttons
  126 +
  127 + JPanel buttonsPanel = new JPanel(new FlowLayout());
  128 + mainPanel.add(buttonsPanel, BorderLayout.SOUTH);
  129 +
  130 + ok = new JButton("Ok");
  131 + ok.addActionListener(this);
  132 + buttonsPanel.add(ok);
  133 +
  134 + cancel = new JButton("Cancel");
  135 + cancel.addActionListener(this);
  136 + buttonsPanel.add(cancel);
  137 +
  138 + setResizable(false);
  139 + pack();
  140 + setLocationRelativeTo(null);
  141 + setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
  142 +
  143 +
  144 + // load prev music
  145 + music = musicPrev;
  146 + if(musicPrev != null)
  147 + updateFeildsToMusic();
  148 +
  149 + // format and compute disabled fields
  150 + updateFields();
  151 + }
  152 +
  153 + private void updateFeildsToMusic() {
  154 + int[] pattern = music.getMusicPattern().getPattern();
  155 + ((JTextField) fields[0]).setText(String.valueOf(pattern[0]));
  156 + ((JTextField) fields[1]).setText(String.valueOf(pattern[1]));
  157 + ((JTextField) fields[2]).setText(String.valueOf(pattern[2]));
  158 + ((JTextField) fields[3]).setText(String.valueOf(pattern[3]));
  159 + ((JTextField) fields[4]).setText(String.valueOf(pattern[4]));
  160 +
  161 + ((JTextField) fields[5]).setText(String.valueOf(music.getMusicPattern().getRepeat()));
  162 + ((JTextField) fields[6]).setText(String.valueOf(music.getMusicPattern().getBegin()));
  163 +
  164 + ((JSlider) fields[7]).setValue((int) (music.getVolume() * 10d));
  165 +
  166 + MusicPath path = music.getMusicPath();
  167 + ((JComboBox<?>) fields[8]).setSelectedIndex(path.getAnimation());
  168 +
  169 + ((JTextField) fields[9]).setText(String.valueOf(path.getEffectDuration()));
  170 + }
  171 +
  172 + public Music showDialog() {
  173 + setVisible(true);
  174 + return music;
  175 + }
  176 +
  177 + @Override
  178 + public void actionPerformed(ActionEvent e) {
  179 + if(e.getSource() == ok) {
  180 + updateFields();
  181 +
  182 + int lowTime = (int) Util.textToTick(((JTextField) fields[0]).getText());
  183 + int raiseTime = (int) Util.textToTick(((JTextField) fields[1]).getText());
  184 + int highTime = (int) Util.textToTick(((JTextField) fields[2]).getText());
  185 + int fallTime = (int) Util.textToTick(((JTextField) fields[3]).getText());
  186 + int pauseTime = (int) Util.textToTick(((JTextField) fields[4]).getText());
  187 + int repeats = Integer.parseInt(((JTextField) fields[5]).getText());
  188 + long beginTime = Util.textToTick(((JTextField) fields[6]).getText());
  189 +
  190 + int animationId = ((JComboBox<?>) fields[8]).getSelectedIndex();
  191 + int effectDuration = (int) Util.textToTick(((JTextField) fields[9]).getText());
  192 +
  193 + MusicPattern musicPattern = new MusicPattern(new int[] {lowTime, raiseTime, highTime, fallTime, pauseTime}, repeats, beginTime);
  194 + MusicPath musicPath = new MusicPath(animationId, effectDuration);
  195 + double volume = (double) ((JSlider) fields[7]).getValue() / (double) ((JSlider) fields[7]).getMaximum();
  196 +
  197 + //invalid params
  198 + if((lowTime == 0 && raiseTime == 0 && highTime == 0 && fallTime == 0 && pauseTime == 0)
  199 + || (repeats <= 0)
  200 + || (beginTime < 0)
  201 + || (effectDuration < 0)) {
  202 + music = null;
  203 + dispose();
  204 + return;
  205 + }
  206 +
  207 + music = new Music(musicPattern, musicPath, volume);
  208 +
  209 + dispose();
  210 + } else if(e.getSource() == cancel) {
  211 + music = null;
  212 + dispose();
  213 + }
  214 + }
  215 +
  216 + public void updateFields() {
  217 + // format textfields
  218 + for(int i=0; i<fields.length; i++) {
  219 + if(fields[i] instanceof JTextField && i != 5)
  220 + ((JTextField) fields[i]).setText(Util.formatTime(((JTextField) fields[i]).getText()));
  221 + else if(i == 5) {
  222 + try {
  223 + int n = Integer.parseInt(((JTextField) fields[i]).getText());
  224 + if(n < 1)
  225 + ((JTextField) fields[i]).setText("1");
  226 + }catch (NumberFormatException e) {
  227 + ((JTextField) fields[i]).setText("1");
  228 + }
  229 + }
  230 + }
  231 +
  232 + // compute patter time and total time
  233 + long lowTime = Util.textToTick(((JTextField) fields[0]).getText());
  234 + long raiseTime = Util.textToTick(((JTextField) fields[1]).getText());
  235 + long highTime = Util.textToTick(((JTextField) fields[2]).getText());
  236 + long fallTime = Util.textToTick(((JTextField) fields[3]).getText());
  237 + long pauseTime = Util.textToTick(((JTextField) fields[4]).getText());
  238 + int repeats = Integer.parseInt(((JTextField) fields[5]).getText());
  239 +
  240 + long patterTime = lowTime + raiseTime + highTime + fallTime + pauseTime;
  241 + ((JTextField) fields[10]).setText(Util.tickToText(patterTime));
  242 + long totalTime = patterTime * repeats;
  243 + ((JTextField) fields[11]).setText(Util.tickToText(totalTime));
  244 + }
  245 +
  246 + @Override
  247 + public void focusGained(FocusEvent e) {}
  248 +
  249 + @Override
  250 + public void focusLost(FocusEvent e) {
  251 + updateFields();
  252 + }
  253 +}
VRGNYMusicLights/Sources/PatternJPanel.java renamed to VRGNYMusicLights/Sources/ApplicationJava/PatternJPanel.java
@@ -2,6 +2,7 @@ import java.awt.Color; @@ -2,6 +2,7 @@ import java.awt.Color;
2 import java.awt.Dimension; 2 import java.awt.Dimension;
3 import java.awt.Graphics; 3 import java.awt.Graphics;
4 4
  5 +import javax.swing.JLabel;
5 import javax.swing.JPanel; 6 import javax.swing.JPanel;
6 7
7 public class PatternJPanel extends JPanel { 8 public class PatternJPanel extends JPanel {
@@ -9,6 +10,7 @@ public class PatternJPanel extends JPanel { @@ -9,6 +10,7 @@ public class PatternJPanel extends JPanel {
9 private static final int HEIGHT = 50; 10 private static final int HEIGHT = 50;
10 private static final int PADDING = 2; 11 private static final int PADDING = 2;
11 public static final int ZOOM_MULTIPLIER = 10; 12 public static final int ZOOM_MULTIPLIER = 10;
  13 + public static final int PATTERN_HEIGHT = (int) (HEIGHT + new JLabel(" ").getPreferredSize().height);
12 14
13 private Music music; 15 private Music music;
14 private TimeLineJPanel timeLine; 16 private TimeLineJPanel timeLine;
@@ -17,12 +19,12 @@ public class PatternJPanel extends JPanel { @@ -17,12 +19,12 @@ public class PatternJPanel extends JPanel {
17 public PatternJPanel(Music music, TimeLineJPanel timeLine) { 19 public PatternJPanel(Music music, TimeLineJPanel timeLine) {
18 this.music = music; 20 this.music = music;
19 this.timeLine = timeLine; 21 this.timeLine = timeLine;
20 - end = transformZoon(music.getMusicPattern().getStop()); 22 + end = Util.transformZoom(music.getMusicPattern().getStop(), timeLine.getZoomLevel());
21 setPreferredSize(new Dimension((int) end, HEIGHT)); 23 setPreferredSize(new Dimension((int) end, HEIGHT));
22 } 24 }
23 25
24 public void refreshPreferedSize() { 26 public void refreshPreferedSize() {
25 - end = transformZoon(music.getMusicPattern().getStop()); 27 + end = Util.transformZoom(music.getMusicPattern().getStop(), timeLine.getZoomLevel());
26 setPreferredSize(new Dimension((int) end, HEIGHT)); 28 setPreferredSize(new Dimension((int) end, HEIGHT));
27 } 29 }
28 30
@@ -34,30 +36,23 @@ public class PatternJPanel extends JPanel { @@ -34,30 +36,23 @@ public class PatternJPanel extends JPanel {
34 super.paintComponent(g); 36 super.paintComponent(g);
35 37
36 g.setColor(Color.WHITE); 38 g.setColor(Color.WHITE);
37 - int begin = transformZoon(music.getMusicPattern().getBegin());  
38 - g.fillRect(begin, 0, end, HEIGHT); 39 + int begin = Util.transformZoom(music.getMusicPattern().getBegin(), timeLine.getZoomLevel());
  40 + g.fillRect(begin, 0, end - begin, HEIGHT);
39 41
40 MusicPattern pattern = music.getMusicPattern(); 42 MusicPattern pattern = music.getMusicPattern();
41 g.setColor(Color.BLACK); 43 g.setColor(Color.BLACK);
42 for(int i=0; i<pattern.getRepeat(); i++) { 44 for(int i=0; i<pattern.getRepeat(); i++) {
43 - int repeatAddition = transformZoon(pattern.getTotalLength() * i) + begin; 45 + int repeatAddition = Util.transformZoom(pattern.getTotalLength() * i, timeLine.getZoomLevel()) + begin;
44 g.drawLine(repeatAddition, HEIGHT - PADDING, 46 g.drawLine(repeatAddition, HEIGHT - PADDING,
45 - transformZoon(pattern.getPatternTiming()[0]) + repeatAddition, HEIGHT - PADDING);  
46 - g.drawLine(transformZoon(pattern.getPatternTiming()[0]) + repeatAddition, HEIGHT - PADDING,  
47 - transformZoon(pattern.getPatternTiming()[1]) + repeatAddition, PADDING);  
48 - g.drawLine(transformZoon(pattern.getPatternTiming()[1]) + repeatAddition, PADDING,  
49 - transformZoon(pattern.getPatternTiming()[2]) + repeatAddition, PADDING);  
50 - g.drawLine(transformZoon(pattern.getPatternTiming()[2]) + repeatAddition, PADDING,  
51 - transformZoon(pattern.getPatternTiming()[3]) + repeatAddition, HEIGHT - PADDING);  
52 - g.drawLine(transformZoon(pattern.getPatternTiming()[3]) + repeatAddition, HEIGHT - PADDING,  
53 - transformZoon(pattern.getPatternTiming()[4]) + repeatAddition, HEIGHT - PADDING); 47 + Util.transformZoom(pattern.getPatternTiming()[0], timeLine.getZoomLevel()) + repeatAddition, HEIGHT - PADDING);
  48 + g.drawLine(Util.transformZoom(pattern.getPatternTiming()[0], timeLine.getZoomLevel()) + repeatAddition, HEIGHT - PADDING,
  49 + Util.transformZoom(pattern.getPatternTiming()[1], timeLine.getZoomLevel()) + repeatAddition, PADDING);
  50 + g.drawLine(Util.transformZoom(pattern.getPatternTiming()[1], timeLine.getZoomLevel()) + repeatAddition, PADDING,
  51 + Util.transformZoom(pattern.getPatternTiming()[2], timeLine.getZoomLevel()) + repeatAddition, PADDING);
  52 + g.drawLine(Util.transformZoom(pattern.getPatternTiming()[2], timeLine.getZoomLevel()) + repeatAddition, PADDING,
  53 + Util.transformZoom(pattern.getPatternTiming()[3], timeLine.getZoomLevel()) + repeatAddition, HEIGHT - PADDING);
  54 + g.drawLine(Util.transformZoom(pattern.getPatternTiming()[3], timeLine.getZoomLevel()) + repeatAddition, HEIGHT - PADDING,
  55 + Util.transformZoom(pattern.getPatternTiming()[4], timeLine.getZoomLevel()) + repeatAddition, HEIGHT - PADDING);
54 } 56 }
55 } 57 }
56 -  
57 - private int transformZoon(int n) {  
58 - return transformZoon((long) n);  
59 - }  
60 - private int transformZoon(long n) {  
61 - return (int) ((double) n / (double) ZOOM_MULTIPLIER * timeLine.getZoomLevel());  
62 - }  
63 } 58 }
VRGNYMusicLights/Sources/PlayJPanel.java renamed to VRGNYMusicLights/Sources/ApplicationJava/PlayJPanel.java
1 import java.awt.BorderLayout; 1 import java.awt.BorderLayout;
  2 +import java.awt.Color;
2 import java.awt.Font; 3 import java.awt.Font;
3 4
  5 +import javax.swing.BorderFactory;
4 import javax.swing.Box; 6 import javax.swing.Box;
5 import javax.swing.BoxLayout; 7 import javax.swing.BoxLayout;
6 import javax.swing.JLabel; 8 import javax.swing.JLabel;
@@ -12,6 +14,7 @@ public class PlayJPanel extends JPanel { @@ -12,6 +14,7 @@ public class PlayJPanel extends JPanel {
12 14
13 public PlayJPanel(Interface interf, LightCanvasJPanel lightCanvas) { 15 public PlayJPanel(Interface interf, LightCanvasJPanel lightCanvas) {
14 super(new BorderLayout()); 16 super(new BorderLayout());
  17 + setBorder(BorderFactory.createMatteBorder(4, 0, 0, 0, Color.LIGHT_GRAY));
15 18
16 // title 19 // title
17 JLabel title = new JLabel("Visualizer :"); 20 JLabel title = new JLabel("Visualizer :");
VRGNYMusicLights/Sources/SerialCom.java renamed to VRGNYMusicLights/Sources/ApplicationJava/SerialCom.java
VRGNYMusicLights/Sources/SerialComPortException.java renamed to VRGNYMusicLights/Sources/ApplicationJava/SerialComPortException.java
VRGNYMusicLights/Sources/SerialComWrongCallbackMethod.java renamed to VRGNYMusicLights/Sources/ApplicationJava/SerialComWrongCallbackMethod.java
VRGNYMusicLights/Sources/SerialCommands.java renamed to VRGNYMusicLights/Sources/ApplicationJava/SerialCommands.java
VRGNYMusicLights/Sources/SerialPortChooserDialog.java renamed to VRGNYMusicLights/Sources/ApplicationJava/SerialPortChooserDialog.java
VRGNYMusicLights/Sources/TimeLineJList.java renamed to VRGNYMusicLights/Sources/ApplicationJava/TimeLineJList.java
@@ -21,16 +21,9 @@ public class TimeLineJList extends JList&lt;Music&gt; { @@ -21,16 +21,9 @@ public class TimeLineJList extends JList&lt;Music&gt; {
21 g.setColor(Color.BLACK); 21 g.setColor(Color.BLACK);
22 22
23 int maxHeight = getPreferredSize().height; 23 int maxHeight = getPreferredSize().height;
24 - int maxWidth = getPreferredSize().width;  
25 24
26 - int mark = transformZoon(interf.tick);  
27 - if(mark > maxWidth)  
28 - mark = maxWidth; 25 + int mark = Util.transformZoom(interf.tick, interf.timeLinePanel.getZoomLevel());
29 26
30 g.fillRect(mark, 0, MARK_WIDTH, maxHeight); 27 g.fillRect(mark, 0, MARK_WIDTH, maxHeight);
31 } 28 }
32 -  
33 - private int transformZoon(long n) {  
34 - return (int) ((double) n / (double) PatternJPanel.ZOOM_MULTIPLIER * interf.timeLinePanel.getZoomLevel());  
35 - }  
36 } 29 }
VRGNYMusicLights/Sources/TimeLineJPanel.java renamed to VRGNYMusicLights/Sources/ApplicationJava/TimeLineJPanel.java
@@ -2,6 +2,8 @@ import java.awt.Dimension; @@ -2,6 +2,8 @@ import java.awt.Dimension;
2 import java.awt.Font; 2 import java.awt.Font;
3 import java.awt.event.ActionEvent; 3 import java.awt.event.ActionEvent;
4 import java.awt.event.ActionListener; 4 import java.awt.event.ActionListener;
  5 +import java.awt.event.AdjustmentEvent;
  6 +import java.awt.event.AdjustmentListener;
5 import java.awt.event.FocusEvent; 7 import java.awt.event.FocusEvent;
6 import java.awt.event.FocusListener; 8 import java.awt.event.FocusListener;
7 import java.awt.event.MouseWheelEvent; 9 import java.awt.event.MouseWheelEvent;
@@ -14,10 +16,13 @@ import javax.swing.JLabel; @@ -14,10 +16,13 @@ import javax.swing.JLabel;
14 import javax.swing.JPanel; 16 import javax.swing.JPanel;
15 import javax.swing.JScrollBar; 17 import javax.swing.JScrollBar;
16 import javax.swing.JScrollPane; 18 import javax.swing.JScrollPane;
  19 +import javax.swing.JSlider;
17 import javax.swing.JTextField; 20 import javax.swing.JTextField;
18 import javax.swing.ListSelectionModel; 21 import javax.swing.ListSelectionModel;
  22 +import javax.swing.event.ChangeEvent;
  23 +import javax.swing.event.ChangeListener;
19 24
20 -public class TimeLineJPanel extends JPanel implements MouseWheelListener, FocusListener, ActionListener { 25 +public class TimeLineJPanel extends JPanel implements MouseWheelListener, FocusListener, ActionListener, ChangeListener, AdjustmentListener {
21 private static final long serialVersionUID = 1L; 26 private static final long serialVersionUID = 1L;
22 private static final Font titleFont = new Font(new JLabel().getFont().getName(), Font.BOLD, 14); 27 private static final Font titleFont = new Font(new JLabel().getFont().getName(), Font.BOLD, 14);
23 28
@@ -32,8 +37,9 @@ public class TimeLineJPanel extends JPanel implements MouseWheelListener, FocusL @@ -32,8 +37,9 @@ public class TimeLineJPanel extends JPanel implements MouseWheelListener, FocusL
32 private Interface interf; 37 private Interface interf;
33 private JTextField currentTick; 38 private JTextField currentTick;
34 private JLabel maxTicks; 39 private JLabel maxTicks;
  40 + private JPanel scrollPanel;
35 41
36 - public TimeLineJPanel(Interface interf, MusicList list) { 42 + public TimeLineJPanel(Interface interf) {
37 this.interf = interf; 43 this.interf = interf;
38 setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS)); 44 setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
39 45
@@ -58,71 +64,129 @@ public class TimeLineJPanel extends JPanel implements MouseWheelListener, FocusL @@ -58,71 +64,129 @@ public class TimeLineJPanel extends JPanel implements MouseWheelListener, FocusL
58 64
59 add(timingPanel); 65 add(timingPanel);
60 66
61 - // timeline 67 + // scroll pane
62 68
63 - listModel = new DefaultListModel<>();  
64 - for(Music music : list.getList())  
65 - listModel.addElement(music); 69 + scrollPanel = new JPanel();
  70 + scrollPanel.setLayout(new BoxLayout(scrollPanel, BoxLayout.PAGE_AXIS));
  71 + scrollPane = new JScrollPane(scrollPanel, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
  72 + scrollPane.addMouseWheelListener(this);
  73 + scrollPane.setWheelScrollingEnabled(false);
  74 + scrollPane.getHorizontalScrollBar().addAdjustmentListener(this);
  75 + scrollPane.setPreferredSize(new Dimension(800, 400));
  76 + add(scrollPane);
  77 +
  78 + // slider
  79 +
  80 + interf.timeSlider = new JSlider(JSlider.HORIZONTAL, 0, 0, 0);
  81 + interf.timeSlider.setMajorTickSpacing(1000);
  82 + interf.timeSlider.setMinorTickSpacing(500);
  83 + interf.timeSlider.setPaintTicks(true);
  84 + interf.timeSlider.setAlignmentX(LEFT_ALIGNMENT);
  85 + interf.timeSlider.setEnabled(false);
  86 + interf.timeSlider.setUI(new CustomSliderUI(interf.timeSlider));
  87 + interf.timeSlider.addChangeListener(this);
  88 + scrollPanel.add(interf.timeSlider);
  89 +
  90 + // timeline
66 91
  92 + listModel = new DefaultListModel<>();
  93 + for(Music music : interf.musicList.getList())
  94 + listModel.addElement(music);
67 interf.timeLineList = new TimeLineJList(listModel, interf); 95 interf.timeLineList = new TimeLineJList(listModel, interf);
68 musicRenderer = new MusicRenderer(this); 96 musicRenderer = new MusicRenderer(this);
69 interf.timeLineList.setCellRenderer(musicRenderer); 97 interf.timeLineList.setCellRenderer(musicRenderer);
70 interf.timeLineList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 98 interf.timeLineList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
71 - scrollPane = new JScrollPane(interf.timeLineList, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);  
72 - scrollPane.addMouseWheelListener(this);  
73 - scrollPane.setWheelScrollingEnabled(false);  
74 - scrollPane.setPreferredSize(new Dimension(800, 400));  
75 - add(scrollPane); 99 + interf.timeLineList.setAlignmentX(LEFT_ALIGNMENT);
  100 + scrollPanel.add(interf.timeLineList);
76 } 101 }
77 102
78 public double getZoomLevel() { return zoomLevel; } 103 public double getZoomLevel() { return zoomLevel; }
79 104
80 - public void updateList(MusicList list) { 105 + public void updateList() {
  106 + final MusicList musicList = interf.musicList;
  107 +
81 listModel.clear(); 108 listModel.clear();
82 - for(Music music : list.getList())  
83 - listModel.addElement(music); 109 + for(Music music : musicList.getList())
  110 + listModel.addElement(music);
  111 +
  112 + // compute max slider
  113 + long maxTick = 0;
  114 + for(Music music : musicList.getList()) {
  115 + if(music.getMusicPattern().getStop() > maxTick)
  116 + maxTick = music.getMusicPattern().getStop();
  117 + }
  118 + interf.timeSlider.setMaximum((int) maxTick);
  119 +
  120 + // update need a delay and have to be call with another thread (note sure why...)
  121 + new Thread(new Runnable() {
  122 + @Override
  123 + public void run() {
  124 + try {
  125 + Thread.sleep(10);
  126 + } catch (InterruptedException e) {
  127 + e.printStackTrace();
  128 + }
  129 + if(musicList.getList().size() != 0)
  130 + updateTimeLine(0);
  131 + }
  132 + }).start();
84 } 133 }
85 134
86 public void updateTick() { 135 public void updateTick() {
87 currentTick.setText(Util.tickToText(interf.tick)); 136 currentTick.setText(Util.tickToText(interf.tick));
88 - long maxTick = 0;  
89 - for(PatternJPanel pattern : musicRenderer.patterns) {  
90 - pattern.refreshPreferedSize();  
91 - long tick = pattern.getMusic().getMusicPattern().getStop();  
92 - if(tick > maxTick)  
93 - maxTick = tick;  
94 - }  
95 - maxTicks.setText(Util.tickToText(maxTick) + " (MM:ss:ms)"); 137 + long maxTick = 0;
  138 + for(PatternJPanel pattern : musicRenderer.patterns) {
  139 + pattern.refreshPreferedSize();
  140 + long tick = pattern.getMusic().getMusicPattern().getStop();
  141 + if(tick > maxTick)
  142 + maxTick = tick;
  143 + }
  144 + maxTicks.setText(Util.tickToText(maxTick) + " (mm:ss:ms)");
96 } 145 }
97 146
98 public void mouseWheelMoved(MouseWheelEvent e) { 147 public void mouseWheelMoved(MouseWheelEvent e) {
99 if(e.getSource() == scrollPane) { 148 if(e.getSource() == scrollPane) {
100 - if (e.isControlDown()) {  
101 - if(e.getWheelRotation() < 0)  
102 - zoomLevel *= (double) e.getWheelRotation() * -1.1;  
103 - else  
104 - zoomLevel *= (double) e.getWheelRotation() / 1.1;  
105 -  
106 - int maxWidth = 0;  
107 - for(PatternJPanel pattern : musicRenderer.patterns) {  
108 - pattern.refreshPreferedSize();  
109 - int width = pattern.getEnd();  
110 - if(width > maxWidth)  
111 - maxWidth = width;  
112 - }  
113 -  
114 - interf.timeLineList.setPreferredSize(new Dimension(maxWidth, interf.getPreferredSize().height));  
115 - scrollPane.repaint();  
116 - scrollPane.getViewport().revalidate();  
117 - } else if(e.isShiftDown()) {  
118 - JScrollBar sb = scrollPane.getHorizontalScrollBar();  
119 - sb.setValue(sb.getValue() + e.getWheelRotation() * SCROLL_SPEED_HORIZONTAL);  
120 - } else {  
121 - JScrollBar sb = scrollPane.getVerticalScrollBar();  
122 - sb.setValue(sb.getValue() + e.getWheelRotation() * SCROLL_SPEED_VERTICAL);  
123 - } 149 + if (e.isControlDown()) {
  150 + if(interf.musicList.getList().size() != 0)
  151 + updateTimeLine(e.getWheelRotation());
  152 + } else if(e.isShiftDown()) {
  153 + JScrollBar sb = scrollPane.getHorizontalScrollBar();
  154 + sb.setValue(sb.getValue() + e.getWheelRotation() * SCROLL_SPEED_HORIZONTAL);
  155 + } else {
  156 + JScrollBar sb = scrollPane.getVerticalScrollBar();
  157 + sb.setValue(sb.getValue() + e.getWheelRotation() * SCROLL_SPEED_VERTICAL);
  158 + }
  159 + }
  160 + }
  161 +
  162 + public void updateTimeLine(int wheelRot) {
  163 + if(wheelRot < 0)
  164 + zoomLevel *= (double) wheelRot * -1.1;
  165 + else if (wheelRot > 0)
  166 + zoomLevel *= (double) wheelRot / 1.1;
  167 +
  168 + interf.timeSlider.setEnabled(musicRenderer.patterns.size() != 0);
  169 + int maxWidth = 0;
  170 + if(musicRenderer.patterns.size() == 0) {
  171 + interf.timeSlider.setValue(0);
  172 + maxWidth = (int) (scrollPane.getPreferredSize().width - new JScrollBar().getPreferredSize().getWidth()) - 1;
  173 + } else {
  174 + for(PatternJPanel pattern : musicRenderer.patterns) {
  175 + pattern.refreshPreferedSize();
  176 + int width = pattern.getEnd();
  177 + if(width > maxWidth)
  178 + maxWidth = width;
  179 + }
124 } 180 }
125 - } 181 +
  182 + interf.timeSlider.setMaximumSize(new Dimension(maxWidth, interf.timeSlider.getPreferredSize().height));
  183 + interf.timeLineList.setMaximumSize(new Dimension(maxWidth, PatternJPanel.PATTERN_HEIGHT * musicRenderer.patterns.size()));
  184 + interf.timeLineList.setPreferredSize(new Dimension(maxWidth, PatternJPanel.PATTERN_HEIGHT * musicRenderer.patterns.size()));
  185 + scrollPanel.setPreferredSize(new Dimension(maxWidth, PatternJPanel.PATTERN_HEIGHT * musicRenderer.patterns.size()));
  186 + scrollPane.repaint();
  187 + scrollPane.getViewport().revalidate();
  188 + scrollPanel.revalidate();
  189 + }
126 190
127 @Override 191 @Override
128 public void focusLost(FocusEvent e) { 192 public void focusLost(FocusEvent e) {
@@ -143,4 +207,22 @@ public class TimeLineJPanel extends JPanel implements MouseWheelListener, FocusL @@ -143,4 +207,22 @@ public class TimeLineJPanel extends JPanel implements MouseWheelListener, FocusL
143 if(e.getSource() == currentTick) 207 if(e.getSource() == currentTick)
144 interf.getContentPane().requestFocus(); 208 interf.getContentPane().requestFocus();
145 } 209 }
  210 +
  211 + @Override
  212 + public void stateChanged(ChangeEvent e) {
  213 + if(e.getSource() == interf.timeSlider) {
  214 + interf.tick = interf.timeSlider.getValue();
  215 + interf.computeTick();
  216 + }
  217 + }
  218 +
  219 + @Override
  220 + public void adjustmentValueChanged(AdjustmentEvent e) {
  221 + if(e.getSource() == scrollPane.getHorizontalScrollBar()) {
  222 + musicRenderer.setInfoPadding(scrollPane.getHorizontalScrollBar().getValue());
  223 + scrollPane.repaint();
  224 + scrollPane.getViewport().revalidate();
  225 + scrollPanel.revalidate();
  226 + }
  227 + }
146 } 228 }
VRGNYMusicLights/Sources/Util.java renamed to VRGNYMusicLights/Sources/ApplicationJava/Util.java
@@ -43,4 +43,12 @@ public class Util { @@ -43,4 +43,12 @@ public class Util {
43 43
44 return str; 44 return str;
45 } 45 }
  46 +
  47 + public static String formatTime(String str) {
  48 + return tickToText(textToTick(str));
  49 + }
  50 +
  51 + public static int transformZoom(long n, double zoom) {
  52 + return (int) ((double) n / (double) PatternJPanel.ZOOM_MULTIPLIER * zoom);
  53 + }
46 } 54 }
VRGNYMusicLights/Sources/ApplicationJava/icons/Thumbs.db 0 → 100644
No preview for this file type
VRGNYMusicLights/Sources/icons/backward.png renamed to VRGNYMusicLights/Sources/ApplicationJava/icons/backward.png

436 Bytes

VRGNYMusicLights/Sources/icons/forward.png renamed to VRGNYMusicLights/Sources/ApplicationJava/icons/forward.png

412 Bytes

VRGNYMusicLights/Sources/icons/pause.png renamed to VRGNYMusicLights/Sources/ApplicationJava/icons/pause.png

295 Bytes

VRGNYMusicLights/Sources/icons/play.png renamed to VRGNYMusicLights/Sources/ApplicationJava/icons/play.png

364 Bytes

VRGNYMusicLights/Sources/icons/stop.png renamed to VRGNYMusicLights/Sources/ApplicationJava/icons/stop.png

320 Bytes