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 @@
  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 @@
  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 152 \ No newline at end of file
... ...
VRGNYMusicLights/Sources/ApplicationJava/ImportExport.java 0 → 100644
... ... @@ -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 1 import java.awt.BorderLayout;
  2 +import java.awt.Dimension;
2 3 import java.awt.event.WindowAdapter;
3 4 import java.awt.event.WindowEvent;
4 5  
5 6 import javax.swing.JFrame;
6 7 import javax.swing.JPanel;
  8 +import javax.swing.JSlider;
7 9  
8 10 public class Interface extends JFrame{
9 11 private static final long serialVersionUID = 1L;
... ... @@ -15,14 +17,16 @@ public class Interface extends JFrame{
15 17 protected TimeLineJPanel timeLinePanel;
16 18 protected TimeLineJList timeLineList;
17 19 protected LightCanvasJPanel lightCanvas;
  20 + protected JSlider timeSlider;
18 21 protected long tick = 0;
19 22  
20 23 public Interface(MusicList musicList, final Runnable executeOnClose) {
21 24 super("VRGNYMusicLights");
22 25 this.musicList = musicList;
23   - setResizable(false);
24 26 populateWindow();
25 27 pack();
  28 + setMinimumSize(new Dimension(600, 500));
  29 + setSize(new Dimension(800, 600));
26 30 setLocationRelativeTo(null); // center window
27 31 getContentPane().requestFocus();
28 32  
... ... @@ -39,6 +43,7 @@ public class Interface extends JFrame{
39 43 }
40 44  
41 45 protected void computeTick() {
  46 + timeSlider.setValue((int) tick);
42 47 lightCanvas.paintLights(musicList.render(tick));
43 48 timeLineList.repaint();
44 49 timeLinePanel.updateTick();
... ... @@ -46,10 +51,11 @@ public class Interface extends JFrame{
46 51  
47 52 private void populateWindow() {
48 53 JPanel mainPanel = new JPanel(new BorderLayout());
49   - timeLinePanel = new TimeLineJPanel(this, musicList);
  54 + timeLinePanel = new TimeLineJPanel(this);
50 55 mainPanel.add(timeLinePanel, BorderLayout.CENTER);
51 56 lightCanvas = new LightCanvasJPanel();
52 57 mainPanel.add(new PlayJPanel(this, lightCanvas), BorderLayout.SOUTH);
  58 + mainPanel.add(new CommandJPanel(this), BorderLayout.EAST);
53 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 3 /* TODO list :
4 4 * - keyboard listener for animation player (play / pause = space, forward = semicolon, backward = comma, stop = backspace)
5 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 11 public class Main {
8 12 public static void main(String[] args) throws InterruptedException {
... ... @@ -21,16 +25,16 @@ public class Main {
21 25 Thread.sleep(1000);*/
22 26  
23 27 MusicList musicList = new MusicList(null);
24   - musicList.addMusic(
  28 + /*musicList.addMusic(
25 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 32 1));
29 33 musicList.addMusic(
30 34 new Music(
31 35 new MusicPattern(new int[] {0, 10, 100, 10, 100}, 1, 0),
32 36 new MusicPath(MusicPath.CENTER_OUT, 1000),
33   - 1));
  37 + 1));*/
34 38  
35 39 Interface i = new Interface(musicList, new Runnable() {
36 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 2 public class Music {
3 3 private MusicPattern pattern;
  4 + public MusicPath path;
4 5 private int[] lightTickDelais;
5 6 private double volume;
6 7  
7 8 public Music(MusicPattern pattern, MusicPath path, double volume) {
8 9 this.pattern = pattern;
  10 + this.path = path;
9 11 this.lightTickDelais = path.calculateTickDelais();
10 12 this.volume = volume;
11 13 }
12   -
  14 +
13 15 public MusicPattern getMusicPattern() { return pattern; }
  16 + public MusicPath getMusicPath() { return path; }
  17 + public double getVolume() { return volume; }
14 18  
15 19 public double[] render(long tick) {
16 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 11  
12 12 public ArrayList<Music> getList() { return musics; }
13 13 public void addMusic(Music music) { musics.add(music); }
  14 + public void setMusicAt(int index, Music music) { musics.set(index, music); }
14 15 public void deleteMusic(int index) { musics.remove(index); }
15 16  
16 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 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 52 public static final int VERTICAL_DOWN = 0;
40 53 public static final int VERTICAL_UP = 1;
41 54 public static final int HORIZONTAL_TO_LEFT = 2;
... ... @@ -58,6 +71,9 @@ public class MusicPath {
58 71 this.effectDuration = effectDuration;
59 72 this.lightsCoords = lightsCoords;
60 73 }
  74 +
  75 + public int getAnimation() { return animation; }
  76 + public int getEffectDuration() { return effectDuration; }
61 77  
62 78 public int[] calculateTickDelais() { // tick in ms
63 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 23 for(int i=1; i<5; i++)
24 24 this.patternTiming[i] = this.patternTiming[i-1] + pattern[i];
25 25 this.begin = begin;
26   - this.stop = repeat * totalLength;
  26 + this.stop = repeat * totalLength + begin;
27 27 this.repeat = repeat;
28 28 }
29 29  
  30 + public int[] getPattern() { return pattern; }
30 31 public int[] getPatternTiming() { return patternTiming; }
31 32 public long getStop() { return stop; }
32 33 public long getBegin() { return begin; }
... ...
VRGNYMusicLights/Sources/MusicRenderer.java renamed to VRGNYMusicLights/Sources/ApplicationJava/MusicRenderer.java
1 1 import java.awt.Color;
2 2 import java.awt.Component;
  3 +import java.awt.Dimension;
  4 +import java.awt.Font;
3 5 import java.util.ArrayList;
4 6  
5 7 import javax.swing.Box;
... ... @@ -12,8 +14,10 @@ import javax.swing.ListCellRenderer;
12 14 public class MusicRenderer extends JPanel implements ListCellRenderer<Music> {
13 15 private static final long serialVersionUID = 1L;
14 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 19 private TimeLineJPanel timeLine;
  20 + private int infoPadding = 0;
17 21  
18 22 public ArrayList<PatternJPanel> patterns;
19 23  
... ... @@ -22,24 +26,34 @@ public class MusicRenderer extends JPanel implements ListCellRenderer&lt;Music&gt; {
22 26 this.patterns = new ArrayList<>();
23 27 }
24 28  
  29 + public void setInfoPadding(int infoPadding) { this.infoPadding = infoPadding; }
  30 +
25 31 @Override
26 32 public Component getListCellRendererComponent(JList<? extends Music> list, Music music, int index,
27 33 boolean isSelected, boolean cellHasFocus) {
28 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 38 setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
37 39  
38 40 JPanel infoPanel = new JPanel();
39 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 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 57 add(infoPanel);
44 58  
45 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 @@
  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 2 import java.awt.Dimension;
3 3 import java.awt.Graphics;
4 4  
  5 +import javax.swing.JLabel;
5 6 import javax.swing.JPanel;
6 7  
7 8 public class PatternJPanel extends JPanel {
... ... @@ -9,6 +10,7 @@ public class PatternJPanel extends JPanel {
9 10 private static final int HEIGHT = 50;
10 11 private static final int PADDING = 2;
11 12 public static final int ZOOM_MULTIPLIER = 10;
  13 + public static final int PATTERN_HEIGHT = (int) (HEIGHT + new JLabel(" ").getPreferredSize().height);
12 14  
13 15 private Music music;
14 16 private TimeLineJPanel timeLine;
... ... @@ -17,12 +19,12 @@ public class PatternJPanel extends JPanel {
17 19 public PatternJPanel(Music music, TimeLineJPanel timeLine) {
18 20 this.music = music;
19 21 this.timeLine = timeLine;
20   - end = transformZoon(music.getMusicPattern().getStop());
  22 + end = Util.transformZoom(music.getMusicPattern().getStop(), timeLine.getZoomLevel());
21 23 setPreferredSize(new Dimension((int) end, HEIGHT));
22 24 }
23 25  
24 26 public void refreshPreferedSize() {
25   - end = transformZoon(music.getMusicPattern().getStop());
  27 + end = Util.transformZoom(music.getMusicPattern().getStop(), timeLine.getZoomLevel());
26 28 setPreferredSize(new Dimension((int) end, HEIGHT));
27 29 }
28 30  
... ... @@ -34,30 +36,23 @@ public class PatternJPanel extends JPanel {
34 36 super.paintComponent(g);
35 37  
36 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 42 MusicPattern pattern = music.getMusicPattern();
41 43 g.setColor(Color.BLACK);
42 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 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 1 import java.awt.BorderLayout;
  2 +import java.awt.Color;
2 3 import java.awt.Font;
3 4  
  5 +import javax.swing.BorderFactory;
4 6 import javax.swing.Box;
5 7 import javax.swing.BoxLayout;
6 8 import javax.swing.JLabel;
... ... @@ -12,6 +14,7 @@ public class PlayJPanel extends JPanel {
12 14  
13 15 public PlayJPanel(Interface interf, LightCanvasJPanel lightCanvas) {
14 16 super(new BorderLayout());
  17 + setBorder(BorderFactory.createMatteBorder(4, 0, 0, 0, Color.LIGHT_GRAY));
15 18  
16 19 // title
17 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 21 g.setColor(Color.BLACK);
22 22  
23 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 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 2 import java.awt.Font;
3 3 import java.awt.event.ActionEvent;
4 4 import java.awt.event.ActionListener;
  5 +import java.awt.event.AdjustmentEvent;
  6 +import java.awt.event.AdjustmentListener;
5 7 import java.awt.event.FocusEvent;
6 8 import java.awt.event.FocusListener;
7 9 import java.awt.event.MouseWheelEvent;
... ... @@ -14,10 +16,13 @@ import javax.swing.JLabel;
14 16 import javax.swing.JPanel;
15 17 import javax.swing.JScrollBar;
16 18 import javax.swing.JScrollPane;
  19 +import javax.swing.JSlider;
17 20 import javax.swing.JTextField;
18 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 26 private static final long serialVersionUID = 1L;
22 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 37 private Interface interf;
33 38 private JTextField currentTick;
34 39 private JLabel maxTicks;
  40 + private JPanel scrollPanel;
35 41  
36   - public TimeLineJPanel(Interface interf, MusicList list) {
  42 + public TimeLineJPanel(Interface interf) {
37 43 this.interf = interf;
38 44 setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
39 45  
... ... @@ -58,71 +64,129 @@ public class TimeLineJPanel extends JPanel implements MouseWheelListener, FocusL
58 64  
59 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 95 interf.timeLineList = new TimeLineJList(listModel, interf);
68 96 musicRenderer = new MusicRenderer(this);
69 97 interf.timeLineList.setCellRenderer(musicRenderer);
70 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 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 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 135 public void updateTick() {
87 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 147 public void mouseWheelMoved(MouseWheelEvent e) {
99 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 191 @Override
128 192 public void focusLost(FocusEvent e) {
... ... @@ -143,4 +207,22 @@ public class TimeLineJPanel extends JPanel implements MouseWheelListener, FocusL
143 207 if(e.getSource() == currentTick)
144 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 43  
44 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