/[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 1743 - (hide annotations) (download)
Sat May 31 23:04:01 2008 UTC (15 years, 11 months ago) by iliev
File size: 48250 byte(s)
* Renamed the column labels in the Channel Routing dialog: The column
  representing the sampler channel's audio channels is "Audio In" and
  the column representing the audio device's channels is "Audio Out"
* Remember the last used tab in the Preferences dialog
* Fantasia: The sampler channels are now referenced by their position
  in the list, not by their ID
* Fantasia: Implemented options to show the channel number and/or the MIDI
  input port/channel on the sampler channel screen when using Small View
  (choose Edit/Preferences, then click the `Channels' tab)
* Fantasia: Migrated to substance 5

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

  ViewVC Help
Powered by ViewVC