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

Diff of /jsampler/trunk/src/org/jsampler/view/fantasia/Channel.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1318 by iliev, Sat Sep 1 13:46:04 2007 UTC revision 1734 by iliev, Sun May 4 18:40:13 2008 UTC
# Line 1  Line 1 
1  /*  /*
2   *   JSampler - a java front-end for LinuxSampler   *   JSampler - a java front-end for LinuxSampler
3   *   *
4   *   Copyright (C) 2005-2007 Grigor Iliev <grigor@grigoriliev.com>   *   Copyright (C) 2005-2008 Grigor Iliev <grigor@grigoriliev.com>
5   *   *
6   *   This file is part of JSampler.   *   This file is part of JSampler.
7   *   *
# Line 22  Line 22 
22    
23  package org.jsampler.view.fantasia;  package org.jsampler.view.fantasia;
24    
25  import java.awt.Cursor;  import java.awt.Container;
26  import java.awt.Dimension;  import java.awt.Dimension;
27  import java.awt.Graphics;  import java.awt.Rectangle;
 import java.awt.Insets;  
28    
29  import java.awt.event.ActionEvent;  import java.awt.event.ActionEvent;
30  import java.awt.event.ActionListener;  import java.awt.event.ActionListener;
# Line 35  import java.awt.event.MouseEvent; Line 34  import java.awt.event.MouseEvent;
34  import java.beans.PropertyChangeEvent;  import java.beans.PropertyChangeEvent;
35  import java.beans.PropertyChangeListener;  import java.beans.PropertyChangeListener;
36    
37  import java.util.logging.Level;  import java.text.NumberFormat;
38    
39    import javax.swing.AbstractAction;
40  import javax.swing.Action;  import javax.swing.Action;
 import javax.swing.BorderFactory;  
 import javax.swing.Box;  
41  import javax.swing.BoxLayout;  import javax.swing.BoxLayout;
42    import javax.swing.ButtonGroup;
43  import javax.swing.DefaultListCellRenderer;  import javax.swing.DefaultListCellRenderer;
44    import javax.swing.ImageIcon;
45  import javax.swing.JButton;  import javax.swing.JButton;
46  import javax.swing.JComboBox;  import javax.swing.JComponent;
47  import javax.swing.JLabel;  import javax.swing.JLabel;
48  import javax.swing.JMenuItem;  import javax.swing.JMenuItem;
49  import javax.swing.JPanel;  import javax.swing.JPanel;
50  import javax.swing.JPopupMenu;  import javax.swing.JPopupMenu;
51    import javax.swing.JRadioButtonMenuItem;
52    import javax.swing.JScrollPane;
53  import javax.swing.JToggleButton;  import javax.swing.JToggleButton;
54  import javax.swing.JToolBar;  import javax.swing.JToolBar;
 import javax.swing.SwingConstants;  
55    
 import javax.swing.event.ChangeEvent;  
 import javax.swing.event.ChangeListener;  
   
 import net.sf.juife.Dial;  
56  import net.sf.juife.InformationDialog;  import net.sf.juife.InformationDialog;
 import net.sf.juife.JuifeUtils;  
57  import net.sf.juife.TitleBar;  import net.sf.juife.TitleBar;
58    
59  import org.jdesktop.swingx.JXCollapsiblePane;  import org.jdesktop.swingx.JXCollapsiblePane;
60    
 import org.jsampler.AudioDeviceModel;  
61  import org.jsampler.CC;  import org.jsampler.CC;
62  import org.jsampler.MidiDeviceModel;  import org.jsampler.HF;
 import org.jsampler.MidiInstrumentMap;  
63  import org.jsampler.SamplerChannelModel;  import org.jsampler.SamplerChannelModel;
 import org.jsampler.SamplerModel;  
64    
 import org.jsampler.event.ListEvent;  
 import org.jsampler.event.ListListener;  
 import org.jsampler.event.MidiDeviceEvent;  
 import org.jsampler.event.MidiDeviceListEvent;  
 import org.jsampler.event.MidiDeviceListListener;  
 import org.jsampler.event.MidiDeviceListener;  
 import org.jsampler.event.SamplerAdapter;  
 import org.jsampler.event.SamplerChannelAdapter;  
65  import org.jsampler.event.SamplerChannelEvent;  import org.jsampler.event.SamplerChannelEvent;
66  import org.jsampler.event.SamplerChannelListEvent;  import org.jsampler.event.SamplerChannelListEvent;
67  import org.jsampler.event.SamplerChannelListListener;  import org.jsampler.event.SamplerChannelListListener;
68  import org.jsampler.event.SamplerChannelListener;  import org.jsampler.event.SamplerChannelListener;
69  import org.jsampler.event.SamplerEvent;  
70  import org.jsampler.event.SamplerListener;  import org.jsampler.view.JSChannel;
71    
72  import org.jsampler.view.std.JSChannelOutputRoutingDlg;  import org.jsampler.view.std.JSChannelOutputRoutingDlg;
73  import org.jsampler.view.std.JSFxSendsPane;  import org.jsampler.view.std.JSFxSendsPane;
74  import org.jsampler.view.std.JSInstrumentChooser;  import org.jsampler.view.std.JSInstrumentChooser;
75    import org.jsampler.view.std.JSVolumeEditorPopup;
76    
 import org.jvnet.lafwidget.animation.FadeConfigurationManager;  
 import org.jvnet.lafwidget.animation.FadeKind;  
   
 import org.jvnet.substance.SubstanceImageCreator;  
 import org.jvnet.substance.SubstanceLookAndFeel;  
   
 import org.linuxsampler.lscp.AudioOutputDevice;  
 import org.linuxsampler.lscp.MidiInputDevice;  
 import org.linuxsampler.lscp.MidiPort;  
77  import org.linuxsampler.lscp.SamplerChannel;  import org.linuxsampler.lscp.SamplerChannel;
 import org.linuxsampler.lscp.SamplerEngine;  
78    
79  import static org.jsampler.view.fantasia.FantasiaI18n.i18n;  import static org.jsampler.view.fantasia.FantasiaI18n.i18n;
80  import static org.jsampler.view.fantasia.FantasiaPrefs.*;  import static org.jsampler.view.fantasia.FantasiaPrefs.*;
81    import static org.jsampler.view.fantasia.FantasiaUtils.*;
82    import static org.jsampler.view.std.JSVolumeEditorPopup.VolumeType;
83    
84    
85  /**  /**
86   *   *
87   * @author Grigor Iliev   * @author Grigor Iliev
88   */   */
89  public class Channel extends org.jsampler.view.JSChannel {  public class Channel extends JSChannel {
90          private final JXCollapsiblePane mainPane;          private final JXCollapsiblePane mainPane;
91          private final ChannelScreen screen = new ChannelScreen(this);          private ChannelOptionsView channelOptionsView;
92          private final ChannelOptions optionsPane = new ChannelOptions(this);          private final ChannelOptionsPane optionsPane = new ChannelOptionsPane();
93                    
94          private final PowerButton btnPower = new PowerButton();          private final ViewTracker viewTracker;
         private final MuteButton btnMute = new MuteButton();  
         private final SoloButton btnSolo = new SoloButton();  
         private final OptionsButton btnOptions = new OptionsButton();  
95                    
96          private final EnhancedDial dialVolume = new EnhancedDial();          private InformationDialog fxSendsDlg = null;
97            
98            private final ContextMenu contextMenu = new ContextMenu();
99                    
100          private boolean selected = false;          private boolean selected = false;
101                    
102            private AnimatedPorpetyListener animatedPorpetyListener = new AnimatedPorpetyListener();
103            
104            class AnimatedPorpetyListener implements PropertyChangeListener {
105                    public void
106                    propertyChange(PropertyChangeEvent e) {
107                            mainPane.setAnimated(preferences().getBoolProperty(ANIMATED));
108                    }
109            }
110            
111          /**          /**
112           * Creates a new instance of <code>Channel</code> using the specified           * Creates a new instance of <code>Channel</code> using the specified
113           * non-<code>null</code> channel model.           * non-<code>null</code> channel model.
# Line 146  public class Channel extends org.jsample Line 132  public class Channel extends org.jsample
132                  super(model);                  super(model);
133                                    
134                  setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));                  setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
                 ChannelPane p = new ChannelPane();  
                 p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));  
                   
                 //p.add(Box.createRigidArea(new Dimension(3, 0)));  
                   
                 btnPower.setAlignmentY(JPanel.TOP_ALIGNMENT);  
                   
                 JPanel tb = new JPanel();  
                 tb.setBorder(BorderFactory.createEmptyBorder(3, 3, 0, 4));  
                 tb.setLayout(new BoxLayout(tb, BoxLayout.X_AXIS));  
                 tb.setOpaque(false);  
                 tb.setAlignmentY(JPanel.TOP_ALIGNMENT);  
                 tb.add(btnPower);  
                 tb.setPreferredSize(new Dimension(tb.getPreferredSize().width, 58));  
                 tb.setMinimumSize(tb.getPreferredSize());  
                 tb.setMaximumSize(tb.getPreferredSize());  
                 p.add(tb);  
                   
                 //p.add(Box.createRigidArea(new Dimension(4, 0)));  
                   
                 p.add(createVSeparator());  
                   
                 //p.add(Box.createRigidArea(new Dimension(3, 0)));  
                   
                 JPanel p2 = new JPanel();  
                 p2.setOpaque(false);  
                 p2.setLayout(new BoxLayout(p2, BoxLayout.Y_AXIS));  
                 p2.setAlignmentY(JPanel.TOP_ALIGNMENT);  
                 p2.setBorder(BorderFactory.createEmptyBorder(5, 3, 0, 2));  
                 p2.add(screen);  
                 p.add(p2);  
                   
                 p.add(createVSeparator());  
                   
                 p2 = new JPanel();  
                 p2.setOpaque(false);  
                 p2.setLayout(new BoxLayout(p2, BoxLayout.Y_AXIS));  
                 p2.setAlignmentY(JPanel.TOP_ALIGNMENT);  
                 p2.setBorder(BorderFactory.createEmptyBorder(4, 0, 0, 0));  
                 p2.add(new JLabel(Res.gfxMuteTitle));  
                 p2.add(btnMute);  
                 p2.add(new JLabel(Res.gfxSoloTitle));  
                 p2.add(btnSolo);  
                   
                 p.add(p2);  
                   
                 p.add(createVSeparator());  
                   
                 p2 = new JPanel();  
                 p2.setOpaque(false);  
                 p2.setLayout(new BoxLayout(p2, BoxLayout.Y_AXIS));  
                 p2.setAlignmentY(JPanel.TOP_ALIGNMENT);  
                 p2.setBorder(BorderFactory.createEmptyBorder(4, 0, 0, 0));  
                 JLabel l = new JLabel(Res.gfxVolumeTitle);  
                 l.setAlignmentX(JPanel.CENTER_ALIGNMENT);  
                 l.setBorder(BorderFactory.createEmptyBorder(0, 0, 2, 0));  
                 p2.add(l);  
                 dialVolume.setDialPixmap(Res.gfxVolumeDial, 30, 330);  
                 dialVolume.setAlignmentX(JPanel.CENTER_ALIGNMENT);  
                 p2.add(dialVolume);  
                 p.add(p2);  
                   
                 p.add(createVSeparator());  
                   
                 p2 = new JPanel();  
                 p2.setOpaque(false);  
                 p2.setLayout(new BoxLayout(p2, BoxLayout.Y_AXIS));  
                 p2.setAlignmentY(JPanel.TOP_ALIGNMENT);  
                 p2.setBorder(BorderFactory.createEmptyBorder(27, 0, 0, 0));  
                 l = new JLabel(Res.gfxOptionsTitle);  
                 l.setAlignmentX(JPanel.CENTER_ALIGNMENT);  
                 l.setBorder(BorderFactory.createEmptyBorder(0, 0, 2, 0));  
                 p2.add(l);  
                   
                 p2.add(Box.createRigidArea(new Dimension(0, 3)));  
                   
                 btnOptions.setAlignmentX(JPanel.CENTER_ALIGNMENT);  
                 p2.add(btnOptions);  
                 p.add(p2);  
                   
                   
                 p.setPreferredSize(new Dimension(420, 60));  
                 p.setMinimumSize(p.getPreferredSize());  
                 p.setMaximumSize(p.getPreferredSize());  
                 //p.setBorder(BorderFactory.createEmptyBorder(1, 0, 1, 0));  
   
                 p.setAlignmentX(JPanel.CENTER_ALIGNMENT);  
135                  optionsPane.setAlignmentX(JPanel.CENTER_ALIGNMENT);                  optionsPane.setAlignmentX(JPanel.CENTER_ALIGNMENT);
136                                    
137                  mainPane = new JXCollapsiblePane();                  mainPane = new JXCollapsiblePane();
138                    viewTracker = new ViewTracker();
139                    
140                  mainPane.getContentPane().setLayout (                  mainPane.getContentPane().setLayout (
141                          new BoxLayout(mainPane.getContentPane(), BoxLayout.Y_AXIS)                          new BoxLayout(mainPane.getContentPane(), BoxLayout.Y_AXIS)
142                  );                  );
143                                    
144                  mainPane.add(p);                  int viewIdx = preferences().getIntProperty(DEFAULT_CHANNEL_VIEW);
145                  mainPane.add(optionsPane);                  if(viewIdx == 0) {
146                            contextMenu.rbmiSmallView.doClick(0);
147                    } else if(viewIdx == 1) {
148                            contextMenu.rbmiNormalView.doClick(0);
149                    } else {
150                            contextMenu.rbmiNormalView.doClick(0);
151                    }
152                                    
153                  setOpaque(false);                  setOpaque(false);
154                                    
# Line 257  public class Channel extends org.jsample Line 164  public class Channel extends org.jsample
164                                  public void                                  public void
165                                  propertyChange(PropertyChangeEvent e) {                                  propertyChange(PropertyChangeEvent e) {
166                                          if(e.getNewValue() == "expanded") {                                          if(e.getNewValue() == "expanded") {
167                                                    // TODO: this should be done regardles the listener != null?
168                                                  mainPane.removePropertyChangeListener(s, this);                                                  mainPane.removePropertyChangeListener(s, this);
169                                                    ///////
170                                                  listener.actionPerformed(null);                                                  listener.actionPerformed(null);
171                                                    ensureChannelIsVisible();
172                                            } else if(e.getNewValue() == "expanding/collapsing") {
173                                                    ensureChannelIsVisible();
174                                          }                                          }
175                                  }                                  }
176                          });                          });
# Line 269  public class Channel extends org.jsample Line 181  public class Channel extends org.jsample
181                  mainPane.setAnimated(preferences().getBoolProperty(ANIMATED));                  mainPane.setAnimated(preferences().getBoolProperty(ANIMATED));
182                  mainPane.setCollapsed(false);                  mainPane.setCollapsed(false);
183                                    
184                  preferences().addPropertyChangeListener(ANIMATED, new PropertyChangeListener() {                  preferences().addPropertyChangeListener(ANIMATED, animatedPorpetyListener);
                         public void  
                         propertyChange(PropertyChangeEvent e) {  
                                 mainPane.setAnimated(preferences().getBoolProperty(ANIMATED));  
                         }  
                 });  
185                                    
186                  if(listener != null) {                  if(listener != null) {
187                          javax.swing.SwingUtilities.invokeLater(new Runnable() {                          javax.swing.SwingUtilities.invokeLater(new Runnable() {
# Line 282  public class Channel extends org.jsample Line 189  public class Channel extends org.jsample
189                                  run() { listener.actionPerformed(null); }                                  run() { listener.actionPerformed(null); }
190                          });                          });
191                  }                  }
192                    
193                    CC.getSamplerModel().addSamplerChannelListListener(getHandler());
194          }          }
195                    
196          private JPanel          private void
197          createVSeparator() {          ensureChannelIsVisible() {
198                  PixmapPane p = new PixmapPane(Res.gfxVLine);                  Container p = getParent();
199                  p.setAlignmentY(JPanel.TOP_ALIGNMENT);                  JScrollPane sp = null;
200                  p.setPreferredSize(new Dimension(2, 60));                  while(p != null) {
201                  p.setMinimumSize(p.getPreferredSize());                          if(p instanceof JScrollPane) {
202                  p.setMaximumSize(p.getPreferredSize());                                  sp = (JScrollPane)p;
203                  return p;                                  break;
204                            }
205                            p = p.getParent();
206                    }
207                    if(sp == null) return;
208                    int h = sp.getViewport().getView().getHeight();
209                    sp.getViewport().scrollRectToVisible(new Rectangle(0, h - 2, 1, 1));
210          }          }
211                    
212          /**          /**
# Line 319  public class Channel extends org.jsample Line 234  public class Channel extends org.jsample
234          /** Shows the channel properties. */          /** Shows the channel properties. */
235          public void          public void
236          expandChannel(boolean animated) {          expandChannel(boolean animated) {
                 if(btnOptions.isSelected()) return;  
                   
237                  boolean b = optionsPane.isAnimated();                  boolean b = optionsPane.isAnimated();
238                  optionsPane.setAnimated(animated);                  optionsPane.setAnimated(animated);
239                  btnOptions.doClick();                  viewTracker.getCurrentView().expandChannel();
240                  optionsPane.setAnimated(b);                  optionsPane.setAnimated(b);
241          }          }
242                    
           
         /** Invoked when the user changes the volume */  
         private void  
         setVolume() {  
                 screen.updateVolumeInfo(dialVolume.getValue());  
                   
                 if(dialVolume.getValueIsAdjusting()) return;  
                   
                 int vol = (int)(getChannelInfo().getVolume() * 100);  
                   
                 if(vol == dialVolume.getValue()) return;  
                   
                   
                 /*  
                  * If the model's volume is not equal to the dial knob  
                  * value we assume that the change is due to user input.  
                  * So we must update the volume at the backend too.  
                  */  
                 float volume = dialVolume.getValue();  
                 volume /= 100;  
                 getModel().setBackendVolume(volume);  
         }  
           
243          /**          /**
244           * Updates the channel settings. This method is invoked when changes to the           * Updates the channel settings. This method is invoked when changes to the
245           * channel were made.           * channel were made.
246           */           */
247          private void          private void
248          updateChannelInfo() {          updateChannelInfo() {
249                  SamplerChannel sc = getChannelInfo();                  viewTracker.getCurrentView().updateChannelInfo();
250                    viewTracker.getCurrentView().getChannelOptionsView().updateChannelInfo();
251            }
252            
253            public void
254            loadInstrument() {
255                    JSInstrumentChooser dlg = FantasiaUtils.createInstrumentChooser(CC.getMainFrame());
256                    dlg.setVisible(true);
257                                    
258                  screen.updateScreenInfo(sc);                  if(!dlg.isCancelled()) {
259                  updateMuteIcon(sc);                          SamplerChannelModel m = getModel();
260                            m.loadBackendInstrument(dlg.getInstrumentFile(), dlg.getInstrumentIndex());
261                    }
262            }
263            
264            public void
265            fallbackToOriginalView() {
266                    viewTracker.fallbackToOriginalView();
267            }
268            
269            public boolean
270            isUsingOriginalView() {
271                    return viewTracker.isUsingOriginalView();
272            }
273            
274            protected void
275            onDestroy() {
276                    CC.getSamplerModel().removeSamplerChannelListListener(getHandler());
277                    preferences().removePropertyChangeListener(ANIMATED, animatedPorpetyListener);
278                                    
279                  if(sc.isSoloChannel()) btnSolo.setIcon(Res.gfxSoloOn);                  viewTracker.onDestroy();
280                  else btnSolo.setIcon(Res.gfxSoloOff);          }
281                                    
282                  dialVolume.setValue((int)(sc.getVolume() * 100));          public void
283            remove() {
284                    if(!mainPane.isAnimated()) {
285                            CC.getSamplerModel().removeBackendChannel(getChannelId());
286                            return;
287                    }
288                                    
289                  boolean b = sc.getEngine() != null;                  String s = JXCollapsiblePane.ANIMATION_STATE_KEY;
290                  dialVolume.setEnabled(b);                  mainPane.addPropertyChangeListener(s, getHandler());
291                  btnSolo.setEnabled(b);                  mainPane.setCollapsed(true);
                 btnMute.setEnabled(b);  
292          }          }
293                    
294          /**          public void
295           * Updates the mute button with the proper icon regarding to information obtained          showOptionsPane(boolean show) { optionsPane.showOptionsPane(show); }
          * from <code>channel</code>.  
          * @param channel A <code>SamplerChannel</code> instance containing the new settings  
          * for this channel.  
          */  
         private void  
         updateMuteIcon(SamplerChannel channel) {  
                 if(channel.isMutedBySolo()) btnMute.setIcon(Res.gfxMutedBySolo);  
                 else if(channel.isMuted()) btnMute.setIcon(Res.gfxMuteOn);  
                 else btnMute.setIcon(Res.gfxMuteOff);  
         }  
296                    
297          private class EnhancedDial extends Dial {          public void
298                  EnhancedDial() {          showFxSendsDialog() {
299                          super(0, 100);                  if(fxSendsDlg != null && fxSendsDlg.isVisible()) {
300                                                    fxSendsDlg.toFront();
301                          setMouseHandlerMode(MouseHandlerMode.LEFT_TO_RIGHT_AND_DOWN_TO_UP);                          return;
                           
                         addMouseListener(new MouseAdapter() {  
                                 public void  
                                 mouseClicked(MouseEvent e) {  
                                         if(e.getButton() == e.BUTTON3) {  
                                                 setValue(getMaximum() / 2);  
                                                 return;  
                                         }  
                                           
                                         if(e.getButton() != e.BUTTON1) return;  
                                           
                                         if(e.getClickCount() < 2) return;  
                                         setValue(getValueByPoint(e.getPoint()));  
                                 }  
                         });  
                           
                         addChangeListener(new ChangeListener() {  
                                 public void  
                                 stateChanged(ChangeEvent e) { setVolume(); }  
                         });  
302                  }                  }
303                    FxSendsPane p = new FxSendsPane(getModel());
304                    int id = getModel().getChannelId();
305                    fxSendsDlg = new InformationDialog(CC.getMainFrame(), p);
306                    fxSendsDlg.setTitle(i18n.getLabel("FxSendsDlg.title", id));
307                    fxSendsDlg.setModal(false);
308                    fxSendsDlg.showCloseButton(false);
309                    fxSendsDlg.setVisible(true);
310          }          }
311                    
312          private final EventHandler eventHandler = new EventHandler();          private final EventHandler eventHandler = new EventHandler();
# Line 418  public class Channel extends org.jsample Line 314  public class Channel extends org.jsample
314          private EventHandler          private EventHandler
315          getHandler() { return eventHandler; }          getHandler() { return eventHandler; }
316                    
317          private class EventHandler implements SamplerChannelListener {          private class EventHandler implements SamplerChannelListener,
318                                            SamplerChannelListListener, PropertyChangeListener {
319                  /**                  /**
320                   * Invoked when changes are made to a sampler channel.                   * Invoked when changes are made to a sampler channel.
321                   * @param e A <code>SamplerChannelEvent</code> instance                   * @param e A <code>SamplerChannelEvent</code> instance
# Line 434  public class Channel extends org.jsample Line 331  public class Channel extends org.jsample
331                   */                   */
332                  public void                  public void
333                  streamCountChanged(SamplerChannelEvent e) {                  streamCountChanged(SamplerChannelEvent e) {
334                          screen.updateStreamCount(getModel().getStreamCount());                          viewTracker.getCurrentView().updateStreamCount(getModel().getStreamCount());
335                  }                  }
336                    
337                  /**                  /**
# Line 444  public class Channel extends org.jsample Line 341  public class Channel extends org.jsample
341                   */                   */
342                  public void                  public void
343                  voiceCountChanged(SamplerChannelEvent e) {                  voiceCountChanged(SamplerChannelEvent e) {
344                          screen.updateVoiceCount(getModel().getVoiceCount());                          viewTracker.getCurrentView().updateVoiceCount(getModel().getVoiceCount());
                 }  
         }  
           
           
         private class PowerButton extends PixmapToggleButton  
                         implements ActionListener, PropertyChangeListener {  
                   
                 PowerButton() {  
                         super(Res.gfxPowerOff, Res.gfxPowerOn);  
                   
                         setSelected(true);  
                         addActionListener(this);  
345                  }                  }
346                                    
347                    /**
348                     * Invoked when a new sampler channel is created.
349                     * @param e A <code>SamplerChannelListEvent</code>
350                     * instance providing the event information.
351                     */
352                  public void                  public void
353                  actionPerformed(ActionEvent e) {                  channelAdded(SamplerChannelListEvent e) { }
354                          if(!mainPane.isAnimated()) {          
355                                  CC.getSamplerModel().removeBackendChannel(getChannelId());                  /**
356                                  return;                   * Invoked when a sampler channel is removed.
357                     * @param e A <code>SamplerChannelListEvent</code>
358                     * instance providing the event information.
359                     */
360                    public void
361                    channelRemoved(SamplerChannelListEvent e) {
362                            // Some cleanup when the channel is removed.
363                            if(e.getChannelModel().getChannelId() == getChannelId()) {
364                                    onDestroy();
365                          }                          }
                           
                         String s = JXCollapsiblePane.ANIMATION_STATE_KEY;  
                         mainPane.addPropertyChangeListener(s, this);  
                         mainPane.setCollapsed(true);  
366                  }                  }
367                                    
368                  public void                  public void
# Line 477  public class Channel extends org.jsample Line 371  public class Channel extends org.jsample
371                                  CC.getSamplerModel().removeBackendChannel(getChannelId());                                  CC.getSamplerModel().removeBackendChannel(getChannelId());
372                          }                          }
373                  }                  }
                   
                 public boolean  
                 contains(int x, int y) { return (x - 11)*(x - 11) + (y - 11)*(y - 11) < 71; }  
