From a8b0b5e27d120df964c5b6d8554a6207951b00d0 Mon Sep 17 00:00:00 2001 From: Einar Pehrson Date: Sun, 18 May 2003 13:37:54 +0000 Subject: [PATCH] no message --- MooDialog.java | 61 ++++++++++++++---------------- MooGUI.java | 23 ++++-------- MooKeyboard.java | 21 ++++++++--- MooMenu.java | 64 ++++++++++++++++++-------------- MooNote.java | 10 ++++- MooNoteElement.java | 48 ++++++++++++------------ MooToolbar.java | 1 + MooTrackView.java | 90 +++++++++++++++++++++++++++++++++------------ Moosique.java | 72 ++++++++++++++++++++++++++---------- To Do.txt | 25 +++++++++---- 10 files changed, 261 insertions(+), 154 deletions(-) diff --git a/MooDialog.java b/MooDialog.java index a83ef8b..f78d24c 100644 --- a/MooDialog.java +++ b/MooDialog.java @@ -6,7 +6,7 @@ import java.io.*; import java.beans.*; /** - * The GUI-class representing the popupdialogs in the Track menu. + * A generator class for the application's dialogs. * * @author Björn Lanneskog */ @@ -21,8 +21,8 @@ public class MooDialog extends JDialog { DELETE_TRACK = 2, COPY_TRACK = 3, MOVE_TRACK = 4, - JUMP = 5, - CONTENTS = 6, + SET_POSITION = 5, + MANUAL = 6, INSERT_MEASURE = 7, DELETE_MEASURE = 8; @@ -42,8 +42,8 @@ public class MooDialog extends JDialog { case DELETE_TRACK: makeDelDialog(pane, tracks); break; case COPY_TRACK: makeCopyDialog(pane, tracks); break; case MOVE_TRACK: makeMoveDialog(pane, tracks); break; - case JUMP: makeJumpDialog(pane); break; - case CONTENTS: makeTextDialog(pane, "Manual.txt"); break; + case SET_POSITION: makeSetPositionDialog(pane); break; + case MANUAL: makeTextDialog(pane, "Manual.txt"); break; case INSERT_MEASURE: makeInsertMeasureDialog(pane); break; case DELETE_MEASURE: makeDeleteMeasureDialog(pane); break; } @@ -78,11 +78,10 @@ public class MooDialog extends JDialog { cancelButton.setBounds(10, 150, 80, 30); okButton.setBounds(120, 150, 60, 30); - setLocation((Toolkit.getDefaultToolkit().getScreenSize().width - this.getWidth()) / 2, - (Toolkit.getDefaultToolkit().getScreenSize().height - this.getHeight()) / 2); setResizable(false); pack(); setSize(200,220); + setLocationRelativeTo(Moosique.getGUI()); setVisible(true); } @@ -109,11 +108,10 @@ public class MooDialog extends JDialog { cancelButton.setBounds(10, 90, 80, 30); okButton.setBounds(120, 90, 60, 30); - setLocation((Toolkit.getDefaultToolkit().getScreenSize().width - this.getWidth()) / 2, - (Toolkit.getDefaultToolkit().getScreenSize().height - this.getHeight()) / 2); setResizable(false); pack(); setSize(200,165); + setLocationRelativeTo(Moosique.getGUI()); setVisible(true); } @@ -147,11 +145,10 @@ public class MooDialog extends JDialog { cancelButton.setBounds(10, 150, 80, 30); okButton.setBounds(120, 150, 60, 30); - setLocation((Toolkit.getDefaultToolkit().getScreenSize().width - this.getWidth()) / 2, - (Toolkit.getDefaultToolkit().getScreenSize().height - this.getHeight()) / 2); setResizable(false); pack(); setSize(200,220); + setLocationRelativeTo(Moosique.getGUI()); setVisible(true); } @@ -185,23 +182,22 @@ public class MooDialog extends JDialog { cancelButton.setBounds(10, 150, 80, 30); okButton.setBounds(120, 150, 60, 30); - setLocation((Toolkit.getDefaultToolkit().getScreenSize().width - this.getWidth()) / 2, - (Toolkit.getDefaultToolkit().getScreenSize().height - this.getHeight()) / 2); setResizable(false); pack(); setSize(200,220); + setLocationRelativeTo(Moosique.getGUI()); setVisible(true); } /** - * Builds the jump popupdialog. + * Builds the set position dialog. * @param pane The container to put the dialog in. * @param tracks A array containing miditracks. */ - private void makeJumpDialog(Container pane) { + private void makeSetPositionDialog(Container pane) { - setTitle("Jump"); - labelA = new JLabel("Msr", JLabel.CENTER); + setTitle("Set edit position"); + labelA = new JLabel("Measure", JLabel.CENTER); pane.add(labelA); labelB = new JLabel("Beat", JLabel.CENTER); pane.add(labelB); @@ -227,11 +223,10 @@ public class MooDialog extends JDialog { cancelButton.setBounds(35, 90, 80, 30); okButton.setBounds(155, 90, 60, 30); - setLocation((Toolkit.getDefaultToolkit().getScreenSize().width - this.getWidth()) / 2, - (Toolkit.getDefaultToolkit().getScreenSize().height - this.getHeight()) / 2); setResizable(false); pack(); setSize(260,165); + setLocationRelativeTo(Moosique.getGUI()); setVisible(true); } @@ -262,11 +257,10 @@ public class MooDialog extends JDialog { cancelButton.setBounds(20 ,95 , 80, 30); okButton.setBounds(120, 95, 60, 30); - setLocation((Toolkit.getDefaultToolkit().getScreenSize().width - this.getWidth()) / 2, - (Toolkit.getDefaultToolkit().getScreenSize().height - this.getHeight()) / 2); setResizable(false); pack(); setSize(210,175); + setLocationRelativeTo(Moosique.getGUI()); setVisible(true); } @@ -297,16 +291,16 @@ public class MooDialog extends JDialog { cancelButton.setBounds(20 ,95 , 80, 30); okButton.setBounds(120, 95, 60, 30); - setLocation((Toolkit.getDefaultToolkit().getScreenSize().width - this.getWidth()) / 2, - (Toolkit.getDefaultToolkit().getScreenSize().height - this.getHeight()) / 2); setResizable(false); pack(); setSize(210,175); + setLocationRelativeTo(Moosique.getGUI()); setVisible(true); } private void makeTextDialog(Container pane, String filename) { - setTitle("Contents"); + setTitle("User Manual"); + pane.setLayout(new BoxLayout(pane, BoxLayout.Y_AXIS)); File manual = new File(filename); String s; try { @@ -317,15 +311,17 @@ public class MooDialog extends JDialog { } catch (Exception ex) { s = "Manual not found"; } - JTextArea contents = new JTextArea(s, 30, 40); - contents.setAutoscrolls(true); - pane.add(contents); - contents.setBounds(10, 10, 500, 350); + pane.add(new JScrollPane(new JTextArea(s, 30, 95))); + Action close = new AbstractAction("Close") { + public void actionPerformed(ActionEvent ae) { + setVisible(false); + }}; + JButton closeButton = new JButton(close); + closeButton.setAlignmentX(Component.CENTER_ALIGNMENT); + pane.add(closeButton); setResizable(false); pack(); - setSize(600,400); - setLocation((Toolkit.getDefaultToolkit().getScreenSize().width - this.getWidth()) / 2, - (Toolkit.getDefaultToolkit().getScreenSize().height - this.getHeight()) / 2); + setLocationRelativeTo(Moosique.getGUI()); setVisible(true); } @@ -347,7 +343,6 @@ public class MooDialog extends JDialog { pitchpanel.add(new Label("Pitch: ")); pitchpanel.add(pitch); - velocity = new JTextField(new Integer(note.getVelocity()).toString(),3); JPanel velocitypanel = new JPanel(); velocitypanel.add(new Label("Velocity: ")); @@ -363,7 +358,7 @@ public class MooDialog extends JDialog { velocitypanel, lengthpanel}; - final String btnString1 = "Enter"; + final String btnString1 = "Apply changes"; final String btnString2 = "Cancel"; Object[] options = {btnString1, btnString2}; diff --git a/MooGUI.java b/MooGUI.java index 4c008f4..77883c9 100644 --- a/MooGUI.java +++ b/MooGUI.java @@ -21,6 +21,7 @@ public class MooGUI extends JFrame { public static final int statusResetDelay = 3000; public static final Font FONT = new Font("Helvetica", Font.PLAIN, 10); public static final Color bgColor = new Color(192, 224, 255); + public static final Image logo = Toolkit.getDefaultToolkit().getImage("images/moose.gif"); /** * Creates the GUI. @@ -59,8 +60,6 @@ public class MooGUI extends JFrame { setBackground(menu); setBackground(toolbar); setBackground(view); - statusBar.setBackground(bgColor); - view.setBackground(bgColor); // Creates timer. timer = new java.util.Timer(); @@ -77,28 +76,22 @@ public class MooGUI extends JFrame { } }}; am.put("Play", playAction); - am.put("Octave change 2", createOctaveAction(2)); - am.put("Octave change 4", createOctaveAction(4)); - am.put("Octave change 6", createOctaveAction(6)); - am.put("Octave change 8", createOctaveAction(8)); + am.put("Change octave up", createOctaveAction(1)); + am.put("Change octave down", createOctaveAction(-1)); InputMap im = getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT); KeyStroke playKey = KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0); - KeyStroke octave2Key = KeyStroke.getKeyStroke(KeyEvent.VK_F9, 0); - KeyStroke octave4Key = KeyStroke.getKeyStroke(KeyEvent.VK_F10, 0); - KeyStroke octave6Key = KeyStroke.getKeyStroke(KeyEvent.VK_F11, 0); - KeyStroke octave8Key = KeyStroke.getKeyStroke(KeyEvent.VK_F12, 0); + KeyStroke octaveUpKey = KeyStroke.getKeyStroke(KeyEvent.VK_F9, 0); + KeyStroke octaveDownKey = KeyStroke.getKeyStroke(KeyEvent.VK_F10, 0); im.put(playKey, "Play"); - im.put(octave2Key, "Octave change 2"); - im.put(octave4Key, "Octave change 4"); - im.put(octave6Key, "Octave change 6"); - im.put(octave8Key, "Octave change 8"); + im.put(octaveUpKey, "Change octave up"); + im.put(octaveDownKey, "Change octave down"); advanceStatus(); // Configures window. addWindowListener(new MooGUICloser()); pack(); - setIconImage(Toolkit.getDefaultToolkit().getImage("images/moose.gif")); + setIconImage(logo); Dimension bounds = Toolkit.getDefaultToolkit().getScreenSize(); setSize(bounds.width,bounds.height - 40); setLocation(0, 0); diff --git a/MooKeyboard.java b/MooKeyboard.java index 35b2496..7031c40 100644 --- a/MooKeyboard.java +++ b/MooKeyboard.java @@ -9,9 +9,18 @@ import java.awt.event.*; public class MooKeyboard extends KeyAdapter { - private boolean[] isOn = new boolean[120]; - private static int startNote = 48; - private static final int[] keyToNote = new int[120]; + private boolean[] isOn; + private static int startNote; + private static int[] keyToNote; + + /** + * Sets up the synthesizer emulation. + */ + public MooKeyboard() { + isOn = new boolean[120]; + keyToNote = new int[120]; + setOctave(4); + } /** * Plays the appropriate MIDI NoteOn event. @@ -48,7 +57,9 @@ public class MooKeyboard extends KeyAdapter { * @param n the octave to start at */ public static void setOctave(int n) { - startNote = n * 12; + if (startNote == 0 || startNote == 108) return; + startNote += n*12; + makeKeyboardMapping(); } /** Maps keycodes (array indices) to MIDI note numbers using the following layout: @@ -58,7 +69,7 @@ public class MooKeyboard extends KeyAdapter { * s d g h j l => # # # # # # * z x c v b n m , . => c d e f g a b c d */ - static { + private static void makeKeyboardMapping() { keyToNote[KeyEvent.VK_Q] = startNote; keyToNote[83] = startNote + 1; keyToNote[88] = startNote + 2; diff --git a/MooMenu.java b/MooMenu.java index f4090bd..3b1e9fa 100644 --- a/MooMenu.java +++ b/MooMenu.java @@ -12,7 +12,7 @@ import java.awt.*; */ public class MooMenu extends JMenuBar implements ActionListener { - private JMenu file, edit, playback, music, help; + private JMenu file, edit, keyboard, playback, music, help; private JFileChooser chooser; private File directory; @@ -26,7 +26,8 @@ public class MooMenu extends JMenuBar implements ActionListener { addItem(file, "New", KeyEvent.VK_N, ActionEvent.CTRL_MASK); addItem(file, "Open...", KeyEvent.VK_O, ActionEvent.CTRL_MASK); addItem(file, "Save", KeyEvent.VK_S, ActionEvent.CTRL_MASK); - addItem(file, "Save as..."); + addItem(file, "Save as...", KeyEvent.VK_A); + file.addSeparator(); addItem(file, "Exit", KeyEvent.VK_Q, ActionEvent.CTRL_MASK); edit = createMenu("Edit", KeyEvent.VK_E); @@ -35,6 +36,7 @@ public class MooMenu extends JMenuBar implements ActionListener { addItem(edit, "Copy", KeyEvent.VK_C, ActionEvent.CTRL_MASK); addItem(edit, "Cut", KeyEvent.VK_X, ActionEvent.CTRL_MASK); addItem(edit, "Paste", KeyEvent.VK_V, ActionEvent.CTRL_MASK); + edit.addSeparator(); addItem(edit, "Select all", KeyEvent.VK_E, ActionEvent.CTRL_MASK); addItem(edit, "Invert selection", KeyEvent.VK_I, ActionEvent.CTRL_MASK); edit.addSeparator(); @@ -43,10 +45,15 @@ public class MooMenu extends JMenuBar implements ActionListener { playback = createMenu("Playback", KeyEvent.VK_P); add(playback); - addItem(playback, "Play", "F5"); - addItem(playback, "Pause", "F7"); - addItem(playback, "Stop", "F6"); - addItem(playback, "Jump..."); + addItem(playback, "Play", "F5", KeyEvent.VK_P); + addItem(playback, "Pause", "F7", KeyEvent.VK_A); + addItem(playback, "Stop", "F6", KeyEvent.VK_S); + playback.addSeparator(); + addItem(playback, "Set position...", KeyEvent.VK_E); + playback.addSeparator(); + keyboard = createMenu("Set keyboard octave", KeyEvent.VK_K); + edit.add(keyboard); + for (int i = 9; i >= 0; i--) addItem(keyboard, "Octave " + i, i + 48); music = createMenu("Music", KeyEvent.VK_M); add(music); @@ -56,20 +63,20 @@ public class MooMenu extends JMenuBar implements ActionListener { addItem(music, "Copy track...", KeyEvent.VK_Y, ActionEvent.CTRL_MASK); addItem(music, "Move track...", KeyEvent.VK_M, ActionEvent.CTRL_MASK); music.addSeparator(); - addItem(music, "Insert measure..."); - addItem(music, "Delete measure..."); + addItem(music, "Insert measure...", KeyEvent.VK_I); + addItem(music, "Delete measure...", KeyEvent.VK_E); music.addSeparator(); - addItem(music, "Set time signature..."); - addItem(music, "Set tempo..."); - addItem(music, "Scale velocity..."); - addItem(music, "Transpose..."); + addItem(music, "Set time signature...", KeyEvent.VK_S); + addItem(music, "Set tempo...", KeyEvent.VK_M); + addItem(music, "Scale velocity...", KeyEvent.VK_V); + addItem(music, "Transpose...", KeyEvent.VK_T); help = createMenu("Help", KeyEvent.VK_L); add(help); - addItem(help, "Contents", "F1"); - addItem(help, "Getting started"); - addItem(help, "About"); + addItem(help, "User manual", "F1", KeyEvent.VK_M); + help.addSeparator(); + addItem(help, "About", KeyEvent.VK_A); } /** * Creats a menu in the menubar. @@ -89,7 +96,7 @@ public class MooMenu extends JMenuBar implements ActionListener { * @param name The name of the menuitem. * @return item The menuitem created. */ - private JMenuItem addItem(JMenu menu, String name) { + private JMenuItem addItem(JMenu menu, String name, int mnemonic) { JMenuItem item = new JMenuItem(name); item.addActionListener(this); menu.add(item); @@ -103,9 +110,10 @@ public class MooMenu extends JMenuBar implements ActionListener { * @param key The keystroke to access this menuitem. * @return item The menuitem created. */ - private JMenuItem addItem(JMenu menu, String name, String key) { + private JMenuItem addItem(JMenu menu, String name, String key, int mnemonic) { JMenuItem item = new JMenuItem(name); item.setAccelerator(KeyStroke.getKeyStroke(key)); + item.setMnemonic(mnemonic); item.addActionListener(this); menu.add(item); return item; @@ -122,6 +130,7 @@ public class MooMenu extends JMenuBar implements ActionListener { private JMenuItem addItem(JMenu menu, String name, int key, int mask) { JMenuItem item = new JMenuItem(name); item.setAccelerator(KeyStroke.getKeyStroke(key, mask)); + item.setMnemonic(key); item.addActionListener(this); menu.add(item); return item; @@ -184,9 +193,11 @@ public class MooMenu extends JMenuBar implements ActionListener { if (Moosique.getSequencer().isRunning()) Moosique.pause(); } else if (command == "Stop") { Moosique.stop(); - } else if (command == "Jump...") { - MooDialog newDialog = new MooDialog(MooDialog.JUMP); + } else if (command == "Set position...") { + MooDialog newDialog = new MooDialog(MooDialog.SET_POSITION); // Moosique.setPosition(???); Räkna ut från msr, beats, ticks, time sig. + } else if (command.startsWith("Octave")) { + MooKeyboard.setOctave(Integer.parseInt(command.substring(7,8))); } else if (command == "Add track...") { MooDialog newDialog = new MooDialog(MooDialog.ADD_TRACK); Moosique.getSequence().createTrack(); @@ -214,15 +225,14 @@ public class MooMenu extends JMenuBar implements ActionListener { } else if (command == "Transpose...") { - } else if (command == "Contents") { - MooDialog contents = new MooDialog(MooDialog.CONTENTS); - } else if (command == "Getting started") { - - JOptionPane.showMessageDialog(null, "här kommer getting started komma"); - + } else if (command == "User manual") { + MooDialog manual = new MooDialog(MooDialog.MANUAL); } else if (command == "About") { - - JOptionPane.showMessageDialog(null, "här kommer about att komma"); + JOptionPane.showMessageDialog(null, + "Moosique\nversion 1.0\n\nby\n\nRoland Andersson\nMichael Andreen\nBjörn Lanneskog\nEinar Pehrson", + "About Moosique", + JOptionPane.INFORMATION_MESSAGE, + new ImageIcon(Moosique.getGUI().logo)); } } diff --git a/MooNote.java b/MooNote.java index fbc0668..78e1564 100644 --- a/MooNote.java +++ b/MooNote.java @@ -75,6 +75,14 @@ public class MooNote extends MidiEvent { } catch (InvalidMidiDataException e) {} } + /** + * Transposes the current note the given number of halftones. + * @param halftones the number of halftones to transpose - positive for up, negative for down + */ + public void transpose(int halftones) { + setPitch(getPitch() + halftones); + } + /** * Sets the velocity of the current note. * @param vel the velocity of the note (0-127) @@ -99,7 +107,7 @@ public class MooNote extends MidiEvent { * @param tick the timestamp of the note in ticks (96 per beat) */ public void setTick(long tick) { - if (hasNoteOffEvent()) noteOffEvent.setTick(tick + getDuration()); + if (hasNoteOffEvent()) noteOffEvent.setTick(tick + getDuration()); super.setTick(tick); } diff --git a/MooNoteElement.java b/MooNoteElement.java index f6bda05..67555fc 100644 --- a/MooNoteElement.java +++ b/MooNoteElement.java @@ -14,7 +14,7 @@ public class MooNoteElement extends JPanel { private MooTrackView mtv; private MooNote note; private JPopupMenu popup; - private JMenuItem popupRemove, popupProp, popupTransposeOctUp, popupTransposeOctDown; + private JMenuItem popupRemove, popupProp, popupTranspOctUp, popupTranspOctDown; private Rectangle pitchRect, veloRect; private String notePitch, noteVelocity; private boolean selected = false; @@ -25,7 +25,7 @@ public class MooNoteElement extends JPanel { /** * Creates a new note element. * @param parent The MooTrackView that this element will be painted on. - * @param mn the note that will be graphically represented + * @param mn the note that will be graphically represented */ public MooNoteElement (MooTrackView parent, MooNote mn) { mtv = parent; @@ -49,12 +49,12 @@ public class MooNoteElement extends JPanel { popupRemove = new JMenuItem("Remove"); popupRemove.addActionListener(pList); popup.add(popupRemove); - popupTransposeOctUp = new JMenuItem("Transpose one octave up"); - popupTransposeOctUp.addActionListener(pList); - popup.add(popupTransposeOctUp); - popupTransposeOctDown = new JMenuItem("Transpose one octave down"); - popupTransposeOctDown.addActionListener(pList); - popup.add(popupTransposeOctDown); + popupTranspOctUp = new JMenuItem("Transpose one octave up"); + popupTranspOctUp.addActionListener(pList); + popup.add(popupTranspOctUp); + popupTranspOctDown = new JMenuItem("Transpose one octave down"); + popupTranspOctDown.addActionListener(pList); + popup.add(popupTranspOctDown); } /** @@ -70,7 +70,7 @@ public class MooNoteElement extends JPanel { */ public void select() { selected = true; - mtv.addSelected(this); + mtv.selectNote(this); setBackground(invBgColor); textColor = Color.white; repaint(); @@ -81,7 +81,7 @@ public class MooNoteElement extends JPanel { */ public void deselect() { selected = false; - // mtv.removeSelected(this); + // mtv.deselectNote(this); setBackground(bgColor); textColor = Color.black; repaint(); @@ -134,7 +134,7 @@ public class MooNoteElement extends JPanel { case 10: notePitch = "A#"; break; case 11: notePitch = "B"; break; } - notePitch += pitch / 12; + notePitch += pitch / 12 - 1; noteVelocity = ""+note.getVelocity(); } @@ -146,6 +146,14 @@ public class MooNoteElement extends JPanel { mtv.removeNote(this); } + /** + * Updates the graphical content of the element and repaints it. + */ + public void update() { + calculateString(); + repaint(); + } + /** * layout this changed elemnt */ @@ -177,9 +185,9 @@ public class MooNoteElement extends JPanel { if (e.isControlDown()) { if (pitchRect.contains(e.getPoint())) { if (SwingUtilities.isRightMouseButton(e)) { - note.setPitch(note.getPitch() + 1); + note.transpose(1); } else if (SwingUtilities.isLeftMouseButton(e)) { - note.setPitch(note.getPitch() - 1); + note.transpose(-1); } Moosique.setEdited(); calculateString(); @@ -223,19 +231,13 @@ public class MooNoteElement extends JPanel { newLayout(); } else if (source == popupRemove) { remove(); - } else if (source == popupTransposeOctUp) { - note.setPitch(note.getPitch() + 12); + } else if (source == popupTranspOctUp) { + note.transpose(12); update(); - } else if (source == popupTransposeOctDown) { - note.setPitch(note.getPitch() - 12); + } else if (source == popupTranspOctDown) { + note.transpose(-12); update(); } } - - private void update() { - calculateString(); - repaint(); - } - } } diff --git a/MooToolbar.java b/MooToolbar.java index 43027c5..50aaf4d 100644 --- a/MooToolbar.java +++ b/MooToolbar.java @@ -24,6 +24,7 @@ public class MooToolbar extends JToolBar { */ public MooToolbar() { + setLayout(new BoxLayout(this, BoxLayout.X_AXIS)); // setAlignmentX(LEFT_ALIGNMENT); setFloatable(false); mouseAdapter = new MAdapter(); diff --git a/MooTrackView.java b/MooTrackView.java index 0e5d09c..f2afcaa 100644 --- a/MooTrackView.java +++ b/MooTrackView.java @@ -17,8 +17,11 @@ public class MooTrackView extends JPanel { private MooTrackTitle title; private Rectangle box; - private JPopupMenu popup; + private JPopupMenu popup, selPopup; + private JMenu selPopupTranspUp, selPopupTranspDown; private JMenuItem popupAdd; + private JMenuItem selPopupRemove, selPopupTranspUpOct, selPopupTranspDownOct; + private ArrayList rects; private ArrayList selected; private Insets insets; @@ -65,13 +68,29 @@ public class MooTrackView extends JPanel { } - // Creates pop-up menu. + // Creates panel pop-up menu. popup = new JPopupMenu(); PopupListener pList = new PopupListener(); popupAdd = new JMenuItem("Add note..."); popupAdd.addActionListener(pList); popup.add(popupAdd); + // Creates selection pop-up menu. + selPopup = new JPopupMenu(); + selPopupRemove = new JMenuItem("Remove selection"); + selPopupRemove.addActionListener(pList); + selPopup.add(selPopupRemove); + selPopupTranspUp = new JMenu("Transpose selection up"); + selPopup.add(selPopupTranspUp); + selPopupTranspUpOct = new JMenuItem("One octave"); + selPopupTranspUpOct.addActionListener(pList); + selPopupTranspUp.add(selPopupTranspUpOct); + selPopupTranspDown = new JMenu("Transpose selection down"); + selPopup.add(selPopupTranspDown); + selPopupTranspDownOct = new JMenuItem("One octave"); + selPopupTranspDownOct.addActionListener(pList); + selPopupTranspDown.add(selPopupTranspDownOct); + // Adds listeners for popup menu and keyboard synthesizer. addMouseListener(new MAdapter()); addKeyListener(new MooKeyboard()); @@ -161,6 +180,15 @@ public class MooTrackView extends JPanel { repaint(); } + /** + * Adds a standard note to this track. + */ + private void addStandardNote() { + int row = (popupY - insets.top) / NOTE_HEIGHT; + long timestamp = (long)(ticksPerSixteenth * row); + addNote(new MooNote(title.getChannel(), 60, 100, timestamp, Moosique.getSequence().getResolution() / 4)); + } + /** * Removes the given note element from the view and its note from the current track. * @param elem the note element to remove @@ -168,38 +196,31 @@ public class MooTrackView extends JPanel { public void removeNote(MooNoteElement elem) { elem.getNote().removeFrom(track); remove(elem); - elem.getNote().removeFrom(track); + Rectangle r = new Rectangle(); + r = elem.getBounds(r); + rects.remove(r); Moosique.setEdited(); repaint(); } - /** - * Adds a standard note to this track. - */ - private void addStandardNote() { - int row = (popupY - insets.top) / NOTE_HEIGHT; - long timestamp = (long)(ticksPerSixteenth * row); - addNote(new MooNote(title.getChannel(), 60, 100, timestamp, Moosique.getSequence().getResolution() / 4)); - } - /** * Deselects all notes. */ - public void addSelected(MooNoteElement elem) { + public void selectNote(MooNoteElement elem) { selected.add(elem); } /** * Deselects all notes. */ - public void removeSelected(MooNoteElement elem) { + public void deselectNote(MooNoteElement elem) { selected.remove(selected.indexOf(elem)); } /** * Deselects all notes. */ - public void deselectAll() { + public void deselectAllNotes() { Iterator it = selected.iterator(); while(it.hasNext()) { ((MooNoteElement)it.next()).deselect(); @@ -226,7 +247,19 @@ public class MooTrackView extends JPanel { * @param y the y-coordinate in which to display the menu */ public void showSelectionPopup(Component c, int x, int y) { - + selPopup.show(c, x, y); + } + + /** + * Transposes all selected notes the given number of halftones. + */ + private void transposeSelectedNotes(int halftones) { + Iterator it = selected.iterator(); + while(it.hasNext()) { + MooNoteElement elem = (MooNoteElement)it.next(); + elem.getNote().transpose(halftones); + elem.update(); + } } /** @@ -254,10 +287,12 @@ public class MooTrackView extends JPanel { * Deselects all note on click, adds a standard note on double click. */ public void mouseClicked(MouseEvent e) { - deselectAll(); - if (e.getClickCount() == 2) { - popupY = e.getY(); - addStandardNote(); + if (SwingUtilities.isLeftMouseButton(e)) { + deselectAllNotes(); + if (e.getClickCount() == 2) { + popupY = e.getY(); + addStandardNote(); + } } } @@ -296,15 +331,24 @@ public class MooTrackView extends JPanel { } /** - * Listens on actions on the popupmenu and executes the appropriate action. + * Listens on actions on the popup menu and executes the appropriate action. */ class PopupListener implements ActionListener { public void actionPerformed(ActionEvent e) { Object source = e.getSource(); - if (source == popupAdd) { + if (source == popupAdd) { addStandardNote(); + } else if (source == selPopupRemove) { + Iterator it = selected.iterator(); + while(it.hasNext()) { + removeNote((MooNoteElement)it.next()); + } + selected.clear(); + } else if (source == selPopupTranspUpOct) { + transposeSelectedNotes(12); + } else if (source == selPopupTranspDownOct) { + transposeSelectedNotes(-12); } - // new MooNote(int channel, int pitch, int velocity, long timestamp, int duration) } } } diff --git a/Moosique.java b/Moosique.java index 0fc6fd7..5cf7af5 100644 --- a/Moosique.java +++ b/Moosique.java @@ -28,7 +28,7 @@ public class Moosique { private static String filename; private static long editPosition; - private static boolean makeGUI = true, isEdited = false, drawEmptyTracks = false; + private static boolean makeGUI = true, initSound = true, isEdited = false, drawEmptyTracks = false; private static Thread player; public static final int DEFAULT_RESOLUTION = 96, DEFAULT_TRACKS = 4; @@ -44,8 +44,9 @@ public class Moosique { // Parses command-line arguments. String fileArg = null; for (int i = 0; i < args.length; i++) { - if (args[i].equals("-n")) {makeGUI = false;} - else if (fileArg == null) {fileArg = args[i];} + if (args[i].equals("-n")) makeGUI = false; + else if (args[i].equals("-m")) initSound = false; + else if (fileArg == null) fileArg = args[i]; } // Acquires MIDI devices and connects them. @@ -63,7 +64,7 @@ public class Moosique { setActiveChannel(0); } catch (MidiUnavailableException e) { System.out.println("Failed, quitting."); - // System.exit(1); + System.exit(1); } System.out.println("Done"); @@ -106,8 +107,8 @@ public class Moosique { /* *** - ** ACCESSOR METHODS ** - *** */ + ** ACCESSOR METHODS ** + *** */ @@ -156,6 +157,22 @@ public class Moosique { return gui; } + /** + * Calculates the position (measures, beats, ticks) in the current sequence for the given tick position. + * @return an array of integers where index 0 is measures, 1 is beats and 2 is ticks. + */ + public static int[] getPositionForTick(long ticks) { + /* + int measures, beats, ticks; + for (int i = 0; i < timeSignatures.length; i++) { + long tick = timeSignatures[i].getTick(); + // Split the ticks in the interval into measures, beats and ticks. + } + */ + int[] pos = {1, 1, 1}; + return pos; + } + /** * Returns the receiver of the current sequencer. * @return the receiver @@ -189,6 +206,21 @@ public class Moosique { // if (tempoMsg == null) return 0; } + /** + * Calculates the tick position in the current sequence for the given position (measures, beats, ticks). + * @return the tick position. + */ + public static long getTicksForPosition(int measures, int beats, int ticks) { + long tickPos = 0; + /* + for (int i = 0; i < timeSignatures.length; i++) { + long tick = timeSignatures[i].getTick(); + // Add the measures, beats and ticks in the interval. + } + */ + return tickPos; + } + /** * Returns the tempo of the current sequence. * @return the tick position @@ -224,8 +256,8 @@ public class Moosique { /* *** - ** MUTATOR METHODS ** - *** */ + ** MUTATOR METHODS ** + *** */ @@ -296,6 +328,14 @@ public class Moosique { public static void setTimeSig(int bpm) { // timeSigMsg } + + public static void setTrackSolo(Track track, boolean on){ + trackSolo.put(track, new Boolean(on)); + } + + public static void setTrackMute(Track track, boolean on){ + trackMute.put(track, new Boolean(on)); + } @@ -305,8 +345,8 @@ public class Moosique { /* *** - ** PLAYBACK METHODS ** - *** */ + ** PLAYBACK METHODS ** + *** */ @@ -404,8 +444,8 @@ public class Moosique { /* *** - ** SYSTEM & IO METHODS ** - *** */ + ** SYSTEM & IO METHODS ** + *** */ @@ -575,12 +615,4 @@ public class Moosique { if (synthesizer.isOpen()) synthesizer.close(); System.exit(0); } - - public static void setTrackSolo(Track track, boolean on){ - trackSolo.put(track, new Boolean(on)); - } - - public static void setTrackMute(Track track, boolean on){ - trackMute.put(track, new Boolean(on)); - } } diff --git a/To Do.txt b/To Do.txt index 8389106..2a768bd 100644 --- a/To Do.txt +++ b/To Do.txt @@ -1,17 +1,28 @@ + +IO +x Implementera ljudlös körning med -m. +x Lägg till alla metameddelanden i filerna vi skapar. Annars är det lite dumt. x Play hänger sig om man ändrar duration på en not.. x Spara konfiguration? Arbetskatalog Fem senast öppnade filerna Valda MIDI-enheter -x Fixa InstrumentList. -x Fixa så att toolbarens rutor sitter fast! + +TEMPO / TAKTART x Räkna ut tempo och taktart. Skicka (på nåt sätt) tempovektorn till MooToolbar. -x Gör en ruta för tempot i MooToolbar. +x Räkna ut position (takt, slag, cent) för tick i Moosique. Behövs i NoteProp, ViewCounter, Menu etc. x Gör en ruta för taktarten i MooViews övre vänstra hörn. -x Implementera klart menyn, med alla dialoger. (Går visst att göra med JOptionPane, kolla denna: - http://java.sun.com/tutorial/uiswing/components/example-swing/CustomDialog.java) -x Lägg till en tom panel i MooGUI för att fylla ut skärmen. Använd setBounds() +x Gör en ruta för tempot i MooToolbar. + +SWING +x Lägg till en tom panel i MooGUI för att fylla ut skärmen. Använd BoxLayout!! +x Fixa så att toolbarens rutor sitter fast! Använd BoxLayout!! +x Implementera klart menyn, med alla dialoger. +x Mnemonicsarna i menyn är konstiga... + +ANNAT +x Fixa InstrumentList. x Textfält som gör att man bara kan skriva in siffror? (MooNoteProp) MooTrackView @@ -29,4 +40,4 @@ x x Integrera MooViewCounter i MooTrackView genom att istället variera de horisontella streckens gråa nyanser?!? (Omöjligt att följa strecken till högra änden av skärmen.) - + \ No newline at end of file -- 2.39.2