/[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 1143 - (hide annotations) (download)
Mon Apr 2 21:18:31 2007 UTC (17 years, 1 month ago) by iliev
File size: 43217 byte(s)
* upgrading to version 0.4a

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     if(!dlg.isCancelled()) {
819 iliev 1143 int idx = dlg.getInstrumentIndex();
820     getModel().loadBackendInstrument(dlg.getFileName(), idx);
821 iliev 787 }
822     }
823     }
824    
825     class ChannelProperties extends JPanel {
826     private final JLabel lMidiDevice =
827     new JLabel(i18n.getLabel("ChannelProperties.lMidiDevice"));
828     private final JLabel lMidiPort =
829     new JLabel(i18n.getLabel("ChannelProperties.lMidiPort"));
830     private final JLabel lMidiChannel =
831     new JLabel(i18n.getLabel("ChannelProperties.lMidiChannel"));
832    
833 iliev 1143 private final JLabel lInstrumentMap =
834     new JLabel(i18n.getLabel("ChannelProperties.lInstrumentMap"));
835    
836 iliev 787 private final JLabel lAudioDevice =
837     new JLabel(i18n.getLabel("ChannelProperties.lAudioDevice"));
838    
839     private final JComboBox cbEngines = new JComboBox();
840    
841 iliev 1143 private final JComboBox cbInstrumentMap = new JComboBox();
842 iliev 787 private final JComboBox cbMidiDevice = new JComboBox();
843     private final JComboBox cbMidiPort = new JComboBox();
844     private final JComboBox cbMidiChannel = new JComboBox();
845     private final JComboBox cbAudioDevice = new JComboBox();
846    
847 iliev 1143 private final JButton btnFxSends = new JButton(Res.iconFxSends22);
848     private final JButton btnAudioProps = new JButton(Res.iconAudioProps16);
849     private InformationDialog fxSendsDlg = null;
850 iliev 787
851     private SamplerChannelModel channelModel = null;
852    
853     private boolean update = false;
854    
855 iliev 1143 private class NoMap {
856     public String
857     toString() { return "[None]"; }
858     }
859    
860     private NoMap noMap = new NoMap();
861    
862     private class DefaultMap {
863     public String
864     toString() { return "[Default]"; }
865     }
866    
867     private DefaultMap defaultMap = new DefaultMap();
868    
869 iliev 787 /**
870     * Creates a new instance of <code>ChannelProperties</code> using the specified non-null
871     * channel model.
872     * @param model The model to be used by this channel properties pane.
873     */
874     ChannelProperties(SamplerChannelModel model) {
875     channelModel = model;
876    
877     setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
878 iliev 1143 setOpaque(false);
879 iliev 787
880     add(new JSeparator());
881    
882 iliev 1143 JPanel enginesPane = createEnginePane();
883 iliev 787
884     JPanel devicesPane = new JPanel();
885 iliev 1143 devicesPane.setOpaque(false);
886 iliev 787 devicesPane.setLayout(new BoxLayout(devicesPane, BoxLayout.X_AXIS));
887    
888     devicesPane.add(Box.createRigidArea(new Dimension(3, 0)));
889    
890     devicesPane.add(createMidiPane());
891    
892     devicesPane.add(Box.createRigidArea(new Dimension(3, 0)));
893    
894     devicesPane.add(enginesPane);
895    
896     devicesPane.add(Box.createRigidArea(new Dimension(3, 0)));
897    
898     JPanel audioPane = createAudioPane();
899     Dimension d = audioPane.getPreferredSize();
900     d.height = Short.MAX_VALUE;
901    
902     audioPane.setMaximumSize(d);
903     devicesPane.add(audioPane);
904    
905     add(devicesPane);
906     add(Box.createRigidArea(new Dimension(0, 6)));
907    
908     add(new JSeparator());
909    
910     cbMidiChannel.addItem("All");
911     for(int i = 1; i <= 16; i++) cbMidiChannel.addItem(String.valueOf(i));
912    
913     cbMidiDevice.addActionListener(new ActionListener() {
914     public void
915     actionPerformed(ActionEvent e) { setMidiDevice(); }
916     });
917    
918     cbMidiPort.addActionListener(new ActionListener() {
919     public void
920     actionPerformed(ActionEvent e) { setMidiPort(); }
921     });
922    
923     cbMidiChannel.addActionListener(new ActionListener() {
924     public void
925     actionPerformed(ActionEvent e) { setMidiChannel(); }
926     });
927    
928     cbEngines.addActionListener(new ActionListener() {
929     public void
930     actionPerformed(ActionEvent e) { setEngineType(); }
931     });
932    
933     cbAudioDevice.addActionListener(new ActionListener() {
934     public void
935     actionPerformed(ActionEvent e) { setAudioDevice(); }
936     });
937    
938     getModel().addSamplerChannelListener(new SamplerChannelAdapter() {
939     public void
940     channelChanged(SamplerChannelEvent e) { updateChannelProperties(); }
941     });
942    
943 iliev 1143 CC.getSamplerModel().addSamplerListener(new SamplerAdapter() {
944     /** Invoked when the default MIDI instrument map is changed. */
945     public void
946     defaultMapChanged(SamplerEvent e) {
947     updateCbInstrumentMapToolTipText();
948    
949     }
950     });
951    
952     cbInstrumentMap.addItem(noMap);
953     cbInstrumentMap.addItem(defaultMap);
954     for(MidiInstrumentMap map : CC.getSamplerModel().getMidiInstrumentMaps()) {
955     cbInstrumentMap.addItem(map);
956     }
957    
958     int map = getModel().getChannelInfo().getMidiInstrumentMapId();
959     cbInstrumentMap.setSelectedItem(CC.getSamplerModel().getMidiInstrumentMapById(map));
960     if(cbInstrumentMap.getSelectedItem() == null) {
961     if(map == -1) cbInstrumentMap.setSelectedItem(noMap);
962     else if(map == -2) {
963     cbInstrumentMap.setSelectedItem(defaultMap);
964     }
965     }
966    
967     updateCbInstrumentMapToolTipText();
968    
969     if(getModel().getChannelInfo().getEngine() == null) {
970     cbInstrumentMap.setEnabled(false);
971     }
972    
973     cbInstrumentMap.addActionListener(new ActionListener() {
974     public void
975     actionPerformed(ActionEvent e) { updateInstrumentMap(); }
976     });
977    
978 iliev 787 CC.getSamplerModel().addMidiDeviceListListener(getHandler());
979     CC.getSamplerModel().addAudioDeviceListListener(getHandler());
980 iliev 911 CC.getSamplerModel().addSamplerChannelListListener(getHandler());
981 iliev 787
982 iliev 1143 CC.getSamplerModel().addMidiInstrumentMapListListener(new MapListListener());
983    
984 iliev 787 btnAudioProps.setToolTipText(i18n.getLabel("ChannelProperties.routing"));
985     btnAudioProps.addActionListener(new ActionListener() {
986     public void
987     actionPerformed(ActionEvent e) {
988     SamplerChannel c = getModel().getChannelInfo();
989     new ChannelOutputRoutingDlg(CC.getMainFrame(), c).setVisible(true);
990    
991     }
992     });
993    
994 iliev 1143 btnFxSends.setToolTipText(i18n.getButtonLabel("ChannelProperties.btnFxSends"));
995     btnFxSends.addActionListener(new ActionListener() {
996     public void
997     actionPerformed(ActionEvent e) {
998     if(fxSendsDlg != null && fxSendsDlg.isVisible()) {
999     fxSendsDlg.toFront();
1000     return;
1001     }
1002    
1003     FxSendsPane p = new FxSendsPane(getModel());
1004     int id = getModel().getChannelId();
1005     fxSendsDlg = new InformationDialog(CC.getMainFrame(), p);
1006     fxSendsDlg.setTitle(i18n.getLabel("FxSendsPane.title", id));
1007     fxSendsDlg.setModal(false);
1008     fxSendsDlg.showCloseButton(false);
1009     fxSendsDlg.setVisible(true);
1010     }
1011     });
1012    
1013 iliev 787 updateMidiDevices();
1014     updateAudioDevices();
1015     updateChannelProperties();
1016     }
1017 iliev 1143
1018 iliev 787 private JPanel
1019 iliev 1143 createEnginePane() {
1020     for(SamplerEngine e : CC.getSamplerModel().getEngines()) cbEngines.addItem(e);
1021    
1022     cbEngines.setMaximumSize(cbEngines.getPreferredSize());
1023    
1024     JPanel p = new JPanel();
1025     p.setOpaque(false);
1026     p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));
1027     p.add(cbEngines);
1028     p.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
1029    
1030     //enginesPane.add(Box.createGlue());
1031     JPanel enginesPane = new JPanel();
1032     enginesPane.setOpaque(false);
1033     enginesPane.setLayout(new BorderLayout());
1034     enginesPane.add(p, BorderLayout.SOUTH);
1035     //enginesPane.add(Box.createRigidArea(new Dimension(0, 3)));
1036    
1037     String s = i18n.getLabel("ChannelProperties.enginesPane");
1038     enginesPane.setBorder(BorderFactory.createTitledBorder(s));
1039     Dimension d = new Dimension(enginesPane.getPreferredSize().width, Short.MAX_VALUE);
1040     enginesPane.setMaximumSize(d);
1041     return enginesPane;
1042     }
1043    
1044     private JPanel
1045 iliev 787 createMidiPane() {
1046     JPanel midiPane = new JPanel();
1047 iliev 1143 midiPane.setOpaque(false);
1048 iliev 787
1049     GridBagLayout gridbag = new GridBagLayout();
1050     GridBagConstraints c = new GridBagConstraints();
1051    
1052     midiPane.setLayout(gridbag);
1053    
1054 iliev 1143 c.gridx = 1;
1055 iliev 787 c.gridy = 0;
1056 iliev 1143 c.insets = new Insets(0, 3, 3, 3);
1057 iliev 787 gridbag.setConstraints(lMidiDevice, c);
1058     midiPane.add(lMidiDevice);
1059    
1060     c.gridx = 2;
1061     c.gridy = 0;
1062     gridbag.setConstraints(lMidiPort, c);
1063     midiPane.add(lMidiPort);
1064    
1065 iliev 1143 c.gridx = 3;
1066 iliev 787 c.gridy = 0;
1067     gridbag.setConstraints(lMidiChannel, c);
1068     midiPane.add(lMidiChannel);
1069    
1070 iliev 1143 c.gridx = 4;
1071 iliev 787 c.gridy = 0;
1072 iliev 1143 c.insets = new Insets(0, 10, 3, 3);
1073     gridbag.setConstraints(lInstrumentMap, c);
1074     midiPane.add(lInstrumentMap);
1075    
1076     btnFxSends.setMargin(new Insets(0, 0, 0, 0));
1077     c.gridx = 0;
1078     c.gridy = 0;
1079     c.gridheight = 2;
1080     c.insets = new Insets(0, 5, 0, 8);
1081     gridbag.setConstraints(btnFxSends, c);
1082     midiPane.add(btnFxSends);
1083    
1084     c.gridx = 1;
1085     c.gridy = 1;
1086     c.gridheight = 1;
1087     c.insets = new Insets(0, 4, 4, 3);
1088     c.fill = GridBagConstraints.HORIZONTAL;
1089     gridbag.setConstraints(cbMidiDevice, c);
1090     midiPane.add(cbMidiDevice);
1091    
1092     c.gridx = 3;
1093     c.gridy = 1;
1094 iliev 787 gridbag.setConstraints(cbMidiChannel, c);
1095     midiPane.add(cbMidiChannel);
1096    
1097 iliev 1143 c.gridx = 2;
1098     c.gridy = 1;
1099 iliev 787 gridbag.setConstraints(cbMidiPort, c);
1100     midiPane.add(cbMidiPort);
1101    
1102 iliev 1143 c.gridx = 4;
1103     c.gridy = 1;
1104     c.weightx = 1.0;
1105     c.insets = new Insets(0, 10, 3, 3);
1106     gridbag.setConstraints(cbInstrumentMap, c);
1107     midiPane.add(cbInstrumentMap);
1108    
1109 iliev 787 String s = i18n.getLabel("ChannelProperties.midiPane");
1110 iliev 1143 TitledBorder border = BorderFactory.createTitledBorder(s);
1111     //border.setTitlePosition(border.TOP);
1112     midiPane.setBorder(border);
1113 iliev 787 return midiPane;
1114     }
1115    
1116     private JPanel
1117     createAudioPane() {
1118     JPanel audioPane = new JPanel();
1119 iliev 1143 audioPane.setOpaque(false);
1120 iliev 787
1121     GridBagLayout gridbag = new GridBagLayout();
1122     GridBagConstraints c = new GridBagConstraints();
1123    
1124     audioPane.setLayout(gridbag);
1125    
1126     c.gridx = 0;
1127     c.gridy = 0;
1128 iliev 1143 c.insets = new Insets(0, 3, 3, 3);
1129 iliev 787 gridbag.setConstraints(lAudioDevice, c);
1130     audioPane.add(lAudioDevice);
1131    
1132 iliev 1143 c.gridx = 0;
1133     c.gridy = 1;
1134     c.fill = GridBagConstraints.HORIZONTAL;
1135 iliev 787 gridbag.setConstraints(cbAudioDevice, c);
1136     audioPane.add(cbAudioDevice);
1137    
1138     btnAudioProps.setMargin(new Insets(0, 0, 0, 0));
1139 iliev 1143 c.gridx = 1;
1140     c.gridy = 1;
1141     c.fill = GridBagConstraints.NONE;
1142 iliev 787 gridbag.setConstraints(btnAudioProps, c);
1143     audioPane.add(btnAudioProps);
1144    
1145     String s = i18n.getLabel("ChannelProperties.audioPane");
1146     audioPane.setBorder(BorderFactory.createTitledBorder(s));
1147    
1148     return audioPane;
1149     }
1150    
1151     /**
1152     * Gets the model that is currently used by this channel properties pane.
1153     * @return model The <code>SamplerChannelModel</code> instance
1154     * that provides information about the channel whose settings are
1155     * represented by this channel properties pane.
1156     */
1157     public SamplerChannelModel
1158     getModel() { return channelModel; }
1159    
1160 iliev 1143
1161     private void
1162     updateInstrumentMap() {
1163     updateCbInstrumentMapToolTipText();
1164    
1165     int id = getModel().getChannelInfo().getMidiInstrumentMapId();
1166     Object o = cbInstrumentMap.getSelectedItem();
1167     if(o == null && id == -1) return;
1168    
1169     int cbId;
1170     if(o == null || o == noMap) cbId = -1;
1171     else if(o == defaultMap) cbId = -2;
1172     else cbId = ((MidiInstrumentMap)o).getMapId();
1173    
1174     if(cbId == id) return;
1175    
1176     channelModel.setBackendMidiInstrumentMap(cbId);
1177     }
1178    
1179     private void
1180     updateCbInstrumentMapToolTipText() {
1181     if(cbInstrumentMap.getSelectedItem() != defaultMap) {
1182     cbInstrumentMap.setToolTipText(null);
1183     return;
1184     }
1185    
1186     MidiInstrumentMap m = CC.getSamplerModel().getDefaultMidiInstrumentMap();
1187     if(m != null) {
1188     String s = i18n.getLabel("Channel.ttDefault", m.getName());
1189     cbInstrumentMap.setToolTipText(s);
1190     } else {
1191     cbInstrumentMap.setToolTipText(null);
1192     }
1193     }
1194    
1195 iliev 787 /**
1196     * Updates the channel settings. This method is invoked when changes to the
1197     * channel were made.
1198     */
1199     private void
1200     updateChannelProperties() {
1201     SamplerModel sm = CC.getSamplerModel();
1202     SamplerChannel sc = getModel().getChannelInfo();
1203    
1204     MidiDeviceModel mm = sm.getMidiDeviceModel(sc.getMidiInputDevice());
1205     AudioDeviceModel am = sm.getAudioDeviceModel(sc.getAudioOutputDevice());
1206    
1207     if(isUpdate()) CC.getLogger().warning("Unexpected update state!");
1208    
1209     setUpdate(true);
1210    
1211     try {
1212     cbMidiDevice.setSelectedItem(mm == null ? null : mm.getDeviceInfo());
1213    
1214     cbEngines.setSelectedItem(sc.getEngine());
1215    
1216     cbAudioDevice.setSelectedItem(am == null ? null : am.getDeviceInfo());
1217     } catch(Exception x) {
1218     CC.getLogger().log(Level.WARNING, "Unkown error", x);
1219     }
1220    
1221 iliev 1143 if(sc.getEngine() != null) {
1222     if(cbInstrumentMap.getItemCount() > 0) cbInstrumentMap.setEnabled(true);
1223     } else {
1224     cbInstrumentMap.setSelectedItem(noMap);
1225     cbInstrumentMap.setEnabled(false);
1226     }
1227    
1228 iliev 787 setUpdate(false);
1229     }
1230    
1231     /**
1232     * Updates the MIDI device list.
1233     */
1234     private void
1235     updateMidiDevices() {
1236     SamplerModel sm = CC.getSamplerModel();
1237     SamplerChannel sc = getModel().getChannelInfo();
1238    
1239     setUpdate(true);
1240    
1241     try {
1242     cbMidiDevice.removeAllItems();
1243    
1244     for(MidiDeviceModel m : sm.getMidiDeviceModels())
1245     cbMidiDevice.addItem(m.getDeviceInfo());
1246    
1247     MidiDeviceModel mm = sm.getMidiDeviceModel(sc.getMidiInputDevice());
1248     cbMidiDevice.setSelectedItem(mm == null ? null : mm.getDeviceInfo());
1249     } catch(Exception x) {
1250     CC.getLogger().log(Level.WARNING, "Unkown error", x);
1251     }
1252    
1253     setUpdate(false);
1254     }
1255    
1256     /**
1257     * Updates the audio device list.
1258     */
1259     private void
1260     updateAudioDevices() {
1261     SamplerModel sm = CC.getSamplerModel();
1262     SamplerChannel sc = getModel().getChannelInfo();
1263    
1264     setUpdate(true);
1265    
1266     try {
1267     cbAudioDevice.removeAllItems();
1268    
1269     for(AudioDeviceModel m : sm.getAudioDeviceModels())
1270     cbAudioDevice.addItem(m.getDeviceInfo());
1271    
1272     AudioDeviceModel am = sm.getAudioDeviceModel(sc.getAudioOutputDevice());
1273     cbAudioDevice.setSelectedItem(am == null ? null : am.getDeviceInfo());
1274     } catch(Exception x) {
1275     CC.getLogger().log(Level.WARNING, "Unkown error", x);
1276     }
1277    
1278     setUpdate(false);
1279     }
1280    
1281     private void
1282     setMidiDevice() {
1283     MidiInputDevice mid = (MidiInputDevice)cbMidiDevice.getSelectedItem();
1284    
1285     if(!isUpdate()) {
1286 iliev 1143 if(mid != null) getModel().setBackendMidiInputDevice(mid.getDeviceId());
1287 iliev 787 return;
1288     }
1289    
1290     cbMidiPort.removeAllItems();
1291    
1292     if(mid == null) {
1293     cbMidiPort.setEnabled(false);
1294    
1295     cbMidiChannel.setSelectedItem(null);
1296     cbMidiChannel.setEnabled(false);
1297     } else {
1298     cbMidiPort.setEnabled(true);
1299    
1300     MidiPort[] ports = mid.getMidiPorts();
1301     for(MidiPort port : ports) cbMidiPort.addItem(port);
1302    
1303     int p = getModel().getChannelInfo().getMidiInputPort();
1304     cbMidiPort.setSelectedItem(p >= 0 && p < ports.length ? ports[p] : null);
1305    
1306     cbMidiChannel.setEnabled(true);
1307     int c = getModel().getChannelInfo().getMidiInputChannel();
1308     cbMidiChannel.setSelectedItem(c == -1 ? "All" : String.valueOf(c + 1));
1309     }
1310    
1311    
1312     }
1313    
1314     private void
1315     setMidiPort() {
1316     if(isUpdate()) return;
1317    
1318 iliev 1143 getModel().setBackendMidiInputPort(cbMidiPort.getSelectedIndex());
1319 iliev 787 }
1320    
1321     private void
1322     setMidiChannel() {
1323     if(isUpdate()) return;
1324    
1325     Object o = cbMidiChannel.getSelectedItem();
1326     if(o == null) return;
1327    
1328     int c = o.toString().equals("All") ? -1 : Integer.parseInt(o.toString()) - 1;
1329    
1330 iliev 1143 getModel().setBackendMidiInputChannel(c);
1331 iliev 787 }
1332    
1333     /** Invoked when the user selects an engine. */
1334     private void
1335     setEngineType() {
1336     Object oldEngine = getModel().getChannelInfo().getEngine();
1337     SamplerEngine newEngine = (SamplerEngine)cbEngines.getSelectedItem();
1338    
1339     if(oldEngine != null) { if(oldEngine.equals(newEngine)) return; }
1340     else if(newEngine == null) return;
1341    
1342 iliev 1143 getModel().setBackendEngineType(newEngine.getName());
1343 iliev 787
1344     }
1345    
1346     private void
1347     setAudioDevice() {
1348     if(isUpdate()) return;
1349     AudioOutputDevice dev = (AudioOutputDevice)cbAudioDevice.getSelectedItem();
1350 iliev 1143 if(dev != null) getModel().setBackendAudioOutputDevice(dev.getDeviceId());
1351 iliev 787 }
1352    
1353     /**
1354     * Determines whether the currently processed changes are due to update.
1355     * @return <code>true</code> if the currently processed changes are due to update and
1356     * <code>false</code> if the currently processed changes are due to user input.
1357     */
1358     private boolean
1359     isUpdate() { return update; }
1360    
1361     /**
1362     * Sets whether the currently processed changes are due to update.
1363     * @param b Specify <code>true</code> to indicate that the currently
1364     * processed changes are due to update; <code>false</code>
1365     * indicates that the currently processed changes are due to user input.
1366     */
1367     private void
1368     setUpdate(boolean b) { update = b; }
1369    
1370     private final Handler handler = new Handler();
1371    
1372     private Handler
1373     getHandler() { return handler; }
1374    
1375 iliev 911 private class Handler implements MidiDeviceListListener,
1376 iliev 1143 ListListener<AudioDeviceModel>, SamplerChannelListListener {
1377 iliev 911
1378 iliev 787 /**
1379     * Invoked when a new MIDI device is created.
1380     * @param e A <code>MidiDeviceListEvent</code>
1381     * instance providing the event information.
1382     */
1383     public void
1384     deviceAdded(MidiDeviceListEvent e) {
1385     cbMidiDevice.addItem(e.getMidiDeviceModel().getDeviceInfo());
1386     }
1387    
1388     /**
1389     * Invoked when a MIDI device is removed.
1390     * @param e A <code>MidiDeviceListEvent</code>
1391     * instance providing the event information.
1392     */
1393     public void
1394     deviceRemoved(MidiDeviceListEvent e) {
1395     cbMidiDevice.removeItem(e.getMidiDeviceModel().getDeviceInfo());
1396     }
1397    
1398     /**
1399     * Invoked when a new audio device is created.
1400     * @param e An <code>AudioDeviceListEvent</code>
1401     * instance providing the event information.
1402     */
1403     public void
1404 iliev 1143 entryAdded(ListEvent<AudioDeviceModel> e) {
1405     cbAudioDevice.addItem(e.getEntry().getDeviceInfo());
1406 iliev 787 }
1407    
1408     /**
1409     * Invoked when an audio device is removed.
1410     * @param e An <code>AudioDeviceListEvent</code>
1411     * instance providing the event information.
1412     */
1413     public void
1414 iliev 1143 entryRemoved(ListEvent<AudioDeviceModel> e) {
1415     cbAudioDevice.removeItem(e.getEntry().getDeviceInfo());
1416 iliev 787 }
1417 iliev 911
1418     /**
1419     * Invoked when a new sampler channel is created.
1420     * @param e A <code>SamplerChannelListEvent</code>
1421     * instance providing the event information.
1422     */
1423     public void
1424     channelAdded(SamplerChannelListEvent e) { }
1425    
1426     /**
1427     * Invoked when a sampler channel is removed.
1428     * @param e A <code>SamplerChannelListEvent</code>
1429     * instance providing the event information.
1430     */
1431     public void
1432     channelRemoved(SamplerChannelListEvent e) {
1433     // Some cleanup when the channel is removed.
1434 iliev 1143 if(e.getChannelModel().getChannelId() == channelModel.getChannelId()) {
1435 iliev 911 CC.getSamplerModel().removeMidiDeviceListListener(getHandler());
1436     CC.getSamplerModel().removeAudioDeviceListListener(getHandler());
1437     }
1438     }
1439 iliev 787 }
1440 iliev 1143
1441     private class MapListListener implements ListListener<MidiInstrumentMap> {
1442     /** Invoked when a new MIDI instrument map is added to a list. */
1443     public void
1444     entryAdded(ListEvent<MidiInstrumentMap> e) {
1445     //cbInstrumentMap.addItem(e.getEntry());
1446     cbInstrumentMap.insertItemAt(e.getEntry(), cbInstrumentMap.getItemCount());
1447     boolean b = getModel().getChannelInfo().getEngine() != null;
1448     if(b && !cbInstrumentMap.isEnabled()) cbInstrumentMap.setEnabled(true);
1449     }
1450    
1451     /** Invoked when a new MIDI instrument map is removed from a list. */
1452     public void
1453     entryRemoved(ListEvent<MidiInstrumentMap> e) {
1454     cbInstrumentMap.removeItem(e.getEntry());
1455     if(cbInstrumentMap.getItemCount() == 0) {
1456     cbInstrumentMap.setSelectedItem(noMap);
1457     cbInstrumentMap.setEnabled(false);
1458     }
1459     }
1460     }
1461 iliev 787 }

  ViewVC Help
Powered by ViewVC