/[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 1540 by iliev, Mon Dec 3 23:22:02 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 24  package org.jsampler.view.fantasia; Line 24  package org.jsampler.view.fantasia;
24    
25  import java.awt.Container;  import java.awt.Container;
26  import java.awt.Dimension;  import java.awt.Dimension;
 import java.awt.Graphics;  
 import java.awt.Graphics2D;  
 import java.awt.Insets;  
27  import java.awt.Rectangle;  import java.awt.Rectangle;
28    
29  import java.awt.event.ActionEvent;  import java.awt.event.ActionEvent;
30  import java.awt.event.ActionListener;  import java.awt.event.ActionListener;
 import java.awt.event.HierarchyEvent;  
 import java.awt.event.HierarchyListener;  
31  import java.awt.event.MouseAdapter;  import java.awt.event.MouseAdapter;
32  import java.awt.event.MouseEvent;  import java.awt.event.MouseEvent;
33    
# Line 41  import java.beans.PropertyChangeListener Line 36  import java.beans.PropertyChangeListener
36    
37  import java.text.NumberFormat;  import java.text.NumberFormat;
38    
39  import java.util.logging.Level;  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;
 import javax.swing.JComboBox;  
46  import javax.swing.JComponent;  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;  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;  
 import javax.swing.Timer;  
   
 import javax.swing.event.ChangeEvent;  
 import javax.swing.event.ChangeListener;  
55    
 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.HF;  import org.jsampler.HF;
 import org.jsampler.MidiDeviceModel;  
 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;  import org.jsampler.view.std.JSVolumeEditorPopup;
76    
 import org.jvnet.substance.SubstanceImageCreator;  
   
 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.*;
# Line 117  import static org.jsampler.view.std.JSVo Line 86  import static org.jsampler.view.std.JSVo
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 ViewTracker viewTracker;
95                    
96          private final PowerButton btnPower = new PowerButton();          private InformationDialog fxSendsDlg = null;
         private final MuteButton btnMute = new MuteButton();  
         private final SoloButton btnSolo = new SoloButton();  
         private final OptionsButton btnOptions = new OptionsButton();  
97                    
98          private final EnhancedDial dialVolume = new EnhancedDial();          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 155  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                                    
                 int i = preferences().getIntProperty(MAXIMUM_CHANNEL_VOLUME);  
                 dialVolume.setMaximum(i);  
                 String mcv = MAXIMUM_CHANNEL_VOLUME;  
                 preferences().addPropertyChangeListener(mcv, new PropertyChangeListener() {  
                         public void  
                         propertyChange(PropertyChangeEvent e) {  
                                 int j = preferences().getIntProperty(MAXIMUM_CHANNEL_VOLUME);  
                                 dialVolume.setMaximum(j);  
                         }  
                 });  
                   
                 String vmud = VOL_MEASUREMENT_UNIT_DECIBEL;  
                 preferences().addPropertyChangeListener(vmud, new PropertyChangeListener() {  
                         public void  
                         propertyChange(PropertyChangeEvent e) {  
                                 boolean b;  
                                 b = preferences().getBoolProperty(VOL_MEASUREMENT_UNIT_DECIBEL);  
                                 screen.updateVolumeInfo(dialVolume.getValue());  
                         }  
                 });  
                   
155                  getModel().addSamplerChannelListener(getHandler());                  getModel().addSamplerChannelListener(getHandler());
156                                    
157                  updateChannelInfo();                  updateChannelInfo();
# Line 304  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 337  public class Channel extends org.jsample Line 209  public class Channel extends org.jsample
209                  sp.getViewport().scrollRectToVisible(new Rectangle(0, h - 2, 1, 1));                  sp.getViewport().scrollRectToVisible(new Rectangle(0, h - 2, 1, 1));
210          }          }
211                    
         private JPanel  
         createVSeparator() {  
                 PixmapPane p = new PixmapPane(Res.gfxVLine);  
                 p.setAlignmentY(JPanel.TOP_ALIGNMENT);  
                 p.setPreferredSize(new Dimension(2, 60));  
                 p.setMinimumSize(p.getPreferredSize());  
                 p.setMaximumSize(p.getPreferredSize());  
                 return p;  
         }  
           