374          }          }
375                    
376          private class MuteButton extends PixmapButton implements ActionListener {          private static boolean viewTrackerMousePressed = false;
377                  MuteButton() {          
378                          super(Res.gfxMuteOff);          class ViewTracker extends MouseAdapter implements PropertyChangeListener {
379                          //setDisabledIcon(Res.gfxMuteSoloDisabled);                  private ChannelView originalView;
380                          setDisabledIcon (                  private ChannelView mouseOverView;
381                                  SubstanceImageCreator.makeTransparent(this, Res.gfxMuteOff, 0.4)                  private ChannelView currentView;
                         );  
                         addActionListener(this);  
                 }  
382                                    
                 public void  
                 actionPerformed(ActionEvent e) {  
                         SamplerChannel sc = getChannelInfo();  
                         boolean b = true;  
383                                    
384                          /*                  private boolean mouseOver = false;
385                           * Changing the mute button icon now instead of                  
386                           * leaving the work to the notification mechanism of the LinuxSampler.                  private final ActionListener guiListener;
387                           */                  
388                          if(sc.isMuted() && !sc.isMutedBySolo()) {                  ViewTracker() {
389                                  b = false;                          guiListener = new ActionListener() {
390                                  boolean hasSolo = CC.getSamplerModel().hasSoloChannel();                                  public void
391                                                            actionPerformed(ActionEvent e) {
392                                  if(sc.isSoloChannel() || !hasSolo) setIcon(Res.gfxMuteOff);                                          if(viewTrackerMousePressed) return;
393                                  else setIcon(Res.gfxMutedBySolo);                                          
394                          } else setIcon(Res.gfxMuteOn);                                          if(mainPane.getMousePosition(true) != null) {
395                                                    mouseEntered(null);
396                                            } else {
397                                                    mouseExited(null);
398                                            }
399                                    }
400                            };
401                            
402                            updateMouseOverViewType();
403                                                    
404                          Channel.this.getModel().setBackendMute(b);                          String s = DIFFERENT_CHANNEL_VIEW_ON_MOUSE_OVER;
405                            preferences().addPropertyChangeListener(s, this);
406                            
407                            s = CHANNEL_VIEW_ON_MOUSE_OVER;
408                            preferences().addPropertyChangeListener(s, this);
409                  }                  }
410                                    
411                  public boolean                  public boolean
412                  contains(int x, int y) { return (x > 5 && x < 23) && (y > 5 && y < 16); }                  isUsingOriginalView() {
413          }                          return currentView == originalView;
           
         private class SoloButton extends PixmapButton implements ActionListener {  
                 SoloButton() {  
                         super(Res.gfxSoloOff);  
                         //setDisabledIcon(Res.gfxMuteSoloDisabled);  
                         setDisabledIcon (  
                                 SubstanceImageCreator.makeTransparent(this, Res.gfxSoloOff, 0.4)  
                         );  
                         addActionListener(this);  
414                  }                  }
415                                    
416                  public void                  private void
417                  actionPerformed(ActionEvent e) {                  installListeners() {
418                          SamplerChannel sc = getChannelInfo();                          ((MainFrame)CC.getMainFrame()).getGuiTimer().addActionListener(guiListener);
419                          boolean b = !sc.isSoloChannel();                  }
420                                    
421                          /*                  private void
422                           * Changing the solo button icon (and related) now instead of                  uninstallListeners() {
423                           * leaving the work to the notification mechanism of the LinuxSampler.                          ((MainFrame)CC.getMainFrame()).getGuiTimer().removeActionListener(guiListener);
424                           */                  }
                         if(b) {  
                                 setIcon(Res.gfxSoloOn);  
                                 if(sc.isMutedBySolo()) btnMute.setIcon(Res.gfxMuteOff);  
                         } else {  
                                 setIcon(Res.gfxSoloOff);  
                                 if(!sc.isMuted() && CC.getSamplerModel().getSoloChannelCount() > 1)  
                                         btnMute.setIcon(Res.gfxMutedBySolo);  
                         }  
425                                    
426                          Channel.this.getModel().setBackendSolo(b);                  private void
427                    updateMouseOverViewType() {
428                            if(mouseOverView != null) {
429                                    mouseOverView.removeEnhancedMouseListener(this);
430                            }
431                            
432                            boolean b;
433                            b = preferences().getBoolProperty(DIFFERENT_CHANNEL_VIEW_ON_MOUSE_OVER);
434                            if(!b) {
435                                    mouseOverView = null;
436                                    uninstallListeners();
437                                    return;
438                            }
439                            
440                            Channel channel = Channel.this;
441                            int i = preferences().getIntProperty(CHANNEL_VIEW_ON_MOUSE_OVER);
442                            
443                            switch(i) {
444                                    case 0: mouseOverView = new SmallChannelView(channel); break;
445                                    case 1: mouseOverView = new NormalChannelView(channel); break;
446                                    default:mouseOverView = null;
447                            }
448                            
449                            if(mouseOverView != null) {
450                                    installListeners();
451                                    mouseOverView.addEnhancedMouseListener(this);
452                            }
453                  }                  }
454                                    
455                  public boolean                  public ChannelView
456                  contains(int x, int y) { return (x > 5 && x < 23) && (y > 5 && y < 16); }                  getCurrentView() { return currentView; }
457          }                  
458                            public void
459          private class OptionsButton extends PixmapToggleButton implements ActionListener {                  setView(ChannelView view) {
460                  OptionsButton() {                          setView(view, true);
                         super(Res.gfxOptionsOff, Res.gfxOptionsOn);  
                         setRolloverIcon(Res.gfxOptionsOffRO);  
                         this.setRolloverSelectedIcon(Res.gfxOptionsOnRO);  
                         addActionListener(this);  
461                  }                  }
462                                    
463                  public void                  public void
464                  actionPerformed(ActionEvent e) {                  setView(ChannelView view, boolean manual) {
465                          showOptionsPane(isSelected());                          boolean selected = false;
466                            if(currentView != null) selected = currentView.isOptionsButtonSelected();
467                                                    
468                          String s;                          if(manual) {
469                          if(isSelected()) s = i18n.getButtonLabel("OptionsButton.ttHideOptions");                                  if(originalView != null) {
470                          else s = i18n.getButtonLabel("OptionsButton.ttShowOptions");                                          originalView.removeEnhancedMouseListener(this);
471                                    }
472                                    
473                                    if(originalView != currentView) destroyOriginalView();
474                                    if(currentView != null && currentView.getType() == view.getType()) {
475                                            originalView = currentView;
476                                            originalView.addEnhancedMouseListener(this);
477                                            destroyView(view);
478                                            return;
479                                    }
480                                    
481                                    removeCurrentView();
482                                    
483                                    originalView = view;
484                                    originalView.addEnhancedMouseListener(this);
485                                    currentView = view;
486                            } else {
487                                    if(view.getType() == getCurrentView().getType()) {
488                                            destroyView(view);
489                                            return;
490                                    }
491                                    
492                                    removeCurrentView();
493                                    currentView = view;
494                            }
495                                                    
496                          setToolTipText(s);                          currentView.setOptionsButtonSelected(selected);
497                            
498                            updateView();
499                  }                  }
500                                    
501                  private void                  private void
502                  showOptionsPane(boolean show) {                  updateView() {
503                          optionsPane.setCollapsed(!show);                          JComponent c = getCurrentView().getChannelOptionsView().getComponent();
504                  }                          optionsPane.setContentPane(c);
505                            
506                            updateChannelInfo();
507                                    
508                  public boolean                          mainPane.add(getCurrentView().getComponent());
509                  contains(int x, int y) { return super.contains(x, y) & y < 13; }                          mainPane.add(optionsPane);
510          }                          mainPane.validate();
511  }                          mainPane.revalidate();
512                            mainPane.repaint();
513  class ChannelPane extends PixmapPane {                  }
         ChannelPane() {  
                 super(Res.gfxChannel);  
                 setPixmapInsets(new Insets(3, 3, 3, 3));  
         }  
 }  
   
 class ChannelScreen extends PixmapPane {  
         private final Channel channel;  
         private JButton btnInstr = new ScreenButton(i18n.getButtonLabel("ChannelScreen.btnInstr"));  
           
         private final JButton btnFxSends =  
                 new ScreenButton(i18n.getButtonLabel("ChannelScreen.btnFxSends"));  
           
         private final JButton btnEngine  
                 = new ScreenButton(i18n.getButtonLabel("ChannelScreen.btnEngine"));  
           
         private final JPopupMenu menuEngines = new JPopupMenu();  
           
         private final JLabel lVolume = new Label();  
         private final JLabel lStreams = new Label("--");  
         private final JLabel lVoices = new Label("--");  
           
         private InformationDialog fxSendsDlg = null;  
           
         private Dimension dimVolume;  
           
         class Label extends JLabel {  
                 Label() { this(""); }  
514                                    
515                  Label(String s) {                  public void
516                          super(s);                  fallbackToOriginalView() {
517                          setFont(Res.fontScreen);                          if(currentView == originalView) return;
518                          setForeground(new java.awt.Color(0xFFA300));                          
519                            boolean selected = false;
520                            if(currentView != null) selected = currentView.isOptionsButtonSelected();
521                            
522                            removeCurrentView();
523                            currentView = originalView;
524                            currentView.setOptionsButtonSelected(selected);
525                            
526                            updateView();
527                  }                  }
         }  
           
         ChannelScreen(final Channel channel) {  
                 super(Res.gfxChannelScreen);  
                 setPixmapInsets(new Insets(6, 6, 6, 6));  
                 setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));  
