/[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 912 by iliev, Mon Aug 7 18:34:40 2006 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, 2006 Grigor Kirilov Iliev   *   Copyright (C) 2005-2008 Grigor Iliev <grigor@grigoriliev.com>
5   *   *
6   *   This file is part of JSampler.   *   This file is part of JSampler.
7   *   *
# Line 22  Line 22 
22    
23  package org.jsampler.view.fantasia;  package org.jsampler.view.fantasia;
24    
25  import java.awt.Cursor;  import java.awt.Container;
26  import java.awt.Dimension;  import java.awt.Dimension;
27  import java.awt.Insets;  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;
31  import java.awt.event.MouseAdapter;  import java.awt.event.MouseAdapter;
32  import java.awt.event.MouseEvent;  import java.awt.event.MouseEvent;
33    
34  import java.util.logging.Level;  import java.beans.PropertyChangeEvent;
35    import java.beans.PropertyChangeListener;
36    
37  import javax.swing.BorderFactory;  import java.text.NumberFormat;
38  import javax.swing.Box;  
39    import javax.swing.AbstractAction;
40    import javax.swing.Action;
41  import javax.swing.BoxLayout;  import javax.swing.BoxLayout;
42    import javax.swing.ButtonGroup;
43  import javax.swing.DefaultListCellRenderer;  import javax.swing.DefaultListCellRenderer;
44    import javax.swing.ImageIcon;
45  import javax.swing.JButton;  import javax.swing.JButton;
46  import javax.swing.JComboBox;  import javax.swing.JComponent;
47  import javax.swing.JLabel;  import javax.swing.JLabel;
48    import javax.swing.JMenuItem;
49  import javax.swing.JPanel;  import javax.swing.JPanel;
50    import javax.swing.JPopupMenu;
51    import javax.swing.JRadioButtonMenuItem;
52    import javax.swing.JScrollPane;
53  import javax.swing.JToggleButton;  import javax.swing.JToggleButton;
54  import javax.swing.SwingConstants;  import javax.swing.JToolBar;
   
 import javax.swing.event.ChangeEvent;  
 import javax.swing.event.ChangeListener;  
55    
56  import net.sf.juife.Dial;  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.jsampler.AudioDeviceModel;  import org.jdesktop.swingx.JXCollapsiblePane;
60    
61  import org.jsampler.CC;  import org.jsampler.CC;
62  import org.jsampler.MidiDeviceModel;  import org.jsampler.HF;
63  import org.jsampler.SamplerChannelModel;  import org.jsampler.SamplerChannelModel;
 import org.jsampler.SamplerModel;  
64    
 import org.jsampler.event.AudioDeviceListEvent;  
 import org.jsampler.event.AudioDeviceListListener;  
 import org.jsampler.event.MidiDeviceListEvent;  
 import org.jsampler.event.MidiDeviceListListener;  
 import org.jsampler.event.SamplerChannelAdapter;  
65  import org.jsampler.event.SamplerChannelEvent;  import org.jsampler.event.SamplerChannelEvent;
66    import org.jsampler.event.SamplerChannelListEvent;
67    import org.jsampler.event.SamplerChannelListListener;
68  import org.jsampler.event.SamplerChannelListener;  import org.jsampler.event.SamplerChannelListener;
69    
70  import org.jsampler.task.RemoveChannel;  import org.jsampler.view.JSChannel;
71    
72    import org.jsampler.view.std.JSChannelOutputRoutingDlg;
73    import org.jsampler.view.std.JSFxSendsPane;
74    import org.jsampler.view.std.JSInstrumentChooser;
75    import org.jsampler.view.std.JSVolumeEditorPopup;
76    
 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.*;
81    import static org.jsampler.view.fantasia.FantasiaUtils.*;
82    import static org.jsampler.view.std.JSVolumeEditorPopup.VolumeType;
83    
84    
85  /**  /**
86   *   *
87   * @author Grigor Iliev   * @author Grigor Iliev
88   */   */
89  public class Channel extends org.jsampler.view.JSChannel {  public class Channel extends JSChannel {
90          private final ChannelScreen screen = new ChannelScreen(this);          private final JXCollapsiblePane mainPane;
91          private final ChannelOptions optionsPane = new ChannelOptions(this);          private ChannelOptionsView channelOptionsView;
92                    private final ChannelOptionsPane optionsPane = new ChannelOptionsPane();
         private final PowerButton btnPower = new PowerButton();  
         private final MuteButton btnMute = new MuteButton();  
         private final SoloButton btnSolo = new SoloButton();  
         private final OptionsButton btnOptions = new OptionsButton();  
93                    
94          private final EnhancedDial dialVolume = new EnhancedDial();          private final ViewTracker viewTracker;
95            
96            private InformationDialog fxSendsDlg = null;
97            
98            private final ContextMenu contextMenu = new ContextMenu();
99                    
100          private boolean selected = false;          private boolean selected = false;
101                    
102            private AnimatedPorpetyListener animatedPorpetyListener = new AnimatedPorpetyListener();
103            
104            class AnimatedPorpetyListener implements PropertyChangeListener {
105                    public void
106                    propertyChange(PropertyChangeEvent e) {
107                            mainPane.setAnimated(preferences().getBoolProperty(ANIMATED));
108                    }
109            }
110            
111          /**          /**
112           * Creates a new instance of <code>Channel</code> using the specified           * Creates a new instance of <code>Channel</code> using the specified
113           * non-<code>null</code> channel model.           * non-<code>null</code> channel model.
# Line 101  public class Channel extends org.jsample Line 116  public class Channel extends org.jsample
116           */           */
117          public          public
118          Channel(SamplerChannelModel model) {          Channel(SamplerChannelModel model) {
119                    this(model, null);
120            }
121            
122            /**
123             * Creates a new instance of <code>Channel</code> using the specified
124             * non-<code>null</code> channel model.
125             * @param model The model to be used by this channel.
126             * @param listener A listener which is notified when the newly created
127             * channel is fully expanded on the screen.
128             * @throws IllegalArgumentException If the model is <code>null</code>.
129             */
130            public
131            Channel(SamplerChannelModel model, final ActionListener listener) {
132                  super(model);                  super(model);
133                                    
134                  setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));                  setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
                 JPanel p = new JPanel();  
                 p.setName("Channel");  
                 p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));  
                   
                 //p.add(Box.createRigidArea(new Dimension(3, 0)));  
                   
                 btnPower.setAlignmentY(JPanel.TOP_ALIGNMENT);  
                   
                 TitleBar tb = new TitleBar();  
                 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.iconMuteTitle));  
                 p2.add(btnMute);  
                 p2.add(new JLabel(Res.iconSoloTitle));  
                 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.iconVolumeTitle);  
                 l.setAlignmentX(JPanel.CENTER_ALIGNMENT);  
                 l.setBorder(BorderFactory.createEmptyBorder(0, 0, 2, 0));  
                 p2.add(l);  
                 dialVolume.setDialPixmap(Res.iconVolumeDial, 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.iconOptionsTitle);  
                 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);
                 add(p);  
                 add(optionsPane);  
