/[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 1143 by iliev, Mon Apr 2 21:18:31 2007 UTC revision 1730 by iliev, Wed Apr 30 23:31:08 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 Iliev <grigor@grigoriliev.com>   *   Copyright (C) 2005-2008 Grigor Iliev <grigor@grigoriliev.com>
5   *   *
6   *   This file is part of JSampler.   *   This file is part of JSampler.
7   *   *
# Line 22  Line 22 
22    
23  package org.jsampler.view.fantasia;  package org.jsampler.view.fantasia;
24    
25  import java.awt.Cursor;  import java.awt.Container;
26  import java.awt.Dimension;  import java.awt.Rectangle;
 import java.awt.Insets;  
27    
28  import java.awt.event.ActionEvent;  import java.awt.event.ActionEvent;
29  import java.awt.event.ActionListener;  import java.awt.event.ActionListener;
 import java.awt.event.MouseAdapter;  
 import java.awt.event.MouseEvent;  
30    
31  import java.util.logging.Level;  import java.beans.PropertyChangeEvent;
32    import java.beans.PropertyChangeListener;
33    
 import javax.swing.BorderFactory;  
 import javax.swing.Box;  
34  import javax.swing.BoxLayout;  import javax.swing.BoxLayout;
35  import javax.swing.DefaultListCellRenderer;  import javax.swing.DefaultListCellRenderer;
36  import javax.swing.JButton;  import javax.swing.JButton;
37  import javax.swing.JComboBox;  import javax.swing.JComponent;
 import javax.swing.JLabel;  
38  import javax.swing.JPanel;  import javax.swing.JPanel;
39    import javax.swing.JScrollPane;
40  import javax.swing.JToggleButton;  import javax.swing.JToggleButton;
 import javax.swing.SwingConstants;  
41    
 import javax.swing.event.ChangeEvent;  
 import javax.swing.event.ChangeListener;  
   
 import net.sf.juife.Dial;  
 import net.sf.juife.JuifeUtils;  
42  import net.sf.juife.TitleBar;  import net.sf.juife.TitleBar;
43    
44  import org.jsampler.AudioDeviceModel;  import org.jdesktop.swingx.JXCollapsiblePane;
45    
46  import org.jsampler.CC;  import org.jsampler.CC;
47  import org.jsampler.MidiDeviceModel;  import org.jsampler.HF;
48  import org.jsampler.SamplerChannelModel;  import org.jsampler.SamplerChannelModel;
 import org.jsampler.SamplerModel;  
49    
 import org.jsampler.event.ListEvent;  
 import org.jsampler.event.ListListener;  
 import org.jsampler.event.MidiDeviceListEvent;  
 import org.jsampler.event.MidiDeviceListListener;  
 import org.jsampler.event.SamplerChannelAdapter;  
50  import org.jsampler.event.SamplerChannelEvent;  import org.jsampler.event.SamplerChannelEvent;
51    import org.jsampler.event.SamplerChannelListEvent;
52    import org.jsampler.event.SamplerChannelListListener;
53  import org.jsampler.event.SamplerChannelListener;  import org.jsampler.event.SamplerChannelListener;
54    
55  import org.linuxsampler.lscp.AudioOutputDevice;  import static org.jsampler.view.fantasia.FantasiaPrefs.*;
 import org.linuxsampler.lscp.MidiInputDevice;  
 import org.linuxsampler.lscp.MidiPort;  
 import org.linuxsampler.lscp.SamplerChannel;  
 import org.linuxsampler.lscp.SamplerEngine;  
   
 import static org.jsampler.view.fantasia.FantasiaI18n.i18n;  
56    
57    
58  /**  /**
# Line 79  import static org.jsampler.view.fantasia Line 60  import static org.jsampler.view.fantasia
60   * @author Grigor Iliev   * @author Grigor Iliev
61   */   */
62  public class Channel extends org.jsampler.view.JSChannel {  public class Channel extends org.jsampler.view.JSChannel {
63          private final ChannelScreen screen = new ChannelScreen(this);          private final JXCollapsiblePane mainPane;
64          private final ChannelOptions optionsPane = new ChannelOptions(this);          private ChannelView channelView;
65            private ChannelOptionsView channelOptionsView;
66            private final ChannelOptionsPane optionsPane = new ChannelOptionsPane();
67                    
68          private final PowerButton btnPower = new PowerButton();          private boolean selected = false;
         private final MuteButton btnMute = new MuteButton();  
         private final SoloButton btnSolo = new SoloButton();  
         private final OptionsButton btnOptions = new OptionsButton();  
69                    
70          private final EnhancedDial dialVolume = new EnhancedDial();          private AnimatedPorpetyListener animatedPorpetyListener = new AnimatedPorpetyListener();
71                    
72          private boolean selected = false;          class AnimatedPorpetyListener implements PropertyChangeListener {
73                    public void
74                    propertyChange(PropertyChangeEvent e) {
75                            mainPane.setAnimated(preferences().getBoolProperty(ANIMATED));
76                    }
77            }
78                    
79          /**          /**
80           * Creates a new instance of <code>Channel</code> using the specified           * Creates a new instance of <code>Channel</code> using the specified
# Line 99  public class Channel extends org.jsample Line 84  public class Channel extends org.jsample
84           */           */
85          public          public
86          Channel(SamplerChannelModel model) {          Channel(SamplerChannelModel model) {
87                    this(model, null);
88            }
89            
90            /**
91             * Creates a new instance of <code>Channel</code> using the specified
92             * non-<code>null</code> channel model.
93             * @param model The model to be used by this channel.
94             * @param listener A listener which is notified when the newly created
95             * channel is fully expanded on the screen.
96             * @throws IllegalArgumentException If the model is <code>null</code>.
97             */
98            public
99            Channel(SamplerChannelModel model, final ActionListener listener) {
100                  super(model);                  super(model);
101                                    
102                  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);  
103                  optionsPane.setAlignmentX(JPanel.CENTER_ALIGNMENT);                  optionsPane.setAlignmentX(JPanel.CENTER_ALIGNMENT);
                 add(p);  
                 add(optionsPane);  
104                                    
105                  setOpaque(true);                  mainPane = new JXCollapsiblePane();
106                    mainPane.getContentPane().setLayout (
107                            new BoxLayout(mainPane.getContentPane(), BoxLayout.Y_AXIS)
108                    );
109                    
110                    channelView = new NormalChannelView(this);
111                    channelOptionsView = channelView.getChannelOptionsView();
112                    
113                    optionsPane.setContentPane(channelOptionsView.getComponent());
114                    
115                    mainPane.add(channelView.getComponent());
116                    mainPane.add(optionsPane);
117                    
118                    setOpaque(false);
119                                    
120                  getModel().addSamplerChannelListener(getHandler());                  getModel().addSamplerChannelListener(getHandler());
121                                    
122                  updateChannelInfo();                  updateChannelInfo();
123                    
124                    add(mainPane);
125                    
126                    if(listener != null) {
127                            final String s = JXCollapsiblePane.ANIMATION_STATE_KEY;
128                            mainPane.addPropertyChangeListener(s, new PropertyChangeListener() {
129                                    public void
130                                    propertyChange(PropertyChangeEvent e) {
131                                            if(e.getNewValue() == "expanded") {
132                                                    // TODO: this should be done regardles the listener != null?
133                                                    mainPane.removePropertyChangeListener(s, this);
134                                                    ///////
135                                                    listener.actionPerformed(null);
136                                                    ensureChannelIsVisible();
137                                            } else if(e.getNewValue() == "expanding/collapsing") {
138                                                    ensureChannelIsVisible();
139                                            }
140                                    }
141                            });
142                    }
143                    
144                    mainPane.setAnimated(false);
145                    mainPane.setCollapsed(true);
146                    mainPane.setAnimated(preferences().getBoolProperty(ANIMATED));
147                    mainPane.setCollapsed(false);
148                    
149                    preferences().addPropertyChangeListener(ANIMATED, animatedPorpetyListener);
150                    
151                    if(listener != null) {
152                            javax.swing.SwingUtilities.invokeLater(new Runnable() {
153                                    public void
154                                    run() { listener.actionPerformed(null); }
155                            });
156                    }
157                    
158                    CC.getSamplerModel().addSamplerChannelListListener(getHandler());
159          }          }
160                    
161          private JPanel          private void
162          createVSeparator() {          ensureChannelIsVisible() {
163                  JPanel p = new JPanel();                  Container p = getParent();
164                  p.setName("VSeparator");                  JScrollPane sp = null;
165                  p.setOpaque(false);                  while(p != null) {
166                  p.setAlignmentY(JPanel.TOP_ALIGNMENT);                          if(p instanceof JScrollPane) {
167                  p.setPreferredSize(new Dimension(2, 60));                                  sp = (JScrollPane)p;
168                  p.setMinimumSize(p.getPreferredSize());                                  break;
169                  p.setMaximumSize(p.getPreferredSize());                          }
170                  return p;                          p = p.getParent();
171                    }
172                    if(sp == null) return;
173                    int h = sp.getViewport().getView().getHeight();
174                    sp.getViewport().scrollRectToVisible(new Rectangle(0, h - 2, 1, 1));
175          }          }
176                    
177          /**          /**
# Line 233  public class Channel extends org.jsample Line 194  public class Channel extends org.jsample
194                    
195          /** Shows the channel properties. */          /** Shows the channel properties. */
196          public void          public void
197          expandChannel() { if(!btnOptions.isSelected()) btnOptions.doClick(); }          expandChannel() { expandChannel(optionsPane.isAnimated()); }
198                    
199                    /** Shows the channel properties. */
200          /** Invoked when the user changes the volume */          public void
201          private void          expandChannel(boolean animated) {
202          setVolume() {                  boolean b = optionsPane.isAnimated();
203                  screen.updateVolumeInfo(dialVolume.getValue());                  optionsPane.setAnimated(animated);
204                                    channelView.expandChannel();
205                  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().setBackendVolume(volume);  
206          }          }
207                    
208          /**          /**
# Line 264  public class Channel extends org.jsample Line 211  public class Channel extends org.jsample
211           */           */
212          private void          private void
213          updateChannelInfo() {          updateChannelInfo() {
214                  SamplerChannel sc = getChannelInfo();                  channelView.updateChannelInfo();
215                                    channelOptionsView.updateChannelInfo();
                 screen.updateScreenInfo(sc);  
                 updateMuteIcon(sc);  
                   
                 if(sc.isSoloChannel()) btnSolo.setIcon(Res.iconSoloOn);  
                 else btnSolo.setIcon(Res.iconSoloOff);  
                   
                 dialVolume.setValue((int)(sc.getVolume() * 100));  
                   
                 boolean b = sc.getEngine() != null;  
                 dialVolume.setEnabled(b);  
                 btnSolo.setEnabled(b);  
                 btnMute.setEnabled(b);  
216          }          }
217                    
218          /**          protected void
219           * Updates the mute button with the proper icon regarding to information obtained          onDestroy() {
220           * from <code>channel</code>.                  CC.getSamplerModel().removeSamplerChannelListListener(getHandler());
221           * @param channel A <code>SamplerChannel</code> instance containing the new settings                  preferences().removePropertyChangeListener(ANIMATED, animatedPorpetyListener);
222           * for this channel.                  
223           */                  channelView.uninstallView();
224          private void                  channelOptionsView.uninstallView();
         updateMuteIcon(SamplerChannel channel) {  
                 if(channel.isMutedBySolo()) btnMute.setIcon(Res.iconMutedBySolo);  
                 else if(channel.isMuted()) btnMute.setIcon(Res.iconMuteOn);  
                 else btnMute.setIcon(Res.iconMuteOff);  
225          }          }
226                            
227          private class EnhancedDial extends Dial {          public void
228                  EnhancedDial() {          remove() {
229                          super(0, 100);                  if(!mainPane.isAnimated()) {
230                                                    CC.getSamplerModel().removeBackendChannel(getChannelId());
231                          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(); }  
                         });  
232                  }                  }
233                    
234                    String s = JXCollapsiblePane.ANIMATION_STATE_KEY;
235                    mainPane.addPropertyChangeListener(s, getHandler());
236                    mainPane.setCollapsed(true);
237          }          }
238                    
239            public void
240            showOptionsPane(boolean show) { optionsPane.showOptionsPane(show); }
241            
242          private final EventHandler eventHandler = new EventHandler();          private final EventHandler eventHandler = new EventHandler();
243                    
244          private EventHandler          private EventHandler
245          getHandler() { return eventHandler; }          getHandler() { return eventHandler; }
246                    
247          private class EventHandler implements SamplerChannelListener {          private class EventHandler implements SamplerChannelListener,
248                                            SamplerChannelListListener, PropertyChangeListener {
249                  /**                  /**
250                   * Invoked when changes are made to a sampler channel.                   * Invoked when changes are made to a sampler channel.
251                   * @param e A <code>SamplerChannelEvent</code> instance                   * @param e A <code>SamplerChannelEvent</code> instance
# Line 342  public class Channel extends org.jsample Line 261  public class Channel extends org.jsample
261                   */                   */
262                  public void                  public void
263                  streamCountChanged(SamplerChannelEvent e) {                  streamCountChanged(SamplerChannelEvent e) {
264                          screen.updateStreamCount(getModel().getStreamCount());                          channelView.updateStreamCount(getModel().getStreamCount());
265                  }                  }
266                    
267                  /**                  /**
# Line 352  public class Channel extends org.jsample Line 271  public class Channel extends org.jsample
271                   */                   */
272                  public void                  public void
273                  voiceCountChanged(SamplerChannelEvent e) {                  voiceCountChanged(SamplerChannelEvent e) {
274                          screen.updateVoiceCount(getModel().getVoiceCount());                          channelView.updateVoiceCount(getModel().getVoiceCount());
                 }  
         }  
           
           
         private class PowerButton extends PixmapToggleButton implements ActionListener {  
                 PowerButton() {  
                         super(Res.iconPowerOff, Res.iconPowerOn);  
                   
                         setSelected(true);  
                         addActionListener(this);  
                 }  
                   
                 public void  
                 actionPerformed(ActionEvent e) {  
                         CC.getSamplerModel().removeBackendChannel(getChannelId());  
                 }  
                   
                 public boolean  
                 contains(int x, int y) { return (x - 11)*(x - 11) + (y - 11)*(y - 11) < 71; }  
         }  
           
         private class MuteButton extends PixmapButton implements ActionListener {  
                 MuteButton() {  
                         super(Res.iconMuteOff);  
                         setDisabledIcon(Res.iconMuteSoloDisabled);  
                         addActionListener(this);  
275                  }                  }
276                                    
277                    /**
278                     * Invoked when a new sampler channel is created.
279                     * @param e A <code>SamplerChannelListEvent</code>
280                     * instance providing the event information.
281                     */
282                  public void                  public void
283                  actionPerformed(ActionEvent e) {                  channelAdded(SamplerChannelListEvent e) { }
                         SamplerChannel sc = getChannelInfo();  
                         boolean b = true;  
                   
                         /*  
                          * Changing the mute button icon now instead of  
                          * leaving the work to the notification mechanism of the LinuxSampler.  
                          */  
                         if(sc.isMuted() && !sc.isMutedBySolo()) {  
                                 b = false;  
                                 boolean hasSolo = CC.getSamplerModel().hasSoloChannel();  
                           
                                 if(sc.isSoloChannel() || !hasSolo) setIcon(Res.iconMuteOff);  
                                 else setIcon(Res.iconMutedBySolo);  
                         } else setIcon(Res.iconMuteOn);  
                           
                         Channel.this.getModel().setBackendMute(b);  
                 }  
                   
                 public boolean  
                 contains(int x, int y) { return (x > 5 && x < 23) && (y > 5 && y < 16); }  
         }  
284                    
285          private class SoloButton extends PixmapButton implements ActionListener {                  /**
286                  SoloButton() {                   * Invoked when a sampler channel is removed.
287                          super(Res.iconSoloOff);                   * @param e A <code>SamplerChannelListEvent</code>
288                          setDisabledIcon(Res.iconMuteSoloDisabled);                   * instance providing the event information.
289                          addActionListener(this);                   */
                 }  
                   
290                  public void                  public void
291                  actionPerformed(ActionEvent e) {                  channelRemoved(SamplerChannelListEvent e) {
292                          SamplerChannel sc = getChannelInfo();                          // Some cleanup when the channel is removed.
293                          boolean b = !sc.isSoloChannel();                          if(e.getChannelModel().getChannelId() == getChannelId()) {
294                                                    onDestroy();
                         /*  
                          * Changing the solo button icon (and related) now instead of  
                          * leaving the work to the notification mechanism of the LinuxSampler.  
                          */  
                         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);  
295                          }                          }
                   
                         Channel.this.getModel().setBackendSolo(b);  
                 }  
                   
                 public boolean  
                 contains(int x, int y) { return (x > 5 && x < 23) && (y > 5 && y < 16); }  
         }  
           
         private class OptionsButton extends PixmapToggleButton implements ActionListener {  
                 OptionsButton() {  
                         super(Res.iconOptionsOff, Res.iconOptionsOn);  
                         setRolloverIcon(Res.iconOptionsOffRO);  
                         this.setRolloverSelectedIcon(Res.iconOptionsOnRO);  
                         addActionListener(this);  
296                  }                  }
297                                    
298                  public void                  public void
299                  actionPerformed(ActionEvent e) {                  propertyChange(PropertyChangeEvent e) {
300                          showOptionsPane(isSelected());                          if(e.getNewValue() == "collapsed") {
301                                                            CC.getSamplerModel().removeBackendChannel(getChannelId());
                         String s;  
                         if(isSelected()) s = i18n.getButtonLabel("OptionsButton.ttHideOptions");  
                         else s = i18n.getButtonLabel("OptionsButton.ttShowOptions");  
                           
                         setToolTipText(s);  
                 }  
                   
                 private void  
                 showOptionsPane(boolean show) {  
                         optionsPane.setVisible(show);  
                         MainFrame.repack(CC.getMainFrame());  
                 }  
                   
                 public boolean  
                 contains(int x, int y) { return super.contains(x, y) & y < 13; }  
         }  
 }  
   
 class ChannelScreen extends JPanel {  
         private final Channel channel;  
         private JButton btnInstr = new ScreenButton(i18n.getButtonLabel("ChannelScreen.btnInstr"));  
         private JButton btnReset = new ScreenButton(i18n.getButtonLabel("ChannelScreen.btnReset"));  
         private JButton btnDuplicate =  
                 new ScreenButton(i18n.getButtonLabel("ChannelScreen.btnDuplicate"));  
           
         private final JLabel lVolume = new JLabel();  
         private final JLabel lStreams = new JLabel("--");  
         private final JLabel lVoices = new JLabel("--");  
           
         ChannelScreen(Channel channel) {  
                 this.channel = channel;  
                   
                 setName("ChannelScreen");  
                 setOpaque(true);  
                   
                 setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));  
                   
                 btnInstr.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0));  
                 btnInstr.setAlignmentX(CENTER_ALIGNMENT);  
                   
                 add(btnInstr);  
                   
                 JPanel p = new JPanel();  
                 p.setOpaque(false);  
                 p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));  
                 p.setAlignmentX(CENTER_ALIGNMENT);  
                 p.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0));  
                 //lVolume.setFont(lVolume.getFont().deriveFont(java.awt.Font.PLAIN));  
                   
                 p.add(btnDuplicate);  
                   
                 p.add(Box.createRigidArea(new Dimension(6, 0)));  
                   
                 p.add(new JLabel("|"));  
                   
                 p.add(Box.createRigidArea(new Dimension(6, 0)));  
                   
                 p.add(btnReset);  
                   
                 p.add(Box.createGlue());  
                   
                 p.add(lStreams);  
                 p.add(new JLabel("/"));  
                 p.add(lVoices);  
                   
                 p.add(Box.createRigidArea(new Dimension(12, 0)));  
                   
                 lVolume.setAlignmentX(RIGHT_ALIGNMENT);  
                 p.add(lVolume);  
                 p.setPreferredSize(new Dimension(250, p.getPreferredSize().height));  
                 p.setMinimumSize(p.getPreferredSize());  
                 p.setMaximumSize(p.getPreferredSize());  
                   
                 add(p);  
                   
                   
                 setPreferredSize(new Dimension(270, 48));  
                 setMinimumSize(getPreferredSize());  
                 setMaximumSize(getPreferredSize());  
                   
                 installListeners();  
         }  
           
         private void  
         installListeners() {  
                 btnInstr.addActionListener(new ActionListener() {  
                         public void  
                         actionPerformed(ActionEvent e) { loadInstrument(); }  
                 });  
           
                 btnReset.addActionListener(new ActionListener() {  
                         public void  
                         actionPerformed(ActionEvent e) { channel.getModel().resetBackendChannel(); }  
                 });  
                   
                 btnDuplicate.addActionListener(new ActionListener() {  
                         public void  
                         actionPerformed(ActionEvent e) {  
                                 channel.getModel().duplicateBackendChannel();  
302                          }                          }
                 });  
         }  
   
         private void  
         loadInstrument() {  
                 InstrumentChooser dlg = new InstrumentChooser(CC.getMainFrame());  
                 dlg.setVisible(true);  
                   
                 if(!dlg.isCancelled()) {  
                         SamplerChannelModel m = channel.getModel();  
                         m.loadBackendInstrument(dlg.getFileName(), dlg.getInstrumentIndex());  
                 }  
         }  
           
         protected void  
         updateScreenInfo(SamplerChannel sc) {  
                 int status = sc.getInstrumentStatus();  
                 if(status >= 0 && status < 100) {  
                         btnInstr.setText(i18n.getLabel("ChannelScreen.loadingInstrument", status));  
                 } 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"));  
                 }  
           
                   
                   
         }  
           
         protected void  
         updateVolumeInfo(int volume) {  
                 lVolume.setText(i18n.getLabel("ChannelScreen.volume", volume));  
                   
         }  
           
         /**  
          * Updates the number of active disk streams.  
          * @param count The new number of active disk streams.  
          */  
         protected void  
         updateStreamCount(int count) {  
                 Dimension d = lStreams.getPreferredSize();  
                 lStreams.setText(count == 0 ? "--" : String.valueOf(count));  
                 d = JuifeUtils.getUnionSize(d, lStreams.getPreferredSize());  
                 lStreams.setMinimumSize(d);  
                 lStreams.setPreferredSize(d);  
                 lStreams.setMaximumSize(d);  
         }  
           
         /**  
          * 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));  
303                  }                  }
304          }          }
305  }  }
306    
307  class ChannelOptions extends JPanel {  class ChannelOptionsPane extends JXCollapsiblePane {
308          private final Channel channel;          ChannelOptionsPane() {
309                            setAnimated(false);
310          private final JComboBox cbMidiDevice = new JComboBox();                  setCollapsed(true);
311          private final JComboBox cbMidiPort = new JComboBox();                  setAnimated(preferences().getBoolProperty(ANIMATED));
         private final JComboBox cbMidiChannel = new JComboBox();  
         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(); }  
                 });  
312                                    
313                  cbMidiPort.addActionListener(new ActionListener() {                  preferences().addPropertyChangeListener(ANIMATED, new PropertyChangeListener() {
314                          public void                          public void
315                          actionPerformed(ActionEvent e) { setMidiPort(); }                          propertyChange(PropertyChangeEvent e) {
316                  });                                  setAnimated(preferences().getBoolProperty(ANIMATED));
                   
                 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) { 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.getMidiDeviceModel(sc.getMidiInputDevice());  
                 AudioDeviceModel am = sm.getAudioDeviceModel(sc.getAudioOutputDevice());  
                   
                 if(isUpdate()) CC.getLogger().warning("Unexpected update state!");  
                   
                 setUpdate(true);  
                   
                 try {  
                         cbMidiDevice.setSelectedItem(mm == null ? null : mm.getDeviceInfo());  
                           
                         cbEngine.setSelectedItem(sc.getEngine());  
                           
                         cbAudioDevice.setSelectedItem(am == null ? null : am.getDeviceInfo());  
                 } catch(Exception x) {  
                         CC.getLogger().log(Level.WARNING, "Unkown error", x);  
                 }  
                   
                 setUpdate(false);  
         }  
           
         /**  
          * Updates the MIDI device list.  
          */  
         private void  
         updateMidiDevices() {  
                 SamplerModel sm = CC.getSamplerModel();  
                 SamplerChannel sc = channel.getModel().getChannelInfo();  
                   
                 setUpdate(true);  
                   
                 try {  
                         cbMidiDevice.removeAllItems();  
                   
                         for(MidiDeviceModel m : sm.getMidiDeviceModels())  
                                 cbMidiDevice.addItem(m.getDeviceInfo());  
                   
                         MidiDeviceModel mm = sm.getMidiDeviceModel(sc.getMidiInputDevice());  
                         cbMidiDevice.setSelectedItem(mm == null ? null : mm.getDeviceInfo());  
                 } catch(Exception x) {  
                         CC.getLogger().log(Level.WARNING, "Unkown error", x);  
                 }  
                   
                 setUpdate(false);  
         }  
           
         /**  
          * Updates the audio device list.  
          */  
         private void  
         updateAudioDevices() {  
                 SamplerModel sm = CC.getSamplerModel();  
                 SamplerChannel sc = channel.getModel().getChannelInfo();  
                   
                 setUpdate(true);  
                   
                 try {  
                         cbAudioDevice.removeAllItems();  
                   
                         for(AudioDeviceModel m : sm.getAudioDeviceModels())  
                                 cbAudioDevice.addItem(m.getDeviceInfo());  
                   
                         AudioDeviceModel am = sm.getAudioDeviceModel(sc.getAudioOutputDevice());  
                         cbAudioDevice.setSelectedItem(am == null ? null : am.getDeviceInfo());  
                 } catch(Exception x) {  
                         CC.getLogger().log(Level.WARNING, "Unkown error", x);  
                 }  
                   
                 setUpdate(false);  
         }  
           
         private void  
         setMidiDevice() {  
                 MidiInputDevice mid = (MidiInputDevice)cbMidiDevice.getSelectedItem();  
                   
                 if(!isUpdate()) {  
                         if(mid != null) {  
                                 channel.getModel().setBackendMidiInputDevice(mid.getDeviceId());  
317                          }                          }
318                                            });
                         return;  
                 }  
                   
                 cbMidiPort.removeAllItems();  
                   
                 if(mid == null) {  
                         cbMidiPort.setEnabled(false);  
                           
                         cbMidiChannel.setSelectedItem(null);  
                         cbMidiChannel.setEnabled(false);  
                 } else {  
                         cbMidiPort.setEnabled(true);  
                           
                         MidiPort[] ports = mid.getMidiPorts();  
                         for(MidiPort port : ports) cbMidiPort.addItem(port);  
                           
                         int p = channel.getModel().getChannelInfo().getMidiInputPort();  
                         cbMidiPort.setSelectedItem(p >= 0 && p < ports.length ? ports[p] : null);  
                           
                         cbMidiChannel.setEnabled(true);  
                         int c = channel.getModel().getChannelInfo().getMidiInputChannel();  
                         cbMidiChannel.setSelectedItem(c == -1 ? "All" : "Channel " + (c + 1));  
                 }  
         }  
           
         private void  
         setMidiPort() {  
                 if(isUpdate()) return;  
                   
                 channel.getModel().setBackendMidiInputPort(cbMidiPort.getSelectedIndex());  
         }  
           
         private void  
         setMidiChannel() {  
                 if(isUpdate()) return;  
                   
                 Object o = cbMidiChannel.getSelectedItem();  
                 if(o == null) return;  
                 String s = o.toString();  
                   
                 int c = s.equals("All") ? -1 : Integer.parseInt(s.substring(8)) - 1;  
                   
                 channel.getModel().setBackendMidiInputChannel(c);  
         }  
           
         /** Invoked when the user selects an engine. */  
         private void  
         setEngineType() {  
                 Object oldEngine = channel.getModel().getChannelInfo().getEngine();  
                 SamplerEngine newEngine = (SamplerEngine)cbEngine.getSelectedItem();  
                   
                 if(oldEngine != null) { if(oldEngine.equals(newEngine)) return; }  
                 else if(newEngine == null) return;  
                   
                 channel.getModel().setBackendEngineType(newEngine.getName());  
                   
         }  
           
         private void  
         setBackendAudioDevice() {  
                 if(isUpdate()) return;  
                 AudioOutputDevice dev = (AudioOutputDevice)cbAudioDevice.getSelectedItem();  
                 if(dev != null) channel.getModel().setBackendAudioOutputDevice(dev.getDeviceId());  
319          }          }
320                    
321          /**          public void
322           * Determines whether the currently processed changes are due to update.          showOptionsPane(boolean show) { setCollapsed(!show); }
          * @return <code>true</code> if the currently processed changes are due to update and  
          * <code>false</code> if the currently processed changes are due to user input.  
          */  
         private boolean  
         isUpdate() { return update; }  
           
         /**  
          * Sets whether the currently processed changes are due to update.  
          * @param b Specify <code>true</code> to indicate that the currently  
          * processed changes are due to update; <code>false</code>  
          * indicates that the currently processed changes are due to user input.  
          */  
         private void  
         setUpdate(boolean b) { update = b; }  
           
         private final Handler handler = new Handler();  
           
         private Handler  
         getHandler() { return handler; }  
           
         private class Handler implements MidiDeviceListListener, ListListener<AudioDeviceModel> {  
                 /**  
                  * 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());  
                 }  
         }  
323  }  }

Legend:
Removed from v.1143  
changed lines
  Added in v.1730

  ViewVC Help
Powered by ViewVC