528                                    
529                  this.channel = channel;                  private void
530                    removeCurrentView() { removeView(currentView); }
531                                    
532                  setOpaque(false);                  private void
533                    destroyCurrentView() { destroyView(currentView); }
534                                    
535                  setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));                  private void
536                    removeOriginalView() { removeView(originalView); }
537                                    
538                  btnInstr.setAlignmentX(CENTER_ALIGNMENT);                  private void
539                  btnInstr.setRolloverEnabled(false);                  destroyOriginalView() { destroyView(originalView); }
                 btnInstr.setBorder(BorderFactory.createEmptyBorder(3, 0, 0, 0));  
                   
                 add(btnInstr);  
                   
                 JPanel p = new JPanel();  
                 p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));  
                 p.setAlignmentX(CENTER_ALIGNMENT);  
                 p.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0));  
540                                    
541                  btnFxSends.setToolTipText(i18n.getButtonLabel("ChannelScreen.btnFxSends.tt"));                  private void
542                  btnFxSends.addActionListener(new ActionListener() {                  removeView(ChannelView view) {
543                          public void                          if(view == null) return;
544                          actionPerformed(ActionEvent e) {                          
545                                  if(fxSendsDlg != null && fxSendsDlg.isVisible()) {                          mainPane.remove(view.getComponent());
546                                          fxSendsDlg.toFront();                          mainPane.remove(optionsPane);
547                                          return;                                  
548                                  }                          destroyView(view);
549                                  FxSendsPane p = new FxSendsPane(channel.getModel());                  }
                                 int id = channel.getModel().getChannelId();  
                                 fxSendsDlg = new InformationDialog(CC.getMainFrame(), p);  
                                 fxSendsDlg.setTitle(i18n.getLabel("FxSendsDlg.title", id));  
                                 fxSendsDlg.setModal(false);  
                                 fxSendsDlg.showCloseButton(false);  
                                 fxSendsDlg.setVisible(true);  
                         }  
                 });  
