/[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 1818 - (hide annotations) (download)
Wed Dec 24 17:29:47 2008 UTC (15 years, 4 months ago) by iliev
File size: 16589 byte(s)
* Added support for controlling the global sampler-wide limit of
  maximum voices and disk streams
  (choose Edit/Preferences, then click the `General' tab)
* Fantasia: store the view configuration of audio/MIDI devices and sampler
  channels in the LSCP script when exporting sampler configuration
* Fantasia: Implemented multiple sampler channels' selection
* Fantasia: Added option to move sampler channels up and down
  in the channels list
* Fantasia: Added option to move sampler channels
  to another channels panels

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

  ViewVC Help
Powered by ViewVC