212          /**          /**
213           * Determines whether the channel is selected.           * Determines whether the channel is selected.
214           * @return <code>true</code> if the channel is selected, <code>false</code> otherwise.           * @return <code>true</code> if the channel is selected, <code>false</code> otherwise.
# Line 372  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                  screen.updateScreenInfo(sc);          }
252                  updateMuteIcon(sc);          
253            public void
254            loadInstrument() {
255                    JSInstrumentChooser dlg = FantasiaUtils.createInstrumentChooser(CC.getMainFrame());
256                    dlg.setVisible(true);
257                                    
258                  if(sc.isSoloChannel()) btnSolo.setIcon(Res.gfxSoloOn);                  if(!dlg.isCancelled()) {
259                  else btnSolo.setIcon(Res.gfxSoloOff);                          SamplerChannelModel m = getModel();
260                  dialVolume.setValue((int)(sc.getVolume() * 100));                          m.loadBackendInstrument(dlg.getInstrumentFile(), dlg.getInstrumentIndex());
261                                    }
                 boolean b = sc.getEngine() != null;  
                 dialVolume.setEnabled(b);  
                 btnSolo.setEnabled(b);  
                 btnMute.setEnabled(b);  
262          }          }
263                    
264          /**          public void
265           * Updates the mute button with the proper icon regarding to information obtained          fallbackToOriginalView() {
266           * from <code>channel</code>.                  viewTracker.fallbackToOriginalView();
          * @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);  
267          }          }
268                    
269          private class EnhancedDial extends Dial {          public boolean
270                  EnhancedDial() {          isUsingOriginalView() {
271                          super(0, 100);                  return viewTracker.isUsingOriginalView();
                           
                         setMouseHandlerMode(MouseHandlerMode.LEFT_TO_RIGHT_AND_DOWN_TO_UP);  
                           
                         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(); }  
                         });  
                 }  
272          }          }
273                    
274          protected void          protected void
275          onDestroy() {          onDestroy() {
276                  CC.getSamplerModel().removeSamplerChannelListListener(getHandler());                  CC.getSamplerModel().removeSamplerChannelListListener(getHandler());
277                    preferences().removePropertyChangeListener(ANIMATED, animatedPorpetyListener);
278                    
279                    viewTracker.onDestroy();
280            }
281                    
282            public void
283            remove() {
284                    if(!mainPane.isAnimated()) {
285                            CC.getSamplerModel().removeBackendChannel(getChannelId());
286                            return;
287                    }
288                                    
289                  screen.onDestroy();                  String s = JXCollapsiblePane.ANIMATION_STATE_KEY;
290                  optionsPane.onDestroy();                  mainPane.addPropertyChangeListener(s, getHandler());
291                    mainPane.setCollapsed(true);
292            }
293            
294            public void
295            showOptionsPane(boolean show) { optionsPane.showOptionsPane(show); }
296            
297            public void
298            showFxSendsDialog() {
299                    if(fxSendsDlg != null && fxSendsDlg.isVisible()) {
300                            fxSendsDlg.toFront();
301                            return;
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 477  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, SamplerChannelListListener {          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 493  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 503  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());
345                  }                  }
346                                    
347                  /**                  /**
# Line 526  public class Channel extends org.jsample Line 364  public class Channel extends org.jsample
364                                  onDestroy();                                  onDestroy();
365                          }                          }
366                  }                  }
367                    
368                    public void
369                    propertyChange(PropertyChangeEvent e) {
370                            if(e.getNewValue() == "collapsed") {
371                                    CC.getSamplerModel().removeBackendChannel(getChannelId());
372                            }
373                    }
374          }          }
375                    
376            private static boolean viewTrackerMousePressed = false;
377                    
378          private class PowerButton extends PixmapToggleButton          class ViewTracker extends MouseAdapter implements PropertyChangeListener {
379                          implements ActionListener, PropertyChangeListener {                  private ChannelView originalView;
380                    private ChannelView mouseOverView;
381                    private ChannelView currentView;
382                                    
                 PowerButton() {  
                         super(Res.gfxPowerOff, Res.gfxPowerOn);  
383                                    
384                          setSelected(true);                  private boolean mouseOver = false;
                         addActionListener(this);  
                 }  
385                                    
386                  public void                  private final ActionListener guiListener;
387                  actionPerformed(ActionEvent e) {                  
388                          if(!mainPane.isAnimated()) {                  ViewTracker() {
389                                  CC.getSamplerModel().removeBackendChannel(getChannelId());                          guiListener = new ActionListener() {
390                                  return;                                  public void
391                          }                                  actionPerformed(ActionEvent e) {
392                                            if(viewTrackerMousePressed) return;
393                                            
394                                            if(mainPane.getMousePosition(true) != null) {
395                                                    mouseEntered(null);
396                                            } else {
397                                                    mouseExited(null);
398                                            }
399                                    }
400                            };
401                            
402                            updateMouseOverViewType();
403                                                    
404                          String s = JXCollapsiblePane.ANIMATION_STATE_KEY;                          String s = DIFFERENT_CHANNEL_VIEW_ON_MOUSE_OVER;
405                          mainPane.addPropertyChangeListener(s, this);                          preferences().addPropertyChangeListener(s, this);
406                          mainPane.setCollapsed(true);                          
407                            s = CHANNEL_VIEW_ON_MOUSE_OVER;
408                            preferences().addPropertyChangeListener(s, this);
409                  }                  }
410                                    
411                  public void                  public boolean
412                  propertyChange(PropertyChangeEvent e) {                  isUsingOriginalView() {
413                          if(e.getNewValue() == "collapsed") {                          return currentView == originalView;
                                 CC.getSamplerModel().removeBackendChannel(getChannelId());  
                         }  
414                  }                  }
415                                    
416                  public boolean                  private void
417                  contains(int x, int y) { return (x - 11)*(x - 11) + (y - 11)*(y - 11) < 71; }                  installListeners() {
418          }                          ((MainFrame)CC.getMainFrame()).getGuiTimer().addActionListener(guiListener);
           
         private class MuteButton extends PixmapButton implements ActionListener {  
                 MuteButton() {  
                         super(Res.gfxMuteOff);  
                         //setDisabledIcon(Res.gfxMuteSoloDisabled);  
                         setDisabledIcon (  
                                 SubstanceImageCreator.makeTransparent(this, Res.gfxMuteOff, 0.4)  
                         );  
                         addActionListener(this);  
419                  }                  }
420                                    
421                  public void                  private void
422                  actionPerformed(ActionEvent e) {                  uninstallListeners() {
423                          SamplerChannel sc = getChannelInfo();                          ((MainFrame)CC.getMainFrame()).getGuiTimer().removeActionListener(guiListener);
424                          boolean b = true;                  }
425                                    
426                          /*                  private void
427                           * Changing the mute button icon now instead of                  updateMouseOverViewType() {
428                           * leaving the work to the notification mechanism of the LinuxSampler.                          if(mouseOverView != null) {
429                           */                                  mouseOverView.removeEnhancedMouseListener(this);
430                          if(sc.isMuted() && !sc.isMutedBySolo()) {                          }
431                                  b = false;                          
432                                  boolean hasSolo = CC.getSamplerModel().hasSoloChannel();                          boolean b;
433                                                    b = preferences().getBoolProperty(DIFFERENT_CHANNEL_VIEW_ON_MOUSE_OVER);
434                                  if(sc.isSoloChannel() || !hasSolo) setIcon(Res.gfxMuteOff);                          if(!b) {
435                                  else setIcon(Res.gfxMutedBySolo);                                  mouseOverView = null;
436                          } else setIcon(Res.gfxMuteOn);                                  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                          Channel.this.getModel().setBackendMute(b);                          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; }
         }  
           
         private class SoloButton extends PixmapButton implements ActionListener {  
                 SoloButton() {  
                         super(Res.gfxSoloOff);  
                         //setDisabledIcon(Res.gfxMuteSoloDisabled);  
                         setDisabledIcon (  
                                 SubstanceImageCreator.makeTransparent(this, Res.gfxSoloOff, 0.4)  
                         );  
                         addActionListener(this);  
                 }  
457                                    
458                  public void                  public void
459                  actionPerformed(ActionEvent e) {                  setView(ChannelView view) {
460                          SamplerChannel sc = getChannelInfo();                          setView(view, true);
461                          boolean b = !sc.isSoloChannel();                  }
462                                    
463                          /*                  public void
464                           * Changing the solo button icon (and related) now instead of                  setView(ChannelView view, boolean manual) {
465                           * leaving the work to the notification mechanism of the LinuxSampler.                          boolean selected = false;
466                           */                          if(currentView != null) selected = currentView.isOptionsButtonSelected();
467                          if(b) {                          
468                                  setIcon(Res.gfxSoloOn);                          if(manual) {
469                                  if(sc.isMutedBySolo()) btnMute.setIcon(Res.gfxMuteOff);                                  if(originalView != null) {
470                                            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 {                          } else {
487                                  setIcon(Res.gfxSoloOff);                                  if(view.getType() == getCurrentView().getType()) {
488                                  if(!sc.isMuted() && CC.getSamplerModel().getSoloChannelCount() > 1)                                          destroyView(view);
489                                          btnMute.setIcon(Res.gfxMutedBySolo);                                          return;
490                                    }
491                                    
492                                    removeCurrentView();
493                                    currentView = view;
494                          }                          }
495                                            
496                          Channel.this.getModel().setBackendSolo(b);                          currentView.setOptionsButtonSelected(selected);
497                            
498                            updateView();
499                  }                  }
500                                    
501                  public boolean                  private void
502                  contains(int x, int y) { return (x > 5 && x < 23) && (y > 5 && y < 16); }                  updateView() {
503          }                          JComponent c = getCurrentView().getChannelOptionsView().getComponent();
504                                    optionsPane.setContentPane(c);
505          private class OptionsButton extends PixmapToggleButton implements ActionListener {                          
506                  OptionsButton() {                          updateChannelInfo();
507                          super(Res.gfxOptionsOff, Res.gfxOptionsOn);                  
508                          setRolloverIcon(Res.gfxOptionsOffRO);                          mainPane.add(getCurrentView().getComponent());
509                          this.setRolloverSelectedIcon(Res.gfxOptionsOnRO);                          mainPane.add(optionsPane);
510                          addActionListener(this);                          mainPane.validate();
511                            mainPane.revalidate();
512                            mainPane.repaint();
513                  }                  }
514                                    
515                  public void                  public void
516                  actionPerformed(ActionEvent e) {                  fallbackToOriginalView() {
517                          showOptionsPane(isSelected());                          if(currentView == originalView) return;
518                                                    
519                          String s;                          boolean selected = false;
520                          if(isSelected()) s = i18n.getButtonLabel("OptionsButton.ttHideOptions");                          if(currentView != null) selected = currentView.isOptionsButtonSelected();
                         else s = i18n.getButtonLabel("OptionsButton.ttShowOptions");  
521                                                    
522                          setToolTipText(s);                          removeCurrentView();
523                            currentView = originalView;
524                            currentView.setOptionsButtonSelected(selected);
525                            
526                            updateView();
527                  }                  }
528                                    
529                  private void                  private void
530                  showOptionsPane(boolean show) {                  removeCurrentView() { removeView(currentView); }
                         optionsPane.setCollapsed(!show);  
                 }  
531                                    
532                  public boolean                  private void
533                  contains(int x, int y) { return super.contains(x, y) & y < 13; }                  destroyCurrentView() { destroyView(currentView); }
         }  
 }  
   
 class ChannelPane extends PixmapPane {  
         ChannelPane() {  
                 super(Res.gfxChannel);  
                 setPixmapInsets(new Insets(3, 3, 3, 3));  
         }  
 }  
   
 class ChannelScreen extends PixmapPane {  
         private final Channel channel;  
           
         private final InstrumentPane instrumentPane;  
           
         private JButton btnInstr =  
                 createScreenButton(i18n.getButtonLabel("ChannelScreen.btnInstr"));  
           
         private final JButton btnEditInstr =  
                 createScreenButton(i18n.getButtonLabel("ChannelScreen.btnEditInstr"));  
         private final ScreenButtonBg sbbEditInstr = new ScreenButtonBg(btnEditInstr);  
           
         private final JButton btnFxSends =  
                 createScreenButton(i18n.getButtonLabel("ChannelScreen.btnFxSends"));  
           
         private final JButton btnEngine  
                 = createScreenButton(i18n.getButtonLabel("ChannelScreen.btnEngine"));  
           
         private final JPopupMenu menuEngines = new JPopupMenu();  
           
         private final JButton btnVolume = createScreenButton("");  
         private JSVolumeEditorPopup popupVolume;  
           
         private final JLabel lStreams = createScreenLabel(" --");  
         private final JLabel lVoices = createScreenLabel("-- ");  
           
         private InformationDialog fxSendsDlg = null;  
           
         private Timer timer;  
           
         private static NumberFormat numberFormat = NumberFormat.getInstance();  
         static {  
                 numberFormat.setMaximumFractionDigits(1);  
         }  
           
         ChannelScreen(final Channel channel) {  
                 super(Res.gfxChannelScreen);  
                 setPixmapInsets(new Insets(6, 6, 6, 6));  
                 setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));  