136                                    
137                  setOpaque(true);                  mainPane = new JXCollapsiblePane();
138                    viewTracker = new ViewTracker();
139                    
140                    mainPane.getContentPane().setLayout (
141                            new BoxLayout(mainPane.getContentPane(), BoxLayout.Y_AXIS)
142                    );
143                    
144                    int viewIdx = preferences().getIntProperty(DEFAULT_CHANNEL_VIEW);
145                    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);
154                                    
155                  getModel().addSamplerChannelListener(getHandler());                  getModel().addSamplerChannelListener(getHandler());
156                                    
157                  updateChannelInfo();                  updateChannelInfo();
158                    
159                    add(mainPane);
160                    
161                    if(listener != null) {
162                            final String s = JXCollapsiblePane.ANIMATION_STATE_KEY;
163                            mainPane.addPropertyChangeListener(s, new PropertyChangeListener() {
164                                    public void
165                                    propertyChange(PropertyChangeEvent e) {
166                                            if(e.getNewValue() == "expanded") {
167                                                    // TODO: this should be done regardles the listener != null?
168                                                    mainPane.removePropertyChangeListener(s, this);
169                                                    ///////
170                                                    listener.actionPerformed(null);
171                                                    ensureChannelIsVisible();
172                                            } else if(e.getNewValue() == "expanding/collapsing") {
173                                                    ensureChannelIsVisible();
174                                            }
175                                    }
176                            });
177                    }
178                    
179                    mainPane.setAnimated(false);
180                    mainPane.setCollapsed(true);
181                    mainPane.setAnimated(preferences().getBoolProperty(ANIMATED));
182                    mainPane.setCollapsed(false);
183                    
184                    preferences().addPropertyChangeListener(ANIMATED, animatedPorpetyListener);
185                    
186                    if(listener != null) {
187                            javax.swing.SwingUtilities.invokeLater(new Runnable() {
188                                    public void
189                                    run() { listener.actionPerformed(null); }
190                            });
191                    }
192                    
193                    CC.getSamplerModel().addSamplerChannelListListener(getHandler());
194          }          }
195                    
196          private JPanel          private void
197          createVSeparator() {          ensureChannelIsVisible() {
198                  JPanel p = new JPanel();                  Container p = getParent();
199                  p.setName("VSeparator");                  JScrollPane sp = null;
200                  p.setOpaque(false);                  while(p != null) {
201                  p.setAlignmentY(JPanel.TOP_ALIGNMENT);                          if(p instanceof JScrollPane) {
202                  p.setPreferredSize(new Dimension(2, 60));                                  sp = (JScrollPane)p;
203                  p.setMinimumSize(p.getPreferredSize());                                  break;
204                  p.setMaximumSize(p.getPreferredSize());                          }
205                  return p;                          p = p.getParent();
206                    }
207                    if(sp == null) return;
208                    int h = sp.getViewport().getView().getHeight();
209                    sp.getViewport().scrollRectToVisible(new Rectangle(0, h - 2, 1, 1));
210          }          }
211                    
212          /**          /**
# Line 235  public class Channel extends org.jsample Line 229  public class Channel extends org.jsample
229                    
230          /** Shows the channel properties. */          /** Shows the channel properties. */
231          public void          public void
232          expandChannel() { if(!btnOptions.isSelected()) btnOptions.doClick(); }          expandChannel() { expandChannel(optionsPane.isAnimated()); }
233                    
234                    /** Shows the channel properties. */
235          /** Invoked when the user changes the volume */          public void
236          private void          expandChannel(boolean animated) {
237          setVolume() {                  boolean b = optionsPane.isAnimated();
238                  screen.updateVolumeInfo(dialVolume.getValue());                  optionsPane.setAnimated(animated);
239                                    viewTracker.getCurrentView().expandChannel();
240                  if(dialVolume.getValueIsAdjusting()) return;                  optionsPane.setAnimated(b);
                   
                 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().setVolume(volume);  
241          }          }
242                    
243          /**          /**
# Line 266  public class Channel extends org.jsample Line 246  public class Channel extends org.jsample
246           */           */
247          private void          private void
248          updateChannelInfo() {          updateChannelInfo() {
249                  SamplerChannel sc = getChannelInfo();                  viewTracker.getCurrentView().updateChannelInfo();
250                    viewTracker.getCurrentView().getChannelOptionsView().updateChannelInfo();
251            }
252            
253            public void
254            loadInstrument() {
255                    JSInstrumentChooser dlg = FantasiaUtils.createInstrumentChooser(CC.getMainFrame());
256                    dlg.setVisible(true);
257                                    
258                  screen.updateScreenInfo(sc);                  if(!dlg.isCancelled()) {
259                  updateMuteIcon(sc);                          SamplerChannelModel m = getModel();
260                            m.loadBackendInstrument(dlg.getInstrumentFile(), dlg.getInstrumentIndex());
261                    }
262            }
263            
264            public void
265            fallbackToOriginalView() {
266                    viewTracker.fallbackToOriginalView();
267            }
268            
269            public boolean
270            isUsingOriginalView() {
271                    return viewTracker.isUsingOriginalView();
272            }
273            
274            protected void
275            onDestroy() {
276                    CC.getSamplerModel().removeSamplerChannelListListener(getHandler());
277                    preferences().removePropertyChangeListener(ANIMATED, animatedPorpetyListener);
278                                    
279                  if(sc.isSoloChannel()) btnSolo.setIcon(Res.iconSoloOn);                  viewTracker.onDestroy();
280                  else btnSolo.setIcon(Res.iconSoloOff);          }
281                                    
282                  dialVolume.setValue((int)(sc.getVolume() * 100));          public void
283            remove() {
284                    if(!mainPane.isAnimated()) {
285                            CC.getSamplerModel().removeBackendChannel(getChannelId());
286                            return;
287                    }
288                                    
289                  boolean b = sc.getEngine() != null;                  String s = JXCollapsiblePane.ANIMATION_STATE_KEY;
290                  dialVolume.setEnabled(b);                  mainPane.addPropertyChangeListener(s, getHandler());
291                  btnSolo.setEnabled(b);                  mainPane.setCollapsed(true);
                 btnMute.setEnabled(b);  
292          }          }
293                    
294          /**          public void
295           * Updates the mute button with the proper icon regarding to information obtained          showOptionsPane(boolean show) { optionsPane.showOptionsPane(show); }
          * from <code>channel</code>.  
          * @param channel A <code>SamplerChannel</code> instance containing the new settings  
          * for this channel.  
          */  
         private void  
         updateMuteIcon(SamplerChannel channel) {  
                 if(channel.isMutedBySolo()) btnMute.setIcon(Res.iconMutedBySolo);  
                 else if(channel.isMuted()) btnMute.setIcon(Res.iconMuteOn);  
                 else btnMute.setIcon(Res.iconMuteOff);  
         }  