550                                    
551                  p.add(btnFxSends);                  private void
552                    destroyView(ChannelView view) {
553                            if(view == null) return;
554                            
555                            view.uninstallView();
556                            view.getChannelOptionsView().uninstallView();
557                            
558                            view = null;
559                    }
560                                    
561                  p.add(Box.createRigidArea(new Dimension(6, 0)));                  private void
562                    mouseEntered() {
563                            if(mouseOverView == null) return;
564                            if(getCurrentView().getType() == mouseOverView.getType()) return;
565                            
566                            JSChannel[] channels = CC.getMainFrame().getChannelsPane(0).getChannels();
567                            for(JSChannel c : channels) {
568                                    if(c == Channel.this) continue;
569                                    
570                                    Channel chn = (Channel)c;
571                                    if(!(chn).isUsingOriginalView()) chn.fallbackToOriginalView();
572                            }
573                            
574                            setView(mouseOverView, false);
575                    }
576                                    
577                  btnEngine.setIcon(Res.iconEngine12);                  private void
578                  p.add(btnEngine);                  mouseExited() {
579                  //p.add(new Label("|"));                          if(mouseOverView == null) return;
580                            if(getCurrentView().getType() == originalView.getType()) return;
581                            
582                            fallbackToOriginalView();
583                    }
584                                    
585                  //p.add(Box.createRigidArea(new Dimension(6, 0)));                  public void
586                    mouseEntered(MouseEvent e) {
587                            if(viewTrackerMousePressed) return;
588                            
589                            if(mouseOver) return;
590                            mouseOver = true;
591                            mouseEntered();
592                    }
593                                    
594                  //p.add(btnReset);                  public void
595                    mouseExited(MouseEvent e) {
596                            if(viewTrackerMousePressed) return;
597                            
598                            if(mainPane.getMousePosition(true) != null) return;
599                            if(!mouseOver) return;
600                            mouseOver = false;
601                            mouseExited();
602                    }
603                                    
604                  p.add(Box.createGlue());                  public void
605                    mousePressed(MouseEvent e) {
606                            viewTrackerMousePressed = true;
607                    }
608                                    
609                  p.add(lStreams);                  public void
610                  p.add(new Label("/"));                  mouseReleased(MouseEvent e) {
611                  p.add(lVoices);                          viewTrackerMousePressed = false;
612                    }
613                                    
614                  p.add(Box.createRigidArea(new Dimension(12, 0)));                  public void
615                    onDestroy() {
616                            destroyCurrentView();
617                            destroyOriginalView();
618                            
619                            uninstallListeners();
620                            
621                            if(currentView != null) {
622                                    currentView.removeEnhancedMouseListener(this);
623                            }
624                            
625                            if(mouseOverView != null) {
626                                    mouseOverView.removeEnhancedMouseListener(this);
627                            }
628                            
629                            String s = DIFFERENT_CHANNEL_VIEW_ON_MOUSE_OVER;
630                            preferences().removePropertyChangeListener(s, this);
631                            
632                            s = CHANNEL_VIEW_ON_MOUSE_OVER;
633                            preferences().removePropertyChangeListener(s, this);
634                    }
635                                    
636                  lVolume.setIcon(Res.iconVolume14);                  public void
637                  lVolume.setAlignmentX(RIGHT_ALIGNMENT);                  propertyChange(PropertyChangeEvent e) {
638                  updateVolumeInfo(100);                          updateMouseOverViewType();
639                  dimVolume = lVolume.getPreferredSize();                  }
640                  p.add(lVolume);          }
641                  p.setPreferredSize(new Dimension(250, p.getPreferredSize().height));          
642                  p.setMinimumSize(p.getPreferredSize());          class EditInstrumentAction extends AbstractAction implements SamplerChannelListener {
643                  p.setMaximumSize(p.getPreferredSize());                  EditInstrumentAction() {
644                            super(i18n.getMenuLabel("channels.editInstrument"));
645                            channelChanged(null);
646                            getModel().addSamplerChannelListener(this);
647                    }
648                                    
649                  //btnInstr.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));                  public void
650                  p.setOpaque(false);                  actionPerformed(ActionEvent e) {
651                  add(p);                          CC.getSamplerModel().editBackendInstrument(getChannelId());
652                    }
653                                    
654                    public void
655                    channelChanged(SamplerChannelEvent e) {
656                            boolean b = getChannelInfo().getInstrumentStatus() == 100;
657                            setEnabled(b);
658                    }
659                                    
660                  setPreferredSize(new Dimension(270, 48));                  public void
661                  setMinimumSize(getPreferredSize());                  streamCountChanged(SamplerChannelEvent e) { }
                 setMaximumSize(getPreferredSize());  
662                                    
663                  createEngineMenu();                  public void
664                  installListeners();                  voiceCountChanged(SamplerChannelEvent e) { }
665          }          }
666                    
667          private void          class FxSendsAction extends AbstractAction {
668          createEngineMenu() {                  FxSendsAction() {
669                  for(final SamplerEngine engine : CC.getSamplerModel().getEngines()) {                          super(i18n.getMenuLabel("channels.fxSends"));
                         JMenuItem mi = new JMenuItem(engine.getDescription());  
                           
                         mi.addActionListener(new ActionListener() {  
                                 public void  
                                 actionPerformed(ActionEvent e) {  
                                         channel.getModel().setBackendEngineType(engine.getName());  
                                 }  
                         });  
                           
                         menuEngines.add(mi);  
670                  }                  }
         }  
           
         private void  
         installListeners() {  
                 btnInstr.addActionListener(new ActionListener() {  
                         public void  
                         actionPerformed(ActionEvent e) { loadInstrument(); }  
                 });  
671                                    
672                  btnEngine.addActionListener(new ActionListener() {                  public void
673                          public void                  actionPerformed(ActionEvent e) {
674                          actionPerformed(ActionEvent e) {                          showFxSendsDialog();
675                                  int y = btnEngine.getHeight() + 1;                  }
                                 menuEngines.show(btnEngine, 0, y);  
                         }  
                 });  
676          }          }
677                    
678          private void          class ChannelRoutingAction extends AbstractAction implements SamplerChannelListener {
679          loadInstrument() {                  ChannelRoutingAction() {
680                  JSInstrumentChooser dlg = new JSInstrumentChooser(CC.getMainFrame());                          super(i18n.getMenuLabel("channels.channelRouting"));
681                  dlg.setVisible(true);                          channelChanged(null);
682                            getModel().addSamplerChannelListener(this);
683                    }
684                                    
685                  if(!dlg.isCancelled()) {                  public void
686                          SamplerChannelModel m = channel.getModel();                  actionPerformed(ActionEvent e) {
687                          m.loadBackendInstrument(dlg.getInstrumentFile(), dlg.getInstrumentIndex());                          SamplerChannel c = getChannelInfo();
688                            new JSChannelOutputRoutingDlg(CC.getMainFrame(), c).setVisible(true);
689                  }                  }
690                    
691                    public void
692                    channelChanged(SamplerChannelEvent e) {
693                            boolean b = getChannelInfo().getAudioOutputDevice() != -1;
694                            setEnabled(b);
695                    }
696                    
697                    public void
698                    streamCountChanged(SamplerChannelEvent e) { }
699                    
700                    public void
701                    voiceCountChanged(SamplerChannelEvent e) { }
702          }          }
703                    
704          protected void          class SetSmallViewAction extends AbstractAction {
705          updateScreenInfo(SamplerChannel sc) {                  SetSmallViewAction() {
706                  int status = sc.getInstrumentStatus();                          super(i18n.getMenuLabel("channels.smallView"));
707                  if(status >= 0 && status < 100) {                  }
708                          btnInstr.setText(i18n.getLabel("ChannelScreen.loadingInstrument", status));                  
709                  } else if(status == -1) {                  public void
710                          btnInstr.setText(i18n.getButtonLabel("ChannelScreen.btnInstr"));                  actionPerformed(ActionEvent e) {
711                  } else if(status < -1) {                          viewTracker.setView(new SmallChannelView(Channel.this));
                          btnInstr.setText(i18n.getLabel("ChannelScreen.errorLoadingInstrument"));  
                 } else {  
                         if(sc.getInstrumentName() != null) btnInstr.setText(sc.getInstrumentName());  
                         else btnInstr.setText(i18n.getButtonLabel("ChannelScreen.btnInstr"));  
712                  }                  }
713            }
714                    
715                  if(sc.getEngine() != null) {          class SetNormalViewAction extends AbstractAction {
716                          String s = sc.getEngine().getDescription();                  SetNormalViewAction() {
717                          if(!s.equals(btnEngine.getText())) btnEngine.setText(s);                          super(i18n.getMenuLabel("channels.normalView"));
718                  }                  }
719                                    
720                    public void
721                    actionPerformed(ActionEvent e) {
722                            viewTracker.setView(new NormalChannelView(Channel.this));
723                    }
724          }          }
725                    
726          protected void          public ContextMenu
727          updateVolumeInfo(int volume) {          getContextMenu() { return contextMenu; }
728                  lVolume.setText(i18n.getLabel("ChannelScreen.volume", volume));          
729                  lVolume.setMinimumSize(dimVolume);          class ContextMenu extends MouseAdapter {
730                  lVolume.setPreferredSize(dimVolume);                  private final JPopupMenu menu = new JPopupMenu();
731                                    
732          }                  protected final JRadioButtonMenuItem rbmiSmallView;
733                    protected final JRadioButtonMenuItem rbmiNormalView;
734                    
735                    ContextMenu() {
736                            menu.add(new JMenuItem(new EditInstrumentAction()));
737                            menu.addSeparator();
738                            
739                            rbmiSmallView = new JRadioButtonMenuItem(new SetSmallViewAction());
740                            rbmiNormalView = new JRadioButtonMenuItem(new SetNormalViewAction());
741                            
742                            ButtonGroup group = new ButtonGroup();
743                            group.add(rbmiSmallView);
744                            group.add(rbmiNormalView);
745                            
746                            menu.add(rbmiSmallView);
747                            menu.add(rbmiNormalView);
748                            
749                            menu.addSeparator();
750                            menu.add(new JMenuItem(new FxSendsAction()));
751                            menu.add(new JMenuItem(new ChannelRoutingAction()));
752                    }
753                    
754                    public void
755                    mousePressed(MouseEvent e) {
756                            if(e.isPopupTrigger()) show(e);
757                    }
758                    
759          /**                  public void
760           * Updates the number of active disk streams.                  mouseReleased(MouseEvent e) {
761           * @param count The new number of active disk streams.                          if(e.isPopupTrigger()) show(e);
762           */                  }
         protected void  
         updateStreamCount(int count) {  
                 Dimension d = lStreams.getPreferredSize();  
                 lStreams.setText(count == 0 ? "--" : String.valueOf(count));  
                 d = JuifeUtils.getUnionSize(d, lStreams.getPreferredSize());  
                 lStreams.setMinimumSize(d);  
                 lStreams.setPreferredSize(d);  
                 lStreams.setMaximumSize(d);  
         }  