534                                    
535                  this.channel = channel;                  private void
536                  popupVolume = new JSVolumeEditorPopup(btnVolume, VolumeType.CHANNEL);                  removeOriginalView() { removeView(originalView); }
537                                    
538                  setOpaque(false);                  private void
539                    destroyOriginalView() { destroyView(originalView); }
540                                    
541                  setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));                  private void
542                    removeView(ChannelView view) {
543                            if(view == null) return;
544                            
545                            mainPane.remove(view.getComponent());
546                            mainPane.remove(optionsPane);
547                                    
548                            destroyView(view);
549                    }
550                                    
551                  btnInstr.setAlignmentX(CENTER_ALIGNMENT);                  private void
552                  btnInstr.setRolloverEnabled(false);                  destroyView(ChannelView view) {
553                  btnInstr.setBorder(BorderFactory.createEmptyBorder(3, 0, 0, 0));                          if(view == null) return;
554                                            
555                  instrumentPane = new InstrumentPane();                          view.uninstallView();
556                  add(instrumentPane);                          view.getChannelOptionsView().uninstallView();
557                                            
558                  JPanel p = new JPanel();                          view = null;
559                  p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));                  }
                 p.setAlignmentX(CENTER_ALIGNMENT);  
                 p.setBorder(BorderFactory.createEmptyBorder(5, 2, 0, 0));  
