]> ruin.nu Git - moosique.git/blob - MooTrackView.java
129b0af0e78aa91ba33f9416f8166fb32d19baec
[moosique.git] / MooTrackView.java
1 import javax.swing.*;
2 import java.awt.*;
3 import java.awt.event.*;
4 import javax.sound.midi.*;
5 import java.util.*;
6
7 /**
8  * Graphical representation of a MIDI track.
9  * 
10  * @author  Andersson , Andreen, Lanneskog, Pehrson
11  * @version 1
12  */
13
14 public class MooTrackView extends JPanel implements ActionListener {
15
16         private Track track;
17         private NoteArea notes;
18         private Rectangle box;
19         private JPopupMenu popup;
20         private JPopupMenu notePopup;
21         private JMenuItem menuItem;
22         protected static int viewLength = 0;
23         public static final int NOTE_HEIGHT = 10, NOTE_WIDTH = 40, VIEW_WIDTH = 200;
24
25         public MooTrackView (Track track) {
26                 super(true);
27                 this.track = track;
28                 setLayout(new BorderLayout());
29
30                 notes = new NoteArea(track);    
31                 notes.setBackground(Color.white);
32                 notes.setBorder(BorderFactory.createLineBorder(Color.black));
33
34                 popup = new JPopupMenu();
35                 menuItem = new JMenuItem("Add...");
36                 menuItem.addActionListener(this);
37                 popup.add(menuItem);
38
39                 notePopup = new JPopupMenu();
40                 menuItem = new JMenuItem("Preferences...");
41                 menuItem.addActionListener(this);
42                 notePopup.add(menuItem);
43
44 //              notes.addMouseListener(new PopupListener());
45                 add(notes, BorderLayout.CENTER);
46         }
47
48         public void actionPerformed(ActionEvent e) {}
49
50         public Track getTrack() {
51                 return track;
52         }
53
54
55         /** 
56          * Updates the track view.
57          */
58         public void update(long tickPosition) {
59                 repaint();
60         }
61
62         class NoteArea extends JPanel {
63                 public static final int NOTE_HEIGHT = 10, NOTE_WIDTH = 40, VIEW_WIDTH = 200;
64                 private ArrayList rects;
65
66                 public NoteArea(Track track) {
67                         // Configuring panel
68                         super(true);
69                         setLayout(null);
70                         setPreferredSize(new Dimension(VIEW_WIDTH, 140 * NOTE_HEIGHT));
71
72                         // Creating temporary variables
73                         MidiEvent note;
74                         MooNoteElement elem;
75                         int x, y, height;
76                         int beatsPerSixteenth = Moosique.getSequence().getResolution() / 4;
77                         rects = new ArrayList(track.size() / 2);
78
79                         // Placing note elements
80                         Insets insets = getInsets();
81                         for (int i = 0; i < track.size(); i++) {
82                                 note = track.get(i);
83                                 if (note instanceof MooNote) {
84                                         // Adds the note element to the note area.
85                                         MooNote mn = (MooNote)note;
86                                         elem = new MooNoteElement(mn);
87                                         add(elem);
88
89                                         // Moves the note element to the appropriate place.
90                                         x = insets.left;
91                                         y = insets.top + (int)(mn.getTick() / beatsPerSixteenth) * NOTE_HEIGHT;
92                                         height = (mn.getDuration() / beatsPerSixteenth) * NOTE_HEIGHT;
93                                         if (height == 0) height = NOTE_HEIGHT;
94                                         Rectangle r = new Rectangle(x, y, NOTE_WIDTH, height);
95                                         while(isOccupied(r)) r.translate(NOTE_WIDTH, 0);
96                                         elem.setBounds(r);
97                                         rects.add(r);
98                                         if (viewLength < (y + height)) viewLength = y + height;
99                                 }
100                                 setPreferredSize(new Dimension(VIEW_WIDTH, viewLength));
101                         }
102                         validate();
103                 }
104                 
105                 private boolean isOccupied(Rectangle r) {
106                         Iterator it = rects.iterator();
107                         while (it.hasNext()) {
108                                 if(r.intersects((Rectangle)it.next())) return true;
109                         }
110                         return false;
111                 }
112
113                 public void paintComponent(Graphics g) {
114                         super.paintComponent(g);
115                         Graphics2D g2 = (Graphics2D)g;
116                         for (int c = 0; c < viewLength || c < getHeight(); c += NOTE_HEIGHT) {
117                                 for (int r = 0; r < (10 * NOTE_WIDTH); r += NOTE_WIDTH) {
118                                         box = new Rectangle(r, c, NOTE_WIDTH, NOTE_HEIGHT);
119                                         g2.setColor(Color.gray);
120                                         g2.draw(box);
121                                 }
122                         }
123                 }
124         }
125
126         class PopupListener extends MouseAdapter {
127                 public void mousePressed(MouseEvent e) {
128                         maybeShowPopup(e);
129                 }
130
131                 public void mouseReleased(MouseEvent e) {
132                         maybeShowPopup(e);
133                 }
134
135                 private void maybeShowPopup(MouseEvent e) {
136                         if (e.isPopupTrigger()) {
137                                 if (findComponentAt(e.getX(), e.getY()) instanceof MooNoteElement)
138                                         notePopup.show(e.getComponent(), e.getX(), e.getY());
139                                 else
140                                         popup.show(e.getComponent(), e.getX(), e.getY());
141                         }
142                 }
143         }
144 }