296                    
297          private class EnhancedDial extends Dial {          public void
298                  EnhancedDial() {          showFxSendsDialog() {
299                          super(0, 100);                  if(fxSendsDlg != null && fxSendsDlg.isVisible()) {
300                                                    fxSendsDlg.toFront();
301                          setMouseHandlerMode(MouseHandlerMode.LEFT_TO_RIGHT_AND_DOWN_TO_UP);                          return;
                           
                         addMouseListener(new MouseAdapter() {  
                                 public void  
                                 mouseClicked(MouseEvent e) {  
                                         if(e.getButton() == e.BUTTON3) {  
                                                 setValue(getMaximum() / 2);  
                                                 return;  
                                         }  
                                           
                                         if(e.getButton() != e.BUTTON1) return;  
                                           
                                         if(e.getClickCount() < 2) return;  
                                         setValue(getValueByPoint(e.getPoint()));  
                                 }  
                         });  
                           
                         addChangeListener(new ChangeListener() {  
                                 public void  
                                 stateChanged(ChangeEvent e) { setVolume(); }  
                         });  
302                  }                  }
303                    FxSendsPane p = new FxSendsPane(getModel());
304                    int id = getModel().getChannelId();
305                    fxSendsDlg = new InformationDialog(CC.getMainFrame(), p);
306                    fxSendsDlg.setTitle(i18n.getLabel("FxSendsDlg.title", id));
307                    fxSendsDlg.setModal(false);
308                    fxSendsDlg.showCloseButton(false);
309                    fxSendsDlg.setVisible(true);
310          }          }
311                    
312          private final EventHandler eventHandler = new EventHandler();          private final EventHandler eventHandler = new EventHandler();
# Line 328  public class Channel extends org.jsample Line 314  public class Channel extends org.jsample
314          private EventHandler          private EventHandler
315          getHandler() { return eventHandler; }          getHandler() { return eventHandler; }
316                    
317          private class EventHandler implements SamplerChannelListener {          private class EventHandler implements SamplerChannelListener,
318                                            SamplerChannelListListener, PropertyChangeListener {
319                  /**                  /**
320                   * Invoked when changes are made to a sampler channel.                   * Invoked when changes are made to a sampler channel.
321                   * @param e A <code>SamplerChannelEvent</code> instance                   * @param e A <code>SamplerChannelEvent</code> instance
# Line 344  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 354  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                  }                  }
         }  
           
           
         private class PowerButton extends PixmapToggleButton implements ActionListener {  
                 PowerButton() {  
                         super(Res.iconPowerOff, Res.iconPowerOn);  
346                                    
347                          setSelected(true);                  /**
348                          addActionListener(this);                   * Invoked when a new sampler channel is created.
349                     * @param e A <code>SamplerChannelListEvent</code>
350                     * instance providing the event information.
351                     */
352                    public void
353                    channelAdded(SamplerChannelListEvent e) { }
354            
355                    /**
356                     * Invoked when a sampler channel is removed.
357                     * @param e A <code>SamplerChannelListEvent</code>
358                     * instance providing the event information.
359                     */
360                    public void
361                    channelRemoved(SamplerChannelListEvent e) {
362                            // Some cleanup when the channel is removed.
363                            if(e.getChannelModel().getChannelId() == getChannelId()) {
364                                    onDestroy();
365                            }
366                  }                  }
367                                    
368                  public void                  public void
369                  actionPerformed(ActionEvent e) {                  propertyChange(PropertyChangeEvent e) {
370                          CC.getTaskQueue().add(new RemoveChannel(getChannelID()));                          if(e.getNewValue() == "collapsed") {
371                                    CC.getSamplerModel().removeBackendChannel(getChannelId());
372                            }
373                  }                  }
                   
                 public boolean  
                 contains(int x, int y) { return (x - 11)*(x - 11) + (y - 11)*(y - 11) < 71; }  
374          }          }
375                    
376          private class MuteButton extends PixmapButton implements ActionListener {          private static boolean viewTrackerMousePressed = false;
377                  MuteButton() {          
378                          super(Res.iconMuteOff);          class ViewTracker extends MouseAdapter implements PropertyChangeListener {
379                          addActionListener(this);                  private ChannelView originalView;
380                  }                  private ChannelView mouseOverView;
381                    private ChannelView currentView;
382                                    
                 public void  
                 actionPerformed(ActionEvent e) {  
                         SamplerChannel sc = getChannelInfo();  
                         boolean b = true;  
383                                    
384                          /*                  private boolean mouseOver = false;
385                           * Changing the mute button icon now instead of                  
386                           * leaving the work to the notification mechanism of the LinuxSampler.                  private final ActionListener guiListener;
387                           */                  
388                          if(sc.isMuted() && !sc.isMutedBySolo()) {                  ViewTracker() {
389                                  b = false;                          guiListener = new ActionListener() {
390                                  boolean hasSolo = CC.getSamplerModel().hasSoloChannel();                                  public void
391                                                            actionPerformed(ActionEvent e) {
392                                  if(sc.isSoloChannel() || !hasSolo) setIcon(Res.iconMuteOff);                                          if(viewTrackerMousePressed) return;
393                                  else setIcon(Res.iconMutedBySolo);                                          
394                          } else setIcon(Res.iconMuteOn);                                          if(mainPane.getMousePosition(true) != null) {
395                                                    mouseEntered(null);
396                                            } else {
397                                                    mouseExited(null);
398                                            }
399                                    }
400                            };
401                            
402                            updateMouseOverViewType();
403                                                    
404                          Channel.this.getModel().setMute(b);                          String s = DIFFERENT_CHANNEL_VIEW_ON_MOUSE_OVER;
405                            preferences().addPropertyChangeListener(s, this);
406                            
407                            s = CHANNEL_VIEW_ON_MOUSE_OVER;
408                            preferences().addPropertyChangeListener(s, this);
409                  }                  }
410                                    
411                  public boolean                  public boolean
412                  contains(int x, int y) { return (x > 5 && x < 23) && (y > 5 && y < 16); }                  isUsingOriginalView() {
413          }                          return currentView == originalView;
           
         private class SoloButton extends PixmapButton implements ActionListener {  
                 SoloButton() {  
                         super(Res.iconSoloOff);  
                         addActionListener(this);  
414                  }                  }
415                                    
416                  public void                  private void
417                  actionPerformed(ActionEvent e) {                  installListeners() {
418                          SamplerChannel sc = getChannelInfo();                          ((MainFrame)CC.getMainFrame()).getGuiTimer().addActionListener(guiListener);
419                          boolean b = !sc.isSoloChannel();                  }
420                                    
421                          /*                  private void
422                           * Changing the solo button icon (and related) now instead of                  uninstallListeners() {
423                           * leaving the work to the notification mechanism of the LinuxSampler.                          ((MainFrame)CC.getMainFrame()).getGuiTimer().removeActionListener(guiListener);
424                           */                  }
                         if(b) {  
                                 setIcon(Res.iconSoloOn);  
                                 if(sc.isMutedBySolo()) btnMute.setIcon(Res.iconMuteOff);  
                         } else {  
                                 setIcon(Res.iconSoloOff);  
                                 if(!sc.isMuted() && CC.getSamplerModel().getSoloChannelCount() > 1)  
                                         btnMute.setIcon(Res.iconMutedBySolo);  
                         }  
425                                    
426                          Channel.this.getModel().setSolo(b);                  private void
427                    updateMouseOverViewType() {
428                            if(mouseOverView != null) {
429                                    mouseOverView.removeEnhancedMouseListener(this);
430                            }
431                            
432                            boolean b;
433                            b = preferences().getBoolProperty(DIFFERENT_CHANNEL_VIEW_ON_MOUSE_OVER);
434                            if(!b) {
435                                    mouseOverView = null;
436                                    uninstallListeners();
437                                    return;
438                            }
439                            
440                            Channel channel = Channel.this;
441                            int i = preferences().getIntProperty(CHANNEL_VIEW_ON_MOUSE_OVER);
442                            
443                            switch(i) {
444                                    case 0: mouseOverView = new SmallChannelView(channel); break;
445                                    case 1: mouseOverView = new NormalChannelView(channel); break;
446                                    default:mouseOverView = null;
447                            }
448                            
449                            if(mouseOverView != null) {
450                                    installListeners();
451                                    mouseOverView.addEnhancedMouseListener(this);
452                            }
453                  }                  }
454                                    
455                  public boolean                  public ChannelView
456                  contains(int x, int y) { return (x > 5 && x < 23) && (y > 5 && y < 16); }                  getCurrentView() { return currentView; }
457          }                  
458                            public void
459          private class OptionsButton extends PixmapToggleButton implements ActionListener {                  setView(ChannelView view) {
460                  OptionsButton() {                          setView(view, true);
                         super(Res.iconOptionsOff, Res.iconOptionsOn);  
                         addActionListener(this);  
461                  }                  }
462                                    
463                  public void                  public void
464                  actionPerformed(ActionEvent e) {                  setView(ChannelView view, boolean manual) {
465                          showOptionsPane(isSelected());                          boolean selected = false;
466                            if(currentView != null) selected = currentView.isOptionsButtonSelected();
467                                                    
468                          String s;                          if(manual) {
469                          if(isSelected()) s = i18n.getButtonLabel("OptionsButton.ttHideOptions");                                  if(originalView != null) {
470                          else s = i18n.getButtonLabel("OptionsButton.ttShowOptions");                                          originalView.removeEnhancedMouseListener(this);
471                                    }
472                                    
473                                    if(originalView != currentView) destroyOriginalView();
474                                    if(currentView != null && currentView.getType() == view.getType()) {
475                                            originalView = currentView;
476                                            originalView.addEnhancedMouseListener(this);
477                                            destroyView(view);
478                                            return;
479                                    }
480                                    
481                                    removeCurrentView();
482                                    
483                                    originalView = view;
484                                    originalView.addEnhancedMouseListener(this);
485                                    currentView = view;
486                            } else {
487                                    if(view.getType() == getCurrentView().getType()) {
488                                            destroyView(view);
489                                            return;
490                                    }
491                                    
492                                    removeCurrentView();
493                                    currentView = view;
494                            }
495                                                    
496                          setToolTipText(s);                          currentView.setOptionsButtonSelected(selected);
497                            
498                            updateView();
499                  }                  }
500                                    
501                  private void                  private void
502                  showOptionsPane(boolean show) {                  updateView() {
503                          optionsPane.setVisible(show);                          JComponent c = getCurrentView().getChannelOptionsView().getComponent();
504                          MainFrame.repack(CC.getMainFrame());                          optionsPane.setContentPane(c);
505                            
506                            updateChannelInfo();
507                    
508                            mainPane.add(getCurrentView().getComponent());
509                            mainPane.add(optionsPane);
510                            mainPane.validate();
511                            mainPane.revalidate();
512                            mainPane.repaint();
513                  }                  }
514                                    
515                  public boolean                  public void
516                  contains(int x, int y) { return y < 13; }                  fallbackToOriginalView() {
517          }                          if(currentView == originalView) return;
518  }                          
519                            boolean selected = false;
520  class ChannelScreen extends JPanel {                          if(currentView != null) selected = currentView.isOptionsButtonSelected();
521          private final Channel channel;                          
522          private JButton btnInstr = new ScreenButton(i18n.getButtonLabel("ChannelScreen.btnInstr"));                          removeCurrentView();
523          private JButton btnReset = new ScreenButton(i18n.getButtonLabel("ChannelScreen.btnReset"));                          currentView = originalView;
524          private JButton btnDuplicate =                          currentView.setOptionsButtonSelected(selected);
525                  new ScreenButton(i18n.getButtonLabel("ChannelScreen.btnDuplicate"));                          
526                                    updateView();
527          private final JLabel lVolume = new JLabel();                  }
         private final JLabel lStreams = new JLabel("--");  
         private final JLabel lVoices = new JLabel("--");  
           
         ChannelScreen(Channel channel) {  
                 this.channel = channel;  
528                                    
529                  setName("ChannelScreen");                  private void
530                  setOpaque(true);                  removeCurrentView() { removeView(currentView); }
531                                    
532                  setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));                  private void
533                    destroyCurrentView() { destroyView(currentView); }
534                                    
535                  btnInstr.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0));                  private void
536                  btnInstr.setAlignmentX(CENTER_ALIGNMENT);                  removeOriginalView() { removeView(originalView); }
537                                    
538                  add(btnInstr);                  private void
539                    destroyOriginalView() { destroyView(originalView); }
540                                    
541                  JPanel p = new JPanel();                  private void
542                  p.setOpaque(false);                  removeView(ChannelView view) {
543                  p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));                          if(view == null) return;
544                  p.setAlignmentX(CENTER_ALIGNMENT);                          
545                  p.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0));                          mainPane.remove(view.getComponent());
546                  //lVolume.setFont(lVolume.getFont().deriveFont(java.awt.Font.PLAIN));                          mainPane.remove(optionsPane);
547                                    
548                            destroyView(view);
549                    }
550                                    
551                  p.add(btnDuplicate);                  private void
552                    destroyView(ChannelView view) {
553                            if(view == null) return;
554                            
555                            view.uninstallView();
556                            view.getChannelOptionsView().uninstallView();
557                            
558                            view = null;
559                    }
560                                    
561                  p.add(Box.createRigidArea(new Dimension(6, 0)));                  private void
562                    mouseEntered() {
563                            if(mouseOverView == null) return;
564                            if(getCurrentView().getType() == mouseOverView.getType()) return;
565                            
566                            JSChannel[] channels = CC.getMainFrame().getChannelsPane(0).getChannels();
567                            for(JSChannel c : channels) {
568                                    if(c == Channel.this) continue;
569                                    
570                                    Channel chn = (Channel)c;
571                                    if(!(chn).isUsingOriginalView()) chn.fallbackToOriginalView();
572                            }
573                            
574                            setView(mouseOverView, false);
575                    }
576                                    
577                  p.add(new JLabel("|"));                  private void
578                    mouseExited() {
579                            if(mouseOverView == null) return;
580                            if(getCurrentView().getType() == originalView.getType()) return;
581                            
582                            fallbackToOriginalView();
583                    }
584                                    
585                  p.add(Box.createRigidArea(new Dimension(6, 0)));                  public void
586                    mouseEntered(MouseEvent e) {
587                            if(viewTrackerMousePressed) return;
588                            
589                            if(mouseOver) return;
590                            mouseOver = true;
591                            mouseEntered();
592                    }
593                                    
594                  p.add(btnReset);                  public void
595                    mouseExited(MouseEvent e) {
596                            if(viewTrackerMousePressed) return;
597                            
598                            if(mainPane.getMousePosition(true) != null) return;
599                            if(!mouseOver) return;
600                            mouseOver = false;
601                            mouseExited();
602                    }
603                                    
604                  p.add(Box.createGlue());                  public void
605                    mousePressed(MouseEvent e) {
606                            viewTrackerMousePressed = true;
607                    }
608                                    
609                  p.add(lStreams);                  public void
610                  p.add(new JLabel("/"));                  mouseReleased(MouseEvent e) {
611                  p.add(lVoices);                          viewTrackerMousePressed = false;
612                    }
613                                    
614                  p.add(Box.createRigidArea(new Dimension(12, 0)));                  public void
615                    onDestroy() {
616                            destroyCurrentView();
617                            destroyOriginalView();
618                            
619                            uninstallListeners();
620                            
621                            if(currentView != null) {
622                                    currentView.removeEnhancedMouseListener(this);
623                            }
624                            
625                            if(mouseOverView != null) {
626                                    mouseOverView.removeEnhancedMouseListener(this);
627                            }
628                            
629                            String s = DIFFERENT_CHANNEL_VIEW_ON_MOUSE_OVER;
630                            preferences().removePropertyChangeListener(s, this);
631                            
632                            s = CHANNEL_VIEW_ON_MOUSE_OVER;
633                            preferences().removePropertyChangeListener(s, this);
634                    }
635                                    
636                  lVolume.setAlignmentX(RIGHT_ALIGNMENT);                  public void
637                  p.add(lVolume);                  propertyChange(PropertyChangeEvent e) {
638                  p.setPreferredSize(new Dimension(250, p.getPreferredSize().height));                          updateMouseOverViewType();
639                  p.setMinimumSize(p.getPreferredSize());                  }
640                  p.setMaximumSize(p.getPreferredSize());          }
641            
642            class EditInstrumentAction extends AbstractAction implements SamplerChannelListener {
643                    EditInstrumentAction() {
644                            super(i18n.getMenuLabel("channels.editInstrument"));
645                            channelChanged(null);
646                            getModel().addSamplerChannelListener(this);
647                    }
648                                    
649                  add(p);                  public void
650                    actionPerformed(ActionEvent e) {
651                            CC.getSamplerModel().editBackendInstrument(getChannelId());
652                    }
653                                    
654                    public void
655                    channelChanged(SamplerChannelEvent e) {
656                            boolean b = getChannelInfo().getInstrumentStatus() == 100;
657                            setEnabled(b);
658                    }
659                                    
660                  setPreferredSize(new Dimension(270, 48));                  public void
661                  setMinimumSize(getPreferredSize());                  streamCountChanged(SamplerChannelEvent e) { }
                 setMaximumSize(getPreferredSize());  
662                                    
663                  installListeners();                  public void
664                    voiceCountChanged(SamplerChannelEvent e) { }
665          }          }
666                    
667          private void          class FxSendsAction extends AbstractAction {
668          installListeners() {                  FxSendsAction() {
669                  btnInstr.addActionListener(new ActionListener() {                          super(i18n.getMenuLabel("channels.fxSends"));
670                          public void                  }
                         actionPerformed(ActionEvent e) { loadInstrument(); }  
                 });  
           
                 btnReset.addActionListener(new ActionListener() {  
                         public void  
                         actionPerformed(ActionEvent e) { channel.getModel().resetChannel(); }  
                 });  
                   
                 btnDuplicate.addActionListener(new ActionListener() {  
                         public void  
                         actionPerformed(ActionEvent e) { channel.getModel().duplicateChannel(); }  
                 });  
         }  
   
         private void  
         loadInstrument() {  
                 InstrumentChooser dlg = new InstrumentChooser(CC.getMainFrame());  
                 dlg.setVisible(true);  
671                                    
672                  if(!dlg.isCancelled()) {                  public void
673                          SamplerChannelModel m = channel.getModel();                  actionPerformed(ActionEvent e) {
674                          m.loadInstrument(dlg.getFileName(), 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                    public void
686                    actionPerformed(ActionEvent e) {
687                            SamplerChannel c = getChannelInfo();
688                            new JSChannelOutputRoutingDlg(CC.getMainFrame(), c).setVisible(true);
689                    }
690                                    
691          }                  public void
692                            channelChanged(SamplerChannelEvent e) {
693          protected void                          boolean b = getChannelInfo().getAudioOutputDevice() != -1;
694          updateVolumeInfo(int volume) {                          setEnabled(b);
695                  lVolume.setText(i18n.getLabel("ChannelScreen.volume", volume));                  }
696                                    
697                    public void
698                    streamCountChanged(SamplerChannelEvent e) { }
699                    
700                    public void
701                    voiceCountChanged(SamplerChannelEvent e) { }
702          }          }
703                    
704          /**          class SetSmallViewAction extends AbstractAction {
705           * Updates the number of active disk streams.                  SetSmallViewAction() {
706           * @param count The new number of active disk streams.                          super(i18n.getMenuLabel("channels.smallView"));
707           */                  }
708          protected void                  
709          updateStreamCount(int count) {                  public void
710                  Dimension d = lStreams.getPreferredSize();                  actionPerformed(ActionEvent e) {
711                  lStreams.setText(count == 0 ? "--" : String.valueOf(count));                          viewTracker.setView(new SmallChannelView(Channel.this));
                 d = JuifeUtils.getUnionSize(d, lStreams.getPreferredSize());  
                 lStreams.setMinimumSize(d);  
                 lStreams.setPreferredSize(d);  
                 lStreams.setMaximumSize(d);  
         }  
           
         /**  
          * Updates the number of active voices.  
          * @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);  
         }  
           
         static class ScreenButton extends JButton {  
                 ScreenButton(String s) {  
                         super(s);  
                         setContentAreaFilled(false);  
                         setFocusPainted(false);  
                         setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));  
                         setMargin(new Insets(0, 0, 0, 0));  
                         setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));  
712                  }                  }
713          }          }
 }  
   
 class ChannelOptions extends JPanel {  
         private final Channel channel;  
714                    
715          private final JComboBox cbMidiDevice = new JComboBox();          class SetNormalViewAction extends AbstractAction {
716          private final JComboBox cbMidiPort = new JComboBox();                  SetNormalViewAction() {
717          private final JComboBox cbMidiChannel = new JComboBox();                          super(i18n.getMenuLabel("channels.normalView"));
718          private final JComboBox cbEngine = new JComboBox();                  }
         private final JComboBox cbAudioDevice = new JComboBox();  
           
         private boolean update = false;  
           
         ChannelOptions(Channel channel) {  
                 this.channel = channel;  
                   
                 setName("ChannelOptions");  
                 setVisible(false);  
                 setBorder(BorderFactory.createEmptyBorder(5, 4, 5, 4));  
                 setLayout(new BoxLayout(this, BoxLayout.X_AXIS));  
                   
                 setPreferredSize(new Dimension(420, 44));  
                 setMinimumSize(getPreferredSize());  
                 setMaximumSize(getPreferredSize());  
                   
                 JPanel p = new JPanel();  
                 p.setOpaque(true);  
                 p.setBorder(BorderFactory.createEmptyBorder(3, 4, 3, 4));  
                 p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));  
                 JLabel l = new JLabel(Res.iconMidiInputTitle);  
                 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(67, 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);  
                 p.add(p2);  
                   
                 add(p);  
                   
                 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.iconEngineTitle);  
                 l.setAlignmentX(LEFT_ALIGNMENT);  
                 l.setAlignmentX(LEFT_ALIGNMENT);  
                 p.add(l);  
                   
                 p.add(Box.createRigidArea(new Dimension(0, 3)));  
                   
                 o = cbEngine.getRenderer();  
                 if(o instanceof JLabel) ((JLabel )o).setHorizontalAlignment(SwingConstants.CENTER);  
                   
                 for(SamplerEngine e : CC.getSamplerModel().getEngines()) cbEngine.addItem(e);  
                 cbEngine.setPreferredSize(new Dimension(125, 18));  
                 cbEngine.setMinimumSize(cbEngine.getPreferredSize());  
                 cbEngine.setMaximumSize(cbEngine.getPreferredSize());  
                 cbEngine.setAlignmentX(LEFT_ALIGNMENT);  
                 p.add(cbEngine);  
                   
                 add(p);  
                   
                 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.iconAudioOutputTitle);  
                 l.setAlignmentX(LEFT_ALIGNMENT);  
                 l.setAlignmentX(LEFT_ALIGNMENT);  
                 p.add(l);  
                   
                 p.add(Box.createRigidArea(new Dimension(0, 3)));  
                   
                 o = cbAudioDevice.getRenderer();  
                 if(o instanceof JLabel) ((JLabel )o).setHorizontalAlignment(SwingConstants.RIGHT);  
                   
                 cbAudioDevice.setPreferredSize(new Dimension(61, 18));  
                 cbAudioDevice.setMinimumSize(cbAudioDevice.getPreferredSize());  
                 cbAudioDevice.setMaximumSize(cbAudioDevice.getPreferredSize());  
                 cbAudioDevice.setAlignmentX(LEFT_ALIGNMENT);  
                 p.add(cbAudioDevice);  
                   
                 add(p);  
                   
                 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(); }  
                 });  
                   
                 cbEngine.addActionListener(new ActionListener() {  
                         public void  
                         actionPerformed(ActionEvent e) { setEngineType(); }  
                 });  
                   
                 cbAudioDevice.addActionListener(new ActionListener() {  
                         public void  
                         actionPerformed(ActionEvent e) { setAudioDevice(); }  
                 });  
                   
                 channel.getModel().addSamplerChannelListener(new SamplerChannelAdapter() {  
                         public void  
                         channelChanged(SamplerChannelEvent e) { updateChannelProperties(); }  
                 });  
                   
                 CC.getSamplerModel().addMidiDeviceListListener(getHandler());  
                 CC.getSamplerModel().addAudioDeviceListListener(getHandler());  
719                                    
720                  updateMidiDevices();                  public void
721                  updateAudioDevices();                  actionPerformed(ActionEvent e) {
722                  updateChannelProperties();                          viewTracker.setView(new NormalChannelView(Channel.this));
723                    }
724          }          }
725                    
726          /**          public ContextMenu
727           * Updates the channel settings. This method is invoked when changes to the          getContextMenu() { return contextMenu; }
728           * channel were made.          
729           */          class ContextMenu extends MouseAdapter {
730          private void                  private final JPopupMenu menu = new JPopupMenu();
         updateChannelProperties() {  
                 SamplerModel sm = CC.getSamplerModel();  
                 SamplerChannel sc = channel.getModel().getChannelInfo();  
                   
                 MidiDeviceModel mm = sm.getMidiDeviceModel(sc.getMidiInputDevice());  
                 AudioDeviceModel am = sm.getAudioDeviceModel(sc.getAudioOutputDevice());  
                   
                 if(isUpdate()) CC.getLogger().warning("Unexpected update state!");  
731                                    
732                  setUpdate(true);                  protected final JRadioButtonMenuItem rbmiSmallView;
733                    protected final JRadioButtonMenuItem rbmiNormalView;
734                                    
735                  try {                  ContextMenu() {
736                          cbMidiDevice.setSelectedItem(mm == null ? null : mm.getDeviceInfo());                          menu.add(new JMenuItem(new EditInstrumentAction()));
737                            menu.addSeparator();
738                            
739                            rbmiSmallView = new JRadioButtonMenuItem(new SetSmallViewAction());
740                            rbmiNormalView = new JRadioButtonMenuItem(new SetNormalViewAction());
741                                                    
742                          cbEngine.setSelectedItem(sc.getEngine());                          ButtonGroup group = new ButtonGroup();
743                            group.add(rbmiSmallView);
744                            group.add(rbmiNormalView);
745                                                    
746                          cbAudioDevice.setSelectedItem(am == null ? null : am.getDeviceInfo());                          menu.add(rbmiSmallView);
747                  } catch(Exception x) {                          menu.add(rbmiNormalView);
748                          CC.getLogger().log(Level.WARNING, "Unkown error", x);                          
749                            menu.addSeparator();
750                            menu.add(new JMenuItem(new FxSendsAction()));
751                            menu.add(new JMenuItem(new ChannelRoutingAction()));
752                  }                  }
753                                    
754                  setUpdate(false);                  public void
755                    mousePressed(MouseEvent e) {
756                            if(e.isPopupTrigger()) show(e);
757                    }
758            
759                    public void
760                    mouseReleased(MouseEvent e) {
761                            if(e.isPopupTrigger()) show(e);
762                    }
763            
764                    void
765                    show(MouseEvent e) {
766                            menu.show(e.getComponent(), e.getX(), e.getY());
767                    }
768          }          }
769                    
770          /**          class FxSendsPane extends JSFxSendsPane {
771           * Updates the MIDI device list.                  FxSendsPane(SamplerChannelModel model) {
772           */                          super(model);
773          private void                          
774          updateMidiDevices() {                          actionAddFxSend.putValue(Action.SMALL_ICON, Res.iconNew16);
775                  SamplerModel sm = CC.getSamplerModel();                          actionRemoveFxSend.putValue(Action.SMALL_ICON, Res.iconDelete16);
776                  SamplerChannel sc = channel.getModel().getChannelInfo();                  }
                   
                 setUpdate(true);  
                   
                 try {  
                         cbMidiDevice.removeAllItems();  
777                                    
778                          for(MidiDeviceModel m : sm.getMidiDeviceModels())                  protected JToolBar
779                                  cbMidiDevice.addItem(m.getDeviceInfo());                  createToolBar() {
780                            JToolBar tb = new JToolBar();
781                            Dimension d = new Dimension(Short.MAX_VALUE, tb.getPreferredSize().height);
782                            tb.setMaximumSize(d);
783                            tb.setFloatable(false);
784                            tb.setAlignmentX(JPanel.RIGHT_ALIGNMENT);
785                            
786                            tb.add(new ToolbarButton(actionAddFxSend));
787                            tb.add(new ToolbarButton(actionRemoveFxSend));
788                                    
789                          MidiDeviceModel mm = sm.getMidiDeviceModel(sc.getMidiInputDevice());                          return tb;
                         cbMidiDevice.setSelectedItem(mm == null ? null : mm.getDeviceInfo());  
                 } catch(Exception x) {  
                         CC.getLogger().log(Level.WARNING, "Unkown error", x);  
790                  }                  }
                   
                 setUpdate(false);  
791          }          }
792                    
793          /**          public static class StreamVoiceCountPane extends JPanel {
794           * Updates the audio device list.                  private final Channel channel;
          */  
         private void  
         updateAudioDevices() {  
                 SamplerModel sm = CC.getSamplerModel();  
                 SamplerChannel sc = channel.getModel().getChannelInfo();  
                   
                 setUpdate(true);  
795                                    
796                  try {                  private final JLabel lStreams = createScreenLabel(" --");
797                          cbAudioDevice.removeAllItems();                  private final JLabel lSlash = createScreenLabel("/");
798                    private final JLabel lVoices = createScreenLabel("-- ");
799                                    
800                          for(AudioDeviceModel m : sm.getAudioDeviceModels())                  public
801                                  cbAudioDevice.addItem(m.getDeviceInfo());                  StreamVoiceCountPane(Channel channel) {
802                            this.channel = channel;
803                            
804                            setOpaque(false);
805                            setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
806                            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                          AudioDeviceModel am = sm.getAudioDeviceModel(sc.getAudioOutputDevice());                  public void
835                          cbAudioDevice.setSelectedItem(am == null ? null : am.getDeviceInfo());                  updateStreamCount(int count) {
836                  } catch(Exception x) {                          lStreams.setText(count == 0 ? " --" : String.valueOf(count));
                         CC.getLogger().log(Level.WARNING, "Unkown error", x);  
837                  }                  }
838                                    
839                  setUpdate(false);                  public void
840                    updateVoiceCount(int count) {
841                            lVoices.setText(count == 0 ? "-- " : String.valueOf(count));
842                    }
843          }          }
844                    
845          private void          public static class VolumePane extends JPanel {
846          setMidiDevice() {                  private final Channel channel;
847                  MidiInputDevice mid = (MidiInputDevice)cbMidiDevice.getSelectedItem();                  private final JButton btnVolume = createScreenButton("");
848                    private JSVolumeEditorPopup popupVolume;
849                                    
850                  if(!isUpdate()) {                  private static NumberFormat numberFormat = NumberFormat.getInstance();
851                          if(mid != null) channel.getModel().setMidiInputDevice(mid.getDeviceID());                  static { numberFormat.setMaximumFractionDigits(1); }
                         return;  
                 }  
852                                    
853                  cbMidiPort.removeAllItems();                  public
854                                    VolumePane(final Channel channel) {
855                  if(mid == null) {                          this.channel = channel;
856                          cbMidiPort.setEnabled(false);                          setOpaque(false);
857                            setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
858                                                    
859                          cbMidiChannel.setSelectedItem(null);                          btnVolume.setIcon(Res.iconVolume14);
860                          cbMidiChannel.setEnabled(false);                          btnVolume.setIconTextGap(2);
861                  } else {                          btnVolume.setAlignmentX(RIGHT_ALIGNMENT);
862                          cbMidiPort.setEnabled(true);                          btnVolume.setHorizontalAlignment(btnVolume.LEFT);
863                            updateVolumeInfo(100);
864                            Dimension d = btnVolume.getPreferredSize();
865                            d.width = 57;
866                            btnVolume.setPreferredSize(d);
867                            btnVolume.setMinimumSize(d);
868                                                    
869                          MidiPort[] ports = mid.getMidiPorts();                          add(btnVolume);
                         for(MidiPort port : ports) cbMidiPort.addItem(port);  
870                                                    
871                          int p = channel.getModel().getChannelInfo().getMidiInputPort();                          btnVolume.addActionListener(new ActionListener() {
872                          cbMidiPort.setSelectedItem(p >= 0 && p < ports.length ? ports[p] : null);                                  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                          cbMidiChannel.setEnabled(true);                          btnVolume.addMouseListener(channel.getContextMenu());
                         int c = channel.getModel().getChannelInfo().getMidiInputChannel();  
                         cbMidiChannel.setSelectedItem(c == -1 ? "All" : "Channel " + (c + 1));  
895                  }                  }
         }  
           
         private void  
         setMidiPort() {  
                 if(isUpdate()) return;  
896                                    
897                  channel.getModel().setMidiInputPort(cbMidiPort.getSelectedIndex());                  public void
898                    updateVolumeInfo(int volume) {
899                            if(CC.getViewConfig().isMeasurementUnitDecibel()) {
900                                    String s = numberFormat.format(HF.percentsToDecibels(volume));
901                                    btnVolume.setText(s + "dB");
902                            } else {
903                                    btnVolume.setText(String.valueOf(volume) + "%");
904                            }
905                    }
906          }          }
907                    
908          private void          public static class PowerButton extends PixmapToggleButton implements ActionListener {
909          setMidiChannel() {                  private final Channel channel;
                 if(isUpdate()) return;  
910                                    
911                  Object o = cbMidiChannel.getSelectedItem();                  PowerButton(Channel channel) {
912                  if(o == null) return;                          this(channel, Res.gfxPowerOff, Res.gfxPowerOn);
913                  String s = o.toString();                  }
                   
                 int c = s.equals("All") ? -1 : Integer.parseInt(s.substring(8)) - 1;  
                   
                 channel.getModel().setMidiInputChannel(c);  
         }  
           
         /** Invoked when the user selects an engine. */  
         private void  
         setEngineType() {  
                 Object oldEngine = channel.getModel().getChannelInfo().getEngine();  
                 SamplerEngine newEngine = (SamplerEngine)cbEngine.getSelectedItem();  
914                                    
915                  if(oldEngine != null) { if(oldEngine.equals(newEngine)) return; }                  PowerButton(Channel channel, ImageIcon defaultIcon, ImageIcon selectedIcon) {
916                  else if(newEngine == null) return;                          super(defaultIcon, selectedIcon);
917                            
918                            this.channel = channel;
919                                    
920                  channel.getModel().setEngineType(newEngine.getName());                          setSelected(true);
921                            addActionListener(this);
922                            setToolTipText(i18n.getButtonLabel("Channel.ttRemoveChannel"));
923                    }
924                                    
         }  
           
         private void  
         setAudioDevice() {  
                 if(isUpdate()) return;  
                 AudioOutputDevice dev = (AudioOutputDevice)cbAudioDevice.getSelectedItem();  
                 if(dev != null) channel.getModel().setAudioOutputDevice(dev.getDeviceID());  
         }  
           
         /**  
          * Determines whether the currently processed changes are due to update.  
          * @return <code>true</code> if the currently processed changes are due to update and  
          * <code>false</code> if the currently processed changes are due to user input.  
          */  
         private boolean  
         isUpdate() { return update; }  
           
         /**  
          * Sets whether the currently processed changes are due to update.  
          * @param b Specify <code>true</code> to indicate that the currently  
          * processed changes are due to update; <code>false</code>  
          * indicates that the currently processed changes are due to user input.  
          */  
         private void  
         setUpdate(boolean b) { update = b; }  
           
         private final Handler handler = new Handler();  
           
         private Handler  
         getHandler() { return handler; }  
           
         private class Handler implements MidiDeviceListListener, AudioDeviceListListener {  
                 /**  
                  * Invoked when a new MIDI device is created.  
                  * @param e A <code>MidiDeviceListEvent</code>  
                  * instance providing the event information.  
                  */  
925                  public void                  public void
926                  deviceAdded(MidiDeviceListEvent e) {                  actionPerformed(ActionEvent e) {
927                          cbMidiDevice.addItem(e.getMidiDeviceModel().getDeviceInfo());                          boolean b = preferences().getBoolProperty(CONFIRM_CHANNEL_REMOVAL);
928                            if(b) {
929                                    String s = i18n.getMessage("Channel.remove?", channel.getChannelId());
930                                    if(!HF.showYesNoDialog(channel, s)) {
931                                            setSelected(true);
932                                            return;
933                                    }
934                            }
935                            channel.remove();
936                  }                  }
937                    
938                    public boolean
939                    contains(int x, int y) { return (x - 11)*(x - 11) + (y - 11)*(y - 11) < 71; }
940            }
941                    
942                  /**          public static class OptionsButton extends PixmapToggleButton implements ActionListener {
943                   * Invoked when a MIDI device is removed.                  private final Channel channel;
                  * @param e A <code>MidiDeviceListEvent</code>  
                  * instance providing the event information.  
                  */  
                 public void  
                 deviceRemoved(MidiDeviceListEvent e) {  
                         cbMidiDevice.removeItem(e.getMidiDeviceModel().getDeviceInfo());  
                 }  
944                                    
945                  /**                  OptionsButton(Channel channel) {
946                   * Invoked when a new audio device is created.                          super(Res.gfxOptionsOff, Res.gfxOptionsOn);
947                   * @param e An <code>AudioDeviceListEvent</code>                          
948                   * instance providing the event information.                          this.channel = channel;
949                   */                          
950                  public void                          setRolloverIcon(Res.gfxOptionsOffRO);
951                  deviceAdded(AudioDeviceListEvent e) {                          this.setRolloverSelectedIcon(Res.gfxOptionsOnRO);
952                          cbAudioDevice.addItem(e.getAudioDeviceModel().getDeviceInfo());                          addActionListener(this);
953                            setToolTipText(i18n.getButtonLabel("Channel.ttShowOptions"));
954                  }                  }
955                            
                 /**  
                  * Invoked when an audio device is removed.  
                  * @param e An <code>AudioDeviceListEvent</code>  
                  * instance providing the event information.  
                  */  
956                  public void                  public void
957                  deviceRemoved(AudioDeviceListEvent e) {                  actionPerformed(ActionEvent e) {
958                          cbAudioDevice.removeItem(e.getAudioDeviceModel().getDeviceInfo());                          channel.showOptionsPane(isSelected());
959                            
960                            String s;
961                            if(isSelected()) s = i18n.getButtonLabel("Channel.ttHideOptions");
962                            else s = i18n.getButtonLabel("Channel.ttShowOptions");
963                            
964                            setToolTipText(s);
965                  }                  }
966                    
967                    public boolean
968                    contains(int x, int y) { return super.contains(x, y) & y < 13; }
969          }          }
970  }  }
971    
972    class ChannelOptionsPane extends JXCollapsiblePane {
973            ChannelOptionsPane() {
974                    setAnimated(false);
975                    setCollapsed(true);
976                    setAnimated(preferences().getBoolProperty(ANIMATED));
977                    
978                    preferences().addPropertyChangeListener(ANIMATED, new PropertyChangeListener() {
979                            public void
980                            propertyChange(PropertyChangeEvent e) {
981                                    setAnimated(preferences().getBoolProperty(ANIMATED));
982                            }
983                    });
984            }
985            
986            public void
987            showOptionsPane(boolean show) { setCollapsed(!show); }
988    }

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

  ViewVC Help
Powered by ViewVC