/[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 1285 - (hide annotations) (download)
Fri Aug 10 19:55:03 2007 UTC (16 years, 8 months ago) by iliev
File size: 45928 byte(s)
* Updated to version 0.6a. The Fantasia distribution is now
  capable of controlling all features available in LinuxSampler

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

  ViewVC Help
Powered by ViewVC