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