560                                    
561                  btnFxSends.setToolTipText(i18n.getButtonLabel("ChannelScreen.btnFxSends.tt"));                  private void
562                  btnFxSends.addActionListener(new ActionListener() {                  mouseEntered() {
563                          public void                          if(mouseOverView == null) return;
564                          actionPerformed(ActionEvent e) {                          if(getCurrentView().getType() == mouseOverView.getType()) return;
565                                  if(fxSendsDlg != null && fxSendsDlg.isVisible()) {                          
566                                          fxSendsDlg.toFront();                          JSChannel[] channels = CC.getMainFrame().getChannelsPane(0).getChannels();
567                                          return;                          for(JSChannel c : channels) {
568                                  }                                  if(c == Channel.this) continue;
569                                  FxSendsPane p = new FxSendsPane(channel.getModel());                                  
570                                  int id = channel.getModel().getChannelId();                                  Channel chn = (Channel)c;
571                                  fxSendsDlg = new InformationDialog(CC.getMainFrame(), p);                                  if(!(chn).isUsingOriginalView()) chn.fallbackToOriginalView();
                                 fxSendsDlg.setTitle(i18n.getLabel("FxSendsDlg.title", id));  
                                 fxSendsDlg.setModal(false);  
                                 fxSendsDlg.showCloseButton(false);  
                                 fxSendsDlg.setVisible(true);  
572                          }                          }
573                  });                          
574                                            setView(mouseOverView, false);
575                  p.add(btnFxSends);                  }
576                                    
577                  //p.add(Box.createRigidArea(new Dimension(6, 0)));                  private void
578                  p.add(Box.createGlue());                  mouseExited() {
579                            if(mouseOverView == null) return;
580                            if(getCurrentView().getType() == originalView.getType()) return;
581                            
582                            fallbackToOriginalView();
583                    }
584                                    
585                  btnEngine.setIcon(Res.iconEngine12);                  public void
586                  btnEngine.setIconTextGap(1);                  mouseEntered(MouseEvent e) {
587                  p.add(btnEngine);                          if(viewTrackerMousePressed) return;
588                  //p.add(new Label("|"));                          
589                                            if(mouseOver) return;
590                  //p.add(Box.createRigidArea(new Dimension(6, 0)));                          mouseOver = true;
591                                            mouseEntered();
592                  //p.add(btnReset);                  }
                   
                 p.add(Box.createGlue());  
                   
                 lStreams.setFont(Res.fontScreenMono);  
                 lStreams.setHorizontalAlignment(JLabel.RIGHT);  
                 lStreams.setToolTipText(i18n.getLabel("ChannelScreen.streamVoiceCount"));  
                 p.add(lStreams);  
                   
                 JLabel l = createScreenLabel("/");  
                 l.setFont(Res.fontScreenMono);  
                 l.setToolTipText(i18n.getLabel("ChannelScreen.streamVoiceCount"));  
                 p.add(l);  
                   
                 lVoices.setFont(Res.fontScreenMono);  
                 lVoices.setToolTipText(i18n.getLabel("ChannelScreen.streamVoiceCount"));  
                 p.add(lVoices);  
                   
                 btnVolume.setIcon(Res.iconVolume14);  
                 btnVolume.setIconTextGap(2);  
                 btnVolume.setAlignmentX(RIGHT_ALIGNMENT);  
                 btnVolume.setHorizontalAlignment(btnVolume.LEFT);  
                 updateVolumeInfo(100);  
                 Dimension d = btnVolume.getPreferredSize();  
                 d.width = 60;  
                 btnVolume.setPreferredSize(d);  
                 btnVolume.setMinimumSize(d);  
593                                    
594                  btnVolume.addActionListener(new ActionListener() {                  public void
595                          public void                  mouseExited(MouseEvent e) {
596                          actionPerformed(ActionEvent e) {                          if(viewTrackerMousePressed) return;
597                                  if(popupVolume.isVisible()) {                          
598                                          popupVolume.commit();                          if(mainPane.getMousePosition(true) != null) return;
599                                          popupVolume.hide();                          if(!mouseOver) return;
600                                  } else {                          mouseOver = false;
601                                          float vol = channel.getModel().getChannelInfo().getVolume();                          mouseExited();
602                                          popupVolume.setCurrentVolume(vol);                  }
                                         popupVolume.show();  
                                 }  
                         }  
                 });  
603                                    
604                  popupVolume.addActionListener(new ActionListener() {                  public void
605                          public void                  mousePressed(MouseEvent e) {
606                          actionPerformed(ActionEvent e) {                          viewTrackerMousePressed = true;
607                                  channel.getModel().setBackendVolume(popupVolume.getVolumeFactor());                  }
                         }  
                 });  
608                                    
609                  p.add(btnVolume);                  public void
610                  p.setPreferredSize(new Dimension(260, p.getPreferredSize().height));                  mouseReleased(MouseEvent e) {
611                  p.setMinimumSize(p.getPreferredSize());                          viewTrackerMousePressed = false;
612                  p.setMaximumSize(p.getPreferredSize());                  }
                   
                 //btnInstr.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));  
                 p.setOpaque(false);  
                 add(p);  
                   
                   
                 setPreferredSize(new Dimension(270, 48));  
                 setMinimumSize(getPreferredSize());  
                 setMaximumSize(getPreferredSize());  
613                                    
614                  createEngineMenu();                  public void
615                  installListeners();                  onDestroy() {
616          }                          destroyCurrentView();
617                                    destroyOriginalView();
         protected void  
         onDestroy() { timer.stop(); }  
           
         private void  
         createEngineMenu() {  
                 for(final SamplerEngine engine : CC.getSamplerModel().getEngines()) {  
                         JMenuItem mi = new JMenuItem(engine.getName() + " engine");  
                         mi.setToolTipText(engine.getDescription());  
618                                                    
619                          mi.addActionListener(new ActionListener() {                          uninstallListeners();
620                                  public void                          
621                                  actionPerformed(ActionEvent e) {                          if(currentView != null) {
622                                          channel.getModel().setBackendEngineType(engine.getName());                                  currentView.removeEnhancedMouseListener(this);
623                                  }                          }
624                          });                          
625                            if(mouseOverView != null) {
626                                    mouseOverView.removeEnhancedMouseListener(this);
627                            }
628                                                    
629                          menuEngines.add(mi);                          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                    public void
637                    propertyChange(PropertyChangeEvent e) {
638                            updateMouseOverViewType();
639                  }                  }
640          }          }
641                    
642          private void          class EditInstrumentAction extends AbstractAction implements SamplerChannelListener {
643          installListeners() {                  EditInstrumentAction() {
644                  btnInstr.addActionListener(new ActionListener() {                          super(i18n.getMenuLabel("channels.editInstrument"));
645                          public void                          channelChanged(null);
646                          actionPerformed(ActionEvent e) { loadInstrument(); }                          getModel().addSamplerChannelListener(this);
647                  });                  }
648                                    
649                  btnEditInstr.addActionListener(new ActionListener() {                  public void
650                          public void                  actionPerformed(ActionEvent e) {
651                          actionPerformed(ActionEvent e) {                          CC.getSamplerModel().editBackendInstrument(getChannelId());
652                                  CC.getSamplerModel().editBackendInstrument(channel.getChannelId());                  }
                         }  
                 });  
653                                    
654                  btnEngine.addActionListener(new ActionListener() {                  public void
655                          public void                  channelChanged(SamplerChannelEvent e) {
656                          actionPerformed(ActionEvent e) {                          boolean b = getChannelInfo().getInstrumentStatus() == 100;
657                                  int y = btnEngine.getHeight() + 1;                          setEnabled(b);
658                                  menuEngines.show(btnEngine, 0, y);                  }
                         }  
                 });  
659                                    
660                  addMouseListener(getHandler());                  public void
661                  addHierarchyListener(getHandler());                  streamCountChanged(SamplerChannelEvent e) { }
662                                    
663                  ActionListener l = new ActionListener() {                  public void
664                          public void                  voiceCountChanged(SamplerChannelEvent e) { }
                         actionPerformed(ActionEvent e) {  
                                 if(getMousePosition(true) != null) {  
                                         getHandler().mouseEntered(null);  
                                 } else {  
                                         getHandler().mouseExited(null);  
                                 }  
                         }  
                 };  
                 timer = new Timer(1000, l);  
                 timer.start();  
665          }          }
666                    
667          private void          class FxSendsAction extends AbstractAction {
668          loadInstrument() {                  FxSendsAction() {
669                  JSInstrumentChooser dlg = FantasiaUtils.createInstrumentChooser(CC.getMainFrame());                          super(i18n.getMenuLabel("channels.fxSends"));
670                  dlg.setVisible(true);                  }
671                                    
672                  if(!dlg.isCancelled()) {                  public void
673                          SamplerChannelModel m = channel.getModel();                  actionPerformed(ActionEvent e) {
674                          m.loadBackendInstrument(dlg.getInstrumentFile(), dlg.getInstrumentIndex());                          showFxSendsDialog();
675                  }                  }
676          }          }
677                    
678          protected void          class ChannelRoutingAction extends AbstractAction implements SamplerChannelListener {
679          updateScreenInfo(SamplerChannel sc) {                  ChannelRoutingAction() {
680                  int status = sc.getInstrumentStatus();                          super(i18n.getMenuLabel("channels.channelRouting"));
681                  if(status >= 0 && status < 100) {                          channelChanged(null);
682                          btnInstr.setText(i18n.getLabel("ChannelScreen.loadingInstrument", status));                          getModel().addSamplerChannelListener(this);
                 } else if(status == -1) {  
                         btnInstr.setText(i18n.getButtonLabel("ChannelScreen.btnInstr"));  
                 } else if(status < -1) {  
                          btnInstr.setText(i18n.getLabel("ChannelScreen.errorLoadingInstrument"));  
                 } else {  
                         if(sc.getInstrumentName() != null) btnInstr.setText(sc.getInstrumentName());  
                         else btnInstr.setText(i18n.getButtonLabel("ChannelScreen.btnInstr"));  
683                  }                  }
684                                    
685                  instrumentPane.update();                  public void
686                            actionPerformed(ActionEvent e) {
687                  if(sc.getEngine() != null) {                          SamplerChannel c = getChannelInfo();
688                          String s = sc.getEngine().getName();                          new JSChannelOutputRoutingDlg(CC.getMainFrame(), c).setVisible(true);
689                          s += " engine";                  }
690                          if(!s.equals(btnEngine.getText())) {                  
691                                  btnEngine.setText(s);                  public void
692                                  btnEngine.setToolTipText(sc.getEngine().getDescription());                  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          updateVolumeInfo(int volume) {                  SetSmallViewAction() {
706                  if(CC.getViewConfig().isMeasurementUnitDecibel()) {                          super(i18n.getMenuLabel("channels.smallView"));
707                          String s = numberFormat.format(HF.percentsToDecibels(volume));                  }
708                          btnVolume.setText(s + "dB");                  
709                  } else {                  public void
710                          btnVolume.setText(String.valueOf(volume) + "%");                  actionPerformed(ActionEvent e) {
711                            viewTracker.setView(new SmallChannelView(Channel.this));
712                  }                  }
713          }          }
714                    
715          /**          class SetNormalViewAction extends AbstractAction {
716           * Updates the number of active disk streams.                  SetNormalViewAction() {
717           * @param count The new number of active disk streams.                          super(i18n.getMenuLabel("channels.normalView"));
718           */                  }
719          protected void                  
720          updateStreamCount(int count) {                  public void
721                  Dimension d = lStreams.getPreferredSize();                  actionPerformed(ActionEvent e) {
722                  lStreams.setText(count == 0 ? "--" : String.valueOf(count));                          viewTracker.setView(new NormalChannelView(Channel.this));
723                  d = JuifeUtils.getUnionSize(d, lStreams.getPreferredSize());                  }
                 lStreams.setMinimumSize(d);  
                 lStreams.setPreferredSize(d);  
                 lStreams.setMaximumSize(d);  
724          }          }
725                    
726          /**          public ContextMenu
727           * Updates the number of active voices.          getContextMenu() { return contextMenu; }
          * @param count The new number of active voices.  
          */  
         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);  
         }  
