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