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

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

Parent Directory Parent Directory | Revision Log Revision Log


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

1 /*
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