728                    
729          class InstrumentPane extends JPanel {          class ContextMenu extends MouseAdapter {
730                  private final JPanel leftPane = new JPanel();                  private final JPopupMenu menu = new JPopupMenu();
                 private final JPanel rightPane = new JPanel();  
731                                    
732                  InstrumentPane() {                  protected final JRadioButtonMenuItem rbmiSmallView;
733                          setOpaque(false);                  protected final JRadioButtonMenuItem rbmiNormalView;
                         setLayout(new BoxLayout(this, BoxLayout.X_AXIS));  
                         add(leftPane);  
                         add(btnInstr);  
                         add(rightPane);  
                         add(sbbEditInstr);  
                         btnEditInstr.setToolTipText(i18n.getLabel("ChannelScreen.btnEditInstr.tt"));  
                         sbbEditInstr.setVisible(false);  
                         setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 6));  
                           
                         update();  
                 }  
734                                    
735                  public void                  ContextMenu() {
736                  update() {                          menu.add(new JMenuItem(new EditInstrumentAction()));
737                          int a = btnInstr.getMinimumSize().width;                          menu.addSeparator();
                         int b = 0;  
                         if(sbbEditInstr.isVisible()) b = sbbEditInstr.getPreferredSize().width;  
                           
                         int max = 254 - b;  
                         if(a > max) a = max;  
738                                                    
739                          int h = btnInstr.getPreferredSize().height;                          rbmiSmallView = new JRadioButtonMenuItem(new SetSmallViewAction());
740                          btnInstr.setPreferredSize(new Dimension(a, h));                          rbmiNormalView = new JRadioButtonMenuItem(new SetNormalViewAction());
                         h = btnInstr.getMaximumSize().height;  
                         btnInstr.setMaximumSize(new Dimension(a, h));  
741                                                    
742                            ButtonGroup group = new ButtonGroup();
743                            group.add(rbmiSmallView);
744                            group.add(rbmiNormalView);
745                                                    
746                          int i = (254 - btnInstr.getPreferredSize().width) / 2;                          menu.add(rbmiSmallView);
747                            menu.add(rbmiNormalView);
748                                                    
749                          int j = i;                          menu.addSeparator();
750                          if(sbbEditInstr.isVisible()) j -= sbbEditInstr.getPreferredSize().width;                          menu.add(new JMenuItem(new FxSendsAction()));
751                          if(i < 0 || j < 0) i = j = 0;                          menu.add(new JMenuItem(new ChannelRoutingAction()));
752                                            }
753                          Dimension d = new Dimension(i, 1);                  
754                          leftPane.setMinimumSize(d);                  public void
755                          leftPane.setPreferredSize(d);                  mousePressed(MouseEvent e) {
756                          leftPane.setMaximumSize(d);                          if(e.isPopupTrigger()) show(e);
757                                            }
758                          d = new Dimension(j, 1);          
759                          rightPane.setMinimumSize(d);                  public void
760                          rightPane.setPreferredSize(d);                  mouseReleased(MouseEvent e) {
761                          rightPane.setMaximumSize(d);                          if(e.isPopupTrigger()) show(e);
762                                            }
763                          validate();          
764                    void
765                    show(MouseEvent e) {
766                            menu.show(e.getComponent(), e.getX(), e.getY());
767                  }                  }
768          }          }
769                    
# Line 1034  class ChannelScreen extends PixmapPane { Line 790  class ChannelScreen extends PixmapPane {
790                  }                  }
791          }          }
792                    
793          static class ScreenButtonBg extends PixmapPane {          public static class StreamVoiceCountPane extends JPanel {
794                  ScreenButtonBg(JButton btn) {                  private final Channel channel;
                         super(Res.gfxScreenBtnBg);  
                         setPixmapInsets(new Insets(4, 4, 4, 4));  
                         setLayout(new BoxLayout(this, BoxLayout.X_AXIS));  
                         setBorder(BorderFactory.createEmptyBorder(0, 7, 0, 7));  
                         add(btn);  
                         setPreferredSize(new Dimension(getPreferredSize().width, 13));  
                 }  
795                                    
796                  public Dimension                  private final JLabel lStreams = createScreenLabel(" --");
797                  getPreferredSize() {                  private final JLabel lSlash = createScreenLabel("/");
798                          return new Dimension(super.getPreferredSize().width, 13);                  private final JLabel lVoices = createScreenLabel("-- ");
799                  }                  
800          }                  public
801                            StreamVoiceCountPane(Channel channel) {
802                                    this.channel = channel;
         private final EventHandler eventHandler = new EventHandler();  
           
         private EventHandler  
         getHandler() { return eventHandler; }  
           
         private class EventHandler extends MouseAdapter implements HierarchyListener {  
                 public void  
                 mouseEntered(MouseEvent e)  {  
                         if(channel.getChannelInfo().getInstrumentStatus() != 100) return;  
803                                                    
804                          if(!sbbEditInstr.isVisible()) {                          setOpaque(false);
805                                  sbbEditInstr.setVisible(true);                          setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
806                                  instrumentPane.update();                          lStreams.setFont(Res.fontScreenMono);
807                          }                          lStreams.setHorizontalAlignment(JLabel.RIGHT);
808                            lStreams.setToolTipText(i18n.getLabel("Channel.streamVoiceCount"));
809                            
810                            Dimension d = lStreams.getPreferredSize();
811                            lStreams.setMinimumSize(d);
812                            lStreams.setPreferredSize(d);
813                            lStreams.setMaximumSize(d);
814                            add(lStreams);
815                            
816                            lSlash.setFont(Res.fontScreenMono);
817                            lSlash.setToolTipText(i18n.getLabel("Channel.streamVoiceCount"));
818                            add(lSlash);
819                            
820                            lVoices.setFont(Res.fontScreenMono);
821                            lVoices.setToolTipText(i18n.getLabel("Channel.streamVoiceCount"));
822                            
823                            d = lStreams.getPreferredSize();
824                            lVoices.setMinimumSize(d);
825                            lVoices.setPreferredSize(d);
826                            lVoices.setMaximumSize(d);
827                            add(lVoices);
828                            
829                            lStreams.addMouseListener(channel.getContextMenu());
830                            lSlash.addMouseListener(channel.getContextMenu());
831                            lVoices.addMouseListener(channel.getContextMenu());
832                  }                  }
833                                    
834                  public void                  public void
835                  mouseExited(MouseEvent e)  {                  updateStreamCount(int count) {
836                          if(getMousePosition(true) != null) return;                          lStreams.setText(count == 0 ? " --" : String.valueOf(count));
                         if(sbbEditInstr.isVisible()) {  
                                 sbbEditInstr.setVisible(false);  
                                 instrumentPane.update();  
                         }  
837                  }                  }
838                                    
                 /** Called when the hierarchy has been changed. */  
839                  public void                  public void
840                  hierarchyChanged(HierarchyEvent e) {                  updateVoiceCount(int count) {
841                          if((e.getChangeFlags() & e.SHOWING_CHANGED) == e.SHOWING_CHANGED) {                          lVoices.setText(count == 0 ? "-- " : String.valueOf(count));
                                 if(getMousePosition() == null) mouseExited(null);  
                                 else mouseEntered(null);  
                         }  
842                  }                  }
843          }          }
 }  
   
 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();  
