/[svn]/jsampler/trunk/src/org/jsampler/view/std/PianoRoll.java
ViewVC logotype

Diff of /jsampler/trunk/src/org/jsampler/view/std/PianoRoll.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1777 by iliev, Thu Sep 11 18:48:36 2008 UTC revision 1778 by iliev, Sun Sep 28 20:38:36 2008 UTC
# Line 22  Line 22 
22    
23  package org.jsampler.view.std;  package org.jsampler.view.std;
24    
 import java.awt.Color;  
 import java.awt.Font;  
 import java.awt.FontMetrics;  
 import java.awt.GradientPaint;  
25  import java.awt.Graphics;  import java.awt.Graphics;
26  import java.awt.Graphics2D;  import java.awt.Graphics2D;
 import java.awt.Point;  
 import java.awt.Rectangle;  
 import java.awt.RenderingHints;  
27    
28    import java.awt.event.ActionEvent;
29    import java.awt.event.ActionListener;
30    import java.awt.event.KeyEvent;
31    import java.awt.event.KeyListener;
32  import java.awt.event.MouseEvent;  import java.awt.event.MouseEvent;
33  import java.awt.event.MouseAdapter;  import java.awt.event.MouseAdapter;
34    
35  import java.awt.geom.RoundRectangle2D;  import java.util.HashMap;
   
