/[svn]/jsampler/trunk/src/org/jsampler/view/fantasia/PianoKeyboardPane.java
ViewVC logotype

Annotation of /jsampler/trunk/src/org/jsampler/view/fantasia/PianoKeyboardPane.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1785 - (hide annotations) (download)
Tue Oct 7 00:07:14 2008 UTC (15 years, 6 months ago) by iliev
File size: 16077 byte(s)
* Fantasia: Implemented multiple channels panels
* Fantasia: Refactoring - all basic UI components moved to
  org.jsampler.view.fantasia.basic package

1 iliev 1776 /*
2     * JSampler - a java front-end for LinuxSampler
3     *
4     * Copyright (C) 2005-2008 Grigor Iliev <grigor@grigoriliev.com>
5     *
6     * This file is part of JSampler.
7     *
8     * JSampler is free software; you can redistribute it and/or modify
9     * it under the terms of the GNU General Public License version 2
10     * as published by the Free Software Foundation.
11     *
12     * JSampler is distributed in the hope that it will be useful,
13     * but WITHOUT ANY WARRANTY; without even the implied warranty of
14     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15     * GNU General Public License for more details.
16     *
17     * You should have received a copy of the GNU General Public License
18     * along with JSampler; if not, write to the Free Software
19     * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20     * MA 02111-1307 USA
21     */
22    
23     package org.jsampler.view.fantasia;
24    
25 iliev 1778 import java.awt.AlphaComposite;
26     import java.awt.Color;
27     import java.awt.Composite;
28     import java.awt.Dimension;
29     import java.awt.GradientPaint;
30     import java.awt.Graphics;
31     import java.awt.Graphics2D;
32     import java.awt.GridBagConstraints;
33     import java.awt.GridBagLayout;
34 iliev 1776 import java.awt.Insets;
35 iliev 1778 import java.awt.Paint;
36     import java.awt.RenderingHints;
37 iliev 1776
38 iliev 1778 import java.awt.event.ActionEvent;
39     import java.awt.event.ActionListener;
40     import java.awt.event.FocusEvent;
41     import java.awt.event.FocusListener;
42     import java.awt.event.MouseEvent;
43     import java.awt.event.MouseAdapter;
44    
45     import java.awt.geom.Line2D;
46     import java.awt.geom.Rectangle2D;
47    
48 iliev 1776 import java.beans.PropertyChangeEvent;
49     import java.beans.PropertyChangeListener;
50    
51     import javax.swing.BorderFactory;
52 iliev 1778 import javax.swing.Box;
53     import javax.swing.BoxLayout;
54     import javax.swing.ImageIcon;
55     import javax.swing.JButton;
56     import javax.swing.JPanel;
57     import javax.swing.JToggleButton;
58 iliev 1776
59     import javax.swing.event.ListSelectionEvent;
60     import javax.swing.event.ListSelectionListener;
61    
62     import net.sf.juife.event.TaskEvent;
63     import net.sf.juife.event.TaskListener;
64    
65     import org.jsampler.CC;
66     import org.jsampler.SamplerChannelModel;
67    
68     import org.jsampler.event.SamplerChannelAdapter;
69     import org.jsampler.event.SamplerChannelEvent;
70     import org.jsampler.event.SamplerChannelListListener;
71     import org.jsampler.event.SamplerChannelListEvent;
72    
73     import org.jsampler.view.JSChannel;
74 iliev 1785 import org.jsampler.view.fantasia.basic.*;
75 iliev 1776 import org.jsampler.view.std.JSPianoRoll;
76    
77     import org.linuxsampler.lscp.Instrument;
78 iliev 1778 import org.linuxsampler.lscp.SamplerChannel;
79 iliev 1776
80     import org.linuxsampler.lscp.event.MidiDataEvent;
81     import org.linuxsampler.lscp.event.MidiDataListener;
82    
83 iliev 1778 import static javax.swing.Action.SMALL_ICON;
84 iliev 1776 import static org.jsampler.task.Global.GetFileInstrument;
85 iliev 1778 import static org.jsampler.view.fantasia.FantasiaI18n.i18n;
86 iliev 1776
87     /**
88     *
89     * @author Grigor Iliev
90     */
91 iliev 1778 public class PianoKeyboardPane extends FantasiaPanel
92 iliev 1776 implements ListSelectionListener, SamplerChannelListListener {
93    
94 iliev 1778 protected final JToggleButton btnPower = new PowerButton();
95     private final FantasiaLabel lDisplay = new FantasiaLabel(" ", true);
96 iliev 1776 private final JSPianoRoll pianoRoll = new JSPianoRoll();
97     private SamplerChannelModel channel = null;
98    
99     private String file = null;
100     private int index = -1;
101    
102     public
103     PianoKeyboardPane() {
104 iliev 1778 pianoRoll.actionDecreaseKeyNumber.putValue(SMALL_ICON, Res.gfxBtnDecrease);
105     pianoRoll.actionIncreaseKeyNumber.putValue(SMALL_ICON, Res.gfxBtnIncrease);
106     pianoRoll.actionScrollLeft.putValue(SMALL_ICON, Res.gfxBtnScrollLeft);
107     pianoRoll.actionScrollRight.putValue(SMALL_ICON, Res.gfxBtnScrollRight);
108    
109 iliev 1776 setOpaque(false);
110    
111 iliev 1778 GridBagLayout gridbag = new GridBagLayout();
112     GridBagConstraints c = new GridBagConstraints();
113 iliev 1776
114 iliev 1778 setLayout(gridbag);
115 iliev 1776
116 iliev 1778 setBorder(BorderFactory.createEmptyBorder(0, 3, 5, 3));
117    
118     c.fill = GridBagConstraints.NONE;
119    
120     c.gridx = 0;
121     c.gridy = 0;
122     c.anchor = GridBagConstraints.NORTHWEST;
123     c.insets = new Insets(3, 3, 3, 3);
124     gridbag.setConstraints(btnPower, c);
125     add(btnPower);
126    
127     JPanel p = createVSeparator();
128     c.gridx = 1;
129     c.gridy = 0;
130     c.gridheight = 2;
131     c.insets = new Insets(3, 0, 5, 3);
132     c.fill = GridBagConstraints.VERTICAL;
133     c.weighty = 1.0;
134     gridbag.setConstraints(p, c);
135     add(p);
136    
137     p = new KeyRangePropsPane();
138    
139     c.gridx = 2;
140     c.gridy = 0;
141     c.gridheight = 1;
142     c.insets = new Insets(0, 0, 0, 0);
143     c.fill = GridBagConstraints.NONE;
144     c.weighty = 0.0;
145     c.anchor = GridBagConstraints.WEST;
146     gridbag.setConstraints(p, c);
147     add(p);
148    
149     p = new KeyRangePropsPane();
150    
151     c.gridx = 6;
152     c.gridy = 0;
153     c.anchor = GridBagConstraints.EAST;
154     c.insets = new Insets(0, 0, 0, 10);
155     gridbag.setConstraints(p, c);
156     add(p);
157    
158     lDisplay.setPreferredSize(new Dimension(300, lDisplay.getPreferredSize().height));
159    
160     c.gridx = 4;
161     c.gridy = 0;
162     c.insets = new Insets(3, 3, 3, 12);
163     c.fill = GridBagConstraints.NONE;
164     c.weightx = 0.0;
165     gridbag.setConstraints(lDisplay, c);
166     add(lDisplay);
167    
168     p = new JPanel();
169     p.setOpaque(false);
170     c.gridx = 3;
171     c.gridy = 0;
172     c.insets = new Insets(0, 0, 0, 0);
173     c.fill = GridBagConstraints.HORIZONTAL;
174     c.weightx = 1.0;
175     gridbag.setConstraints(p, c);
176     add(p);
177    
178     p = new JPanel();
179     p.setOpaque(false);
180     c.gridx = 5;
181     c.gridy = 0;
182     gridbag.setConstraints(p, c);
183     add(p);
184    
185     pianoRoll.setFocusable(false);
186     pianoRoll.setBackground(new Color(0x2e2e2e));
187     //pianoRoll.setOpaque(false);
188    
189 iliev 1776 disablePianoRoll();
190    
191 iliev 1778 c.gridx = 2;
192     c.gridy = 1;
193     c.gridwidth = 5;
194     c.insets = new Insets(0, 3, 0, 12);
195     c.fill = GridBagConstraints.BOTH;
196     c.weightx = 1.0;
197     c.weighty = 1.0;
198     gridbag.setConstraints(pianoRoll, c);
199     add(pianoRoll);
200    
201 iliev 1776 CC.getSamplerModel().addSamplerChannelListListener(this);
202     pianoRoll.addMidiDataListener(getHandler());
203    
204     updateKeyRange();
205    
206     PropertyChangeListener l = new PropertyChangeListener() {
207     public void
208     propertyChange(PropertyChangeEvent e) {
209     updateKeyRange();
210     }
211     };
212    
213     CC.preferences().addPropertyChangeListener("midiKeyboard.firstKey", l);
214     CC.preferences().addPropertyChangeListener("midiKeyboard.lastKey", l);
215 iliev 1778
216     addFocusListener(getHandler());
217    
218     MouseAdapter l2 = new MouseAdapter() {
219     public void
220     mouseClicked(MouseEvent e) { requestFocusInWindow(); }
221     };
222    
223     addKeyListener(pianoRoll.getKeyListener());
224     pianoRoll.registerKeys(this);
225    
226     addMouseListener(l2);
227     pianoRoll.addMouseListener(l2);
228     lDisplay.addMouseListener(l2);
229 iliev 1776 }
230    
231     public JSPianoRoll
232     getPianoRoll() { return pianoRoll; }
233    
234     private void
235     updateKeyRange() {
236     int firstKey = CC.preferences().getIntProperty("midiKeyboard.firstKey");
237     int lastKey = CC.preferences().getIntProperty("midiKeyboard.lastKey");
238     pianoRoll.setKeyRange(firstKey, lastKey);
239     }
240    
241     @Override public void
242     valueChanged(ListSelectionEvent e) {
243     if(e.getValueIsAdjusting()) return;
244    
245 iliev 1785 JSChannel[] chnS = CC.getMainFrame().getSelectedChannelsPane().getSelectedChannels();
246 iliev 1776 if(chnS == null || chnS.length == 0) {
247     disconnectChannel();
248     return;
249     }
250    
251     if(chnS[0].getModel() == channel) return;
252     disconnectChannel();
253     connectChannel(chnS[0].getModel());
254     }
255    
256     private void
257     updateInstrumentInfo() {
258     final GetFileInstrument i = new GetFileInstrument(file, index);
259    
260     i.addTaskListener(new TaskListener() {
261     public void
262     taskPerformed(TaskEvent e) {
263     if(i.doneWithErrors()) return;
264     updatePianoKeyboard(i.getResult());
265     }
266     });
267    
268     CC.getTaskQueue().add(i);
269     }
270    
271     private void
272     disablePianoRoll() {
273     pianoRoll.reset(true);
274     pianoRoll.setPlayingEnabled(false);
275     }
276    
277     private void
278     updatePianoKeyboard(Instrument instr) {
279     // The selected channel may have changed before this update
280     // due to concurency, so also checking whether file is null
281     if(instr == null || file == null) {
282     disablePianoRoll();
283     return;
284     }
285    
286     pianoRoll.setPlayingEnabled(true);
287    
288     pianoRoll.setShouldRepaint(false);
289     pianoRoll.reset(true);
290     pianoRoll.setDisabled(instr.getKeyMapping(), false);
291     pianoRoll.setKeyswitches(instr.getKeyswitchMapping(), true);
292     pianoRoll.setShouldRepaint(true);
293     pianoRoll.repaint();
294     }
295    
296     private void
297     connectChannel(SamplerChannelModel chn) {
298     channel = chn;
299     channel.addMidiDataListener(pianoRoll);
300     channel.addSamplerChannelListener(getHandler());
301    
302 iliev 1778 updateDisplay();
303    
304 iliev 1776 file = channel.getChannelInfo().getInstrumentFile();
305     if(file == null) {
306     disablePianoRoll();
307     return;
308     }
309     index = channel.getChannelInfo().getInstrumentIndex();
310     updateInstrumentInfo();
311     }
312    
313     private void
314     disconnectChannel() {
315     if(channel != null) {
316     channel.removeMidiDataListener(pianoRoll);
317     channel.removeSamplerChannelListener(getHandler());
318     channel = null;
319     file = null;
320     index = -1;
321     disablePianoRoll();
322     }
323 iliev 1778
324     updateDisplay();
325 iliev 1776 }
326    
327     @Override public void
328 iliev 1778 channelAdded(SamplerChannelListEvent e) {
329     updateDisplay();
330     }
331 iliev 1776
332     @Override public void
333     channelRemoved(SamplerChannelListEvent e) {
334     if(e.getChannelModel() == channel) {
335     disconnectChannel();
336     }
337 iliev 1778
338     updateDisplay();
339 iliev 1776 }
340    
341 iliev 1778 private JPanel
342     createVSeparator() {
343     PixmapPane p = new PixmapPane(Res.gfxVLine);
344     p.setAlignmentY(JPanel.TOP_ALIGNMENT);
345     p.setPreferredSize(new Dimension(2, 60));
346     p.setMaximumSize(new Dimension(2, Short.MAX_VALUE));
347     return p;
348     }
349    
350     private Color color1 = new Color(0x7a7a7a);
351     private Color color2 = new Color(0x5e5e5e);
352     private Color color3 = new Color(0x2e2e2e);
353    
354     @Override
355     public void
356     paintComponent(Graphics g) {
357     Graphics2D g2 = (Graphics2D)g;
358    
359     Paint oldPaint = g2.getPaint();
360     Composite oldComposite = g2.getComposite();
361    
362     Insets insets = this.getInsets();
363     double x1 = insets.left;
364     double y1 = insets.top;
365    
366     double w = getSize().getWidth();
367     double x2 = w - insets.right - 1;
368     double h = getSize().getHeight();
369     double y2 = h - insets.bottom - 1;
370    
371     FantasiaPainter.paintGradient(g2, x1, y1, x2, y2 - 10, color1, color2);
372    
373     g2.setRenderingHint (
374     RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF
375     );
376    
377     double y3 = y2 - 10;
378     if(y3 < 0) y3 = 0;
379    
380     Rectangle2D.Double rect = new Rectangle2D.Double(x1, y3, x2 - x1 + 1, 11);
381    
382     GradientPaint gr = new GradientPaint (
383     0.0f, (float)y3, color2,
384     0.0f, (float)h, color3
385     );
386    
387     g2.setPaint(gr);
388     g2.fill(rect);
389    
390     drawOutBorder(g2, x1, y1, x2, y2);
391    
392     double prX = pianoRoll.getLocation().getX();
393     double prY = pianoRoll.getLocation().getY();
394     drawInBorder (
395     g2, prX - 2, prY - 2,
396     prX + pianoRoll.getSize().getWidth() + 1, prY + pianoRoll.getSize().getHeight() - 3
397     );
398    
399     g2.setPaint(oldPaint);
400     g2.setComposite(oldComposite);
401     }
402    
403     private void
404     drawOutBorder(Graphics2D g2, double x1, double y1, double x2, double y2) {
405     AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.40f);
406     g2.setComposite(ac);
407    
408     g2.setPaint(Color.WHITE);
409     Line2D.Double l = new Line2D.Double(x1, y1, x2, y1);
410     g2.draw(l);
411    
412     g2.setComposite(ac.derive(0.20f));
413     l = new Line2D.Double(x1, y1 + 1, x2, y1 + 1);
414     g2.draw(l);
415    
416     g2.setComposite(ac.derive(0.255f));
417    
418     l = new Line2D.Double(x1, y1, x1, y2);
419     g2.draw(l);
420    
421     g2.setComposite(ac.derive(0.40f));
422     g2.setPaint(Color.BLACK);
423    
424     //l = new Line2D.Double(x1, y2, x2, y2);
425     //g2.draw(l);
426    
427     g2.setComposite(ac.derive(0.20f));
428    
429     l = new Line2D.Double(x2, y1, x2, y2);
430     g2.draw(l);
431     }
432    
433     private void
434     drawInBorder(Graphics2D g2, double x1, double y1, double x2, double y2) {
435     AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.40f);
436     g2.setComposite(ac);
437    
438     g2.setPaint(Color.WHITE);
439     Line2D.Double l = new Line2D.Double(x1, y2, x2, y2);
440     //g2.draw(l);
441    
442     g2.setComposite(ac.derive(0.255f));
443    
444     l = new Line2D.Double(x2 - 1, y1 + 1, x2 - 1, y2 + 1);
445     g2.draw(l);
446    
447     g2.setComposite(ac.derive(0.13f));
448    
449     l = new Line2D.Double(x2, y1, x2, y2);
450     g2.draw(l);
451    
452     g2.setComposite(ac.derive(0.20f));
453     g2.setPaint(Color.BLACK);
454    
455     l = new Line2D.Double(x1, y1, x2, y1);
456     g2.draw(l);
457    
458     g2.setComposite(ac.derive(0.40f));
459     g2.setPaint(Color.BLACK);
460    
461     l = new Line2D.Double(x1 + 1, y1 + 1, x2 - 1, y1 + 1);
462     g2.draw(l);
463    
464     g2.setComposite(ac.derive(0.20f));
465    
466     l = new Line2D.Double(x1, y1, x1, y2);
467     g2.draw(l);
468    
469     g2.setComposite(ac.derive(0.40f));
470    
471     l = new Line2D.Double(x1 + 1, y1 + 1, x1 + 1, y2 + 1);
472     g2.draw(l);
473     }
474    
475     private void
476     updateDisplay() {
477     // TODO: called too often?
478     if(channel == null) {
479     lDisplay.setText(i18n.getLabel("PianoKeyboardPane.noChannel"));
480     return;
481     }
482    
483     SamplerChannel sc = channel.getChannelInfo();
484 iliev 1785 String s = CC.getMainFrame().getChannelPath(channel);
485 iliev 1778
486     StringBuffer sb = new StringBuffer();
487 iliev 1785 sb.append(i18n.getLabel("PianoKeyboardPane.channel", s)).append(" - ");
488 iliev 1778
489     int status = sc.getInstrumentStatus();
490     if(status >= 0 && status < 100) {
491     sb.append(i18n.getLabel("ChannelScreen.loadingInstrument", status));
492     } else if(status == -1) {
493     sb.append(i18n.getLabel("PianoKeyboardPane.noInstrument"));
494     } else if(status < -1) {
495     sb.append(i18n.getLabel("ChannelScreen.errorLoadingInstrument"));
496     } else {
497     if(sc.getInstrumentName() != null) sb.append(sc.getInstrumentName());
498     }
499    
500     lDisplay.setText(sb.toString());
501     }
502    
503    
504     class KeyRangePropsPane extends JPanel {
505     private final JButton btnIncrease =
506     new PixmapButton(pianoRoll.actionIncreaseKeyNumber, Res.gfxBtnIncrease);
507    
508     private final JButton btnDecrease =
509     new PixmapButton(pianoRoll.actionDecreaseKeyNumber, Res.gfxBtnDecrease);
510    
511     private final JButton btnScrollLeft =
512     new PixmapButton(pianoRoll.actionScrollLeft, Res.gfxBtnScrollLeft);
513    
514     private final JButton btnScrollRight =
515     new PixmapButton(pianoRoll.actionScrollRight, Res.gfxBtnScrollRight);
516    
517     KeyRangePropsPane() {
518     setOpaque(false);
519     setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
520    
521     btnIncrease.setFocusable(false);
522     btnDecrease.setFocusable(false);
523     btnScrollLeft.setFocusable(false);
524     btnScrollRight.setFocusable(false);
525    
526    
527     btnDecrease.setPressedIcon(Res.gfxBtnDecreaseRO);
528     add(btnDecrease);
529    
530     btnIncrease.setPressedIcon(Res.gfxBtnIncreaseRO);
531     add(btnIncrease);
532    
533     add(Box.createRigidArea(new Dimension(6, 0)));
534    
535     btnScrollLeft.setPressedIcon(Res.gfxBtnScrollLeftRO);
536     add(btnScrollLeft);
537    
538     btnScrollRight.setPressedIcon(Res.gfxBtnScrollRightRO);
539     add(btnScrollRight);
540     }
541     }
542    
543    
544     public static class PowerButton extends PixmapToggleButton implements ActionListener {
545     PowerButton() {
546     this(Res.gfxPowerOff, Res.gfxPowerOn);
547     }
548    
549     PowerButton(ImageIcon defaultIcon, ImageIcon selectedIcon) {
550     super(defaultIcon, selectedIcon);
551    
552     setSelected(true);
553     addActionListener(this);
554     }
555    
556     @Override
557     public void
558     actionPerformed(ActionEvent e) {
559     boolean b = isSelected();
560     MainFrame frm = (MainFrame)CC.getMainFrame();
561     if(frm == null) return;
562     frm.setMidiKeyboardVisible(b);
563     }
564    
565     @Override
566     public boolean
567     contains(int x, int y) { return (x - 11)*(x - 11) + (y - 11)*(y - 11) < 71; }
568     }
569    
570 iliev 1776 private final Handler handler = new Handler();
571    
572     private Handler
573     getHandler() { return handler; }
574    
575 iliev 1778 private class Handler extends SamplerChannelAdapter implements FocusListener, MidiDataListener {
576     @Override
577 iliev 1776 public void
578     midiDataArrived(MidiDataEvent e) {
579     if(channel == null) return;
580     channel.sendBackendMidiData(e);
581     }
582    
583 iliev 1778 @Override
584 iliev 1776 public void
585     channelChanged(SamplerChannelEvent e) {
586 iliev 1778 updateDisplay();
587    
588 iliev 1776 String newFile = channel.getChannelInfo().getInstrumentFile();
589     int newIndex = channel.getChannelInfo().getInstrumentIndex();
590    
591     if(channel.getChannelInfo().getInstrumentStatus() != 100) {
592     //don't use disablePianoRoll because of unnecessary repainting
593     pianoRoll.setAllKeysPressed(false);
594     pianoRoll.removeAllKeyswitches();
595     pianoRoll.setAllKeysDisabled(true);
596     pianoRoll.setPlayingEnabled(false);
597     return;
598     }
599    
600     if(newFile == null) {
601     if(file != null) disablePianoRoll();
602     file = null;
603     index = -1;
604     return;
605     }
606    
607     if(newFile.equals(file) && newIndex == index) return;
608    
609     file = newFile;
610     index = newIndex;
611     updateInstrumentInfo();
612     }
613 iliev 1778
614     @Override
615     public void
616     focusGained(FocusEvent e) {
617    
618     }
619    
620     @Override
621     public void
622     focusLost(FocusEvent e) {
623    
624     }
625 iliev 1776 }
626     }

  ViewVC Help
Powered by ViewVC