763                    
764          /**                  void
765           * Updates the number of active voices.                  show(MouseEvent e) {
766           * @param count The new number of active voices.                          menu.show(e.getComponent(), e.getX(), e.getY());
767           */                  }
         protected void  
         updateVoiceCount(int count) {  
                 Dimension d = lVoices.getPreferredSize();  
                 lVoices.setText(count == 0 ? "--" : String.valueOf(count));  
                 d = JuifeUtils.getUnionSize(d, lVoices.getPreferredSize());  
                 lVoices.setMinimumSize(d);  
                 lVoices.setPreferredSize(d);  
                 lVoices.setMaximumSize(d);  
768          }          }
769                    
770          class FxSendsPane extends JSFxSendsPane {          class FxSendsPane extends JSFxSendsPane {
# Line 822  class ChannelScreen extends PixmapPane { Line 790  class ChannelScreen extends PixmapPane {
790                  }                  }
791          }          }
792                    
793          static class ScreenButton extends JButton {          public static class StreamVoiceCountPane extends JPanel {
794                  ScreenButton(String s) {                  private final Channel channel;
                         super(s);  
                         setContentAreaFilled(false);  
                         setFocusPainted(false);  
                         setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));  
                         setMargin(new Insets(0, 0, 0, 0));  
                           
                         putClientProperty (  
                                 SubstanceLookAndFeel.BUTTON_NO_MIN_SIZE_PROPERTY, Boolean.TRUE  
                         );  
                           
                         putClientProperty (  
                                 SubstanceLookAndFeel.BUTTON_PAINT_NEVER_PROPERTY, Boolean.TRUE  
                         );  
                           
                         putClientProperty(SubstanceLookAndFeel.FLAT_PROPERTY, Boolean.TRUE);  
                           
                         FadeConfigurationManager.getInstance().disallowFades(FadeKind.ROLLOVER, this);  
                           
                         setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));  
                         setFont(Res.fontScreen);  
                         setForeground(new java.awt.Color(0xFFA300));  
                 }  
         }  
 }  
   
 class ChannelOptions extends JXCollapsiblePane {  
         private final Channel channel;  
         private MidiDeviceModel midiDevice = null;  
           
         private final JComboBox cbMidiDevice = new FantasiaComboBox();  
         private final JComboBox cbMidiPort = new FantasiaComboBox();  
         private final JComboBox cbMidiChannel = new FantasiaComboBox();  
         private final JComboBox cbInstrumentMap = new FantasiaComboBox();  
         private final JComboBox cbAudioDevice = new FantasiaComboBox();  
           
         private final PixmapButton btnChannelRouting;  
           
         private boolean update = false;  
           
         private final SamplerListener samplerListener;  
         private final MapListListener mapListListener = new MapListListener();  
           
         private class NoMap {  
                 public String  
                 toString() { return "[None]"; }  
         }  
           
         private NoMap noMap = new NoMap();  
           
         private class DefaultMap {  
                 public String  
                 toString() { return "[Default]"; }  
         }  
           
         private DefaultMap defaultMap = new DefaultMap();  
           
         ChannelOptions(final Channel channel) {  
                 setAnimated(false);  
                 setCollapsed(true);  
                 setAnimated(preferences().getBoolProperty(ANIMATED));  
795                                    
796                  preferences().addPropertyChangeListener(ANIMATED, new PropertyChangeListener() {                  private final JLabel lStreams = createScreenLabel(" --");
797                          public void                  private final JLabel lSlash = createScreenLabel("/");
798                          propertyChange(PropertyChangeEvent e) {                  private final JLabel lVoices = createScreenLabel("-- ");
                                 setAnimated(preferences().getBoolProperty(ANIMATED));  
                         }  
                 });  
                   
                 PixmapPane bgp = new PixmapPane(Res.gfxChannelOptions);  
                 bgp.setPixmapInsets(new Insets(1, 1, 1, 1));  
                   
                 this.channel = channel;  
                   
                 bgp.setBorder(BorderFactory.createEmptyBorder(5, 4, 5, 4));  
                 bgp.setLayout(new BoxLayout(bgp, BoxLayout.X_AXIS));  
                   
                 bgp.setPreferredSize(new Dimension(420, 44));  
                 bgp.setMinimumSize(getPreferredSize());  
                 bgp.setMaximumSize(getPreferredSize());  
                   
                 JPanel p = new JPanel();  
                 p.setBorder(BorderFactory.createEmptyBorder(3, 4, 3, 4));  
                 p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));  
                 JLabel l = new JLabel(Res.gfxMidiInputTitle);  
                 l.setAlignmentX(LEFT_ALIGNMENT);  
                 p.add(l);  
                   
                 JPanel p2 = new JPanel();  
                 p2.setBorder(BorderFactory.createEmptyBorder(3, 0, 0, 0));  
                 p2.setLayout(new BoxLayout(p2, BoxLayout.X_AXIS));  
                   
                 Object o = cbMidiDevice.getRenderer();  
                 if(o instanceof JLabel) ((JLabel )o).setHorizontalAlignment(SwingConstants.CENTER);  
                   
                 cbMidiDevice.setPreferredSize(new Dimension(40, 18));  
                 cbMidiDevice.setMinimumSize(cbMidiDevice.getPreferredSize());  
                 cbMidiDevice.setMaximumSize(cbMidiDevice.getPreferredSize());  
                 p2.add(cbMidiDevice);  
                   
                 p2.add(Box.createRigidArea(new Dimension(3, 0)));  
                   
                 o = cbMidiPort.getRenderer();  
                 if(o instanceof JLabel) ((JLabel )o).setHorizontalAlignment(SwingConstants.CENTER);  
                   
                 cbMidiPort.setPreferredSize(new Dimension(62, 18));  
                 cbMidiPort.setMinimumSize(cbMidiPort.getPreferredSize());  
                 cbMidiPort.setMaximumSize(cbMidiPort.getPreferredSize());  
                 p2.add(cbMidiPort);  
                   
                 p2.add(Box.createRigidArea(new Dimension(3, 0)));  
                   
                 o = cbMidiChannel.getRenderer();  
                 if(o instanceof JLabel) ((JLabel )o).setHorizontalAlignment(SwingConstants.CENTER);  
                   
                 cbMidiChannel.addItem("All");  
                 for(int i = 1; i <= 16; i++) cbMidiChannel.addItem("Channel " + String.valueOf(i));  
                 cbMidiChannel.setPreferredSize(new Dimension(80, 18));  
                 cbMidiChannel.setMinimumSize(cbMidiChannel.getPreferredSize());  
                 cbMidiChannel.setMaximumSize(cbMidiChannel.getPreferredSize());  
                   
                 p2.add(cbMidiChannel);  
                 p2.setAlignmentX(LEFT_ALIGNMENT);  
                 p2.setOpaque(false);  
                 p.add(p2);  
                 p.setBackground(new java.awt.Color(0x818181));  
                   
                 bgp.add(p);  
                   
                 bgp.add(Box.createRigidArea(new Dimension(4, 0)));  
                   
                 p = new JPanel();  
                 p.setOpaque(true);  
                 p.setBorder(BorderFactory.createEmptyBorder(3, 4, 3, 4));  
                 p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));  
                 l = new JLabel(Res.gfxInstrumentMapTitle);  
                 l.setAlignmentX(LEFT_ALIGNMENT);  
                 l.setAlignmentX(LEFT_ALIGNMENT);  
                 p.add(l);  
                   
                 p.add(Box.createRigidArea(new Dimension(0, 3)));  
                   
                 //o = cbInstrumentMap.getRenderer();  
                 //if(o instanceof JLabel) ((JLabel )o).setHorizontalAlignment(SwingConstants.CENTER);  
                   
                 cbInstrumentMap.setPreferredSize(new Dimension(126, 18));  
                 cbInstrumentMap.setMinimumSize(cbInstrumentMap.getPreferredSize());  
                 cbInstrumentMap.setMaximumSize(cbInstrumentMap.getPreferredSize());  
                 cbInstrumentMap.setAlignmentX(LEFT_ALIGNMENT);  
                 p.add(cbInstrumentMap);  
                 p.setBackground(new java.awt.Color(0x818181));  
                 bgp.add(p);  
                   
                 bgp.add(Box.createRigidArea(new Dimension(4, 0)));  
                   
                 p = new JPanel();  
                 p.setOpaque(true);  
                 p.setBorder(BorderFactory.createEmptyBorder(3, 4, 3, 4));  
                 p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));  
                 l = new JLabel(Res.gfxAudioOutputTitle);  
                 l.setAlignmentX(LEFT_ALIGNMENT);  
                 p.add(l);  
                   
                 //p.add(Box.createRigidArea(new Dimension(0, 3)));  
                   
                 p2 = new JPanel();  
                 p2.setBorder(BorderFactory.createEmptyBorder(3, 0, 0, 0));  
                 p2.setLayout(new BoxLayout(p2, BoxLayout.X_AXIS));  
                 p2.setOpaque(false);  
                 p2.setAlignmentX(LEFT_ALIGNMENT);  
                   
                 o = cbAudioDevice.getRenderer();  
                 if(o instanceof JLabel) ((JLabel )o).setHorizontalAlignment(SwingConstants.RIGHT);  
                   
                 cbAudioDevice.setPreferredSize(new Dimension(40, 18));  
                 cbAudioDevice.setMinimumSize(cbAudioDevice.getPreferredSize());  
                 cbAudioDevice.setMaximumSize(cbAudioDevice.getPreferredSize());  
                   
                 p2.add(cbAudioDevice);  
                 p2.add(Box.createRigidArea(new Dimension(3, 0)));  
                 btnChannelRouting = new PixmapButton(Res.gfxBtnCr, Res.gfxBtnCrRO);  
                 btnChannelRouting.setPressedIcon(Res.gfxBtnCrRO);  
                 btnChannelRouting.setEnabled(false);  
                 btnChannelRouting.setToolTipText(i18n.getLabel("ChannelOptions.routing"));  
