]> ruin.nu Git - moosique.git/blob - MooNoteElement.java
Fixed drag select in track view.
[moosique.git] / MooNoteElement.java
1 import javax.swing.*;
2 import java.awt.*;
3 import java.awt.event.*;
4
5 /**
6  * Graphical representation of a MIDI note.
7  * 
8  * @author  Andersson, Andreen, Lanneskog, Pehrson
9  * @version 1
10  */
11  
12 public class MooNoteElement extends JPanel {
13
14         private MooTrackView mtv;
15         private MooNote note;
16         private JPopupMenu popup;
17         private JMenuItem popupRemove, popupProp, popupTranspOctUp, popupTranspOctDown;
18         private Rectangle pitchRect, veloRect;
19         private String notePitch, noteVelocity;
20         private boolean selected = false;
21         public Color textColor;
22         public static final Color bgColor = new Color(160, 218, 255);
23         public static final Color invBgColor = new Color(96, 38, 0);
24
25         /** 
26          * Creates a new note element.
27          * @param parent        The MooTrackView that this element will be painted on.
28          * @param mn            the note that will be graphically represented
29          */
30         public MooNoteElement (MooTrackView parent, MooNote mn) {
31                 mtv = parent;
32                 note = mn;
33                 calculateString();
34                 addMouseListener(new MAdapter());
35                 setBorder(BorderFactory.createLineBorder(Color.black));
36                 setBackground(bgColor);
37                 textColor = Color.black;
38
39                 // Defines coordinates.
40                 pitchRect = new Rectangle(0, 0, 15, 10);
41                 veloRect = new Rectangle(20, 0, 40, 10);
42
43                 // Creates pop-up menu.
44                 popup = new JPopupMenu();
45                 PopupListener pList = new PopupListener();
46                 popupProp = new JMenuItem("Preferences...");
47                 popupProp.addActionListener(pList);
48                 popup.add(popupProp);
49                 popupRemove = new JMenuItem("Remove");
50                 popupRemove.addActionListener(pList);
51                 popup.add(popupRemove);
52                 popupTranspOctUp = new JMenuItem("Transpose one octave up");
53                 popupTranspOctUp.addActionListener(pList);
54                 popup.add(popupTranspOctUp);
55                 popupTranspOctDown = new JMenuItem("Transpose one octave down");
56                 popupTranspOctDown.addActionListener(pList);
57                 popup.add(popupTranspOctDown);
58         }
59
60         /** 
61          * Returns the note of this element.
62          * @return the note
63          */
64         public MooNote getNote() {
65                 return note;
66         }
67
68         /** 
69          * Selects the current NoteElement.
70          */
71         public void select() {
72                 selected = true;
73                 mtv.selectNote(this);
74                 setBackground(invBgColor);
75                 textColor = Color.white;
76                 repaint();
77         }
78
79         /** 
80          * Deselects the current NoteElement.
81          */
82         public void deselect() {
83                 selected = false;
84                 // mtv.deselectNote(this);
85                 setBackground(bgColor);
86                 textColor = Color.black;
87                 repaint();
88         }
89
90         /** 
91          * Transposes the current note element the given number of halftones.
92          * @param halftones     the number of halftones to transpose - positive for up, negative for down
93          */
94         public void transpose(int halftones) {
95                 note.transpose(halftones);
96                 update();
97         }
98
99         /**
100          * Draws the string that shows the note's properties.
101          * @param g     The Graphics object used to draw the strings.
102          */
103         public void paintComponent(Graphics g)
104         {
105                 super.paintComponent(g);
106                 if (!(g instanceof Graphics2D)) return;
107                 Graphics2D g2 = (Graphics2D)g;
108                 g2.setColor(textColor);
109                 g2.setFont(new Font("Helvetica", Font.PLAIN, 8));
110         /*
111                 switch(columns) {
112                         case 0:
113                         case 1:
114                         ...
115                 }
116         */
117                 
118                 g2.drawString(notePitch, 1, 8);
119                 g2.drawString("" + noteVelocity, 21, 8);
120         }
121
122         /**
123          * Calculate what the string that shows the note properties should look like.
124          */
125         protected void calculateString(){
126
127                 noteVelocity = ""; 
128                 notePitch = "";
129                 if(note == null) return;
130
131                 int pitch = note.getPitch();
132                 switch (pitch % 12) {
133                         case  0: notePitch = "C";  break;
134                         case  1: notePitch = "C#"; break;
135                         case  2: notePitch = "D";  break;
136                         case  3: notePitch = "D#"; break;
137                         case  4: notePitch = "E";  break;
138                         case  5: notePitch = "F";  break;
139                         case  6: notePitch = "F#"; break;
140                         case  7: notePitch = "G";  break;
141                         case  8: notePitch = "G#"; break;
142                         case  9: notePitch = "A";  break;
143                         case 10: notePitch = "A#"; break;
144                         case 11: notePitch = "B";  break;
145                 }
146                 notePitch += pitch / 12 - 1;
147                 noteVelocity = ""+note.getVelocity();
148         }
149
150
151         /**
152          * Asks the MooTrackView that the note element is painted on to remove this element and the note.
153          */
154         protected void remove(){
155                 mtv.removeNote(this);
156         }
157
158         /**
159          * Updates the graphical content of the element and repaints it.
160          */
161         public void update() {
162                 calculateString();
163                 repaint();
164         }
165
166         /**
167          * Layout this changed elemnt.
168          */
169         protected void newLayout(){
170                 mtv.layoutElement(this,true);
171         }
172
173         /**
174          * Listener that checks the mouse actions on this element.
175          */
176         class MAdapter extends MouseAdapter {
177         
178                 /**
179                  * Selects the note if 
180                  */
181                 public void mouseEntered(MouseEvent e) {
182                         if (mtv.isLeftMouseButtonPressed()) select();
183                 }
184
185                 /**
186                  * If left mouse button is clicked, selects the note and plays it.
187                  */
188                 public void mouseClicked(MouseEvent e) {
189                         if (SwingUtilities.isLeftMouseButton(e) && !e.isControlDown()) {
190                                 select();
191                                 // Play the note
192                         }
193                 }
194
195                 /**
196                  * Checks if the mouse is pressed.
197                  * Increases the pitch or velocity if the right mouse button is pressed while holding CTRL.
198                  * Decreases the pitch or velocity if the left mouse button is pressed while holding CTRL.
199                  * @param e the event recieved.
200                  */
201                 public void mousePressed(MouseEvent e) {
202                         if (e.isControlDown()) {
203                                 if (pitchRect.contains(e.getPoint())) {
204                                         if (SwingUtilities.isRightMouseButton(e)) {
205                                                 note.transpose(1);
206                                         } else if (SwingUtilities.isLeftMouseButton(e)) {
207                                                 note.transpose(-1);
208                                         }
209                                         Moosique.setEdited();
210                                         calculateString();
211                                         repaint();
212                                 } else if (veloRect.contains(e.getPoint())) {
213                                         if (SwingUtilities.isRightMouseButton(e)) {
214                                                 note.setVelocity(note.getVelocity() + 1);
215                                         } else if (SwingUtilities.isLeftMouseButton(e)) {
216                                                 note.setVelocity(note.getVelocity() - 1);
217                                         }
218                                         Moosique.setEdited();
219                                         calculateString();
220                                         repaint();
221                                 }
222                         } else maybeShowPopup(e);
223                 }
224
225                 public void mouseReleased(MouseEvent e) {
226                         maybeShowPopup(e);
227                 }
228
229                 /**
230                  * Shows the menu if an OS-specific popup-trigger was activated.
231                  */
232                 private void maybeShowPopup(MouseEvent e) {
233                         if (e.isPopupTrigger() && !e.isControlDown()) {
234                                 if (!selected || mtv.isTheOnlySelected((MooNoteElement)e.getComponent())) popup.show(e.getComponent(), e.getX(), e.getY());
235                                 else mtv.showSelectionPopup(e.getComponent(), e.getX(), e.getY());
236                         }
237                 }
238         }
239
240         /**
241          * Listens on the actions made to the popupmenu.
242          */
243         class PopupListener implements ActionListener {
244                 public void actionPerformed(ActionEvent e) {
245                         Object source = e.getSource();
246                         if (source == popupProp) {
247                                 new MooDialog(note);
248                                 newLayout();
249                         } else if (source == popupRemove) {
250                                 remove();
251                         } else if (source == popupTranspOctUp) {
252                                 transpose(12);
253                         } else if (source == popupTranspOctDown) {
254                                 transpose(-12);
255                         }
256                 }
257         }
258 }