844                    
845          ChannelOptions(final Channel channel) {          public static class VolumePane extends JPanel {
846                  setAnimated(false);                  private final Channel channel;
847                  setCollapsed(true);                  private final JButton btnVolume = createScreenButton("");
848                  setAnimated(preferences().getBoolProperty(ANIMATED));                  private JSVolumeEditorPopup popupVolume;
                   
                 preferences().addPropertyChangeListener(ANIMATED, new PropertyChangeListener() {  
                         public void  
                         propertyChange(PropertyChangeEvent e) {  
                                 setAnimated(preferences().getBoolProperty(ANIMATED));  
                         }  
                 });  
849                                    
850                  PixmapPane bgp = new PixmapPane(Res.gfxChannelOptions);                  private static NumberFormat numberFormat = NumberFormat.getInstance();
851                  bgp.setPixmapInsets(new Insets(1, 1, 1, 1));                  static { numberFormat.setMaximumFractionDigits(1); }
852                                    
853                  this.channel = channel;                  public
854                                    VolumePane(final Channel channel) {
855                  bgp.setBorder(BorderFactory.createEmptyBorder(5, 4, 5, 4));                          this.channel = channel;
856                  bgp.setLayout(new BoxLayout(bgp, BoxLayout.X_AXIS));                          setOpaque(false);
857                                            setLayout(new BoxLayout(this, 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"));  
                   
                 btnChannelRouting.addActionListener(new ActionListener() {  
                         public void  
                         actionPerformed(ActionEvent e) {  
                                 SamplerChannel c = channel.getChannelInfo();  
                                 new JSChannelOutputRoutingDlg(CC.getMainFrame(), c).setVisible(true);  
858                                                    
859                          }                          btnVolume.setIcon(Res.iconVolume14);
860                  });                          btnVolume.setIconTextGap(2);
861                                            btnVolume.setAlignmentX(RIGHT_ALIGNMENT);
862                  p2.add(btnChannelRouting);                          btnVolume.setHorizontalAlignment(btnVolume.LEFT);
863                                            updateVolumeInfo(100);
864                  p.add(p2);                          Dimension d = btnVolume.getPreferredSize();
865                  p.setBackground(new java.awt.Color(0x818181));                          d.width = 57;
866                  p2 = new JPanel();                          btnVolume.setPreferredSize(d);
867                  p2.setLayout(new java.awt.BorderLayout());                          btnVolume.setMinimumSize(d);
                 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().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());  
868                                                    
869                          cbAudioDevice.setSelectedItem(am == null ? null : am.getDeviceInfo());                          add(btnVolume);
870                          btnChannelRouting.setEnabled(am != null);                          
871                  } catch(Exception x) {                          btnVolume.addActionListener(new ActionListener() {
872                          CC.getLogger().log(Level.WARNING, "Unkown error", x);                                  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                            popupVolume = new JSVolumeEditorPopup(btnVolume, VolumeType.CHANNEL);
886                            
887                            popupVolume.addActionListener(new ActionListener() {
888                                    public void
889                                    actionPerformed(ActionEvent e) {
890                                            channel.getModel().setBackendVolume(popupVolume.getVolumeFactor());
891                                    }
892                            });
893                            
894                            btnVolume.addMouseListener(channel.getContextMenu());
895                  }                  }
896                                    
897                  if(sc.getEngine() != null) {                  public void
898                          cbInstrumentMap.setEnabled(true);                  updateVolumeInfo(int volume) {
899                          int id = sc.getMidiInstrumentMapId();                          if(CC.getViewConfig().isMeasurementUnitDecibel()) {
900                          Object o;                                  String s = numberFormat.format(HF.percentsToDecibels(volume));
901                          if(id == -2) o = defaultMap;                                  btnVolume.setText(s + "dB");
902                          else if(id == -1) o = noMap;                          } else {
903                          else o = CC.getSamplerModel().getMidiInstrumentMapById(id);                                  btnVolume.setText(String.valueOf(volume) + "%");
                           
                         if(cbInstrumentMap.getSelectedItem() != o) {  
                                 cbInstrumentMap.setSelectedItem(o);  
904                          }                          }
                 } else {  
                         cbInstrumentMap.setSelectedItem(noMap);  
                         cbInstrumentMap.setEnabled(false);  
905                  }                  }
                   
                 setUpdate(false);  
906          }          }
907                    
908          /**          public static class PowerButton extends PixmapToggleButton implements ActionListener {
909           * Updates the MIDI device list.                  private final Channel channel;
          */  
         private void  
         updateMidiDevices() {  
                 SamplerModel sm = CC.getSamplerModel();  
                 SamplerChannel sc = channel.getModel().getChannelInfo();  
                   
                 setUpdate(true);  
                   
                 try {  
                         cbMidiDevice.removeAllItems();  
                   
                         for(MidiDeviceModel m : sm.getMidiDevices())  
                                 cbMidiDevice.addItem(m.getDeviceInfo());  
910                                    
911                          MidiDeviceModel mm = sm.getMidiDeviceById(sc.getMidiInputDevice());                  PowerButton(Channel channel) {
912                          cbMidiDevice.setSelectedItem(mm == null ? null : mm.getDeviceInfo());                          this(channel, Res.gfxPowerOff, Res.gfxPowerOn);
                 } catch(Exception x) {  
                         CC.getLogger().log(Level.WARNING, "Unkown error", x);  
913                  }                  }
                   
                 setUpdate(false);  
         }  
           
           
         private void  
         updateInstrumentMap() {  
                 updateCbInstrumentMapToolTipText();  
914                                    
915                  int id = channel.getModel().getChannelInfo().getMidiInstrumentMapId();                  PowerButton(Channel channel, ImageIcon defaultIcon, ImageIcon selectedIcon) {
916                  Object o = cbInstrumentMap.getSelectedItem();                          super(defaultIcon, selectedIcon);
917                  if(o == null && id == -1) return;                          
918                                            this.channel = channel;
                 int cbId;  
                 if(o == null || o == noMap) cbId = -1;  
                 else if(o == defaultMap) cbId = -2;  
                 else cbId = ((MidiInstrumentMap)o).getMapId();  
                   
                 if(cbId == id) return;  
                   
                 channel.getModel().setBackendMidiInstrumentMap(cbId);  
         }  
           
         private void  
         updateCbInstrumentMapToolTipText() {  
                 if(cbInstrumentMap.getSelectedItem() != defaultMap) {  
                         cbInstrumentMap.setToolTipText(null);  
                         return;  
                 }  
919                                    
920                  MidiInstrumentMap m = CC.getSamplerModel().getDefaultMidiInstrumentMap();                          setSelected(true);
921                  if(m != null) {                          addActionListener(this);
922                          String s = i18n.getLabel("Channel.ttDefault", m.getName());                          setToolTipText(i18n.getButtonLabel("Channel.ttRemoveChannel"));
                         cbInstrumentMap.setToolTipText(s);  
                 } else {  
                         cbInstrumentMap.setToolTipText(null);  
923                  }                  }
         }  
           
         /**  
          * Updates the audio device list.  
          */  
         private void  
         updateAudioDevices() {  
                 SamplerModel sm = CC.getSamplerModel();  
                 SamplerChannel sc = channel.getModel().getChannelInfo();  
                   
                 setUpdate(true);  
924                                    
925                  try {                  public void
926                          cbAudioDevice.removeAllItems();                  actionPerformed(ActionEvent e) {
927                                            boolean b = preferences().getBoolProperty(CONFIRM_CHANNEL_REMOVAL);
928                          for(AudioDeviceModel m : sm.getAudioDevices())                          if(b) {
929                                  cbAudioDevice.addItem(m.getDeviceInfo());                                  String s = i18n.getMessage("Channel.remove?", channel.getChannelId());
930                                                    if(!HF.showYesNoDialog(channel, s)) {
931                          AudioDeviceModel am = sm.getAudioDeviceById(sc.getAudioOutputDevice());                                          setSelected(true);
932                          cbAudioDevice.setSelectedItem(am == null ? null : am.getDeviceInfo());                                          return;
933                  } catch(Exception x) {                                  }
934                          CC.getLogger().log(Level.WARNING, "Unkown error", x);                          }
935                            channel.remove();
936                  }                  }
937                                    
938                  setUpdate(false);                  public boolean
939                    contains(int x, int y) { return (x - 11)*(x - 11) + (y - 11)*(y - 11) < 71; }
940          }          }
941                    
942          private void          public static class OptionsButton extends PixmapToggleButton implements ActionListener {
943          setMidiDevice() {                  private final Channel channel;
                 MidiInputDevice mid = (MidiInputDevice)cbMidiDevice.getSelectedItem();  
944                                    
945                  if(!isUpdate()) {                  OptionsButton(Channel channel) {
946                          if(mid != null) {                          super(Res.gfxOptionsOff, Res.gfxOptionsOn);
                                 channel.getModel().setBackendMidiInputDevice(mid.getDeviceId());  
                         }  
947                                                    
948                          return;                          this.channel = channel;
949                            
950                            setRolloverIcon(Res.gfxOptionsOffRO);
951                            this.setRolloverSelectedIcon(Res.gfxOptionsOnRO);
952                            addActionListener(this);
953                            setToolTipText(i18n.getButtonLabel("Channel.ttShowOptions"));
954                  }                  }
955                                    
956                  if(midiDevice != null) midiDevice.removeMidiDeviceListener(getHandler());                  public void
957                                    actionPerformed(ActionEvent e) {
958                  cbMidiPort.removeAllItems();                          channel.showOptionsPane(isSelected());
                   
                 if(mid == null) {  
                         midiDevice = null;  
                         cbMidiPort.setEnabled(false);  
                           
                         cbMidiChannel.setSelectedItem(null);  
                         cbMidiChannel.setEnabled(false);  
                 } else {  
                         midiDevice = CC.getSamplerModel().getMidiDeviceById(mid.getDeviceId());  
                         if(midiDevice != null) midiDevice.addMidiDeviceListener(getHandler());  
                           
                         cbMidiPort.setEnabled(true);  
                           
                         MidiPort[] ports = mid.getMidiPorts();  
                         for(MidiPort port : ports) cbMidiPort.addItem(port);  
959                                                    
960                          int p = channel.getModel().getChannelInfo().getMidiInputPort();                          String s;
961                          cbMidiPort.setSelectedItem(p >= 0 && p < ports.length ? ports[p] : null);                          if(isSelected()) s = i18n.getButtonLabel("Channel.ttHideOptions");
962                            else s = i18n.getButtonLabel("Channel.ttShowOptions");
963                                                    
964                          cbMidiChannel.setEnabled(true);                          setToolTipText(s);
                         int c = channel.getModel().getChannelInfo().getMidiInputChannel();  
                         cbMidiChannel.setSelectedItem(c == -1 ? "All" : "Channel " + (c + 1));  
965                  }                  }
         }  
           
         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();  
966                                    
967                  int c = s.equals("All") ? -1 : Integer.parseInt(s.substring(8)) - 1;                  public boolean
968                                    contains(int x, int y) { return super.contains(x, y) & y < 13; }
                 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; }  
           
         protected void  
         onDestroy() {  
                 SamplerModel sm = CC.getSamplerModel();  
                   
                 sm.removeMidiDeviceListListener(getHandler());  
                 sm.removeAudioDeviceListListener(getHandler());  
                 sm.removeMidiInstrumentMapListListener(mapListListener);  
                 sm.removeSamplerListener(samplerListener);  
                   
                 if(midiDevice != null) {  
                         midiDevice.removeMidiDeviceListener(getHandler());  
                 }  
969          }          }
970            }
971          private final Handler handler = new Handler();  
972            class ChannelOptionsPane extends JXCollapsiblePane {
973          private Handler          ChannelOptionsPane() {
974          getHandler() { return handler; }                  setAnimated(false);
975                            setCollapsed(true);
976          private class Handler implements MidiDeviceListListener, ListListener<AudioDeviceModel>,                  setAnimated(preferences().getBoolProperty(ANIMATED));
                                         MidiDeviceListener {  
                 /**  
                  * Invoked when a new MIDI device is created.  
                  * @param e A <code>MidiDeviceListEvent</code>  
                  * instance providing the event information.  
                  */  
                 public void  
                 deviceAdded(MidiDeviceListEvent e) {  
                         cbMidiDevice.addItem(e.getMidiDeviceModel().getDeviceInfo());  
                 }  
           
                 /**  
                  * Invoked when a MIDI device is removed.  
                  * @param e A <code>MidiDeviceListEvent</code>  
                  * instance providing the event information.  
                  */  
                 public void  
                 deviceRemoved(MidiDeviceListEvent e) {  
                         cbMidiDevice.removeItem(e.getMidiDeviceModel().getDeviceInfo());  
                 }  
                   
                 /**  
                  * Invoked when a new audio device is created.  
                  * @param e An <code>AudioDeviceListEvent</code>  
                  * instance providing the event information.  
                  */  
                 public void  
                 entryAdded(ListEvent<AudioDeviceModel> e) {  
                         cbAudioDevice.addItem(e.getEntry().getDeviceInfo());  
                 }  
           
                 /**  
                  * Invoked when an audio device is removed.  
                  * @param e An <code>AudioDeviceListEvent</code>  
                  * instance providing the event information.  
                  */  
                 public void  
                 entryRemoved(ListEvent<AudioDeviceModel> e) {  
                         cbAudioDevice.removeItem(e.getEntry().getDeviceInfo());  
                 }  
977                                    
978                  public void                  preferences().addPropertyChangeListener(ANIMATED, new PropertyChangeListener() {
979                  settingsChanged(MidiDeviceEvent e) {                          public void
980                          if(isUpdate()) {                          propertyChange(PropertyChangeEvent e) {
981                                  CC.getLogger().warning("Invalid update state");                                  setAnimated(preferences().getBoolProperty(ANIMATED));
                                 return;  
982                          }                          }
983                                            });
                         setUpdate(true);  
                         int idx = cbMidiPort.getSelectedIndex();  
                         MidiInputDevice d = e.getMidiDeviceModel().getDeviceInfo();  
                           
                         cbMidiPort.removeAllItems();  
                         for(MidiPort port : d.getMidiPorts()) cbMidiPort.addItem(port);  
                           
                         if(idx >= cbMidiPort.getModel().getSize()) idx = 0;  
                           
                         setUpdate(false);  
                           
                         if(cbMidiPort.getModel().getSize() > 0) cbMidiPort.setSelectedIndex(idx);  
                 }  
984          }          }
985                    
986          private class MapListListener implements ListListener<MidiInstrumentMap> {          public void
987                  /** Invoked when a new MIDI instrument map is added to a list. */          showOptionsPane(boolean show) { setCollapsed(!show); }
                 public void  
                 entryAdded(ListEvent<MidiInstrumentMap> e) {  
                         cbInstrumentMap.insertItemAt(e.getEntry(), cbInstrumentMap.getItemCount());  
                         boolean b = channel.getModel().getChannelInfo().getEngine() != null;  
                         if(b && !cbInstrumentMap.isEnabled()) cbInstrumentMap.setEnabled(true);  
                 }  
           
                 /** Invoked when a new MIDI instrument map is removed from a list. */  
                 public void  
                 entryRemoved(ListEvent<MidiInstrumentMap> e) {  
                         cbInstrumentMap.removeItem(e.getEntry());  
                         if(cbInstrumentMap.getItemCount() == 0) { // TODO: ?  
                                 cbInstrumentMap.setSelectedItem(noMap);  
                                 cbInstrumentMap.setEnabled(false);  
                         }  
                 }  
         }  
988  }  }

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

  ViewVC Help
Powered by ViewVC