/[svn]/jsampler/trunk/src/org/jsampler/view/classic/Channel.java
ViewVC logotype

Annotation of /jsampler/trunk/src/org/jsampler/view/classic/Channel.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1204 - (hide annotations) (download)
Thu May 24 21:43:45 2007 UTC (16 years, 11 months ago) by iliev
File size: 43430 byte(s)
upgrading to version 0.5a

1 iliev 787 /*
2     * JSampler - a java front-end for LinuxSampler
3     *
4 iliev 1143 * Copyright (C) 2005-2007 Grigor Iliev <grigor@grigoriliev.com>
5 iliev 787 *
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.classic;
24    
25 iliev 1143 import java.awt.BorderLayout;
26 iliev 787 import java.awt.Color;
27 iliev 842 import java.awt.Cursor;
28 iliev 787 import java.awt.Dimension;
29     import java.awt.GridBagConstraints;
30     import java.awt.GridBagLayout;
31     import java.awt.Insets;
32    
33 iliev 911 import java.awt.datatransfer.Transferable;
34    
35 iliev 787 import java.awt.event.ActionEvent;
36     import java.awt.event.ActionListener;
37 iliev 1143 import java.awt.event.HierarchyEvent;
38     import java.awt.event.HierarchyListener;
39 iliev 911 import java.awt.event.MouseAdapter;
40     import java.awt.event.MouseEvent;
41     import java.awt.event.MouseMotionAdapter;
42 iliev 787
43 iliev 842 import java.beans.PropertyChangeEvent;
44     import java.beans.PropertyChangeListener;
45    
46 iliev 787 import java.net.URL;
47    
48 iliev 842 import java.util.Vector;
49    
50 iliev 787 import java.util.logging.Level;
51    
52 iliev 911 import javax.swing.Action;
53     import javax.swing.AbstractAction;
54 iliev 787 import javax.swing.BorderFactory;
55     import javax.swing.Box;
56     import javax.swing.BoxLayout;
57 iliev 911 import javax.swing.JComponent;
58 iliev 787 import javax.swing.ImageIcon;
59     import javax.swing.JButton;
60     import javax.swing.JComboBox;
61     import javax.swing.JLabel;
62     import javax.swing.JPanel;
63     import javax.swing.JSeparator;
64     import javax.swing.JSlider;
65     import javax.swing.JToggleButton;
66 iliev 911 import javax.swing.TransferHandler;
67 iliev 787
68 iliev 842 import javax.swing.border.Border;
69     import javax.swing.border.LineBorder;
70 iliev 1143 import javax.swing.border.TitledBorder;
71 iliev 842
72 iliev 787 import javax.swing.event.ChangeEvent;
73     import javax.swing.event.ChangeListener;
74    
75 iliev 1143 import net.sf.juife.InformationDialog;
76 iliev 787 import net.sf.juife.JuifeUtils;
77    
78 iliev 911 import org.jsampler.AudioDeviceModel;
79 iliev 787 import org.jsampler.CC;
80 iliev 911 import org.jsampler.HF;
81     import org.jsampler.Instrument;
82 iliev 787 import org.jsampler.MidiDeviceModel;
83 iliev 1143 import org.jsampler.MidiInstrumentMap;
84 iliev 787 import org.jsampler.SamplerChannelModel;
85     import org.jsampler.SamplerModel;
86    
87 iliev 1143 import org.jsampler.event.ListEvent;
88     import org.jsampler.event.ListListener;
89 iliev 787 import org.jsampler.event.MidiDeviceListEvent;
90     import org.jsampler.event.MidiDeviceListListener;
91 iliev 1143 import org.jsampler.event.SamplerAdapter;
92 iliev 787 import org.jsampler.event.SamplerChannelAdapter;
93     import org.jsampler.event.SamplerChannelEvent;
94 iliev 911 import org.jsampler.event.SamplerChannelListEvent;
95     import org.jsampler.event.SamplerChannelListListener;
96 iliev 787 import org.jsampler.event.SamplerChannelListener;
97 iliev 1143 import org.jsampler.event.SamplerEvent;
98 iliev 787
99     import org.linuxsampler.lscp.AudioOutputDevice;
100     import org.linuxsampler.lscp.MidiInputDevice;
101     import org.linuxsampler.lscp.MidiPort;
102     import org.linuxsampler.lscp.SamplerChannel;
103     import org.linuxsampler.lscp.SamplerEngine;
104    
105     import static org.jsampler.view.classic.ClassicI18n.i18n;
106    
107    
108     /**
109     *
110     * @author Grigor Iliev
111     */
112     public class Channel extends org.jsampler.view.JSChannel {
113     private final static ImageIcon iconMuteOn;
114     private final static ImageIcon iconMuteOff;
115     private final static ImageIcon iconMutedBySolo;
116    
117     private final static ImageIcon iconSoloOn;
118     private final static ImageIcon iconSoloOff;
119    
120     private final static ImageIcon iconShowProperties;
121     private final static ImageIcon iconHideProperties;
122    
123 iliev 842 private static Border borderSelected;
124 iliev 1143 private static Border borderHighlighted;
125 iliev 842 private static Border borderDeselected;
126    
127 iliev 1143 private static Color chnColor;
128 iliev 842 private static Color borderColor;
129 iliev 1143 private static Color borderHighlightedColor;
130     private static Color chnSelectedColor;
131     private static Color chnHighlightedColor;
132 iliev 842
133     private final static Vector<PropertyChangeListener> propertyChangeListeners
134     = new Vector<PropertyChangeListener>();
135    
136 iliev 787 static {
137     String path = "org/jsampler/view/classic/res/icons/";
138     URL url = ClassLoader.getSystemClassLoader().getResource(path + "mute_on.png");
139     iconMuteOn = new ImageIcon(url);
140    
141     url = ClassLoader.getSystemClassLoader().getResource(path + "mute_off.png");
142     iconMuteOff = new ImageIcon(url);
143    
144     url = ClassLoader.getSystemClassLoader().getResource(path + "muted_by_solo.png");
145     iconMutedBySolo = new ImageIcon(url);
146    
147     url = ClassLoader.getSystemClassLoader().getResource(path + "solo_on.png");
148     iconSoloOn = new ImageIcon(url);
149    
150     url = ClassLoader.getSystemClassLoader().getResource(path + "solo_off.png");
151     iconSoloOff = new ImageIcon(url);
152    
153     url = ClassLoader.getSystemClassLoader().getResource(path + "Back16.gif");
154     iconShowProperties = new ImageIcon(url);
155    
156 iliev 911 iconHideProperties = Res.iconDown16;
157 iliev 842
158     if(ClassicPrefs.getCustomChannelBorderColor())
159     setBorderColor(ClassicPrefs.getChannelBorderColor());
160     else setBorderColor(ClassicPrefs.getDefaultChannelBorderColor());
161    
162 iliev 1143 if(ClassicPrefs.getCustomChannelBorderHlColor())
163     setBorderHighlightedColor(ClassicPrefs.getChannelBorderHlColor());
164     else setBorderHighlightedColor(ClassicPrefs.getDefaultChannelBorderHlColor());
165    
166 iliev 842 borderSelected = new LineBorder(getBorderColor(), 2, true);
167 iliev 1143 borderHighlighted = new LineBorder(getBorderHighlightedColor(), 2, true);
168 iliev 842 borderDeselected = BorderFactory.createEmptyBorder(2, 2, 2, 2);
169 iliev 1143
170     chnColor = new JPanel().getBackground();
171    
172     if(ClassicPrefs.getCustomSelectedChannelBgColor()) {
173     chnSelectedColor = ClassicPrefs.getSelectedChannelBgColor();
174     } else {
175     int r = chnColor.getRed() - 14 < 0 ? 0 : chnColor.getRed() - 14;
176     int g = chnColor.getGreen() - 8 < 0 ? 0 : chnColor.getGreen() - 8;
177     int b = chnColor.getBlue() - 3 < 0 ? 0 : chnColor.getBlue() - 3;
178    
179     chnSelectedColor = new Color(r, g, b);
180     }
181    
182     /*r = r + 5 > 255 ? 255 : r + 5;
183     g = g + 4 > 255 ? 255 : g + 4;
184     b = b + 1 > 255 ? 255 : b + 1;*/
185    
186     chnHighlightedColor = new Color(chnColor.getRGB());
187 iliev 787 }
188    
189 iliev 842 /**
190     * Registers the specified listener for receiving property change events.
191     * @param l The <code>PropertyChangeListener</code> to register.
192     */
193     public void
194     addPropertyChangeListener(PropertyChangeListener l) {
195     propertyChangeListeners.add(l);
196     }
197 iliev 787
198 iliev 842 /**
199     * Removes the specified listener.
200     * @param l The <code>PropertyChangeListener</code> to remove.
201     */
202     public void
203     removePropertyChangeListener(PropertyChangeListener l) {
204     propertyChangeListeners.remove(l);
205     }
206    
207     /**
208     * Gets the border color that is used when the channel is selected.
209     * @return The border color that is used when the channel is selected.
210     */
211     public static Color
212     getBorderColor() { return borderColor; }
213    
214     /**
215     * Sets the border color to be used when the channel is selected.
216     * @param c The border color to be used when the channel is selected.
217     */
218     public static void
219     setBorderColor(Color c) {
220     if(borderColor != null && borderColor.getRGB() == c.getRGB()) return;
221    
222     Color oldColor = borderColor;
223     borderColor = c;
224     borderSelected = new LineBorder(getBorderColor(), 2, true);
225     firePropertyChanged("borderColor", oldColor, borderColor);
226     }
227    
228 iliev 1143 /**
229     * Gets the border color that is used when the mouse pointer is over a channel.
230     * @return The border color that is used when the mouse pointer is over a channel.
231     */
232     public static Color
233     getBorderHighlightedColor() { return borderHighlightedColor; }
234    
235     /**
236     * Sets the border color to be used when the mouse pointer is over a channel.
237     * @param c The border color to be used when the mouse pointer is over a channel.
238     */
239     public static void
240     setBorderHighlightedColor(Color c) {
241     Color oldColor = borderHighlightedColor;
242     if(oldColor != null && oldColor.getRGB() == c.getRGB()) return;
243    
244     borderHighlightedColor = c;
245     borderHighlighted = new LineBorder(getBorderHighlightedColor(), 2, true);
246     firePropertyChanged("borderHighlightedColor", oldColor, borderHighlightedColor);
247     }
248    
249     /**
250     * Gets the background color that is used when a channel is selected.
251     * @return The background color that is used when a channel is selected.
252     */
253     public static Color
254     getSelectedChannelBgColor() { return chnSelectedColor; }
255    
256     /**
257     * Sets the background color that is used when a channel is selected.
258     * @param c The background color to be used when a channel is selected.
259     */
260     public static void
261     setSelectedChannelBgColor(Color c) {
262     Color oldColor = chnSelectedColor;
263     if(oldColor != null && oldColor.getRGB() == c.getRGB()) return;
264    
265     chnSelectedColor = c;
266     firePropertyChanged("selectedChannelBgColor", oldColor, chnSelectedColor);
267     }
268    
269     /**
270     * Gets the background color that is used when the mouse pointer is over a channel.
271     * @return The background color that is used when the mouse pointer is over a channel.
272     */
273     public static Color
274     getHighlightedChannelBgColor() { return chnHighlightedColor; }
275    
276     /**
277     * Sets the background color to be used when the mouse pointer is over a channel.
278     * @param c The background color to be used when the mouse pointer is over a channel.
279     */
280     public static void
281     setHighlightedChannelBgColor(Color c) {
282     Color oldColor = chnHighlightedColor;
283     if(oldColor != null && oldColor.getRGB() == c.getRGB()) return;
284    
285     chnHighlightedColor = c;
286     firePropertyChanged("highlightedChannelBgColor", oldColor, chnHighlightedColor);
287     }
288    
289 iliev 842 private static void
290     firePropertyChanged(String propertyName, Object oldValue, Object newValue) {
291     PropertyChangeEvent e =
292     new PropertyChangeEvent(Channel.class, propertyName, oldValue, newValue);
293    
294     for(PropertyChangeListener l : propertyChangeListeners) l.propertyChange(e);
295     }
296    
297    
298 iliev 787 private final JPanel mainPane = new JPanel();
299     private final ChannelProperties propertiesPane;
300 iliev 911 private final JButton btnInstr = new InstrumentButton(i18n.getLabel("Channel.btnInstr"));
301     private final Action actInstr;
302 iliev 787 private final JButton btnMute = new JButton();
303     private final JButton btnSolo = new JButton();
304     private final JSlider slVolume = new JSlider(0, 100);
305     private final JLabel lVolume = new JLabel();
306 iliev 1143 private final JLabel lVolImg = new JLabel(Res.iconVolume16);
307 iliev 787 private final JLabel lStreams = new JLabel("--");
308     private final JLabel lVoices = new JLabel("--");
309     private final JToggleButton btnProperties = new JToggleButton();
310    
311     private static int count = 2;
312    
313     private boolean selected = false;
314 iliev 1143 private boolean mouseOver = false;
315 iliev 787
316    
317     /**
318     * Creates a new instance of <code>Channel</code> using the specified
319     * non-<code>null</code> channel model.
320     * @param model The model to be used by this channel.
321     * @throws IllegalArgumentException If the model is <code>null</code>.
322     */
323     public
324     Channel(SamplerChannelModel model) {
325     super(model);
326    
327     setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
328    
329     mainPane.setLayout(new BoxLayout(mainPane, BoxLayout.Y_AXIS));
330 iliev 1143 addMouseListener(getHandler());
331 iliev 787
332     JPanel p = new JPanel();
333 iliev 1143 p.setOpaque(false);
334 iliev 787 p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));
335     p.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
336    
337 iliev 1143 setToolTipText(i18n.getLabel("Channel.tt", getModel().getChannelId()));
338 iliev 787
339     Dimension d = btnInstr.getPreferredSize();
340     btnInstr.setMaximumSize(new Dimension(Short.MAX_VALUE, d.height));
341     p.add(btnInstr);
342     p.add(Box.createRigidArea(new Dimension(6, 0)));
343    
344     lStreams.setHorizontalAlignment(JLabel.CENTER);
345     lVoices.setHorizontalAlignment(JLabel.CENTER);
346    
347     JPanel statPane = new JPanel();
348 iliev 1143 statPane.setOpaque(false);
349 iliev 787 statPane.setBorder(BorderFactory.createLoweredBevelBorder());
350     statPane.setLayout(new BoxLayout(statPane, BoxLayout.X_AXIS));
351     statPane.add(Box.createRigidArea(new Dimension(6, 0)));
352     statPane.add(lStreams);
353     statPane.add(new JLabel("/"));
354     statPane.add(lVoices);
355     statPane.add(Box.createRigidArea(new Dimension(6, 0)));
356    
357     p.add(statPane);
358    
359     p.add(Box.createRigidArea(new Dimension(6, 0)));
360    
361     btnMute.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
362     p.add(btnMute);
363     p.add(Box.createRigidArea(new Dimension(6, 0)));
364    
365     btnSolo.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
366     p.add(btnSolo);
367     p.add(Box.createRigidArea(new Dimension(6, 0)));
368    
369     JPanel volumePane = new JPanel();
370 iliev 1143 volumePane.setOpaque(false);
371 iliev 787 volumePane.setBorder(BorderFactory.createLoweredBevelBorder());
372     volumePane.setLayout(new BoxLayout(volumePane, BoxLayout.X_AXIS));
373     volumePane.add(Box.createRigidArea(new Dimension(6, 0)));
374    
375 iliev 1143 volumePane.add(lVolImg);
376     volumePane.add(Box.createRigidArea(new Dimension(1, 0)));
377    
378 iliev 787 d = slVolume.getPreferredSize();
379     slVolume.setMaximumSize(new Dimension(d.width > 300 ? d.width : 300, d.height));
380 iliev 1143 slVolume.setOpaque(false);
381 iliev 787 volumePane.add(slVolume);
382    
383     lVolume.setBorder(BorderFactory.createEmptyBorder(3, 6, 3, 6));
384     lVolume.setHorizontalAlignment(lVolume.RIGHT);
385    
386     // We use this to set the size of the lVolume that will be used in setVolume()
387     // to prevent the frequent resizing of lVolume
388     lVolume.setText("100%");
389    
390     volumePane.add(lVolume);
391    
392     p.add(volumePane);
393     p.add(Box.createRigidArea(new Dimension(6, 0)));
394    
395     btnProperties.setContentAreaFilled(false);
396     btnProperties.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
397     btnProperties.setIcon(iconShowProperties);
398     btnProperties.setSelectedIcon(iconHideProperties);
399     p.add(btnProperties);
400    
401     mainPane.add(p);
402    
403     propertiesPane = new ChannelProperties(model);
404     propertiesPane.setBorder(BorderFactory.createEmptyBorder(0, 3, 3, 3));
405     propertiesPane.setVisible(false);
406     mainPane.add(propertiesPane);
407     add(mainPane);
408    
409     d = getPreferredSize();
410     setMaximumSize(new Dimension(getMaximumSize().width, d.height));
411    
412 iliev 842 getModel().addSamplerChannelListener(getHandler());
413 iliev 787
414 iliev 911 actInstr = new AbstractAction() {
415 iliev 787 public void
416 iliev 911 actionPerformed(ActionEvent e) {
417     if(actInstr.isEnabled()) loadInstrument();
418     }
419     };
420 iliev 787
421 iliev 911 btnInstr.addActionListener(actInstr);
422    
423 iliev 787 btnMute.addActionListener(new ActionListener() {
424     public void
425     actionPerformed(ActionEvent e) { changeMute(); }
426     });
427    
428     btnSolo.addActionListener(new ActionListener() {
429     public void
430     actionPerformed(ActionEvent e) { changeSolo(); }
431     });
432    
433     slVolume.addChangeListener(new ChangeListener() {
434     public void
435     stateChanged(ChangeEvent e) { setVolume(); }
436     });
437    
438     btnProperties.addActionListener(new ActionListener() {
439     public void
440     actionPerformed(ActionEvent e) {
441     showProperties(btnProperties.isSelected());
442 iliev 842
443     String s;
444     if(btnProperties.isSelected()) {
445     s = i18n.getButtonLabel("Channel.ttHideProps");
446     } else {
447     s = i18n.getButtonLabel("Channel.ttShowProps");
448     }
449    
450     btnProperties.setToolTipText(s);
451 iliev 787 }
452     });
453    
454 iliev 842 btnProperties.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
455    
456     String s;
457     if(btnProperties.isSelected()) s = i18n.getButtonLabel("Channel.ttHideProps");
458     else s = i18n.getButtonLabel("Channel.ttShowProps");
459    
460     btnProperties.setToolTipText(s);
461    
462     addPropertyChangeListener(getHandler());
463    
464 iliev 787 updateChannelInfo();
465     }
466    
467 iliev 911 public class InstrumentButton extends JButton {
468     private boolean dragging = false;
469    
470     InstrumentButton(String s) {
471     super(s);
472    
473     setTransferHandler(new TransferHandler("instrument"));
474    
475     addMouseListener(new MouseAdapter() {
476     public void
477     mouseExited(MouseEvent e) {
478     if(!dragging) return;
479    
480     int b1 = e.BUTTON1_DOWN_MASK;
481     if((e.getModifiersEx() & b1) != b1) return;
482    
483     actInstr.setEnabled(false);
484     doClick(0);
485     actInstr.setEnabled(true);
486    
487     JComponent c = (JComponent)e.getSource();
488     TransferHandler handler = c.getTransferHandler();
489     handler.exportAsDrag(c, e, TransferHandler.COPY);
490     }
491    
492     public void
493     mouseReleased(MouseEvent e) { dragging = false; }
494     });
495    
496     addMouseMotionListener(new MouseMotionAdapter() {
497     public void
498     mouseDragged(MouseEvent e) { dragging = true; }
499     });
500     }
501    
502     public String
503     getInstrument() {
504     SamplerChannel sc = Channel.this.getChannelInfo();
505    
506     if(sc.getInstrumentName() == null || sc.getInstrumentStatus() < 0)
507     return null;
508    
509     Instrument instr = new Instrument();
510     instr.setName(sc.getInstrumentName());
511     instr.setInstrumentIndex(sc.getInstrumentIndex());
512     instr.setPath(sc.getInstrumentFile());
513     return instr.getDnDString();
514     }
515    
516     public void setInstrument(String instr) {
517     if(!Instrument.isDnDString(instr)) return;
518    
519     String[] args = instr.split("\n");
520     if(args.length < 6) return;
521    
522     try {
523     int idx = Integer.parseInt(args[5]);
524 iliev 1143 Channel.this.getModel().loadBackendInstrument(args[4], idx);
525 iliev 911 } catch(Exception x) {
526     CC.getLogger().log(Level.INFO, HF.getErrorMessage(x), x);
527     }
528     }
529     }
530    
531     private final EventHandler eventHandler = new EventHandler();
532    
533 iliev 842 private EventHandler
534     getHandler() { return eventHandler; }
535    
536 iliev 1143 private class EventHandler extends MouseAdapter implements SamplerChannelListener,
537     PropertyChangeListener, HierarchyListener {
538 iliev 787 /**
539     * Invoked when changes are made to a sampler channel.
540     * @param e A <code>SamplerChannelEvent</code> instance
541     * containing event information.
542     */
543     public void
544     channelChanged(SamplerChannelEvent e) { updateChannelInfo(); }
545    
546     /**
547     * Invoked when the number of active disk streams has changed.
548     * @param e A <code>SamplerChannelEvent</code> instance
549     * containing event information.
550     */
551     public void
552     streamCountChanged(SamplerChannelEvent e) {
553     updateStreamCount(getModel().getStreamCount());
554     }
555    
556     /**
557     * Invoked when the number of active voices has changed.
558     * @param e A <code>SamplerChannelEvent</code> instance
559     * containing event information.
560     */
561     public void
562     voiceCountChanged(SamplerChannelEvent e) {
563     updateVoiceCount(getModel().getVoiceCount());
564     }
565 iliev 842
566     public void
567     propertyChange(PropertyChangeEvent e) {
568 iliev 1143 if (
569     e.getPropertyName() == "borderColor" ||
570     e.getPropertyName() == "borderHighlightedColor" ||
571     e.getPropertyName() == "selectedChannelBgColor" ||
572     e.getPropertyName() == "highlightedChannelBgColor"
573     ) {
574     updateColors(isSelected());
575     }
576 iliev 842 }
577 iliev 1143
578     public void
579     mouseEntered(MouseEvent e) {
580     mouseOver = true;
581     updateColors(isSelected());
582     }
583    
584     public void
585     mouseExited(MouseEvent e) {
586     if(getMousePosition(true) != null) return;
587    
588     mouseOver = false;
589     updateColors(isSelected());
590     }
591    
592    
593    
594     /** Called when the hierarchy has been changed. */
595     public void
596     hierarchyChanged(HierarchyEvent e) {
597     if((e.getChangeFlags() & e.SHOWING_CHANGED) == e.SHOWING_CHANGED) {
598     if(getMousePosition() == null) mouseExited(null);
599     else mouseEntered(null);
600     }
601     }
602 iliev 787 }
603    
604     /**
605     * Determines whether the channel is selected.
606     * @return <code>true</code> if the channel is selected, <code>false</code> otherwise.
607     */
608     public boolean isSelected() { return selected; }
609    
610     /**
611     * Sets the selection state of this channel.
612     * This method is invoked when the selection state of the channel has changed.
613     * @param select Specifies the new selection state of this channel;
614     * <code>true</code> to select the channel, <code>false</code> otherwise.
615     */
616     public void
617     setSelected(boolean select) {
618 iliev 1143 updateColors(select);
619 iliev 787
620     selected = select;
621     }
622    
623 iliev 1143 /**
624     * Updates the channel background and border colors.
625     * @param selected Specifies the selection state of this channel.
626     */
627     private void
628     updateColors(boolean selected) {
629     if(selected) {
630     mainPane.setBorder(borderSelected);
631     mainPane.setBackground(chnSelectedColor);
632     } else {
633     if(mouseOver) {
634     mainPane.setBorder(borderHighlighted);
635     mainPane.setBackground(chnHighlightedColor);
636     } else {
637     mainPane.setBorder(borderDeselected);
638     mainPane.setBackground(chnColor);
639     }
640     }
641     }
642    
643 iliev 787 /** Hides the channel properties. */
644     public void
645     collapseChannel() { if(btnProperties.isSelected()) btnProperties.doClick(); }
646    
647     /** Shows the channel properties. */
648     public void
649     expandChannel() { if(!btnProperties.isSelected()) btnProperties.doClick(); }
650    
651     /**
652     * Updates the channel settings. This method is invoked when changes to the
653     * channel were made.
654     */
655     private void
656     updateChannelInfo() {
657     SamplerChannel sc = getChannelInfo();
658    
659     int status = sc.getInstrumentStatus();
660     if(status >= 0 && status < 100) {
661     btnInstr.setText(i18n.getLabel("Channel.loadingInstrument", status));
662 iliev 911 } else if(status == -1) {
663     btnInstr.setText(i18n.getLabel("Channel.btnInstr"));
664     } else if(status < -1) {
665     btnInstr.setText(i18n.getLabel("Channel.errorLoadingInstrument"));
666 iliev 787 } else {
667     if(sc.getInstrumentName() != null) btnInstr.setText(sc.getInstrumentName());
668     else btnInstr.setText(i18n.getLabel("Channel.btnInstr"));
669     }
670    
671 iliev 911 updateMuteIcon(sc);
672 iliev 787
673     if(sc.isSoloChannel()) btnSolo.setIcon(iconSoloOn);
674     else btnSolo.setIcon(iconSoloOff);
675    
676     slVolume.setValue((int)(sc.getVolume() * 100));
677    
678     boolean b = sc.getEngine() != null;
679     slVolume.setEnabled(b);
680     btnSolo.setEnabled(b);
681     btnMute.setEnabled(b);
682     }
683    
684     /** Invoked when the user clicks the mute button. */
685     private void
686     changeMute() {
687     SamplerChannel sc = getChannelInfo();
688     boolean b = true;
689    
690     /*
691     * Changing the mute button icon now instead of
692     * leaving the work to the notification mechanism of the LinuxSampler.
693     */
694     if(sc.isMuted() && !sc.isMutedBySolo()) {
695     b = false;
696     boolean hasSolo = CC.getSamplerModel().hasSoloChannel();
697    
698     if(sc.isSoloChannel() || !hasSolo) btnMute.setIcon(iconMuteOff);
699     else btnMute.setIcon(iconMutedBySolo);
700     } else btnMute.setIcon(iconMuteOn);
701    
702 iliev 1143 getModel().setBackendMute(b);
703 iliev 787 }
704    
705     /** Invoked when the user clicks the solo button. */
706     private void
707     changeSolo() {
708     SamplerChannel sc = getChannelInfo();
709     boolean b = !sc.isSoloChannel();
710    
711     /*
712     * Changing the solo button icon (and related) now instead of
713     * leaving the work to the notification mechanism of the LinuxSampler.
714     */
715     if(b) {
716     btnSolo.setIcon(iconSoloOn);
717     if(sc.isMutedBySolo()) btnMute.setIcon(iconMuteOff);
718     } else {
719     btnSolo.setIcon(iconSoloOff);
720     if(!sc.isMuted() && CC.getSamplerModel().getSoloChannelCount() > 1)
721     btnMute.setIcon(iconMutedBySolo);
722     }
723    
724 iliev 1143 getModel().setBackendSolo(b);
725 iliev 787 }
726    
727     /** Invoked when the user changes the volume */
728     private void
729     setVolume() {
730     updateVolume();
731    
732     if(slVolume.getValueIsAdjusting()) return;
733    
734     int vol = (int)(getChannelInfo().getVolume() * 100);
735    
736     if(vol == slVolume.getValue()) return;
737    
738     /*
739     * If the model's volume is not equal to the slider
740     * value we assume that the change is due to user input.
741     * So we must update the volume at the backend too.
742     */
743     float volume = slVolume.getValue();
744     volume /= 100;
745 iliev 1143 getModel().setBackendVolume(volume);
746 iliev 787 }
747    
748     private void
749     updateVolume() {
750     int volume = slVolume.getValue();
751     slVolume.setToolTipText(i18n.getLabel("Channel.volume", volume));
752 iliev 1143 lVolImg.setToolTipText(i18n.getLabel("Channel.volume", volume));
753 iliev 787
754     setVolumeLabel(volume);
755    
756    
757     }
758    
759     private void
760     setVolumeLabel(int volume) {
761     Dimension d = lVolume.getPreferredSize();
762     lVolume.setText(String.valueOf(volume) + '%');
763     d = JuifeUtils.getUnionSize(d, lVolume.getPreferredSize());
764     lVolume.setMinimumSize(d);
765     lVolume.setPreferredSize(d);
766     lVolume.setMaximumSize(d);
767     }
768    
769     /**
770     * Updates the mute button with the proper icon regarding to information obtained
771     * from <code>channel</code>.
772     * @param channel A <code>SamplerChannel</code> instance containing the new settings
773     * for this channel.
774     */
775     private void
776 iliev 911 updateMuteIcon(SamplerChannel channel) {
777 iliev 787 if(channel.isMutedBySolo()) btnMute.setIcon(iconMutedBySolo);
778     else if(channel.isMuted()) btnMute.setIcon(iconMuteOn);
779     else btnMute.setIcon(iconMuteOff);
780     }
781    
782     /**
783     * Updates the number of active disk streams.
784     * @param count The new number of active disk streams.
785     */
786     private void
787     updateStreamCount(int count) {
788     Dimension d = lStreams.getPreferredSize();
789     lStreams.setText(count == 0 ? "--" : String.valueOf(count));
790     d = JuifeUtils.getUnionSize(d, lStreams.getPreferredSize());
791     lStreams.setMinimumSize(d);
792     lStreams.setPreferredSize(d);
793     lStreams.setMaximumSize(d);
794     }
795    
796     /**
797     * Updates the number of active voices.
798     * @param count The new number of active voices.
799     */
800     private void
801     updateVoiceCount(int count) {
802     Dimension d = lVoices.getPreferredSize();
803     lVoices.setText(count == 0 ? "--" : String.valueOf(count));
804     d = JuifeUtils.getUnionSize(d, lVoices.getPreferredSize());
805     lVoices.setMinimumSize(d);
806     lVoices.setPreferredSize(d);
807     lVoices.setMaximumSize(d);
808     }
809    
810     private void
811     showProperties(boolean show) {propertiesPane.setVisible(show); }
812    
813     private void
814     loadInstrument() {
815     InstrumentChooser dlg = new InstrumentChooser(CC.getMainFrame());
816     dlg.setVisible(true);
817    
818 iliev 1204 if(dlg.isCancelled()) return;
819    
820     SamplerEngine engine = getChannelInfo().getEngine();
821     if(dlg.getEngine() != null) {
822     if(engine == null || !dlg.getEngine().equals(engine.getName()));
823     getModel().setBackendEngineType(dlg.getEngine());
824 iliev 787 }
825 iliev 1204
826     int idx = dlg.getInstrumentIndex();
827     getModel().loadBackendInstrument(dlg.getInstrumentFile(), idx);
828    
829 iliev 787 }
830     }
831    
832     class ChannelProperties extends JPanel {
833     private final JLabel lMidiDevice =
834     new JLabel(i18n.getLabel("ChannelProperties.lMidiDevice"));
835     private final JLabel lMidiPort =
836     new JLabel(i18n.getLabel("ChannelProperties.lMidiPort"));
837     private final JLabel lMidiChannel =
838     new JLabel(i18n.getLabel("ChannelProperties.lMidiChannel"));
839    
840 iliev 1143 private final JLabel lInstrumentMap =
841     new JLabel(i18n.getLabel("ChannelProperties.lInstrumentMap"));
842    
843 iliev 787 private final JLabel lAudioDevice =
844     new JLabel(i18n.getLabel("ChannelProperties.lAudioDevice"));
845    
846     private final JComboBox cbEngines = new JComboBox();
847    
848 iliev 1143 private final JComboBox cbInstrumentMap = new JComboBox();
849 iliev 787 private final JComboBox cbMidiDevice = new JComboBox();
850     private final JComboBox cbMidiPort = new JComboBox();
851     private final JComboBox cbMidiChannel = new JComboBox();
852     private final JComboBox cbAudioDevice = new JComboBox();
853    
854 iliev 1143 private final JButton btnFxSends = new JButton(Res.iconFxSends22);
855     private final JButton btnAudioProps = new JButton(Res.iconAudioProps16);
856     private InformationDialog fxSendsDlg = null;
857 iliev 787
858     private SamplerChannelModel channelModel = null;
859    
860     private boolean update = false;
861    
862 iliev 1143 private class NoMap {
863     public String
864     toString() { return "[None]"; }
865     }
866    
867     private NoMap noMap = new NoMap();
868    
869     private class DefaultMap {
870     public String
871     toString() { return "[Default]"; }
872     }
873    
874     private DefaultMap defaultMap = new DefaultMap();
875    
876 iliev 787 /**
877     * Creates a new instance of <code>ChannelProperties</code> using the specified non-null
878     * channel model.
879     * @param model The model to be used by this channel properties pane.
880     */
881     ChannelProperties(SamplerChannelModel model) {
882     channelModel = model;
883    
884     setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
885 iliev 1143 setOpaque(false);
886 iliev 787
887     add(new JSeparator());
888    
889 iliev 1143 JPanel enginesPane = createEnginePane();
890 iliev 787
891     JPanel devicesPane = new JPanel();
892 iliev 1143 devicesPane.setOpaque(false);
893 iliev 787 devicesPane.setLayout(new BoxLayout(devicesPane, BoxLayout.X_AXIS));
894    
895     devicesPane.add(Box.createRigidArea(new Dimension(3, 0)));
896    
897     devicesPane.add(createMidiPane());
898    
899     devicesPane.add(Box.createRigidArea(new Dimension(3, 0)));
900    
901     devicesPane.add(enginesPane);
902    
903     devicesPane.add(Box.createRigidArea(new Dimension(3, 0)));
904    
905     JPanel audioPane = createAudioPane();
906     Dimension d = audioPane.getPreferredSize();
907     d.height = Short.MAX_VALUE;
908    
909     audioPane.setMaximumSize(d);
910     devicesPane.add(audioPane);
911    
912     add(devicesPane);
913     add(Box.createRigidArea(new Dimension(0, 6)));
914    
915     add(new JSeparator());
916    
917     cbMidiChannel.addItem("All");
918     for(int i = 1; i <= 16; i++) cbMidiChannel.addItem(String.valueOf(i));
919    
920     cbMidiDevice.addActionListener(new ActionListener() {
921     public void
922     actionPerformed(ActionEvent e) { setMidiDevice(); }
923     });
924    
925     cbMidiPort.addActionListener(new ActionListener() {
926     public void
927     actionPerformed(ActionEvent e) { setMidiPort(); }
928     });
929    
930     cbMidiChannel.addActionListener(new ActionListener() {
931     public void
932     actionPerformed(ActionEvent e) { setMidiChannel(); }
933     });
934    
935     cbEngines.addActionListener(new ActionListener() {
936     public void
937     actionPerformed(ActionEvent e) { setEngineType(); }
938     });
939    
940     cbAudioDevice.addActionListener(new ActionListener() {
941     public void
942     actionPerformed(ActionEvent e) { setAudioDevice(); }
943     });
944    
945     getModel().addSamplerChannelListener(new SamplerChannelAdapter() {
946     public void
947     channelChanged(SamplerChannelEvent e) { updateChannelProperties(); }
948     });
949    
950 iliev 1143 CC.getSamplerModel().addSamplerListener(new SamplerAdapter() {
951     /** Invoked when the default MIDI instrument map is changed. */
952     public void
953     defaultMapChanged(SamplerEvent e) {
954     updateCbInstrumentMapToolTipText();
955    
956     }
957     });
958    
959     cbInstrumentMap.addItem(noMap);
960     cbInstrumentMap.addItem(defaultMap);
961     for(MidiInstrumentMap map : CC.getSamplerModel().getMidiInstrumentMaps()) {
962     cbInstrumentMap.addItem(map);
963     }
964    
965     int map = getModel().getChannelInfo().getMidiInstrumentMapId();
966     cbInstrumentMap.setSelectedItem(CC.getSamplerModel().getMidiInstrumentMapById(map));
967     if(cbInstrumentMap.getSelectedItem() == null) {
968     if(map == -1) cbInstrumentMap.setSelectedItem(noMap);
969     else if(map == -2) {
970     cbInstrumentMap.setSelectedItem(defaultMap);
971     }
972     }
973    
974     updateCbInstrumentMapToolTipText();
975    
976     if(getModel().getChannelInfo().getEngine() == null) {
977     cbInstrumentMap.setEnabled(false);
978     }
979    
980     cbInstrumentMap.addActionListener(new ActionListener() {
981     public void
982     actionPerformed(ActionEvent e) { updateInstrumentMap(); }
983     });
984    
985 iliev 787 CC.getSamplerModel().addMidiDeviceListListener(getHandler());
986     CC.getSamplerModel().addAudioDeviceListListener(getHandler());
987 iliev 911 CC.getSamplerModel().addSamplerChannelListListener(getHandler());
988 iliev 787
989 iliev 1143 CC.getSamplerModel().addMidiInstrumentMapListListener(new MapListListener());
990    
991 iliev 787 btnAudioProps.setToolTipText(i18n.getLabel("ChannelProperties.routing"));
992     btnAudioProps.addActionListener(new ActionListener() {
993     public void
994     actionPerformed(ActionEvent e) {
995     SamplerChannel c = getModel().getChannelInfo();
996     new ChannelOutputRoutingDlg(CC.getMainFrame(), c).setVisible(true);
997    
998     }
999     });
1000    
1001 iliev 1143 btnFxSends.setToolTipText(i18n.getButtonLabel("ChannelProperties.btnFxSends"));
1002     btnFxSends.addActionListener(new ActionListener() {
1003     public void
1004     actionPerformed(ActionEvent e) {
1005     if(fxSendsDlg != null && fxSendsDlg.isVisible()) {
1006     fxSendsDlg.toFront();
1007     return;
1008     }
1009    
1010     FxSendsPane p = new FxSendsPane(getModel());
1011     int id = getModel().getChannelId();
1012     fxSendsDlg = new InformationDialog(CC.getMainFrame(), p);
1013     fxSendsDlg.setTitle(i18n.getLabel("FxSendsPane.title", id));
1014     fxSendsDlg.setModal(false);
1015     fxSendsDlg.showCloseButton(false);
1016     fxSendsDlg.setVisible(true);
1017     }
1018     });
1019    
1020 iliev 787 updateMidiDevices();
1021     updateAudioDevices();
1022     updateChannelProperties();
1023     }
1024 iliev 1143
1025 iliev 787 private JPanel
1026 iliev 1143 createEnginePane() {
1027     for(SamplerEngine e : CC.getSamplerModel().getEngines()) cbEngines.addItem(e);
1028    
1029     cbEngines.setMaximumSize(cbEngines.getPreferredSize());
1030    
1031     JPanel p = new JPanel();
1032     p.setOpaque(false);
1033     p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));
1034     p.add(cbEngines);
1035     p.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
1036    
1037     //enginesPane.add(Box.createGlue());
1038     JPanel enginesPane = new JPanel();
1039     enginesPane.setOpaque(false);
1040     enginesPane.setLayout(new BorderLayout());
1041     enginesPane.add(p, BorderLayout.SOUTH);
1042     //enginesPane.add(Box.createRigidArea(new Dimension(0, 3)));
1043    
1044     String s = i18n.getLabel("ChannelProperties.enginesPane");
1045     enginesPane.setBorder(BorderFactory.createTitledBorder(s));
1046     Dimension d = new Dimension(enginesPane.getPreferredSize().width, Short.MAX_VALUE);
1047     enginesPane.setMaximumSize(d);
1048     return enginesPane;
1049     }
1050    
1051     private JPanel
1052 iliev 787 createMidiPane() {
1053     JPanel midiPane = new JPanel();
1054 iliev 1143 midiPane.setOpaque(false);
1055 iliev 787
1056     GridBagLayout gridbag = new GridBagLayout();
1057     GridBagConstraints c = new GridBagConstraints();
1058    
1059     midiPane.setLayout(gridbag);
1060    
1061 iliev 1143 c.gridx = 1;
1062 iliev 787 c.gridy = 0;
1063 iliev 1143 c.insets = new Insets(0, 3, 3, 3);
1064 iliev 787 gridbag.setConstraints(lMidiDevice, c);
1065     midiPane.add(lMidiDevice);
1066    
1067     c.gridx = 2;
1068     c.gridy = 0;
1069     gridbag.setConstraints(lMidiPort, c);
1070     midiPane.add(lMidiPort);
1071    
1072 iliev 1143 c.gridx = 3;
1073 iliev 787 c.gridy = 0;
1074     gridbag.setConstraints(lMidiChannel, c);
1075     midiPane.add(lMidiChannel);
1076    
1077 iliev 1143 c.gridx = 4;
1078 iliev 787 c.gridy = 0;
1079 iliev 1143 c.insets = new Insets(0, 10, 3, 3);
1080     gridbag.setConstraints(lInstrumentMap, c);
1081     midiPane.add(lInstrumentMap);
1082    
1083     btnFxSends.setMargin(new Insets(0, 0, 0, 0));
1084     c.gridx = 0;
1085     c.gridy = 0;
1086     c.gridheight = 2;
1087     c.insets = new Insets(0, 5, 0, 8);
1088     gridbag.setConstraints(btnFxSends, c);
1089     midiPane.add(btnFxSends);
1090    
1091     c.gridx = 1;
1092     c.gridy = 1;
1093     c.gridheight = 1;
1094     c.insets = new Insets(0, 4, 4, 3);
1095     c.fill = GridBagConstraints.HORIZONTAL;
1096     gridbag.setConstraints(cbMidiDevice, c);
1097     midiPane.add(cbMidiDevice);
1098    
1099     c.gridx = 3;
1100     c.gridy = 1;
1101 iliev 787 gridbag.setConstraints(cbMidiChannel, c);
1102     midiPane.add(cbMidiChannel);
1103    
1104 iliev 1143 c.gridx = 2;
1105     c.gridy = 1;
1106 iliev 787 gridbag.setConstraints(cbMidiPort, c);
1107     midiPane.add(cbMidiPort);
1108    
1109 iliev 1143 c.gridx = 4;
1110     c.gridy = 1;
1111     c.weightx = 1.0;
1112     c.insets = new Insets(0, 10, 3, 3);
1113     gridbag.setConstraints(cbInstrumentMap, c);
1114     midiPane.add(cbInstrumentMap);
1115    
1116 iliev 787 String s = i18n.getLabel("ChannelProperties.midiPane");
1117 iliev 1143 TitledBorder border = BorderFactory.createTitledBorder(s);
1118     //border.setTitlePosition(border.TOP);
1119     midiPane.setBorder(border);
1120 iliev 787 return midiPane;
1121     }
1122    
1123     private JPanel
1124     createAudioPane() {
1125     JPanel audioPane = new JPanel();
1126 iliev 1143 audioPane.setOpaque(false);
1127 iliev 787
1128     GridBagLayout gridbag = new GridBagLayout();
1129     GridBagConstraints c = new GridBagConstraints();
1130    
1131     audioPane.setLayout(gridbag);
1132    
1133     c.gridx = 0;
1134     c.gridy = 0;
1135 iliev 1143 c.insets = new Insets(0, 3, 3, 3);
1136 iliev 787 gridbag.setConstraints(lAudioDevice, c);
1137     audioPane.add(lAudioDevice);
1138    
1139 iliev 1143 c.gridx = 0;
1140     c.gridy = 1;
1141     c.fill = GridBagConstraints.HORIZONTAL;
1142 iliev 787 gridbag.setConstraints(cbAudioDevice, c);
1143     audioPane.add(cbAudioDevice);
1144    
1145     btnAudioProps.setMargin(new Insets(0, 0, 0, 0));
1146 iliev 1143 c.gridx = 1;
1147     c.gridy = 1;
1148     c.fill = GridBagConstraints.NONE;
1149 iliev 787 gridbag.setConstraints(btnAudioProps, c);
1150     audioPane.add(btnAudioProps);
1151    
1152     String s = i18n.getLabel("ChannelProperties.audioPane");
1153     audioPane.setBorder(BorderFactory.createTitledBorder(s));
1154    
1155     return audioPane;
1156     }
1157    
1158     /**
1159     * Gets the model that is currently used by this channel properties pane.
1160     * @return model The <code>SamplerChannelModel</code> instance
1161     * that provides information about the channel whose settings are
1162     * represented by this channel properties pane.
1163     */
1164     public SamplerChannelModel
1165     getModel() { return channelModel; }
1166    
1167 iliev 1143
1168     private void
1169     updateInstrumentMap() {
1170     updateCbInstrumentMapToolTipText();
1171    
1172     int id = getModel().getChannelInfo().getMidiInstrumentMapId();
1173     Object o = cbInstrumentMap.getSelectedItem();
1174     if(o == null && id == -1) return;
1175    
1176     int cbId;
1177     if(o == null || o == noMap) cbId = -1;
1178     else if(o == defaultMap) cbId = -2;
1179     else cbId = ((MidiInstrumentMap)o).getMapId();
1180    
1181     if(cbId == id) return;
1182    
1183     channelModel.setBackendMidiInstrumentMap(cbId);
1184     }
1185    
1186     private void
1187     updateCbInstrumentMapToolTipText() {
1188     if(cbInstrumentMap.getSelectedItem() != defaultMap) {
1189     cbInstrumentMap.setToolTipText(null);
1190     return;
1191     }
1192    
1193     MidiInstrumentMap m = CC.getSamplerModel().getDefaultMidiInstrumentMap();
1194     if(m != null) {
1195     String s = i18n.getLabel("Channel.ttDefault", m.getName());
1196     cbInstrumentMap.setToolTipText(s);
1197     } else {
1198     cbInstrumentMap.setToolTipText(null);
1199     }
1200     }
1201    
1202 iliev 787 /**
1203     * Updates the channel settings. This method is invoked when changes to the
1204     * channel were made.
1205     */
1206     private void
1207     updateChannelProperties() {
1208     SamplerModel sm = CC.getSamplerModel();
1209     SamplerChannel sc = getModel().getChannelInfo();
1210    
1211 iliev 1204 MidiDeviceModel mm = sm.getMidiDeviceById(sc.getMidiInputDevice());
1212     AudioDeviceModel am = sm.getAudioDeviceById(sc.getAudioOutputDevice());
1213 iliev 787
1214     if(isUpdate()) CC.getLogger().warning("Unexpected update state!");
1215    
1216     setUpdate(true);
1217    
1218     try {
1219     cbMidiDevice.setSelectedItem(mm == null ? null : mm.getDeviceInfo());
1220    
1221     cbEngines.setSelectedItem(sc.getEngine());
1222    
1223     cbAudioDevice.setSelectedItem(am == null ? null : am.getDeviceInfo());
1224     } catch(Exception x) {
1225     CC.getLogger().log(Level.WARNING, "Unkown error", x);
1226     }
1227    
1228 iliev 1143 if(sc.getEngine() != null) {
1229     if(cbInstrumentMap.getItemCount() > 0) cbInstrumentMap.setEnabled(true);
1230     } else {
1231     cbInstrumentMap.setSelectedItem(noMap);
1232     cbInstrumentMap.setEnabled(false);
1233     }
1234    
1235 iliev 787 setUpdate(false);
1236     }
1237    
1238     /**
1239     * Updates the MIDI device list.
1240     */
1241     private void
1242     updateMidiDevices() {
1243     SamplerModel sm = CC.getSamplerModel();
1244     SamplerChannel sc = getModel().getChannelInfo();
1245    
1246     setUpdate(true);
1247    
1248     try {
1249     cbMidiDevice.removeAllItems();
1250    
1251 iliev 1204 for(MidiDeviceModel m : sm.getMidiDevices())
1252 iliev 787 cbMidiDevice.addItem(m.getDeviceInfo());
1253    
1254 iliev 1204 MidiDeviceModel mm = sm.getMidiDeviceById(sc.getMidiInputDevice());
1255 iliev 787 cbMidiDevice.setSelectedItem(mm == null ? null : mm.getDeviceInfo());
1256     } catch(Exception x) {
1257     CC.getLogger().log(Level.WARNING, "Unkown error", x);
1258     }
1259    
1260     setUpdate(false);
1261     }
1262    
1263     /**
1264     * Updates the audio device list.
1265     */
1266     private void
1267     updateAudioDevices() {
1268     SamplerModel sm = CC.getSamplerModel();
1269     SamplerChannel sc = getModel().getChannelInfo();
1270    
1271     setUpdate(true);
1272    
1273     try {
1274     cbAudioDevice.removeAllItems();
1275    
1276 iliev 1204 for(AudioDeviceModel m : sm.getAudioDevices())
1277 iliev 787 cbAudioDevice.addItem(m.getDeviceInfo());
1278    
1279 iliev 1204 AudioDeviceModel am = sm.getAudioDeviceById(sc.getAudioOutputDevice());
1280 iliev 787 cbAudioDevice.setSelectedItem(am == null ? null : am.getDeviceInfo());
1281     } catch(Exception x) {
1282     CC.getLogger().log(Level.WARNING, "Unkown error", x);
1283     }
1284    
1285     setUpdate(false);
1286     }
1287    
1288     private void
1289     setMidiDevice() {
1290     MidiInputDevice mid = (MidiInputDevice)cbMidiDevice.getSelectedItem();
1291    
1292     if(!isUpdate()) {
1293 iliev 1143 if(mid != null) getModel().setBackendMidiInputDevice(mid.getDeviceId());
1294 iliev 787 return;
1295     }
1296    
1297     cbMidiPort.removeAllItems();
1298    
1299     if(mid == null) {
1300     cbMidiPort.setEnabled(false);
1301    
1302     cbMidiChannel.setSelectedItem(null);
1303     cbMidiChannel.setEnabled(false);
1304     } else {
1305     cbMidiPort.setEnabled(true);
1306    
1307     MidiPort[] ports = mid.getMidiPorts();
1308     for(MidiPort port : ports) cbMidiPort.addItem(port);
1309    
1310     int p = getModel().getChannelInfo().getMidiInputPort();
1311     cbMidiPort.setSelectedItem(p >= 0 && p < ports.length ? ports[p] : null);
1312    
1313     cbMidiChannel.setEnabled(true);
1314     int c = getModel().getChannelInfo().getMidiInputChannel();
1315     cbMidiChannel.setSelectedItem(c == -1 ? "All" : String.valueOf(c + 1));
1316     }
1317    
1318    
1319     }
1320    
1321     private void
1322     setMidiPort() {
1323     if(isUpdate()) return;
1324    
1325 iliev 1143 getModel().setBackendMidiInputPort(cbMidiPort.getSelectedIndex());
1326 iliev 787 }
1327    
1328     private void
1329     setMidiChannel() {
1330     if(isUpdate()) return;
1331    
1332     Object o = cbMidiChannel.getSelectedItem();
1333     if(o == null) return;
1334    
1335     int c = o.toString().equals("All") ? -1 : Integer.parseInt(o.toString()) - 1;
1336    
1337 iliev 1143 getModel().setBackendMidiInputChannel(c);
1338 iliev 787 }
1339    
1340     /** Invoked when the user selects an engine. */
1341     private void
1342     setEngineType() {
1343     Object oldEngine = getModel().getChannelInfo().getEngine();
1344     SamplerEngine newEngine = (SamplerEngine)cbEngines.getSelectedItem();
1345    
1346     if(oldEngine != null) { if(oldEngine.equals(newEngine)) return; }
1347     else if(newEngine == null) return;
1348    
1349 iliev 1143 getModel().setBackendEngineType(newEngine.getName());
1350 iliev 787
1351     }
1352    
1353     private void
1354     setAudioDevice() {
1355     if(isUpdate()) return;
1356     AudioOutputDevice dev = (AudioOutputDevice)cbAudioDevice.getSelectedItem();
1357 iliev 1143 if(dev != null) getModel().setBackendAudioOutputDevice(dev.getDeviceId());
1358 iliev 787 }
1359    
1360     /**
1361     * Determines whether the currently processed changes are due to update.
1362     * @return <code>true</code> if the currently processed changes are due to update and
1363     * <code>false</code> if the currently processed changes are due to user input.
1364     */
1365     private boolean
1366     isUpdate() { return update; }
1367    
1368     /**
1369     * Sets whether the currently processed changes are due to update.
1370     * @param b Specify <code>true</code> to indicate that the currently
1371     * processed changes are due to update; <code>false</code>
1372     * indicates that the currently processed changes are due to user input.
1373     */
1374     private void
1375     setUpdate(boolean b) { update = b; }
1376    
1377     private final Handler handler = new Handler();
1378    
1379     private Handler
1380     getHandler() { return handler; }
1381    
1382 iliev 911 private class Handler implements MidiDeviceListListener,
1383 iliev 1143 ListListener<AudioDeviceModel>, SamplerChannelListListener {
1384 iliev 911
1385 iliev 787 /**
1386     * Invoked when a new MIDI device is created.
1387     * @param e A <code>MidiDeviceListEvent</code>
1388     * instance providing the event information.
1389     */
1390     public void
1391     deviceAdded(MidiDeviceListEvent e) {
1392     cbMidiDevice.addItem(e.getMidiDeviceModel().getDeviceInfo());
1393     }
1394    
1395     /**
1396     * Invoked when a MIDI device is removed.
1397     * @param e A <code>MidiDeviceListEvent</code>
1398     * instance providing the event information.
1399     */
1400     public void
1401     deviceRemoved(MidiDeviceListEvent e) {
1402     cbMidiDevice.removeItem(e.getMidiDeviceModel().getDeviceInfo());
1403     }
1404    
1405     /**
1406     * Invoked when a new audio device is created.
1407     * @param e An <code>AudioDeviceListEvent</code>
1408     * instance providing the event information.
1409     */
1410     public void
1411 iliev 1143 entryAdded(ListEvent<AudioDeviceModel> e) {
1412     cbAudioDevice.addItem(e.getEntry().getDeviceInfo());
1413 iliev 787 }
1414    
1415     /**
1416     * Invoked when an audio device is removed.
1417     * @param e An <code>AudioDeviceListEvent</code>
1418     * instance providing the event information.
1419     */
1420     public void
1421 iliev 1143 entryRemoved(ListEvent<AudioDeviceModel> e) {
1422     cbAudioDevice.removeItem(e.getEntry().getDeviceInfo());
1423 iliev 787 }
1424 iliev 911
1425     /**
1426     * Invoked when a new sampler channel is created.
1427     * @param e A <code>SamplerChannelListEvent</code>
1428     * instance providing the event information.
1429     */
1430     public void
1431     channelAdded(SamplerChannelListEvent e) { }
1432    
1433     /**
1434     * Invoked when a sampler channel is removed.
1435     * @param e A <code>SamplerChannelListEvent</code>
1436     * instance providing the event information.
1437     */
1438     public void
1439     channelRemoved(SamplerChannelListEvent e) {
1440     // Some cleanup when the channel is removed.
1441 iliev 1143 if(e.getChannelModel().getChannelId() == channelModel.getChannelId()) {
1442 iliev 911 CC.getSamplerModel().removeMidiDeviceListListener(getHandler());
1443     CC.getSamplerModel().removeAudioDeviceListListener(getHandler());
1444     }
1445     }
1446 iliev 787 }
1447 iliev 1143
1448     private class MapListListener implements ListListener<MidiInstrumentMap> {
1449     /** Invoked when a new MIDI instrument map is added to a list. */
1450     public void
1451     entryAdded(ListEvent<MidiInstrumentMap> e) {
1452     //cbInstrumentMap.addItem(e.getEntry());
1453     cbInstrumentMap.insertItemAt(e.getEntry(), cbInstrumentMap.getItemCount());
1454     boolean b = getModel().getChannelInfo().getEngine() != null;
1455     if(b && !cbInstrumentMap.isEnabled()) cbInstrumentMap.setEnabled(true);
1456     }
1457    
1458     /** Invoked when a new MIDI instrument map is removed from a list. */
1459     public void
1460     entryRemoved(ListEvent<MidiInstrumentMap> e) {
1461     cbInstrumentMap.removeItem(e.getEntry());
1462     if(cbInstrumentMap.getItemCount() == 0) {
1463     cbInstrumentMap.setSelectedItem(noMap);
1464     cbInstrumentMap.setEnabled(false);
1465     }
1466     }
1467     }
1468 iliev 787 }

  ViewVC Help
Powered by ViewVC