799                                    
800                  btnChannelRouting.addActionListener(new ActionListener() {                  public
801                          public void                  StreamVoiceCountPane(Channel channel) {
802                          actionPerformed(ActionEvent e) {                          this.channel = channel;
                                 SamplerChannel c = channel.getChannelInfo();  
                                 new JSChannelOutputRoutingDlg(CC.getMainFrame(), c).setVisible(true);  
803                                                    
804                          }                          setOpaque(false);
805                  });                          setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
806                                            lStreams.setFont(Res.fontScreenMono);
807                  p2.add(btnChannelRouting);                          lStreams.setHorizontalAlignment(JLabel.RIGHT);
808                                            lStreams.setToolTipText(i18n.getLabel("Channel.streamVoiceCount"));
                 p.add(p2);  
                 p.setBackground(new java.awt.Color(0x818181));  
                 p2 = new JPanel();  
                 p2.setLayout(new java.awt.BorderLayout());  
                 p.add(p2);  
                 bgp.add(p);  
                   
                 setContentPane(bgp);  
                   
                 cbMidiDevice.addActionListener(new ActionListener() {  
                         public void  
                         actionPerformed(ActionEvent e) { setMidiDevice(); }  
                 });  
                   
                 cbMidiPort.addActionListener(new ActionListener() {  
                         public void  
                         actionPerformed(ActionEvent e) { setMidiPort(); }  
                 });  
                   
                 cbMidiChannel.addActionListener(new ActionListener() {  
                         public void  
                         actionPerformed(ActionEvent e) { setMidiChannel(); }  
                 });  
                   
                 samplerListener = new SamplerAdapter() {  
                         /** Invoked when the default MIDI instrument map is changed. */  
                         public void  
                         defaultMapChanged(SamplerEvent e) {  
                                 updateCbInstrumentMapToolTipText();  
                                   
                         }  
                 };  
                   
                 CC.getSamplerModel().addSamplerListener(samplerListener);  
                   
                 cbInstrumentMap.addItem(noMap);  
                 cbInstrumentMap.addItem(defaultMap);  
                 for(MidiInstrumentMap map : CC.getSamplerModel().getMidiInstrumentMaps()) {  
                         cbInstrumentMap.addItem(map);  
                 }  
                   
                 int map = channel.getModel().getChannelInfo().getMidiInstrumentMapId();  
                 cbInstrumentMap.setSelectedItem(CC.getSamplerModel().getMidiInstrumentMapById(map));  
                 if(cbInstrumentMap.getSelectedItem() == null) {  
                         if(map == -1) cbInstrumentMap.setSelectedItem(noMap);  
                         else if(map == -2) {  
                                 cbInstrumentMap.setSelectedItem(defaultMap);  
                         }  
                 }  
                   
                 updateCbInstrumentMapToolTipText();  
                   
                 if(channel.getModel().getChannelInfo().getEngine() == null) {  
                         cbInstrumentMap.setEnabled(false);  
                 }  
                   
                 cbInstrumentMap.addActionListener(new ActionListener() {  
                         public void  
                         actionPerformed(ActionEvent e) { updateInstrumentMap(); }  
                 });  
                   
                 CC.getSamplerModel().addSamplerChannelListListener(getHandler());  
                 CC.getSamplerModel().addMidiInstrumentMapListListener(mapListListener);  
                   
                 cbAudioDevice.addActionListener(new ActionListener() {  
                         public void  
                         actionPerformed(ActionEvent e) { setBackendAudioDevice(); }  
                 });  
                   
                 channel.getModel().addSamplerChannelListener(new SamplerChannelAdapter() {  
                         public void  
                         channelChanged(SamplerChannelEvent e) { updateChannelProperties(); }  
                 });  
                   
                 CC.getSamplerModel().addMidiDeviceListListener(getHandler());  
                 CC.getSamplerModel().addAudioDeviceListListener(getHandler());  
                   
                 updateMidiDevices();  
                 updateAudioDevices();  
                 updateChannelProperties();  
         }  
           
         /**  
          * Updates the channel settings. This method is invoked when changes to the  
          * channel were made.  
          */  
         private void  
         updateChannelProperties() {  
                 SamplerModel sm = CC.getSamplerModel();  
                 SamplerChannel sc = channel.getModel().getChannelInfo();  
                   
                 MidiDeviceModel mm = sm.getMidiDeviceById(sc.getMidiInputDevice());  
                 AudioDeviceModel am = sm.getAudioDeviceById(sc.getAudioOutputDevice());  
                   
                 if(isUpdate()) CC.getLogger().warning("Unexpected update state!");  
                   
                 setUpdate(true);  
                   
                 try {  
                         cbMidiDevice.setSelectedItem(mm == null ? null : mm.getDeviceInfo());  
809                                                    
810                          cbAudioDevice.setSelectedItem(am == null ? null : am.getDeviceInfo());                          Dimension d = lStreams.getPreferredSize();
811                          btnChannelRouting.setEnabled(am != null);                          lStreams.setMinimumSize(d);
812                  } catch(Exception x) {                          lStreams.setPreferredSize(d);
813                          CC.getLogger().log(Level.WARNING, "Unkown error", x);                          lStreams.setMaximumSize(d);
814                  }                          add(lStreams);
                   
                 if(sc.getEngine() != null) {  
                         cbInstrumentMap.setEnabled(true);  
                         int id = sc.getMidiInstrumentMapId();  
                         Object o;  
                         if(id == -2) o = defaultMap;  
                         else if(id == -1) o = noMap;  
                         else o = CC.getSamplerModel().getMidiInstrumentMapById(id);  
815                                                    
816                          if(cbInstrumentMap.getSelectedItem() != o) {                          lSlash.setFont(Res.fontScreenMono);
817                                  cbInstrumentMap.setSelectedItem(o);                          lSlash.setToolTipText(i18n.getLabel("Channel.streamVoiceCount"));
818                          }                          add(lSlash);
819                  } else {                          
820                          cbInstrumentMap.setSelectedItem(noMap);                          lVoices.setFont(Res.fontScreenMono);
821                          cbInstrumentMap.setEnabled(false);                          lVoices.setToolTipText(i18n.getLabel("Channel.streamVoiceCount"));
822                  }                          
823                                            d = lStreams.getPreferredSize();
824                  setUpdate(false);                          lVoices.setMinimumSize(d);
825          }                          lVoices.setPreferredSize(d);
826                                    lVoices.setMaximumSize(d);
827          /**                          add(lVoices);
828           * Updates the MIDI device list.                          
829           */                          lStreams.addMouseListener(channel.getContextMenu());
830          private void                          lSlash.addMouseListener(channel.getContextMenu());
831          updateMidiDevices() {                          lVoices.addMouseListener(channel.getContextMenu());
                 SamplerModel sm = CC.getSamplerModel();  
                 SamplerChannel sc = channel.getModel().getChannelInfo();  
                   
                 setUpdate(true);  
                   
                 try {  
                         cbMidiDevice.removeAllItems();  
                   
                         for(MidiDeviceModel m : sm.getMidiDevices())  
                                 cbMidiDevice.addItem(m.getDeviceInfo());  
                   
                         MidiDeviceModel mm = sm.getMidiDeviceById(sc.getMidiInputDevice());  
                         cbMidiDevice.setSelectedItem(mm == null ? null : mm.getDeviceInfo());  
                 } catch(Exception x) {  
                         CC.getLogger().log(Level.WARNING, "Unkown error", x);  
832                  }                  }
                   
                 setUpdate(false);  
         }  
           
           
         private void  
         updateInstrumentMap() {  
                 updateCbInstrumentMapToolTipText();  
                   
                 int id = channel.getModel().getChannelInfo().getMidiInstrumentMapId();  
                 Object o = cbInstrumentMap.getSelectedItem();  
                 if(o == null && id == -1) return;  
                   
                 int cbId;  
                 if(o == null || o == noMap) cbId = -1;  
                 else if(o == defaultMap) cbId = -2;  
                 else cbId = ((MidiInstrumentMap)o).getMapId();  
833                                    
834                  if(cbId == id) return;                  public void
835                                    updateStreamCount(int count) {
836                  channel.getModel().setBackendMidiInstrumentMap(cbId);                          lStreams.setText(count == 0 ? " --" : String.valueOf(count));
         }  
           
         private void  
         updateCbInstrumentMapToolTipText() {  
                 if(cbInstrumentMap.getSelectedItem() != defaultMap) {  
                         cbInstrumentMap.setToolTipText(null);  
                         return;  
837                  }                  }
838                                    
839                  MidiInstrumentMap m = CC.getSamplerModel().getDefaultMidiInstrumentMap();                  public void
840                  if(m != null) {                  updateVoiceCount(int count) {
841                          String s = i18n.getLabel("Channel.ttDefault", m.getName());                          lVoices.setText(count == 0 ? "-- " : String.valueOf(count));
                         cbInstrumentMap.setToolTipText(s);  
                 } else {  
                         cbInstrumentMap.setToolTipText(null);  
842                  }                  }
843          }          }
844                    
845          /**          public static class VolumePane extends JPanel {
846           * Updates the audio device list.                  private final Channel channel;
847           */                  private final JButton btnVolume = createScreenButton("");
848          private void                  private JSVolumeEditorPopup popupVolume;
         updateAudioDevices() {  
                 SamplerModel sm = CC.getSamplerModel();  
                 SamplerChannel sc = channel.getModel().getChannelInfo();  
                   
                 setUpdate(true);  
                   
                 try {  
                         cbAudioDevice.removeAllItems();  
849                                    
850                          for(AudioDeviceModel m : sm.getAudioDevices())                  private static NumberFormat numberFormat = NumberFormat.getInstance();
851                                  cbAudioDevice.addItem(m.getDeviceInfo());                  static { numberFormat.setMaximumFractionDigits(1); }
852                                    
853                          AudioDeviceModel am = sm.getAudioDeviceById(sc.getAudioOutputDevice());                  public
854                          cbAudioDevice.setSelectedItem(am == null ? null : am.getDeviceInfo());                  VolumePane(final Channel channel) {
855                  } catch(Exception x) {                          this.channel = channel;
856                          CC.getLogger().log(Level.WARNING, "Unkown error", x);                          setOpaque(false);
857                  }                          setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
                   
                 setUpdate(false);  
         }  
           
         private void  
         setMidiDevice() {  
                 MidiInputDevice mid = (MidiInputDevice)cbMidiDevice.getSelectedItem();  
                   
                 if(!isUpdate()) {  
                         if(mid != null) {  
                                 channel.getModel().setBackendMidiInputDevice(mid.getDeviceId());  
                         }  
858                                                    
859                          return;                          btnVolume.setIcon(Res.iconVolume14);
860                  }                          btnVolume.setIconTextGap(2);
861                                            btnVolume.setAlignmentX(RIGHT_ALIGNMENT);
862                  if(midiDevice != null) midiDevice.removeMidiDeviceListener(getHandler());                          btnVolume.setHorizontalAlignment(btnVolume.LEFT);
863                                            updateVolumeInfo(100);
864                  cbMidiPort.removeAllItems();                          Dimension d = btnVolume.getPreferredSize();
865                                            d.width = 57;
866                  if(mid == null) {                          btnVolume.setPreferredSize(d);
867                          midiDevice = null;                          btnVolume.setMinimumSize(d);
                         cbMidiPort.setEnabled(false);  
868                                                    
869                          cbMidiChannel.setSelectedItem(null);                          add(btnVolume);
                         cbMidiChannel.setEnabled(false);  
                 } else {  
                         midiDevice = CC.getSamplerModel().getMidiDeviceById(mid.getDeviceId());  
                         if(midiDevice != null) midiDevice.addMidiDeviceListener(getHandler());  
870                                                    
871                          cbMidiPort.setEnabled(true);                          btnVolume.addActionListener(new ActionListener() {
872                                    public void
873                                    actionPerformed(ActionEvent e) {
874                                            if(popupVolume.isVisible()) {
875                                                    popupVolume.commit();
876                                                    popupVolume.hide();
877                                            } else {
878                                                    float vol = channel.getModel().getChannelInfo().getVolume();
879                                                    popupVolume.setCurrentVolume(vol);
880                                                    popupVolume.show();
881                                            }
882                                    }
883                            });
884                                                    
885                          MidiPort[] ports = mid.getMidiPorts();                          popupVolume = new JSVolumeEditorPopup(btnVolume, VolumeType.CHANNEL);
                         for(MidiPort port : ports) cbMidiPort.addItem(port);  
886                                                    
887                          int p = channel.getModel().getChannelInfo().getMidiInputPort();                          popupVolume.addActionListener(new ActionListener() {
888                          cbMidiPort.setSelectedItem(p >= 0 && p < ports.length ? ports[p] : null);                                  public void
889                                    actionPerformed(ActionEvent e) {
890                                            channel.getModel().setBackendVolume(popupVolume.getVolumeFactor());
891                                    }
892                            });
893                                                    
894                          cbMidiChannel.setEnabled(true);                          btnVolume.addMouseListener(channel.getContextMenu());
                         int c = channel.getModel().getChannelInfo().getMidiInputChannel();  
                         cbMidiChannel.setSelectedItem(c == -1 ? "All" : "Channel " + (c + 1));  
895                  }                  }
         }  
           
         private void  
         setMidiPort() {  
                 if(isUpdate()) return;  
                   
                 channel.getModel().setBackendMidiInputPort(cbMidiPort.getSelectedIndex());  
         }  
           
         private void  
         setMidiChannel() {  
                 if(isUpdate()) return;  
                   
                 Object o = cbMidiChannel.getSelectedItem();  
                 if(o == null) return;  
                 String s = o.toString();  
                   
                 int c = s.equals("All") ? -1 : Integer.parseInt(s.substring(8)) - 1;  
896                                    
                 channel.getModel().setBackendMidiInputChannel(c);  
         }  
           
         private void  
         setBackendAudioDevice() {  
                 if(isUpdate()) return;  
                 AudioOutputDevice dev = (AudioOutputDevice)cbAudioDevice.getSelectedItem();  
                 if(dev != null) channel.getModel().setBackendAudioOutputDevice(dev.getDeviceId());  
         }  
           
         /**  
          * Determines whether the currently processed changes are due to update.  
          * @return <code>true</code> if the currently processed changes are due to update and  
          * <code>false</code> if the currently processed changes are due to user input.  
          */  
         private boolean  
         isUpdate() { return update; }  
           
         /**  
          * Sets whether the currently processed changes are due to update.  
          * @param b Specify <code>true</code> to indicate that the currently  
          * processed changes are due to update; <code>false</code>  
          * indicates that the currently processed changes are due to user input.  
          */  
         private void  
         setUpdate(boolean b) { update = b; }  
           
         private final Handler handler = new Handler();  
           
         private Handler  
         getHandler() { return handler; }  
           
         private class Handler implements MidiDeviceListListener, ListListener<AudioDeviceModel>,  
                                         SamplerChannelListListener, MidiDeviceListener {  
                 /**  
                  * Invoked when a new MIDI device is created.  
                  * @param e A <code>MidiDeviceListEvent</code>  
                  * instance providing the event information.  
                  */  
897                  public void                  public void
898                  deviceAdded(MidiDeviceListEvent e) {                  updateVolumeInfo(int volume) {
899                          cbMidiDevice.addItem(e.getMidiDeviceModel().getDeviceInfo());                          if(CC.getViewConfig().isMeasurementUnitDecibel()) {
900                                    String s = numberFormat.format(HF.percentsToDecibels(volume));
901                                    btnVolume.setText(s + "dB");
902                            } else {
903                                    btnVolume.setText(String.valueOf(volume) + "%");
904                            }
905                  }                  }
906            }
907                    
908                  /**          public static class PowerButton extends PixmapToggleButton implements ActionListener {
909                   * Invoked when a MIDI device is removed.                  private final Channel channel;
                  * @param e A <code>MidiDeviceListEvent</code>  
                  * instance providing the event information.  
                  */  
                 public void  
                 deviceRemoved(MidiDeviceListEvent e) {  
                         cbMidiDevice.removeItem(e.getMidiDeviceModel().getDeviceInfo());  
                 }  
