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

Annotation of /jsampler/trunk/src/org/jsampler/view/fantasia/NormalChannelView.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1730 - (hide annotations) (download)
Wed Apr 30 23:31:08 2008 UTC (16 years, 1 month ago) by iliev
File size: 25107 byte(s)
* Implemented pluggable channel view
* Some UI changes due to some substance changes

1 iliev 1730 /*
2     * JSampler - a java front-end for LinuxSampler
3     *
4     * Copyright (C) 2005-2008 Grigor Iliev <grigor@grigoriliev.com>
5     *
6     * This file is part of JSampler.
7     *
8     * JSampler is free software; you can redistribute it and/or modify
9     * it under the terms of the GNU General Public License version 2
10     * as published by the Free Software Foundation.
11     *
12     * JSampler is distributed in the hope that it will be useful,
13     * but WITHOUT ANY WARRANTY; without even the implied warranty of
14     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15     * GNU General Public License for more details.
16     *
17     * You should have received a copy of the GNU General Public License
18     * along with JSampler; if not, write to the Free Software
19     * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20     * MA 02111-1307 USA
21     */
22    
23     package org.jsampler.view.fantasia;
24    
25     import java.awt.Dimension;
26     import java.awt.Insets;
27    
28     import java.awt.event.ActionEvent;
29     import java.awt.event.ActionListener;
30     import java.awt.event.HierarchyEvent;
31     import java.awt.event.HierarchyListener;
32     import java.awt.event.MouseAdapter;
33     import java.awt.event.MouseEvent;
34    
35     import java.beans.PropertyChangeEvent;
36     import java.beans.PropertyChangeListener;
37    
38     import java.text.NumberFormat;
39    
40     import javax.swing.Action;
41     import javax.swing.BorderFactory;
42     import javax.swing.Box;
43     import javax.swing.BoxLayout;
44     import javax.swing.JButton;
45     import javax.swing.JComponent;
46     import javax.swing.JLabel;
47     import javax.swing.JMenuItem;
48     import javax.swing.JPanel;
49     import javax.swing.JPopupMenu;
50     import javax.swing.JToolBar;
51     import javax.swing.Timer;
52    
53     import javax.swing.event.ChangeEvent;
54     import javax.swing.event.ChangeListener;
55    
56     import net.sf.juife.Dial;
57     import net.sf.juife.InformationDialog;
58     import net.sf.juife.JuifeUtils;
59    
60     import org.jsampler.CC;
61     import org.jsampler.HF;
62     import org.jsampler.SamplerChannelModel;
63    
64     import org.jsampler.view.std.JSFxSendsPane;
65     import org.jsampler.view.std.JSInstrumentChooser;
66     import org.jsampler.view.std.JSVolumeEditorPopup;
67    
68     import org.jvnet.substance.SubstanceImageCreator;
69    
70     import org.linuxsampler.lscp.SamplerChannel;
71     import org.linuxsampler.lscp.SamplerEngine;
72    
73     import static org.jsampler.view.fantasia.FantasiaI18n.i18n;
74     import static org.jsampler.view.fantasia.FantasiaPrefs.*;
75     import static org.jsampler.view.fantasia.FantasiaUtils.*;
76     import static org.jsampler.view.std.JSVolumeEditorPopup.VolumeType;
77    
78     /**
79     *
80     * @author Grigor Iliev
81     */
82     public class NormalChannelView extends JPanel implements ChannelView {
83     private final Channel channel;
84     private final ChannelOptionsView channelOptionsView;
85    
86     private final EnhancedDial dialVolume = new EnhancedDial();
87     private final ChannelScreen screen;
88    
89     private final PowerButton btnPower = new PowerButton();
90     private final MuteButton btnMute = new MuteButton();
91     private final SoloButton btnSolo = new SoloButton();
92     private final OptionsButton btnOptions = new OptionsButton();
93    
94    
95     /** Creates a new instance of <code>NormalChannelView</code> */
96     public
97     NormalChannelView(Channel channel) {
98     this(channel, new NormalChannelOptionsView(channel));
99     }
100    
101     /** Creates a new instance of <code>NormalChannelView</code> */
102     public
103     NormalChannelView(Channel channel, ChannelOptionsView channelOptionsView) {
104     this.channel = channel;
105     this.channelOptionsView = channelOptionsView;
106    
107     setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
108    
109     screen = new ChannelScreen(channel);
110     ChannelPane p = new ChannelPane();
111     p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));
112    
113     //p.add(Box.createRigidArea(new Dimension(3, 0)));
114    
115     btnPower.setAlignmentY(JPanel.TOP_ALIGNMENT);
116    
117     JPanel tb = new JPanel();
118     tb.setBorder(BorderFactory.createEmptyBorder(3, 3, 0, 4));
119     tb.setLayout(new BoxLayout(tb, BoxLayout.X_AXIS));
120     tb.setOpaque(false);
121     tb.setAlignmentY(JPanel.TOP_ALIGNMENT);
122     tb.add(btnPower);
123     tb.setPreferredSize(new Dimension(tb.getPreferredSize().width, 58));
124     tb.setMinimumSize(tb.getPreferredSize());
125     tb.setMaximumSize(tb.getPreferredSize());
126     p.add(tb);
127    
128     //p.add(Box.createRigidArea(new Dimension(4, 0)));
129    
130     p.add(createVSeparator());
131    
132     //p.add(Box.createRigidArea(new Dimension(3, 0)));
133    
134     JPanel p2 = new JPanel();
135     p2.setOpaque(false);
136     p2.setLayout(new BoxLayout(p2, BoxLayout.Y_AXIS));
137     p2.setAlignmentY(JPanel.TOP_ALIGNMENT);
138     p2.setBorder(BorderFactory.createEmptyBorder(5, 3, 0, 2));
139     p2.add(screen);
140     p.add(p2);
141    
142     p.add(createVSeparator());
143    
144     p2 = new JPanel();
145     p2.setOpaque(false);
146     p2.setLayout(new BoxLayout(p2, BoxLayout.Y_AXIS));
147     p2.setAlignmentY(JPanel.TOP_ALIGNMENT);
148     p2.setBorder(BorderFactory.createEmptyBorder(4, 0, 0, 0));
149     p2.add(new JLabel(Res.gfxMuteTitle));
150     p2.add(btnMute);
151     p2.add(new JLabel(Res.gfxSoloTitle));
152     p2.add(btnSolo);
153    
154     p.add(p2);
155    
156     p.add(createVSeparator());
157    
158     p2 = new JPanel();
159     p2.setOpaque(false);
160     p2.setLayout(new BoxLayout(p2, BoxLayout.Y_AXIS));
161     p2.setAlignmentY(JPanel.TOP_ALIGNMENT);
162     p2.setBorder(BorderFactory.createEmptyBorder(4, 0, 0, 0));
163     JLabel l = new JLabel(Res.gfxVolumeTitle);
164     l.setAlignmentX(JPanel.CENTER_ALIGNMENT);
165     l.setBorder(BorderFactory.createEmptyBorder(0, 0, 2, 0));
166     p2.add(l);
167     dialVolume.setDialPixmap(Res.gfxVolumeDial, 30, 330);
168     dialVolume.setAlignmentX(JPanel.CENTER_ALIGNMENT);
169     p2.add(dialVolume);
170     p.add(p2);
171    
172     p.add(createVSeparator());
173    
174     p2 = new JPanel();
175     p2.setOpaque(false);
176     p2.setLayout(new BoxLayout(p2, BoxLayout.Y_AXIS));
177     p2.setAlignmentY(JPanel.TOP_ALIGNMENT);
178     p2.setBorder(BorderFactory.createEmptyBorder(27, 0, 0, 0));
179     l = new JLabel(Res.gfxOptionsTitle);
180     l.setAlignmentX(JPanel.CENTER_ALIGNMENT);
181     l.setBorder(BorderFactory.createEmptyBorder(0, 0, 2, 0));
182     p2.add(l);
183    
184     p2.add(Box.createRigidArea(new Dimension(0, 3)));
185    
186     btnOptions.setAlignmentX(JPanel.CENTER_ALIGNMENT);
187     p2.add(btnOptions);
188     p.add(p2);
189    
190    
191     p.setPreferredSize(new Dimension(420, 60));
192     p.setMinimumSize(p.getPreferredSize());
193     p.setMaximumSize(p.getPreferredSize());
194     //p.setBorder(BorderFactory.createEmptyBorder(1, 0, 1, 0));
195    
196     p.setAlignmentX(JPanel.CENTER_ALIGNMENT);
197    
198     add(p);
199    
200     installView();
201     }
202    
203     //////////////////////////////////////////////
204     // Implementation of the ChannelView interface
205     //////////////////////////////////////////////
206    
207     public JComponent
208     getComponent() { return this; }
209    
210     public void
211     installView() {
212     String vmud = VOL_MEASUREMENT_UNIT_DECIBEL;
213     preferences().addPropertyChangeListener(vmud, new PropertyChangeListener() {
214     public void
215     propertyChange(PropertyChangeEvent e) {
216     boolean b;
217     b = preferences().getBoolProperty(VOL_MEASUREMENT_UNIT_DECIBEL);
218     screen.updateVolumeInfo(dialVolume.getValue());
219     }
220     });
221     }
222    
223     public void
224     uninstallView() {
225     screen.onDestroy();
226     }
227    
228     public ChannelOptionsView
229     getChannelOptionsView() { return channelOptionsView; }
230    
231     public void
232     updateChannelInfo() {
233     SamplerChannel sc = channel.getChannelInfo();
234    
235     screen.updateScreenInfo(sc);
236     updateMuteIcon(sc);
237    
238     if(sc.isSoloChannel()) btnSolo.setIcon(Res.gfxSoloOn);
239     else btnSolo.setIcon(Res.gfxSoloOff);
240     dialVolume.setValue((int)(sc.getVolume() * 100));
241    
242     boolean b = sc.getEngine() != null;
243     dialVolume.setEnabled(b);
244     btnSolo.setEnabled(b);
245     btnMute.setEnabled(b);
246     }
247    
248     public void
249     updateStreamCount(int count) { screen.updateStreamCount(count); }
250    
251     public void
252     updateVoiceCount(int count) { screen.updateVoiceCount(count); }
253    
254     public void
255     expandChannel() {
256     if(btnOptions.isSelected()) return;
257     btnOptions.doClick();
258     }
259    
260     //////////////////////////////////////////////
261    
262    
263     /**
264     * Updates the mute button with the proper icon regarding to information obtained
265     * from <code>channel</code>.
266     * @param channel A <code>SamplerChannel</code> instance containing the new settings
267     * for this channel.
268     */
269     private void
270     updateMuteIcon(SamplerChannel channel) {
271     if(channel.isMutedBySolo()) btnMute.setIcon(Res.gfxMutedBySolo);
272     else if(channel.isMuted()) btnMute.setIcon(Res.gfxMuteOn);
273     else btnMute.setIcon(Res.gfxMuteOff);
274     }
275    
276     /** Invoked when the user changes the volume */
277     private void
278     setVolume() {
279     screen.updateVolumeInfo(dialVolume.getValue());
280    
281     if(dialVolume.getValueIsAdjusting()) return;
282    
283     int vol = (int)(channel.getChannelInfo().getVolume() * 100);
284    
285     if(vol == dialVolume.getValue()) return;
286    
287     /*
288     * If the model's volume is not equal to the dial knob
289     * value we assume that the change is due to user input.
290     * So we must update the volume at the backend too.
291     */
292     float volume = dialVolume.getValue();
293     volume /= 100;
294     channel.getModel().setBackendVolume(volume);
295     }
296    
297     private JPanel
298     createVSeparator() {
299     PixmapPane p = new PixmapPane(Res.gfxVLine);
300     p.setAlignmentY(JPanel.TOP_ALIGNMENT);
301     p.setPreferredSize(new Dimension(2, 60));
302     p.setMinimumSize(p.getPreferredSize());
303     p.setMaximumSize(p.getPreferredSize());
304     return p;
305     }
306    
307     private class EnhancedDial extends Dial {
308     EnhancedDial() {
309     super(0, 100, 0);
310    
311     setMouseHandlerMode(MouseHandlerMode.LEFT_TO_RIGHT_AND_DOWN_TO_UP);
312    
313     int i = preferences().getIntProperty(MAXIMUM_CHANNEL_VOLUME);
314     setMaximum(i);
315     String mcv = MAXIMUM_CHANNEL_VOLUME;
316     preferences().addPropertyChangeListener(mcv, new PropertyChangeListener() {
317     public void
318     propertyChange(PropertyChangeEvent e) {
319     int j = preferences().getIntProperty(MAXIMUM_CHANNEL_VOLUME);
320     setMaximum(j);
321     }
322     });
323    
324     addMouseListener(new MouseAdapter() {
325     public void
326     mouseClicked(MouseEvent e) {
327     if(e.getButton() == e.BUTTON3) {
328     setValue(getMaximum() / 2);
329     return;
330     }
331    
332     if(e.getButton() != e.BUTTON1) return;
333    
334     if(e.getClickCount() < 2) return;
335     setValue(getValueByPoint(e.getPoint()));
336     }
337     });
338    
339     addChangeListener(new ChangeListener() {
340     public void
341     stateChanged(ChangeEvent e) { setVolume(); }
342     });
343     }
344     }
345    
346    
347     private class PowerButton extends PixmapToggleButton implements ActionListener {
348    
349     PowerButton() {
350     super(Res.gfxPowerOff, Res.gfxPowerOn);
351    
352     setSelected(true);
353     addActionListener(this);
354     setToolTipText(i18n.getButtonLabel("Channel.ttRemoveChannel"));
355     }
356    
357     public void
358     actionPerformed(ActionEvent e) {
359     boolean b = preferences().getBoolProperty(CONFIRM_CHANNEL_REMOVAL);
360     if(b) {
361     String s = i18n.getMessage("Channel.remove?", channel.getChannelId());
362     if(!HF.showYesNoDialog(NormalChannelView.this, s)) {
363     setSelected(true);
364     return;
365     }
366     }
367     channel.remove();
368     }
369    
370     public boolean
371     contains(int x, int y) { return (x - 11)*(x - 11) + (y - 11)*(y - 11) < 71; }
372     }
373    
374     private class MuteButton extends PixmapButton implements ActionListener {
375     MuteButton() {
376     super(Res.gfxMuteOff);
377     //setDisabledIcon(Res.gfxMuteSoloDisabled);
378     setDisabledIcon (
379     SubstanceImageCreator.makeTransparent(this, Res.gfxMuteOff, 0.4)
380     );
381     addActionListener(this);
382     }
383    
384     public void
385     actionPerformed(ActionEvent e) {
386     SamplerChannel sc = channel.getChannelInfo();
387     boolean b = true;
388    
389     /*
390     * Changing the mute button icon now instead of
391     * leaving the work to the notification mechanism of the LinuxSampler.
392     */
393     if(sc.isMuted() && !sc.isMutedBySolo()) {
394     b = false;
395     boolean hasSolo = CC.getSamplerModel().hasSoloChannel();
396    
397     if(sc.isSoloChannel() || !hasSolo) setIcon(Res.gfxMuteOff);
398     else setIcon(Res.gfxMutedBySolo);
399     } else setIcon(Res.gfxMuteOn);
400    
401     channel.getModel().setBackendMute(b);
402     }
403    
404     public boolean
405     contains(int x, int y) { return (x > 5 && x < 23) && (y > 5 && y < 16); }
406     }
407    
408     private class SoloButton extends PixmapButton implements ActionListener {
409     SoloButton() {
410     super(Res.gfxSoloOff);
411     //setDisabledIcon(Res.gfxMuteSoloDisabled);
412     setDisabledIcon (
413     SubstanceImageCreator.makeTransparent(this, Res.gfxSoloOff, 0.4)
414     );
415     addActionListener(this);
416     }
417    
418     public void
419     actionPerformed(ActionEvent e) {
420     SamplerChannel sc = channel.getChannelInfo();
421     boolean b = !sc.isSoloChannel();
422    
423     /*
424     * Changing the solo button icon (and related) now instead of
425     * leaving the work to the notification mechanism of the LinuxSampler.
426     */
427     if(b) {
428     setIcon(Res.gfxSoloOn);
429     if(sc.isMutedBySolo()) btnMute.setIcon(Res.gfxMuteOff);
430     } else {
431     setIcon(Res.gfxSoloOff);
432     if(!sc.isMuted() && CC.getSamplerModel().getSoloChannelCount() > 1)
433     btnMute.setIcon(Res.gfxMutedBySolo);
434     }
435    
436     channel.getModel().setBackendSolo(b);
437     }
438    
439     public boolean
440     contains(int x, int y) { return (x > 5 && x < 23) && (y > 5 && y < 16); }
441     }
442    
443     private class OptionsButton extends PixmapToggleButton implements ActionListener {
444     OptionsButton() {
445     super(Res.gfxOptionsOff, Res.gfxOptionsOn);
446     setRolloverIcon(Res.gfxOptionsOffRO);
447     this.setRolloverSelectedIcon(Res.gfxOptionsOnRO);
448     addActionListener(this);
449     setToolTipText(i18n.getButtonLabel("Channel.ttShowOptions"));
450     }
451    
452     public void
453     actionPerformed(ActionEvent e) {
454     channel.showOptionsPane(isSelected());
455    
456     String s;
457     if(isSelected()) s = i18n.getButtonLabel("Channel.ttHideOptions");
458     else s = i18n.getButtonLabel("Channel.ttShowOptions");
459    
460     setToolTipText(s);
461     }
462    
463     public boolean
464     contains(int x, int y) { return super.contains(x, y) & y < 13; }
465     }
466     }
467    
468    
469    
470     class ChannelPane extends PixmapPane {
471     ChannelPane() {
472     super(Res.gfxChannel);
473     setPixmapInsets(new Insets(3, 3, 3, 3));
474     }
475     }
476    
477     class ChannelScreen extends PixmapPane {
478     private final Channel channel;
479    
480     private final InstrumentPane instrumentPane;
481    
482     private JButton btnInstr =
483     createScreenButton(i18n.getButtonLabel("ChannelScreen.btnInstr"));
484    
485     private final JButton btnEditInstr =
486     createScreenButton(i18n.getButtonLabel("ChannelScreen.btnEditInstr"));
487     private final ScreenButtonBg sbbEditInstr = new ScreenButtonBg(btnEditInstr);
488    
489     private final JButton btnFxSends =
490     createScreenButton(i18n.getButtonLabel("ChannelScreen.btnFxSends"));
491    
492     private final JButton btnEngine
493     = createScreenButton(i18n.getButtonLabel("ChannelScreen.btnEngine"));
494    
495     private final JPopupMenu menuEngines = new JPopupMenu();
496    
497     private final JButton btnVolume = createScreenButton("");
498     private JSVolumeEditorPopup popupVolume;
499    
500     private final JLabel lStreams = createScreenLabel(" --");
501     private final JLabel lVoices = createScreenLabel("-- ");
502    
503     private InformationDialog fxSendsDlg = null;
504    
505     private Timer timer;
506    
507     private static NumberFormat numberFormat = NumberFormat.getInstance();
508     static {
509     numberFormat.setMaximumFractionDigits(1);
510     }
511    
512     ChannelScreen(final Channel channel) {
513     super(Res.gfxChannelScreen);
514     setPixmapInsets(new Insets(6, 6, 6, 6));
515     setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
516    
517     this.channel = channel;
518     popupVolume = new JSVolumeEditorPopup(btnVolume, VolumeType.CHANNEL);
519    
520     setOpaque(false);
521    
522     setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
523    
524     btnInstr.setAlignmentX(CENTER_ALIGNMENT);
525     btnInstr.setRolloverEnabled(false);
526     btnInstr.setBorder(BorderFactory.createEmptyBorder(3, 0, 0, 0));
527    
528     instrumentPane = new InstrumentPane();
529     add(instrumentPane);
530    
531     JPanel p = new JPanel();
532     p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));
533     p.setAlignmentX(CENTER_ALIGNMENT);
534     p.setBorder(BorderFactory.createEmptyBorder(5, 2, 0, 0));
535    
536     btnFxSends.setToolTipText(i18n.getButtonLabel("ChannelScreen.btnFxSends.tt"));
537     btnFxSends.addActionListener(new ActionListener() {
538     public void
539     actionPerformed(ActionEvent e) {
540     if(fxSendsDlg != null && fxSendsDlg.isVisible()) {
541     fxSendsDlg.toFront();
542     return;
543     }
544     FxSendsPane p = new FxSendsPane(channel.getModel());
545     int id = channel.getModel().getChannelId();
546     fxSendsDlg = new InformationDialog(CC.getMainFrame(), p);
547     fxSendsDlg.setTitle(i18n.getLabel("FxSendsDlg.title", id));
548     fxSendsDlg.setModal(false);
549     fxSendsDlg.showCloseButton(false);
550     fxSendsDlg.setVisible(true);
551     }
552     });
553    
554     p.add(btnFxSends);
555    
556     //p.add(Box.createRigidArea(new Dimension(6, 0)));
557     p.add(Box.createGlue());
558    
559     btnEngine.setIcon(Res.iconEngine12);
560     btnEngine.setIconTextGap(1);
561     p.add(btnEngine);
562     //p.add(new Label("|"));
563    
564     //p.add(Box.createRigidArea(new Dimension(6, 0)));
565    
566     //p.add(btnReset);
567    
568     p.add(Box.createGlue());
569    
570     lStreams.setFont(Res.fontScreenMono);
571     lStreams.setHorizontalAlignment(JLabel.RIGHT);
572     lStreams.setToolTipText(i18n.getLabel("ChannelScreen.streamVoiceCount"));
573     p.add(lStreams);
574    
575     JLabel l = createScreenLabel("/");
576     l.setFont(Res.fontScreenMono);
577     l.setToolTipText(i18n.getLabel("ChannelScreen.streamVoiceCount"));
578     p.add(l);
579    
580     lVoices.setFont(Res.fontScreenMono);
581     lVoices.setToolTipText(i18n.getLabel("ChannelScreen.streamVoiceCount"));
582     p.add(lVoices);
583    
584     btnVolume.setIcon(Res.iconVolume14);
585     btnVolume.setIconTextGap(2);
586     btnVolume.setAlignmentX(RIGHT_ALIGNMENT);
587     btnVolume.setHorizontalAlignment(btnVolume.LEFT);
588     updateVolumeInfo(100);
589     Dimension d = btnVolume.getPreferredSize();
590     d.width = 60;
591     btnVolume.setPreferredSize(d);
592     btnVolume.setMinimumSize(d);
593    
594     btnVolume.addActionListener(new ActionListener() {
595     public void
596     actionPerformed(ActionEvent e) {
597     if(popupVolume.isVisible()) {
598     popupVolume.commit();
599     popupVolume.hide();
600     } else {
601     float vol = channel.getModel().getChannelInfo().getVolume();
602     popupVolume.setCurrentVolume(vol);
603     popupVolume.show();
604     }
605     }
606     });
607    
608     popupVolume.addActionListener(new ActionListener() {
609     public void
610     actionPerformed(ActionEvent e) {
611     channel.getModel().setBackendVolume(popupVolume.getVolumeFactor());
612     }
613     });
614    
615     p.add(btnVolume);
616     p.setPreferredSize(new Dimension(260, p.getPreferredSize().height));
617     p.setMinimumSize(p.getPreferredSize());
618     p.setMaximumSize(p.getPreferredSize());
619    
620     //btnInstr.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
621     p.setOpaque(false);
622     add(p);
623    
624    
625     setPreferredSize(new Dimension(270, 48));
626     setMinimumSize(getPreferredSize());
627     setMaximumSize(getPreferredSize());
628    
629     createEngineMenu();
630     installListeners();
631     }
632    
633     protected void
634     onDestroy() { timer.stop(); }
635    
636     private void
637     createEngineMenu() {
638     for(final SamplerEngine engine : CC.getSamplerModel().getEngines()) {
639     JMenuItem mi = new JMenuItem(engine.getName() + " engine");
640     mi.setToolTipText(engine.getDescription());
641    
642     mi.addActionListener(new ActionListener() {
643     public void
644     actionPerformed(ActionEvent e) {
645     channel.getModel().setBackendEngineType(engine.getName());
646     }
647     });
648    
649     menuEngines.add(mi);
650     }
651     }
652    
653     private void
654     installListeners() {
655     btnInstr.addActionListener(new ActionListener() {
656     public void
657     actionPerformed(ActionEvent e) { loadInstrument(); }
658     });
659    
660     btnEditInstr.addActionListener(new ActionListener() {
661     public void
662     actionPerformed(ActionEvent e) {
663     CC.getSamplerModel().editBackendInstrument(channel.getChannelId());
664     }
665     });
666    
667     btnEngine.addActionListener(new ActionListener() {
668     public void
669     actionPerformed(ActionEvent e) {
670     int y = btnEngine.getHeight() + 1;
671     menuEngines.show(btnEngine, 0, y);
672     }
673     });
674    
675     addMouseListener(getHandler());
676     addHierarchyListener(getHandler());
677    
678     ActionListener l = new ActionListener() {
679     public void
680     actionPerformed(ActionEvent e) {
681     if(getMousePosition(true) != null) {
682     getHandler().mouseEntered(null);
683     } else {
684     getHandler().mouseExited(null);
685     }
686     }
687     };
688     timer = new Timer(1000, l);
689     timer.start();
690     }
691    
692     private void
693     loadInstrument() {
694     JSInstrumentChooser dlg = FantasiaUtils.createInstrumentChooser(CC.getMainFrame());
695     dlg.setVisible(true);
696    
697     if(!dlg.isCancelled()) {
698     SamplerChannelModel m = channel.getModel();
699     m.loadBackendInstrument(dlg.getInstrumentFile(), dlg.getInstrumentIndex());
700     }
701     }
702    
703     protected void
704     updateScreenInfo(SamplerChannel sc) {
705     int status = sc.getInstrumentStatus();
706     if(status >= 0 && status < 100) {
707     btnInstr.setText(i18n.getLabel("ChannelScreen.loadingInstrument", status));
708     } else if(status == -1) {
709     btnInstr.setText(i18n.getButtonLabel("ChannelScreen.btnInstr"));
710     } else if(status < -1) {
711     btnInstr.setText(i18n.getLabel("ChannelScreen.errorLoadingInstrument"));
712     } else {
713     if(sc.getInstrumentName() != null) btnInstr.setText(sc.getInstrumentName());
714     else btnInstr.setText(i18n.getButtonLabel("ChannelScreen.btnInstr"));
715     }
716    
717     instrumentPane.update();
718    
719     if(sc.getEngine() != null) {
720     String s = sc.getEngine().getName();
721     s += " engine";
722     if(!s.equals(btnEngine.getText())) {
723     btnEngine.setText(s);
724     btnEngine.setToolTipText(sc.getEngine().getDescription());
725     }
726     }
727    
728     }
729    
730     protected void
731     updateVolumeInfo(int volume) {
732     if(CC.getViewConfig().isMeasurementUnitDecibel()) {
733     String s = numberFormat.format(HF.percentsToDecibels(volume));
734     btnVolume.setText(s + "dB");
735     } else {
736     btnVolume.setText(String.valueOf(volume) + "%");
737     }
738     }
739    
740     /**
741     * Updates the number of active disk streams.
742     * @param count The new number of active disk streams.
743     */
744     protected void
745     updateStreamCount(int count) {
746     Dimension d = lStreams.getPreferredSize();
747     lStreams.setText(count == 0 ? "--" : String.valueOf(count));
748     d = JuifeUtils.getUnionSize(d, lStreams.getPreferredSize());
749     lStreams.setMinimumSize(d);
750     lStreams.setPreferredSize(d);
751     lStreams.setMaximumSize(d);
752     }
753    
754     /**
755     * Updates the number of active voices.
756     * @param count The new number of active voices.
757     */
758     protected void
759     updateVoiceCount(int count) {
760     Dimension d = lVoices.getPreferredSize();
761     lVoices.setText(count == 0 ? "--" : String.valueOf(count));
762     d = JuifeUtils.getUnionSize(d, lVoices.getPreferredSize());
763     lVoices.setMinimumSize(d);
764     lVoices.setPreferredSize(d);
765     lVoices.setMaximumSize(d);
766     }
767    
768     class InstrumentPane extends JPanel {
769     private final JPanel leftPane = new JPanel();
770     private final JPanel rightPane = new JPanel();
771    
772     InstrumentPane() {
773     setOpaque(false);
774     setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
775     add(leftPane);
776     add(btnInstr);
777     add(rightPane);
778     add(sbbEditInstr);
779     btnEditInstr.setToolTipText(i18n.getLabel("ChannelScreen.btnEditInstr.tt"));
780     sbbEditInstr.setVisible(false);
781     setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 6));
782    
783     update();
784     }
785    
786     public void
787     update() {
788     int a = btnInstr.getMinimumSize().width;
789     int b = 0;
790     if(sbbEditInstr.isVisible()) b = sbbEditInstr.getPreferredSize().width;
791    
792     int max = 254 - b;
793     if(a > max) a = max;
794    
795     int h = btnInstr.getPreferredSize().height;
796     btnInstr.setPreferredSize(new Dimension(a, h));
797     h = btnInstr.getMaximumSize().height;
798     btnInstr.setMaximumSize(new Dimension(a, h));
799    
800    
801     int i = (254 - btnInstr.getPreferredSize().width) / 2;
802    
803     int j = i;
804     if(sbbEditInstr.isVisible()) j -= sbbEditInstr.getPreferredSize().width;
805     if(i < 0 || j < 0) i = j = 0;
806    
807     Dimension d = new Dimension(i, 1);
808     leftPane.setMinimumSize(d);
809     leftPane.setPreferredSize(d);
810     leftPane.setMaximumSize(d);
811    
812     d = new Dimension(j, 1);
813     rightPane.setMinimumSize(d);
814     rightPane.setPreferredSize(d);
815     rightPane.setMaximumSize(d);
816    
817     validate();
818     }
819     }
820    
821     class FxSendsPane extends JSFxSendsPane {
822     FxSendsPane(SamplerChannelModel model) {
823     super(model);
824    
825     actionAddFxSend.putValue(Action.SMALL_ICON, Res.iconNew16);
826     actionRemoveFxSend.putValue(Action.SMALL_ICON, Res.iconDelete16);
827     }
828    
829     protected JToolBar
830     createToolBar() {
831     JToolBar tb = new JToolBar();
832     Dimension d = new Dimension(Short.MAX_VALUE, tb.getPreferredSize().height);
833     tb.setMaximumSize(d);
834     tb.setFloatable(false);
835     tb.setAlignmentX(JPanel.RIGHT_ALIGNMENT);
836    
837     tb.add(new ToolbarButton(actionAddFxSend));
838     tb.add(new ToolbarButton(actionRemoveFxSend));
839    
840     return tb;
841     }
842     }
843    
844     static class ScreenButtonBg extends PixmapPane {
845     ScreenButtonBg(JButton btn) {
846     super(Res.gfxScreenBtnBg);
847     setPixmapInsets(new Insets(4, 4, 4, 4));
848     setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
849     setBorder(BorderFactory.createEmptyBorder(0, 7, 0, 7));
850     add(btn);
851     setPreferredSize(new Dimension(getPreferredSize().width, 13));
852     }
853    
854     public Dimension
855     getPreferredSize() {
856     return new Dimension(super.getPreferredSize().width, 13);
857     }
858     }
859    
860    
861     private final EventHandler eventHandler = new EventHandler();
862    
863     private EventHandler
864     getHandler() { return eventHandler; }
865    
866     private class EventHandler extends MouseAdapter implements HierarchyListener {
867     public void
868     mouseEntered(MouseEvent e) {
869     if(channel.getChannelInfo().getInstrumentStatus() != 100) return;
870    
871     if(!sbbEditInstr.isVisible()) {
872     sbbEditInstr.setVisible(true);
873     instrumentPane.update();
874     }
875     }
876    
877     public void
878     mouseExited(MouseEvent e) {
879     if(getMousePosition(true) != null) return;
880     if(sbbEditInstr.isVisible()) {
881     sbbEditInstr.setVisible(false);
882     instrumentPane.update();
883     }
884     }
885    
886     /** Called when the hierarchy has been changed. */
887     public void
888     hierarchyChanged(HierarchyEvent e) {
889     if((e.getChangeFlags() & e.SHOWING_CHANGED) == e.SHOWING_CHANGED) {
890     if(getMousePosition() == null) mouseExited(null);
891     else mouseEntered(null);
892     }
893     }
894     }
895     }

  ViewVC Help
Powered by ViewVC