]> ruin.nu Git - moosique.git/blobdiff - MooTrackView.java
Implemented editing functions - biggie!
[moosique.git] / MooTrackView.java
index f2afcaae2be4e18373b97a3250d4cfe5ce7b29e0..bf3590aedc59e2f25663b367beb3f85aef0763cd 100644 (file)
@@ -19,11 +19,10 @@ public class MooTrackView extends JPanel {
 
        private JPopupMenu popup, selPopup;
        private JMenu selPopupTranspUp, selPopupTranspDown;
-       private JMenuItem popupAdd;
-       private JMenuItem selPopupRemove, selPopupTranspUpOct, selPopupTranspDownOct;
+       private JMenuItem popupAdd, popupPaste;
+       private JMenuItem selPopupCopy, selPopupCut, selPopupRemove, selPopupTranspUpOct, selPopupTranspDownOct;
 
-       private ArrayList rects;
-       private ArrayList selected;
+       private ArrayList coords, selection, copyBuffer; 
        private Insets insets;
        private int ticksPerSixteenth, popupY = 0;
        protected static int viewLength = 0;
@@ -39,8 +38,17 @@ public class MooTrackView extends JPanel {
                super(true);
                this.track = track;
                this.title = title;
+
+               // Creates instance variables
                insets = getInsets();
-               selected = new ArrayList();
+               coords = new ArrayList(track.size() / 2);
+               selection = new ArrayList();
+               copyBuffer = new ArrayList();
+
+               // Creates temporary variables
+               MidiEvent note;
+               MooNoteElement elem;
+               extraHeight = Toolkit.getDefaultToolkit().getScreenSize().height - 150;
 
                // Configures panel
                setBackground(Color.white);
@@ -48,12 +56,6 @@ public class MooTrackView extends JPanel {
                setLayout(null);
                setPreferredSize(new Dimension(VIEW_WIDTH, 140 * NOTE_HEIGHT));
 
-               // Creates temporary variables
-               MidiEvent note;
-               MooNoteElement elem;
-               rects = new ArrayList(track.size() / 2);
-               extraHeight = Toolkit.getDefaultToolkit().getScreenSize().height - 150;
-
                // Places note elements
                for (int i = 0; i < track.size(); i++) {
                        note = track.get(i);
@@ -74,9 +76,18 @@ public class MooTrackView extends JPanel {
                popupAdd = new JMenuItem("Add note...");
                popupAdd.addActionListener(pList);
                popup.add(popupAdd);
+               popupPaste = new JMenuItem("Paste");
+               popupPaste.addActionListener(pList);
+               popup.add(popupPaste);
 
                // Creates selection pop-up menu.
                selPopup = new JPopupMenu();
+               selPopupCopy = new JMenuItem("Copy selection");
+               selPopupCopy.addActionListener(pList);
+               selPopup.add(selPopupCopy);
+               selPopupCut = new JMenuItem("Cut selection");
+               selPopupCut.addActionListener(pList);
+               selPopup.add(selPopupCut);
                selPopupRemove = new JMenuItem("Remove selection");
                selPopupRemove.addActionListener(pList);
                selPopup.add(selPopupRemove);
@@ -106,10 +117,10 @@ public class MooTrackView extends JPanel {
                Rectangle r = new Rectangle();
                if (old){
                        r = elem.getBounds(r);
-                       for (Iterator i = rects.iterator(); i.hasNext();){
+                       for (Iterator i = coords.iterator(); i.hasNext();){
                                Object ob = i.next();
                                if (r.equals(ob)){
-                                       rects.remove(ob);
+                                       coords.remove(ob);
                                        break;
                                }
                        }
@@ -130,12 +141,15 @@ public class MooTrackView extends JPanel {
                // Places the element in the appropriate place.
                while(isOccupied(r)) r.translate(NOTE_WIDTH, 0);
                elem.setBounds(r);
-               rects.add(r);
+               coords.add(r);
                if (viewLength < (y + height)){
                        viewLength = y + height;
                        if(old)setPreferredSize(new Dimension(VIEW_WIDTH, viewLength + extraHeight));
                }
-               if(old)repaint();
+               if (old) {
+                       validate();
+                       repaint();
+               }
        }
 
        /** 
@@ -159,7 +173,7 @@ public class MooTrackView extends JPanel {
         * @return true if the position is occupied.
         */
        private boolean isOccupied(Rectangle r) {
-               Iterator it = rects.iterator();
+               Iterator it = coords.iterator();
                while (it.hasNext()) {
                        if(r.intersects((Rectangle)it.next())) return true;
                }
@@ -177,6 +191,7 @@ public class MooTrackView extends JPanel {
                layoutElement(elem, false);
                setPreferredSize(new Dimension(VIEW_WIDTH, viewLength + extraHeight));
                Moosique.setEdited();
+               validate();
                repaint();
        }
 
@@ -184,7 +199,7 @@ public class MooTrackView extends JPanel {
         * Adds a standard note to this track.
         */
        private void addStandardNote() {
-               int row =  (popupY - insets.top) / NOTE_HEIGHT;
+               int row = (popupY - insets.top) / NOTE_HEIGHT;
                long timestamp = (long)(ticksPerSixteenth * row);
                addNote(new MooNote(title.getChannel(), 60, 100, timestamp, Moosique.getSequence().getResolution() / 4));
        }
@@ -198,34 +213,37 @@ public class MooTrackView extends JPanel {
                remove(elem);
                Rectangle r = new Rectangle();
                r = elem.getBounds(r);
-               rects.remove(r);
+               coords.remove(r);
                Moosique.setEdited();
+               validate();
                repaint();
        }
 
        /**
-        * Deselects all notes.
+        * Selects the given note
+        * @param the note to select
         */
        public void selectNote(MooNoteElement elem) {
-               selected.add(elem);
+               selection.add(elem);
        }
 
        /**
-        * Deselects all notes.
+        * Deselects the given note
+        * @param the note to deselect
         */
        public void deselectNote(MooNoteElement elem) {
-               selected.remove(selected.indexOf(elem));
+               selection.remove(selection.indexOf(elem));
        }
 
        /**
         * Deselects all notes.
         */
        public void deselectAllNotes() {
-               Iterator it = selected.iterator();
+               Iterator it = selection.iterator();
                while(it.hasNext()) {
                        ((MooNoteElement)it.next()).deselect();
                }
-               selected.clear();
+               selection.clear();
        }
 
        /**
@@ -233,7 +251,7 @@ public class MooTrackView extends JPanel {
         * @return if the given element is the only selected one
         */
        public boolean isTheOnlySelected(MooNoteElement elem) {
-               Iterator it = selected.iterator();
+               Iterator it = selection.iterator();
                while(it.hasNext()) {
                        if (!it.next().equals(elem)) return false;
                }
@@ -241,27 +259,74 @@ public class MooTrackView extends JPanel {
        }
 
        /**
-        * Shows a popup-menu with options for the current selection of note elements.
-        * @param c     the component over which to display the menu
-        * @param x     the x-coordinate in which to display the menu
-        * @param y     the y-coordinate in which to display the menu
+        * Copies the current selection.
         */
-       public void showSelectionPopup(Component c, int x, int y) {
-               selPopup.show(c, x, y);
+       public void copySelectedNotes() {
+               copyBuffer = new ArrayList(selection.size());
+               Iterator it = selection.iterator();
+               while(it.hasNext()) {
+                       copyBuffer.add(((MooNoteElement)it.next()).getNote().clone());
+               }
+               Collections.sort(copyBuffer, new Moosique.NoteComparator());
+       }
+
+       /**
+        * Cuts the current selection.
+        */
+       public void cutSelectedNotes() {
+               copySelectedNotes();
+               removeSelectedNotes();
+       }
+
+       /**
+        * Pastes the current copy buffer at the given timestamp.
+        */
+       public void pasteCopiedNotes() {
+               int row = (popupY - insets.top) / NOTE_HEIGHT;
+               long timestamp = (long)(ticksPerSixteenth * row);
+               if (copyBuffer.size() > 0) {
+                       long startTime = ((MooNote)copyBuffer.get(0)).getTick();
+                       Iterator it = copyBuffer.iterator();
+                       while(it.hasNext()) {
+                               MooNote mn = (MooNote)((MooNote)it.next()).clone();
+                               mn.setTick(mn.getTick() - startTime + timestamp);
+                               addNote(mn);
+                       }
+               }
+       }
+
+       /**
+        * Removes the current selection.
+        */
+       public void removeSelectedNotes() {
+               Iterator it = selection.iterator();
+               while(it.hasNext()) {
+                       removeNote((MooNoteElement)it.next());
+               }
+               selection.clear();
        }
 
        /**
         * Transposes all selected notes the given number of halftones.
         */
        private void transposeSelectedNotes(int halftones) {
-               Iterator it = selected.iterator();
+               Iterator it = selection.iterator();
                while(it.hasNext()) {
                        MooNoteElement elem = (MooNoteElement)it.next();
-                       elem.getNote().transpose(halftones);
-                       elem.update();
+                       elem.transpose(halftones);
                }
        }
 
+       /**
+        * Shows a popup-menu with options for the current selection of note elements.
+        * @param c     the component over which to display the menu
+        * @param x     the x-coordinate in which to display the menu
+        * @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);
+       }
+
        /**
         * Draws the grid that is on the background.
         * @param g The Graphics object used to draw the grid.
@@ -336,14 +401,18 @@ public class MooTrackView extends JPanel {
        class PopupListener implements ActionListener {
                public void actionPerformed(ActionEvent e) {
                        Object source = e.getSource();
+                       // Handling panel popup actions.
                        if (source == popupAdd) {
                                addStandardNote();
+                       } else if (source == popupPaste) {
+                               pasteCopiedNotes();
+                       // Handling selection popup actions.
+                       } else if (source == selPopupCopy) {
+                               copySelectedNotes();
+                       } else if (source == selPopupCut) {
+                               cutSelectedNotes();
                        } else if (source == selPopupRemove) {
-                               Iterator it = selected.iterator();
-                               while(it.hasNext()) {
-                                       removeNote((MooNoteElement)it.next());
-                               }
-                               selected.clear();
+                               removeSelectedNotes();
                        } else if (source == selPopupTranspUpOct) {
                                transposeSelectedNotes(12);
                        } else if (source == selPopupTranspDownOct) {