36  import java.util.Vector;  import java.util.Vector;
37    
38    import javax.swing.Action;
39    import javax.swing.AbstractAction;
40    import javax.swing.JComponent;
41  import javax.swing.JPanel;  import javax.swing.JPanel;
42    import javax.swing.KeyStroke;
43    import javax.swing.SwingUtilities;
44    import javax.swing.Timer;
45    
46    import org.jsampler.CC;
47    
48  import org.linuxsampler.lscp.event.MidiDataEvent;  import org.linuxsampler.lscp.event.MidiDataEvent;
49  import org.linuxsampler.lscp.event.MidiDataListener;  import org.linuxsampler.lscp.event.MidiDataListener;
50    
51    import static org.jsampler.view.std.StdI18n.i18n;
52    
53  /**  /**
54   *   *
55   * @author Grigor Iliev   * @author Grigor Iliev
# Line 91  public class PianoRoll extends JPanel im Line 97  public class PianoRoll extends JPanel im
97          private int lastKey = -1;          private int lastKey = -1;
98          private int whiteKeyCount = 68;          private int whiteKeyCount = 68;
99                    
100          private Color borderColor = Color.BLACK;          private Integer[] enabledKeys = null;
101          private Color keyColor = Color.WHITE;          private Integer[] disabledKeys = null;
102          private Color disabledKeyColor = Color.GRAY;          private Integer[] keyswitches = null;
103          private Color pressedKeyColor = Color.GREEN;          private Integer[] notKeyswitches = null;
104          private Color keySwitchColor = Color.PINK;          
105          private Color blackKeyColor = Color.BLACK;          private int currentOctave = 3;
106            private int constantVelocity = 80;
107            private HashMap<Integer, Integer> keyMap = new HashMap<Integer, Integer>();
108                    
109          private final Vector<MidiDataListener> listeners = new Vector<MidiDataListener>();          private final Vector<MidiDataListener> listeners = new Vector<MidiDataListener>();
110                    
111          private boolean shouldRepaint = false;          private boolean shouldRepaint = true;
112            
113            private PianoRollPainter painter;
114            
115            public final Action actionScrollLeft = new ActionScrollLeft();
116            public final Action actionScrollRight = new ActionScrollRight();
117            public final Action actionIncreaseKeyNumber = new ActionIncreaseKeyNumber();
118            public final Action actionDecreaseKeyNumber = new ActionDecreaseKeyNumber();
119                    
120          /**          /**
121           * Creates a new horizontal, not mirrored <code>PianoRoll</code>.           * Creates a new horizontal, not mirrored <code>PianoRoll</code>.
# Line 127  public class PianoRoll extends JPanel im Line 142  public class PianoRoll extends JPanel im
142                  this.vertical = vertical;                  this.vertical = vertical;
143                  this.mirror = mirror;                  this.mirror = mirror;
144                                    
145                  this.addMouseListener(getHandler());                  setPainter(new BasicPianoRollPainter(this));
146                    
147                  setKeyRange(0, 127);                  setKeyRange(0, 127);
148                    
149                    installListeneres();
150            }
151            
152            private void
153            installListeneres() {
154                    addMouseListener(getHandler());
155                    addMouseMotionListener(getHandler());
156                    addKeyListener(getHandler());
157                    
158                    registerKeys(this);
159                    
160                    
161            }
162            
163            public KeyListener
164            getKeyListener() { return getHandler(); }
165            
166            public void
167            registerKeys(JComponent c) {
168                    KeyStroke k = KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, KeyEvent.CTRL_MASK);
169                    c.getInputMap(JComponent.WHEN_FOCUSED).put(k, "scrollLeft");
170                    c.getActionMap().put("scrollLeft", actionScrollLeft);
171                    
172                    k = KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, KeyEvent.CTRL_MASK);
173                    c.getInputMap(JComponent.WHEN_FOCUSED).put(k, "scrollRight");
174                    c.getActionMap().put("scrollRight", actionScrollRight);
175                    
176                    k = KeyStroke.getKeyStroke(KeyEvent.VK_UP, KeyEvent.CTRL_MASK);
177                    c.getInputMap(JComponent.WHEN_FOCUSED).put(k, "increaseKeyRange");
178                    c.getActionMap().put("increaseKeyRange", actionIncreaseKeyNumber);
179                    
180                    k = KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, KeyEvent.CTRL_MASK);
181                    c.getInputMap(JComponent.WHEN_FOCUSED).put(k, "decreaseKeyRange");
182                    c.getActionMap().put("decreaseKeyRange", actionDecreaseKeyNumber);
183                    
184                    k = KeyStroke.getKeyStroke(KeyEvent.VK_0, 0);
185                    c.getInputMap(JComponent.WHEN_FOCUSED).put(k, "changeCurrentOctave0");
186                    c.getActionMap().put("changeCurrentOctave0", new ActionChangeCurrentOctave(0));
187                    
188                    k = KeyStroke.getKeyStroke(KeyEvent.VK_1, 0);
189                    c.getInputMap(JComponent.WHEN_FOCUSED).put(k, "changeCurrentOctave1");
190                    c.getActionMap().put("changeCurrentOctave1", new ActionChangeCurrentOctave(1));
191                    
192                    k = KeyStroke.getKeyStroke(KeyEvent.VK_2, 0);
193                    c.getInputMap(JComponent.WHEN_FOCUSED).put(k, "changeCurrentOctave2");
194                    c.getActionMap().put("changeCurrentOctave2", new ActionChangeCurrentOctave(2));
195                    
196                    k = KeyStroke.getKeyStroke(KeyEvent.VK_3, 0);
197                    c.getInputMap(JComponent.WHEN_FOCUSED).put(k, "changeCurrentOctave3");
198                    c.getActionMap().put("changeCurrentOctave3", new ActionChangeCurrentOctave(3));
199                    
200                    k = KeyStroke.getKeyStroke(KeyEvent.VK_4, 0);
201                    c.getInputMap(JComponent.WHEN_FOCUSED).put(k, "changeCurrentOctave4");
202                    c.getActionMap().put("changeCurrentOctave4", new ActionChangeCurrentOctave(4));
203                    
204                    k = KeyStroke.getKeyStroke(KeyEvent.VK_5, 0);
205                    c.getInputMap(JComponent.WHEN_FOCUSED).put(k, "changeCurrentOctave5");
206                    c.getActionMap().put("changeCurrentOctave5", new ActionChangeCurrentOctave(5));
207                    
208                    k = KeyStroke.getKeyStroke(KeyEvent.VK_6, 0);
209                    c.getInputMap(JComponent.WHEN_FOCUSED).put(k, "changeCurrentOctave6");
210                    c.getActionMap().put("changeCurrentOctave6", new ActionChangeCurrentOctave(6));
211                    
212                    k = KeyStroke.getKeyStroke(KeyEvent.VK_7, 0);
213                    c.getInputMap(JComponent.WHEN_FOCUSED).put(k, "changeCurrentOctave7");
214                    c.getActionMap().put("changeCurrentOctave7", new ActionChangeCurrentOctave(7));
215            }
216            
217            public PianoRollPainter
218            getPainter() { return painter; }
219            
220            public void
221            setPainter(PianoRollPainter painter) {
222                    if(painter == null) painter = new BasicPianoRollPainter(this);
223                    this.painter = painter;
224          }          }
225                    
226          /**          /**
# Line 151  public class PianoRoll extends JPanel im Line 243  public class PianoRoll extends JPanel im
243                  for(MidiDataListener l : listeners) l.midiDataArrived(e);                  for(MidiDataListener l : listeners) l.midiDataArrived(e);
244          }          }
245                    
246            private void
247            fireNoteOn(int key, int velocity) {
248                    MidiDataEvent evt = new MidiDataEvent (
249                            PianoRoll.this, MidiDataEvent.Type.NOTE_ON, key, velocity
250                    );
251                    
252                    fireMidiDataEvent(evt);
253            }
254            
255            private void
256            fireNoteOff(int key, int velocity) {
257                    MidiDataEvent evt = new MidiDataEvent (
258                            PianoRoll.this, MidiDataEvent.Type.NOTE_OFF, key, velocity
259                    );
260                    
261                    fireMidiDataEvent(evt);
262            }
263            
264            /**
265             * Used to determine which note to play when using
266             * the computer keyboard's key bindings.
267             * @return
268             */
269            public int
270            getCurrentOctave() { return currentOctave; }
271            
272            /**
273             * @see #getCurrentOctave
274             * @param octave Specifies the octave to be used as current.
275             */
276            public void
277            setCurrentOctave(int octave) { currentOctave = octave; }
278            
279            public int
280            getConstantVelocity() { return constantVelocity; }
281            
282            public void
283            setConstantVelocity(int velocity) { constantVelocity = velocity; }
284            
285          /**          /**
286           * Determines whether the user input is processed           * Determines whether the user input is processed
287           * and respective MIDI data events are sent.           * and respective MIDI data events are sent.
# Line 200  public class PianoRoll extends JPanel im Line 331  public class PianoRoll extends JPanel im
331                  if(k.isPressed() == press) return;                  if(k.isPressed() == press) return;
332                                    
333                  getKey(key).setPressed(press);                  getKey(key).setPressed(press);
334                  if(getShouldRepaint()) repaint(getKeyRectangle(key));                  if(getShouldRepaint()) repaint(painter.getKeyRectangle(key));
335          }          }
336                    
337          public boolean          public boolean
# Line 214  public class PianoRoll extends JPanel im Line 345  public class PianoRoll extends JPanel im
345                  if(k.isKeyswitch() == keyswitch) return;                  if(k.isKeyswitch() == keyswitch) return;
346                                    
347                  getKey(key).setKeyswitch(keyswitch);                  getKey(key).setKeyswitch(keyswitch);
348                  if(getShouldRepaint()) repaint(getKeyRectangle(key));                  if(getShouldRepaint()) repaint(painter.getKeyRectangle(key));
349          }          }
350                    
351          public void          public void
# Line 254  public class PianoRoll extends JPanel im Line 385  public class PianoRoll extends JPanel im
385          }          }
386                    
387          /**          /**
388           * Keys outside the keyboard range are ignored.           * Keys outside the keyboard range are remembered and
389             * applied if needed when the key range is changed.
390           * @param keys List of keys           * @param keys List of keys
391           */           */
392          public void          public void
393          setKeyswitches(Integer[] keys, boolean keyswitches) {          setKeyswitches(Integer[] keys, boolean b) {
394                    if(b) keyswitches = keys;
395                    else notKeyswitches = keys;
396                    if(keys == null) return;
397                    
398                  boolean changed = false;                  boolean changed = false;
399                  for(int k : keys) {                  for(int k : keys) {
400                          if(!hasKey(k)) continue;                          if(!hasKey(k)) continue;
401                          if(getKey(k).isKeyswitch() != keyswitches) {                          if(getKey(k).isKeyswitch() != b) {
402                                  getKey(k).setKeyswitch(keyswitches);                                  getKey(k).setKeyswitch(b);
403                                  changed = true;                                  changed = true;
404                          }                          }
405                  }                  }
# Line 282  public class PianoRoll extends JPanel im Line 418  public class PianoRoll extends JPanel im
418                    
419          /**          /**
420           * Enables or disables the specified list of keys.           * Enables or disables the specified list of keys.
421           * Keys outside the keyboard range are ignored.           * Disabled keys outside the keyboard range are remembered and
422             * applied if needed when the key range is changed.
423           * @param keys List of keys           * @param keys List of keys
424           */           */
425          public void          public void
426          setDisabled(Integer[] keys, boolean disable) {          setDisabled(Integer[] keys, boolean disable) {
427                    if(disable) disabledKeys = keys;
428                    else enabledKeys = keys;
429                    
430                    if(keys == null) return;
431                    
432                  boolean changed = false;                  boolean changed = false;
433                  for(int k : keys) {                  for(int k : keys) {
434                          if(!hasKey(k)) continue;                          if(!hasKey(k)) continue;
# Line 340  public class PianoRoll extends JPanel im Line 482  public class PianoRoll extends JPanel im
482                                    
483                  whiteKeyCount = getWhiteKeyCount(firstKey, lastKey);                  whiteKeyCount = getWhiteKeyCount(firstKey, lastKey);
484                                    
485                  /*setAllKeysDisabled(true);                  boolean b = getShouldRepaint();
486                    setShouldRepaint(false);
487                    
488                    reset(true, false);
489                  setDisabled(enabledKeys, false);                  setDisabled(enabledKeys, false);
490                  setKeyswitches(keyswitches, true);*/                  setDisabled(disabledKeys, true);
491                    setKeyswitches(keyswitches, true);
492                    setKeyswitches(notKeyswitches, false);
493                                    
494                    setShouldRepaint(b);
495                  if(getShouldRepaint()) repaint();                  if(getShouldRepaint()) repaint();
496          }          }
497                    
498            public int
499            getFirstKey() { return firstKey; }
500            
501            public int
502            getLastKey() { return lastKey; }
503            
504          public boolean          public boolean
505          getOctaveLabelsVisible() {          getOctaveLabelsVisible() {
506                  return octaveLabelsVisible;                  return octaveLabelsVisible;
# Line 361  public class PianoRoll extends JPanel im Line 515  public class PianoRoll extends JPanel im
515           * Gets the number of white keys int the specified range (inclusive).           * Gets the number of white keys int the specified range (inclusive).
516           * @see #setKeyRange           * @see #setKeyRange
517           */           */
518          private static int          public static int
519          getWhiteKeyCount(int firstKey, int lastKey) {          getWhiteKeyCount(int firstKey, int lastKey) {
520                  int count = 0;                  int count = 0;
521                  for(int j = firstKey; j <= lastKey; j++) { // FIXME: Stupid but works                  for(int j = firstKey; j <= lastKey; j++) { // FIXME: Stupid but works
# Line 371  public class PianoRoll extends JPanel im Line 525  public class PianoRoll extends JPanel im
525                  return count;                  return count;
526          }          }
527                    
528          private int          /**
529             * Gets the MIDI note number of the specified white key position.
530             * @param whiteKey The white key position on the keyboard (zero-based)
531             * @return The MIDI number of the note
532             */
533            public int
534          getWhiteKeyByNumber(int whiteKey) {          getWhiteKeyByNumber(int whiteKey) {
535                  int count = 0;                  int count = 0;
536                  for(int j = firstKey; j <= lastKey; j++) { // FIXME: Stupid but works                  for(int j = firstKey; j <= lastKey; j++) { // FIXME: Stupid but works
# Line 384  public class PianoRoll extends JPanel im Line 543  public class PianoRoll extends JPanel im
543                  return -1;                  return -1;
544          }          }
545                    
546          private int          /** Gets the number of white keys in the piano roll. */
547          getWhiteKeyCount() {          public int
548                  return whiteKeyCount;          getWhiteKeyCount() { return whiteKeyCount; }
         }  
549                    
550          /**          /**
551           * Determines whether the specified key is a white key.           * Determines whether the specified key is a white key.
# Line 423  public class PianoRoll extends JPanel im Line 581  public class PianoRoll extends JPanel im
581                  return getWhiteKeyCount(0, k) - 1;                  return getWhiteKeyCount(0, k) - 1;
582          }          }
583                    
         private Color  
         getKeyColor(int key) {  
                 Key k = getKey(key);  
                 if(isWhiteKey(key)) {  
                         if(k.isPressed()) return pressedKeyColor;  
                         if(k.isKeyswitch()) return keySwitchColor;  
                         if(k.isDisabled()) return disabledKeyColor;  
                         return keyColor;  
                 } else {  
                         if(k.isPressed()) return Color.GREEN;  
                         return blackKeyColor;  
                 }  
         }  
           
584          /**          /**
585           * Releases all pressed keys, enables all keys and removes all keyswitches.           * Releases all pressed keys, enables all keys and removes all keyswitches.
586           */           */
# Line 449  public class PianoRoll extends JPanel im Line 593  public class PianoRoll extends JPanel im
593           */           */
594          public void          public void
595          reset(boolean dissableAllKeys) {          reset(boolean dissableAllKeys) {
596                    reset(dissableAllKeys, true);
597            }
598            
599            private void
600            reset(boolean dissableAllKeys, boolean clear) {
601                    if(clear) {
602                            enabledKeys = null;
603                            disabledKeys = null;
604                            keyswitches = null;
605                            notKeyswitches = null;
606                    }
607                    
608                  boolean b = getShouldRepaint();                  boolean b = getShouldRepaint();
609                  setShouldRepaint(false);                  setShouldRepaint(false);
610                  setAllKeysPressed(false);                  setAllKeysPressed(false);
# Line 464  public class PianoRoll extends JPanel im Line 620  public class PianoRoll extends JPanel im
620          public void          public void
621          setShouldRepaint(boolean b) { shouldRepaint = b; }          setShouldRepaint(boolean b) { shouldRepaint = b; }
622                    
623          private int          @Override public void
624          getKey(Point p) {          paint(Graphics g) {
625                  double w = getWhiteKeyWidth() + /* space between keys */ 1.0d;                  super.paint(g);
626                  if(w == 0) return -1;                  painter.paint(this, (Graphics2D)g);
                 int whiteKeyNumber = (int) (p.getX() / w);  
                 double leftBorder = whiteKeyNumber * w;  
                 int key = getWhiteKeyByNumber(whiteKeyNumber);  
                 if(key == -1) return -1;  
                   
                 double bh = getBlackKeyHeight();  
                 double blackKeyOffset = w / 4.0d;  
                 if(p.getY() > bh) return key;  
                 if(key != firstKey && !isWhiteKey(key - 1)) {  
                         if(p.getX() <= leftBorder + blackKeyOffset) return key - 1;  
                 }  
                 if(key != lastKey && !isWhiteKey(key + 1)) {  
                         if(p.getX() >= leftBorder + 3 * blackKeyOffset - 3) return key + 1;  
                 }  
                   
                 return key;  
         }  
           
         private int  
         getVelocity(Point p, boolean whiteKey) {  
                 double h = whiteKey ? getWhiteKeyHeight() : getBlackKeyHeight();  
                 int velocity = (int) ((p.getY() / h) * 127.0d + 1);  
                 if(velocity < 0) velocity = 0;  
                 if(velocity > 127) velocity = 127;  
                 return velocity;  
627          }          }
628                    
629          private double          @Override public void
630          getWhiteKeyWidth() {          midiDataArrived(MidiDataEvent e) {
631                  double w = getSize().getWidth();                  switch(e.getType()) {
632                  return (w - getWhiteKeyCount()) / getWhiteKeyCount();                          case NOTE_ON:
633                                    setKeyPressed(e.getNote(), true);
634                                    break;
635                            case NOTE_OFF:
636                                    setKeyPressed(e.getNote(), false);
637                    }
638          }          }
639                    
         private double  
         getWhiteKeyHeight() {  
                 return getSize().getHeight() - 3.0d;  
         }  
640                    
641          private double          private class ActionScrollLeft extends AbstractAction {
642          getBlackKeyWidth() {                  ActionScrollLeft() {
643                  return getWhiteKeyWidth() / 2.0d;                          super(i18n.getLabel("PianoRoll.scrollLeft"));
644                            
645                            String s = i18n.getLabel("PianoRoll.scrollLeft");
646                            putValue(SHORT_DESCRIPTION, s);
647                    }
648                    
649                    public void
650                    actionPerformed(ActionEvent e) {
651                            if(getFirstKey() == 0) return;
652                            int k = getFirstKey() - 1;
653                            if(!isWhiteKey(k)) k--;
654                            int k2 = getLastKey() - 1;
655                            if(!isWhiteKey(k2)) k2--;
656                            
657                            setKeyRange(k, k2);
658                            CC.preferences().setIntProperty("midiKeyboard.firstKey", k);
659                            CC.preferences().setIntProperty("midiKeyboard.lastKey", k2);
660                            
661                    }
662          }          }
663                    
         private double  
         getBlackKeyHeight() {  
                 return getWhiteKeyHeight() / 1.5d;  
         }  
664                    
665          protected void          private class ActionScrollRight extends AbstractAction {
666          paintOctaveLabel(Graphics2D g, int octave, int whiteKeyIndex) {                  ActionScrollRight() {
667                  double h = getSize().getHeight();                          super(i18n.getLabel("PianoRoll.scrollRight"));
668                  double whiteKeyWidth = getWhiteKeyWidth();                          
669                  g.setPaint(Color.BLACK);                          String s = i18n.getLabel("PianoRoll.scrollRight");
670                  int fsize = (int) (whiteKeyWidth / (1.5 + whiteKeyWidth / 50));                          putValue(SHORT_DESCRIPTION, s);
                 if(fsize < 8) fsize = 8;  
                 g.setFont(g.getFont().deriveFont(Font.BOLD, fsize));  
                   
                 float x = (float) (whiteKeyWidth * whiteKeyIndex + whiteKeyIndex);  
                 float y = (float) (h - 1);  
                   
                 String s = String.valueOf(octave);  
                 FontMetrics fm = g.getFontMetrics();  
                   
                 // center text  
                 int i = fm.stringWidth(s);  
                 if(i < whiteKeyWidth) {  
                         x += (whiteKeyWidth - i) / 2;  
                 } else {  
                         x += 2;  
671                  }                  }
672                                    
673                  y -= (h / 12);                  public void
674                                    actionPerformed(ActionEvent e) {
675                  g.drawString(s, x, y);                          if(getLastKey() == 127) return;
676                            int k = getFirstKey() + 1;
677                            if(!isWhiteKey(k)) k++;
678                            int k2 = getLastKey() + 1;
679                            if(!isWhiteKey(k2)) k2++;
680                            
681                            setKeyRange(k, k2);
682                            CC.preferences().setIntProperty("midiKeyboard.firstKey", k);
683                            CC.preferences().setIntProperty("midiKeyboard.lastKey", k2);
684                            
685                    }
686          }          }
687                    
688          /**          private class ActionIncreaseKeyNumber extends AbstractAction {
689           * Gets the rectangle in which the key is drawn and empty rectangle                  ActionIncreaseKeyNumber() {
690           * if the specified key is not shown on the piano roll or is invalid.                          super(i18n.getLabel("PianoRoll.increaseKeyNumber"));
691           */                          
692          public Rectangle                          String s = i18n.getLabel("PianoRoll.increaseKeyNumber");
693          getKeyRectangle(int key) {                          putValue(SHORT_DESCRIPTION, s);
                 Rectangle r = new Rectangle();  
                 if(!hasKey(key)) return r;  
                   
                 int whiteKeyIndex = getWhiteKeyCount(firstKey, key) - 1;  
                   
                 if(isWhiteKey(key)) {  
                         double whiteKeyWidth = getWhiteKeyWidth();  
                         double whiteKeyHeight = getWhiteKeyHeight();  
                         double x = whiteKeyWidth * whiteKeyIndex + whiteKeyIndex;  
                         r.setRect(x, 0, whiteKeyWidth, whiteKeyHeight);  
                 } else {  
                         double blackKeyWidth = getBlackKeyWidth();  
                         double blackKeyHeight = getBlackKeyHeight();  
                         int i = whiteKeyIndex;  
                         double x = blackKeyWidth * (2*(i + 1)) - blackKeyWidth * 0.5d + i;  
                         r.setRect(x, 0, blackKeyWidth, blackKeyHeight);  
694                  }                  }
695                                    
696                  return r;                  public void
697                    actionPerformed(ActionEvent e) {
698                            if(getFirstKey() == 0 && getLastKey() == 127) return;
699                            int k = getFirstKey() == 0 ? 0 : getFirstKey() - 1;
700                            if(!isWhiteKey(k)) k--;
701                            int k2 = getLastKey() == 127 ? 127 : getLastKey() + 1;
702                            if(!isWhiteKey(k2)) k2++;
703                            
704                            setKeyRange(k, k2);
705                            CC.preferences().setIntProperty("midiKeyboard.firstKey", k);
706                            CC.preferences().setIntProperty("midiKeyboard.lastKey", k2);
707                            
708                    }
709          }          }
710                    
711          @Override public void          private class ActionDecreaseKeyNumber extends AbstractAction {
712          paint(Graphics g) {                  ActionDecreaseKeyNumber() {
713                  super.paint(g);                          super(i18n.getLabel("PianoRoll.decreaseKeyNumber"));
                 Graphics2D g2 = (Graphics2D) g;  
                   
                 double whiteKeyWidth = getWhiteKeyWidth();  
                 double whiteKeyHeight = getWhiteKeyHeight();  
                 double arcw = whiteKeyWidth/4.0d;  
                 double arch = whiteKeyHeight/14.0d;  
                   
                 g2.setPaint(keyColor);  
                   
                 RoundRectangle2D.Double rect;  
                   
                 g2.setRenderingHint (  
                         RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF  
                 );  
                   
                 int i = 0;  
                 for(int j = firstKey; j <= lastKey; j++) {  
                         if(!isWhiteKey(j)) continue;  
                           
                         Color c = getKeyColor(j);  
                         if(g2.getPaint() != c) g2.setPaint(c);  
                           
                         rect = new RoundRectangle2D.Double (  
                                 // If you change this you should also change getKeyRectangle()  
                                 whiteKeyWidth * i + i, 0,  
                                 whiteKeyWidth, whiteKeyHeight,  
                                 arcw, arch  
                         );  
714                                                    
715                          g2.fill(rect);                          String s = i18n.getLabel("PianoRoll.decreaseKeyNumber");
716                          i++;                          putValue(SHORT_DESCRIPTION, s);
717                  }                  }
718                                    
719                  g2.setRenderingHint (                  public void
720                          RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON                  actionPerformed(ActionEvent e) {
721                  );                          if(getLastKey() - getFirstKey() < 31) return;
722                                            int k = getFirstKey() + 1;
723                  g2.setStroke(new java.awt.BasicStroke(1.5f));                          if(!isWhiteKey(k)) k++;
724                  g2.setPaint(borderColor);                          int k2 = getLastKey() - 1;
725                                            if(!isWhiteKey(k2)) k2--;
726                  i = 0;                          
727                  for(int j = firstKey; j <= lastKey; j++) {                          setKeyRange(k, k2);
728                          if(!isWhiteKey(j)) continue;                          CC.preferences().setIntProperty("midiKeyboard.firstKey", k);
729                                                    CC.preferences().setIntProperty("midiKeyboard.lastKey", k2);
730                          rect = new RoundRectangle2D.Double (                          
                                 whiteKeyWidth * i + i, 0,  
                                 whiteKeyWidth, whiteKeyHeight,  
                                 arcw, arch  
                         );  
                   
                         g2.draw(rect);  
                         i++;  
731                  }                  }
732            }
733            
734            private class ActionChangeCurrentOctave extends AbstractAction {
735                    private int octave;
736                                    
737                    ActionChangeCurrentOctave(int octave) {
738                            super("");
739                            this.octave = octave;
740                    }
741                                    
742                  g2.setStroke(new java.awt.BasicStroke(2.5f));                  public void
743                  double blackKeyWidth = getBlackKeyWidth();                  actionPerformed(ActionEvent e) {
744                  double blackKeyHeight = getBlackKeyHeight();                          setCurrentOctave(octave);
                   
                 i = 0;  
                 for(int j = firstKey; j <= lastKey; j++) {  
                         if(getOctaveLabelsVisible() && j % 12 == 0) {  
                                 int octave = j / 12 - 2;  
                                 paintOctaveLabel(g2, octave, i);  
                         }  
                         if(!isWhiteKey(j)) continue;  
                           
                         int k = (i + getKeyOctaveIndex(firstKey)) % 7;  
                         if(k == 2 || k == 6) { i++; continue; }  
                           
                         Color c = (j == lastKey) ? blackKeyColor : getKeyColor(j + 1);  
                         if(g2.getPaint() != c) g2.setPaint(c);  
                           
                         // If you change this you should also change getKeyRectangle()  
                         double x = blackKeyWidth * (2*(i + 1)) - blackKeyWidth * 0.5d + i;  
                         rect = new RoundRectangle2D.Double (  
                                 // If you change this you should also change getKeyRectangle()  
                                 x, 0,  
                                 blackKeyWidth, blackKeyHeight,  
                                 arcw, arch  
                         );  
                         ///////  
                           
                         boolean pressed = (j == lastKey) ? false : getKey(j + 1).isPressed();  
                         if(!pressed) g2.fill(rect);  
                           
                         RoundRectangle2D.Double rect2;  
                         rect2 = new RoundRectangle2D.Double (  
                                 x, 0,  
                                 blackKeyWidth, arch,  
                                 arcw, arch / 1.8d  
                         );  
                           
                         g2.fill(rect2);  
                         g2.setPaint(borderColor);  
                         g2.draw(rect);  
                           
                         if(pressed) {  
                         GradientPaint gr = new GradientPaint (  
                                 (float)(x + blackKeyWidth/2), (float)(blackKeyHeight/4), Color.BLACK,  
                                 (float)(x + blackKeyWidth/2), (float)blackKeyHeight, new Color(0x058a02)  
                         );  
                         g2.setPaint(gr);  
                         g2.fill(rect);  
                         }  
                         i++;  
745                  }                  }
746          }          }
747                    
748          @Override public void          private void
749          midiDataArrived(MidiDataEvent e) {          keyPressed(int keyCode, int note) {
750                  switch(e.getType()) {                  fireNoteOn(note, getConstantVelocity());
751                          case NOTE_ON:                  keyMap.put(keyCode, note);
752                                  setKeyPressed(e.getNote(), true);          }
753                                  break;          
754                          case NOTE_OFF:          private void
755                                  setKeyPressed(e.getNote(), false);          keyPressed(int keyCode) {
756                    if(!isPlayingEnabled()) return;
757                    
758                    int offset = (getCurrentOctave() + 2) * 12;
759                    
760                    switch(keyCode) {
761                            case KeyEvent.VK_A:
762                                    keyPressed(keyCode, offset); break;
763                            case KeyEvent.VK_W:
764                                    keyPressed(keyCode, offset + 1); break;
765                            case KeyEvent.VK_S:
766                                    keyPressed(keyCode, offset + 2); break;
767                            case KeyEvent.VK_E:
768                                    keyPressed(keyCode, offset + 3); break;
769                            case KeyEvent.VK_D:
770                                    keyPressed(keyCode, offset + 4); break;
771                            case KeyEvent.VK_F:
772                                    keyPressed(keyCode, offset + 5); break;
773                            case KeyEvent.VK_T:
774                                    keyPressed(keyCode, offset + 6); break;
775                            case KeyEvent.VK_G:
776                                    keyPressed(keyCode, offset + 7); break;
777                            case KeyEvent.VK_Y:
778                                    keyPressed(keyCode, offset + 8); break;
779                            case KeyEvent.VK_H:
780                                    keyPressed(keyCode, offset + 9); break;
781                            case KeyEvent.VK_U:
782                                    keyPressed(keyCode, offset + 10); break;
783                            case KeyEvent.VK_J:
784                                    keyPressed(keyCode, offset + 11); break;
785                            case KeyEvent.VK_K:
786                                    keyPressed(keyCode, offset + 12); break;
787                            case KeyEvent.VK_O:
788                                    keyPressed(keyCode, offset + 13); break;
789                            case KeyEvent.VK_L:
790                                    keyPressed(keyCode, offset + 14); break;
791                            case KeyEvent.VK_P:
792                                    keyPressed(keyCode, offset + 15); break;
793                            case KeyEvent.VK_SEMICOLON:
794                                    keyPressed(keyCode, offset + 16); break;
795                            case KeyEvent.VK_QUOTE:
796                                    keyPressed(keyCode, offset + 17); break;
797                    }
798            }
799            
800            public void
801            keyReleased(int keyCode) {
802                    if(!isPlayingEnabled()) return;
803                    
804                    switch(keyCode) {
805                            case KeyEvent.VK_A:
806                            case KeyEvent.VK_W:
807                            case KeyEvent.VK_S:
808                            case KeyEvent.VK_E:
809                            case KeyEvent.VK_D:
810                            case KeyEvent.VK_F:
811                            case KeyEvent.VK_T:
812                            case KeyEvent.VK_G:
813                            case KeyEvent.VK_Y:
814                            case KeyEvent.VK_H:
815                            case KeyEvent.VK_U:
816                            case KeyEvent.VK_J:
817                            case KeyEvent.VK_K:
818                            case KeyEvent.VK_O:
819                            case KeyEvent.VK_L:
820                            case KeyEvent.VK_P:
821                            case KeyEvent.VK_SEMICOLON:
822                            case KeyEvent.VK_QUOTE:
823                                    if(keyMap.get(keyCode) == null) return;
824                                    fireNoteOff(keyMap.get(keyCode), getConstantVelocity());
825                                    keyMap.remove(keyCode);
826                  }                  }
827          }          }
828                    
# Line 699  public class PianoRoll extends JPanel im Line 831  public class PianoRoll extends JPanel im
831          private Handler          private Handler
832          getHandler() { return handler; }          getHandler() { return handler; }
833                    
834          private class Handler extends MouseAdapter {          private class Handler extends MouseAdapter implements KeyListener {
835                    @Override
836                    public void
837                    mouseClicked(MouseEvent e) { requestFocusInWindow(); }
838                    
839                  private int pressedKey = -1;                  private int pressedKey = -1;
840                                    
841                  @Override public void                  @Override
842                    public void
843                  mousePressed(MouseEvent e) {                  mousePressed(MouseEvent e) {
844                          if(!isPlayingEnabled()) return;                          if(!isPlayingEnabled()) return;
845                          if(e.getButton() != MouseEvent.BUTTON1) return;                          if(e.getButton() != MouseEvent.BUTTON1) return;
846                                                    
847                          int key = getKey(e.getPoint());                          int key = painter.getKeyByPoint(e.getPoint());
848                          if(key == -1) return;                          if(key == -1) return;
849                          pressedKey = key;                          pressedKey = key;
850                          setKeyPressed(key, true);                          setKeyPressed(key, true);
851                          int velocity = getVelocity(e.getPoint(), isWhiteKey(key));                          int velocity = painter.getVelocity(e.getPoint(), key);
852                                                    
853                          MidiDataEvent evt = new MidiDataEvent (                          fireNoteOn(key, velocity);
                                 PianoRoll.this, MidiDataEvent.Type.NOTE_ON, key, velocity  
                         );  
                           
                         fireMidiDataEvent(evt);  
854                  }                  }
855                                    
856                  @Override public void                  @Override
857                    public void
858                  mouseReleased(MouseEvent e) {                  mouseReleased(MouseEvent e) {
859                          if(!isPlayingEnabled()) return;                          if(!isPlayingEnabled()) return;
860                          if(e.getButton() != MouseEvent.BUTTON1) return;                          if(e.getButton() != MouseEvent.BUTTON1) return;
# Line 728  public class PianoRoll extends JPanel im Line 862  public class PianoRoll extends JPanel im
862                          if(pressedKey == -1) return;                          if(pressedKey == -1) return;
863                          setKeyPressed(pressedKey, false);                          setKeyPressed(pressedKey, false);
864                                                    
865                          int velocity = getVelocity(e.getPoint(), isWhiteKey(pressedKey));                          int velocity = painter.getVelocity(e.getPoint(), pressedKey);
866                          MidiDataEvent evt = new MidiDataEvent (                          MidiDataEvent evt = new MidiDataEvent (
867                                  PianoRoll.this, MidiDataEvent.Type.NOTE_OFF, pressedKey, velocity                                  PianoRoll.this, MidiDataEvent.Type.NOTE_OFF, pressedKey, velocity
868                          );                          );
# Line 737  public class PianoRoll extends JPanel im Line 871  public class PianoRoll extends JPanel im
871                                                    
872                          fireMidiDataEvent(evt);                          fireMidiDataEvent(evt);
873                  }                  }
874                    
875                    @Override
876                    public void
877                    mouseDragged(MouseEvent e) {
878                            if(!isPlayingEnabled()) return;
879                            //if(e.getButton() != MouseEvent.BUTTON1) return;
880                            
881                            if(pressedKey == -1) return;
882                            int key = painter.getKeyByPoint(e.getPoint());
883                            if(key == pressedKey) return;
884                            setKeyPressed(pressedKey, false);
885                            
886                            int velocity = painter.getVelocity(e.getPoint(), pressedKey);
887                            fireNoteOff(pressedKey, velocity);
888                            
889                            pressedKey = key;
890                            if(pressedKey == -1) return;
891                            
892                            setKeyPressed(key, true);
893                            velocity = painter.getVelocity(e.getPoint(), key);
894                            
895                            fireNoteOn(key, velocity);
896                    }
897                    
898                    private HashMap<Integer, Long> pressedKeysMap = new HashMap<Integer, Long>();
899                    
900                    public void
901                    keyPressed(KeyEvent e) {
902                            // Ugly fix for bug 4153069
903                            if(pressedKeysMap.get(e.getKeyCode()) == null) {
904                                    keyPressedNoAutoRepeat(e);
905                            }
906                            
907                            pressedKeysMap.put(e.getKeyCode(), e.getWhen());
908                    }
909                    
910                    public void
911                    keyPressedNoAutoRepeat(KeyEvent e) {
912                            //System.out.println("Pressed: " + e.getKeyCode() + " " + e.getWhen());
913                            if(e.isControlDown() || e.isAltDown() || e.isShiftDown() || e.isMetaDown());
914                            else PianoRoll.this.keyPressed(e.getKeyCode());
915                    }
916                    
917                    public void
918                    keyReleased(final KeyEvent e) {
919                            // Ugly fix for bug 4153069
920                            SwingUtilities.invokeLater(new Fix4153069(e));
921                    }
922                    
923                    public void
924                    keyReleasedNoAutoRepeat(KeyEvent e) {
925                            //System.out.println("Released: " + e.getKeyCode() + " " + e.getWhen());
926                            PianoRoll.this.keyReleased(e.getKeyCode());
927                    }
928                    
929                    public void
930                    keyTyped(KeyEvent e) { }
931            }
932            
933            class Fix4153069 implements Runnable, ActionListener {
934                    KeyEvent e;
935                    int count = 0;
936                    
937                    Fix4153069(KeyEvent e) {
938                            this.e = e;
939                    }
940                    
941                    public void
942                    actionPerformed(ActionEvent e) { run(); }
943                    
944                    public void
945                    run() {
946                            Long l = getHandler().pressedKeysMap.get(e.getKeyCode());
947                            if(l == null || l.longValue() < e.getWhen()) {
948                                    if(l != null) {
949                                            if(delay()) return;
950                                    }
951                                    getHandler().pressedKeysMap.remove(e.getKeyCode());
952                                    getHandler().keyReleasedNoAutoRepeat(e);
953                            }
954                            
955                    }
956                    
957                    private boolean
958                    delay() {
959                            if(count < 1) {
960                                    //System.out.println("Delaying...");
961                                    count++;
962                                    
963                                    Timer t = new Timer(4, this);
964                                    t.setRepeats(false);
965                                    t.start();
966                                    return true;
967                            }
968                            
969                            return false;
970                    }
971          }          }
972  }  }

Legend:
Removed from v.1777  
changed lines
  Added in v.1778

  ViewVC Help
Powered by ViewVC