910                                    
911                  /**                  PowerButton(Channel channel) {
912                   * Invoked when a new audio device is created.                          this(channel, Res.gfxPowerOff, Res.gfxPowerOn);
                  * @param e An <code>AudioDeviceListEvent</code>  
                  * instance providing the event information.  
                  */  
                 public void  
                 entryAdded(ListEvent<AudioDeviceModel> e) {  
                         cbAudioDevice.addItem(e.getEntry().getDeviceInfo());  
913                  }                  }
914                            
915                  /**                  PowerButton(Channel channel, ImageIcon defaultIcon, ImageIcon selectedIcon) {
916                   * Invoked when an audio device is removed.                          super(defaultIcon, selectedIcon);
917                   * @param e An <code>AudioDeviceListEvent</code>                          
918                   * instance providing the event information.                          this.channel = channel;
919                   */                  
920                  public void                          setSelected(true);
921                  entryRemoved(ListEvent<AudioDeviceModel> e) {                          addActionListener(this);
922                          cbAudioDevice.removeItem(e.getEntry().getDeviceInfo());                          setToolTipText(i18n.getButtonLabel("Channel.ttRemoveChannel"));
923                  }                  }
924                                    
                 /**  
                  * Invoked when a new sampler channel is created.  
                  * @param e A <code>SamplerChannelListEvent</code>  
                  * instance providing the event information.  
                  */  
925                  public void                  public void
926                  channelAdded(SamplerChannelListEvent e) { }                  actionPerformed(ActionEvent e) {
927                                    boolean b = preferences().getBoolProperty(CONFIRM_CHANNEL_REMOVAL);
928                  /**                          if(b) {
929                   * Invoked when a sampler channel is removed.                                  String s = i18n.getMessage("Channel.remove?", channel.getChannelId());
930                   * @param e A <code>SamplerChannelListEvent</code>                                  if(!HF.showYesNoDialog(channel, s)) {
931                   * instance providing the event information.                                          setSelected(true);
932                   */                                          return;
                 public void  
                 channelRemoved(SamplerChannelListEvent e) {  
                         // Some cleanup when the channel is removed.  
                         if(e.getChannelModel().getChannelId() == channel.getChannelId()) {  
                                 SamplerModel sm = CC.getSamplerModel();  
                                   
                                 sm.removeMidiDeviceListListener(getHandler());  
                                 sm.removeAudioDeviceListListener(getHandler());  
                                 sm.removeMidiInstrumentMapListListener(mapListListener);  
                                 sm.removeSamplerListener(samplerListener);  
                                 sm.removeSamplerChannelListListener(getHandler());  
                                   
                                 if(midiDevice != null) {  
                                         midiDevice.removeMidiDeviceListener(getHandler());  
933                                  }                                  }
934                          }                          }
935                            channel.remove();
936                  }                  }
937                                    
938                  public void                  public boolean
939                  settingsChanged(MidiDeviceEvent e) {                  contains(int x, int y) { return (x - 11)*(x - 11) + (y - 11)*(y - 11) < 71; }
940                          if(isUpdate()) {          }
941                                  CC.getLogger().warning("Invalid update state");          
942                                  return;          public static class OptionsButton extends PixmapToggleButton implements ActionListener {
943                          }                  private final Channel channel;
944                                            
945                          setUpdate(true);                  OptionsButton(Channel channel) {
946                          int idx = cbMidiPort.getSelectedIndex();                          super(Res.gfxOptionsOff, Res.gfxOptionsOn);
                         MidiInputDevice d = e.getMidiDeviceModel().getDeviceInfo();  
947                                                    
948                          cbMidiPort.removeAllItems();                          this.channel = channel;
                         for(MidiPort port : d.getMidiPorts()) cbMidiPort.addItem(port);  
949                                                    
950                          if(idx >= cbMidiPort.getModel().getSize()) idx = 0;                          setRolloverIcon(Res.gfxOptionsOffRO);
951                            this.setRolloverSelectedIcon(Res.gfxOptionsOnRO);
952                            addActionListener(this);
953                            setToolTipText(i18n.getButtonLabel("Channel.ttShowOptions"));
954                    }
955                    
956                    public void
957                    actionPerformed(ActionEvent e) {
958                            channel.showOptionsPane(isSelected());
959                                                    
960                          setUpdate(false);                          String s;
961                            if(isSelected()) s = i18n.getButtonLabel("Channel.ttHideOptions");
962                            else s = i18n.getButtonLabel("Channel.ttShowOptions");
963                                                    
964                          if(cbMidiPort.getModel().getSize() > 0) cbMidiPort.setSelectedIndex(idx);                          setToolTipText(s);
965                  }                  }
966                    
967                    public boolean
968                    contains(int x, int y) { return super.contains(x, y) & y < 13; }
969          }          }
970            }
971          private class MapListListener implements ListListener<MidiInstrumentMap> {  
972                  /** Invoked when a new MIDI instrument map is added to a list. */  class ChannelOptionsPane extends JXCollapsiblePane {
973                  public void          ChannelOptionsPane() {
974                  entryAdded(ListEvent<MidiInstrumentMap> e) {                  setAnimated(false);
975                          cbInstrumentMap.insertItemAt(e.getEntry(), cbInstrumentMap.getItemCount());                  setCollapsed(true);
976                          boolean b = channel.getModel().getChannelInfo().getEngine() != null;                  setAnimated(preferences().getBoolProperty(ANIMATED));
977                          if(b && !cbInstrumentMap.isEnabled()) cbInstrumentMap.setEnabled(true);                  
978                  }                  preferences().addPropertyChangeListener(ANIMATED, new PropertyChangeListener() {
979                                    public void
980                  /** Invoked when a new MIDI instrument map is removed from a list. */                          propertyChange(PropertyChangeEvent e) {
981                  public void                                  setAnimated(preferences().getBoolProperty(ANIMATED));
                 entryRemoved(ListEvent<MidiInstrumentMap> e) {  
                         cbInstrumentMap.removeItem(e.getEntry());  
                         if(cbInstrumentMap.getItemCount() == 0) { // TODO: ?  
                                 cbInstrumentMap.setSelectedItem(noMap);  
                                 cbInstrumentMap.setEnabled(false);  
982                          }                          }
983                  }                  });
984          }          }
985            
986            public void
987            showOptionsPane(boolean show) { setCollapsed(!show); }
988  }  }

Legend:
Removed from v.1318  
changed lines
  Added in v.1734

  ViewVC Help
Powered by ViewVC