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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1767 - (show annotations) (download)
Mon Sep 8 00:19:27 2008 UTC (15 years, 7 months ago) by iliev
File size: 18609 byte(s)
* Added `Copy To' and `Move To' commands to the MIDI bank context menu
  and to the MIDI instrument context menu
* Added commands to the MIDI instrument context menu for moving
  a MIDI instrument to another program
  (right-click on a MIDI instrument and choose `Change Program')
* Added option to choose between zero-based and one-based
  MIDI bank/program numbering
  (choose Edit/Preferences, then click the `Advanced' button)
* Added option to choose whether to include MIDI instrument
  mappings when exporting a sampler configuration to LSCP script.
  (choose Edit/Preferences, then click the `Advanced' button)
* Added option to set the MIDI instrument loading in background
  when exporting MIDI instrument mappings to LSCP script.
  (choose Edit/Preferences, then click the `Advanced' button)
* Implemented an option to change the socket read timeout
  (choose Edit/Preferences, then click the `Backend' tab)
* Updated LscpTree
* Fantasia: Added option to hide the active stream/voice count statistic
  in the sampler channel's small view
  (choose Edit/Preferences, then click the `Channels' tab)
* Fantasia: `Turn off animation effects' checkbox moved to the `View' tab

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.MouseListener;
31
32 import java.beans.PropertyChangeEvent;
33 import java.beans.PropertyChangeListener;
34
35 import java.util.Vector;
36
37 import javax.swing.BorderFactory;
38 import javax.swing.Box;
39 import javax.swing.BoxLayout;
40 import javax.swing.JButton;
41 import javax.swing.JComponent;
42 import javax.swing.JLabel;
43 import javax.swing.JPanel;
44
45 import org.jsampler.CC;
46 import org.jsampler.event.SamplerChannelListEvent;
47 import org.jsampler.event.SamplerChannelListListener;
48
49 import org.jvnet.substance.utils.SubstanceImageCreator;
50
51 import org.linuxsampler.lscp.SamplerChannel;
52
53 import static org.jsampler.view.fantasia.FantasiaI18n.i18n;
54 import static org.jsampler.view.fantasia.FantasiaPrefs.*;
55 import static org.jsampler.view.fantasia.FantasiaUtils.*;
56
57
58 /**
59 *
60 * @author Grigor Iliev
61 */
62 public class SmallChannelView extends PixmapPane implements ChannelView {
63 private final Channel channel;
64 private ChannelOptionsView channelOptionsView = null;
65
66 private final ChannelScreen screen;
67 private final Channel.PowerButton btnPower;
68 private final MuteButton btnMute = new MuteButton();
69 private final SoloButton btnSolo = new SoloButton();
70 private final Channel.OptionsButton btnOptions;
71
72 private final Vector<JComponent> components = new Vector<JComponent>();
73
74
75 /** Creates a new instance of <code>SmallChannelView</code> */
76 public
77 SmallChannelView(Channel channel) {
78 super(Res.gfxDeviceBg);
79 setPixmapInsets(new Insets(1, 1, 1, 1));
80
81 components.add(this);
82
83 this.channel = channel;
84
85 screen = new ChannelScreen(channel);
86
87 btnPower = new Channel.PowerButton(channel);
88 components.add(btnPower);
89
90 btnOptions = new Channel.OptionsButton(channel);
91 components.add(btnOptions);
92
93 setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
94
95 setBorder(BorderFactory.createEmptyBorder(1, 3, 0, 11));
96
97 add(btnPower);
98 add(Box.createRigidArea(new Dimension(4, 0)));
99
100 add(createVSeparator());
101 add(Box.createRigidArea(new Dimension(3, 0)));
102
103 add(screen);
104
105 add(Box.createRigidArea(new Dimension(2, 0)));
106 add(createVSeparator());
107 add(new FxSendsButton());
108
109 add(createVSeparator());
110 add(Box.createRigidArea(new Dimension(1, 0)));
111
112 components.add(btnMute);
113 components.add(btnSolo);
114
115 add(btnMute);
116 add(btnSolo);
117
118 add(Box.createRigidArea(new Dimension(1, 0)));
119 add(createVSeparator());
120 add(Box.createRigidArea(new Dimension(8, 0)));
121
122 add(btnOptions);
123
124 setPreferredSize(new Dimension(420, 22));
125 setMinimumSize(getPreferredSize());
126 setMaximumSize(getPreferredSize());
127
128 installView();
129 }
130
131 //////////////////////////////////////////////
132 // Implementation of the ChannelView interface
133 //////////////////////////////////////////////
134
135 public Type
136 getType() { return Type.SMALL; }
137
138 public JComponent
139 getComponent() { return this; }
140
141 public void
142 installView() {
143 String vmud = VOL_MEASUREMENT_UNIT_DECIBEL;
144 preferences().addPropertyChangeListener(vmud, new PropertyChangeListener() {
145 public void
146 propertyChange(PropertyChangeEvent e) {
147 boolean b;
148 b = preferences().getBoolProperty(VOL_MEASUREMENT_UNIT_DECIBEL);
149 screen.updateVolumeInfo();
150 }
151 });
152
153 addEnhancedMouseListener(channel.getContextMenu());
154 CC.getSamplerModel().addSamplerChannelListListener(getHandler());
155 }
156
157 public void
158 uninstallView() {
159 //removeEnhancedMouseListener(channel.getContextMenu());
160 CC.getSamplerModel().removeSamplerChannelListListener(getHandler());
161 screen.onDestroy();
162 btnOptions.onDestroy();
163 uninstallChannelOptionsView();
164 }
165
166 public void
167 installChannelOptionsView() {
168 if(channelOptionsView != null) return;
169
170 channelOptionsView = new NormalChannelOptionsView(channel);
171 channelOptionsView.installView();
172
173 }
174
175 public void
176 uninstallChannelOptionsView() {
177 if(channelOptionsView == null) return;
178 channelOptionsView.uninstallView();
179 channelOptionsView = null;
180 }
181
182 public ChannelOptionsView
183 getChannelOptionsView() { return channelOptionsView; }
184
185 public void
186 updateChannelInfo() {
187 SamplerChannel sc = channel.getChannelInfo();
188
189 screen.updateScreenInfo(sc);
190 screen.updateVolumeInfo();
191 updateMuteIcon(sc);
192
193 if(sc.isSoloChannel()) btnSolo.setIcon(Res.gfxSoloSmallOn);
194 else btnSolo.setIcon(Res.gfxSoloSmallOff);
195
196 boolean b = sc.getEngine() != null;
197 btnSolo.setEnabled(b);
198 btnMute.setEnabled(b);
199
200 if(getChannelOptionsView() != null) getChannelOptionsView().updateChannelInfo();
201 }
202
203 public void
204 updateStreamCount(int count) { screen.updateStreamCount(count); }
205
206 public void
207 updateVoiceCount(int count) { screen.updateVoiceCount(count); }
208
209 public void
210 expandChannel() {
211 if(btnOptions.isSelected()) return;
212 btnOptions.doClick();
213 }
214
215 public boolean
216 isOptionsButtonSelected() { return btnOptions.isSelected(); }
217
218 public void
219 setOptionsButtonSelected(boolean b) {
220 btnOptions.setSelected(b);
221 }
222
223 public void
224 addEnhancedMouseListener(MouseListener l) {
225 removeEnhancedMouseListener(l);
226
227 for(JComponent c : components) c.addMouseListener(l);
228 screen.addEnhancedMouseListener(l);
229 }
230
231 public void
232 removeEnhancedMouseListener(MouseListener l) {
233 for(JComponent c : components) c.removeMouseListener(l);
234 screen.removeEnhancedMouseListener(l);
235 }
236
237 //////////////////////////////////////////////
238
239
240 /**
241 * Updates the mute button with the proper icon regarding to information obtained
242 * from <code>channel</code>.
243 * @param channel A <code>SamplerChannel</code> instance containing the new settings
244 * for this channel.
245 */
246 private void
247 updateMuteIcon(SamplerChannel channel) {
248 if(channel.isMutedBySolo()) btnMute.setIcon(Res.gfxMutedBySoloSmall);
249 else if(channel.isMuted()) btnMute.setIcon(Res.gfxMuteSmallOn);
250 else btnMute.setIcon(Res.gfxMuteSmallOff);
251 }
252
253 protected JPanel
254 createVSeparator() {
255 PixmapPane p = new PixmapPane(Res.gfxVLine);
256 p.setOpaque(false);
257 p.setPreferredSize(new Dimension(2, 22));
258 p.setMinimumSize(p.getPreferredSize());
259 p.setMaximumSize(p.getPreferredSize());
260 return p;
261 }
262
263
264 private final EventHandler eventHandler = new EventHandler();
265
266 private EventHandler
267 getHandler() { return eventHandler; }
268
269 private class EventHandler implements SamplerChannelListListener {
270 public void
271 channelAdded(SamplerChannelListEvent e) {
272 if(CC.getSamplerModel().getChannelListIsAdjusting()) return;
273 screen.channelInfoPane.updateChannelIndex();
274 }
275
276 public void
277 channelRemoved(SamplerChannelListEvent e) {
278 //if(CC.getSamplerModel().getChannelListIsAdjusting()) return; //TODO:
279
280 screen.channelInfoPane.updateChannelIndex();
281 }
282 }
283
284
285 private class MuteButton extends PixmapButton implements ActionListener {
286 MuteButton() {
287 super(Res.gfxMuteSmallOff);
288 setDisabledIcon (
289 SubstanceImageCreator.makeTransparent(this, Res.gfxMuteSmallOff, 0.4)
290 );
291 addActionListener(this);
292 }
293
294 public void
295 actionPerformed(ActionEvent e) {
296 SamplerChannel sc = channel.getChannelInfo();
297 boolean b = true;
298
299 /*
300 * Changing the mute button icon now instead of
301 * leaving the work to the notification mechanism of the LinuxSampler.
302 */
303 if(sc.isMuted() && !sc.isMutedBySolo()) {
304 b = false;
305 boolean hasSolo = CC.getSamplerModel().hasSoloChannel();
306
307 if(sc.isSoloChannel() || !hasSolo) setIcon(Res.gfxMuteSmallOff);
308 else setIcon(Res.gfxMutedBySoloSmall);
309 } else setIcon(Res.gfxMuteSmallOn);
310
311 channel.getModel().setBackendMute(b);
312 }
313
314 //public boolean
315 //contains(int x, int y) { return (x > 5 && x < 23) && (y > 5 && y < 16); }
316 }
317
318 private class SoloButton extends PixmapButton implements ActionListener {
319 SoloButton() {
320 super(Res.gfxSoloSmallOff);
321 //setDisabledIcon(Res.gfxMuteSoloDisabled);
322 setDisabledIcon (
323 SubstanceImageCreator.makeTransparent(this, Res.gfxSoloSmallOff, 0.4)
324 );
325 addActionListener(this);
326 }
327
328 public void
329 actionPerformed(ActionEvent e) {
330 SamplerChannel sc = channel.getChannelInfo();
331 boolean b = !sc.isSoloChannel();
332
333 /*
334 * Changing the solo button icon (and related) now instead of
335 * leaving the work to the notification mechanism of the LinuxSampler.
336 */
337 if(b) {
338 setIcon(Res.gfxSoloSmallOn);
339 if(sc.isMutedBySolo()) btnMute.setIcon(Res.gfxMuteSmallOff);
340 } else {
341 setIcon(Res.gfxSoloSmallOff);
342 if(!sc.isMuted() && CC.getSamplerModel().getSoloChannelCount() > 1)
343 btnMute.setIcon(Res.gfxMutedBySoloSmall);
344 }
345
346 channel.getModel().setBackendSolo(b);
347 }
348
349 //public boolean
350 //contains(int x, int y) { return (x > 5 && x < 23) && (y > 5 && y < 16); }
351 }
352
353 static class ChannelScreen extends PixmapPane {
354 private final Channel channel;
355
356 private final ChannelInfoPane channelInfoPane;
357
358 private final Channel.StreamVoiceCountPane streamVoiceCountPane;
359
360
361 private final Channel.VolumePane volumePane;
362
363 private JButton btnInstr =
364 createScreenButton(i18n.getButtonLabel("ChannelScreen.btnInstr"));
365
366
367 private static Insets pixmapInsets = new Insets(5, 5, 4, 5);
368
369 private final Vector<JComponent> components = new Vector<JComponent>();
370
371 private final PropertyChangeListener chnNumberingListener;
372 private final PropertyChangeListener showMidiInfoListener;
373 private final PropertyChangeListener showStreamVoiceCountListener;
374
375 private boolean bShowNumbering;
376 private boolean bShowMidiInfo;
377
378 ChannelScreen(final Channel channel) {
379 super(Res.gfxTextField);
380
381 components.add(this);
382
383 this.channel = channel;
384
385 streamVoiceCountPane = new Channel.StreamVoiceCountPane(channel);
386 components.add(streamVoiceCountPane);
387
388 channelInfoPane = new ChannelInfoPane(channel);
389 volumePane = new Channel.VolumePane(channel);
390 components.add(volumePane);
391
392 setPixmapInsets(pixmapInsets);
393 setBorder(BorderFactory.createEmptyBorder(4, 3, 3, 4));
394
395 setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
396
397 JPanel p = new JPanel();
398 components.add(p);
399 p.setOpaque(false);
400 p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));
401
402 p.add(channelInfoPane);
403
404 btnInstr.setRolloverEnabled(false);
405 btnInstr.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
406 btnInstr.setHorizontalAlignment(btnInstr.LEFT);
407
408 int h = btnInstr.getPreferredSize().height;
409 btnInstr.setPreferredSize(new Dimension(100, h));
410 btnInstr.setMinimumSize(btnInstr.getPreferredSize());
411 btnInstr.setMaximumSize(new Dimension(Short.MAX_VALUE, h));
412 components.add(btnInstr);
413
414 p.add(btnInstr);
415 p.add(streamVoiceCountPane);
416
417 h = p.getPreferredSize().height;
418 p.setPreferredSize(new Dimension(201, h));
419 p.setMinimumSize(p.getPreferredSize());
420 p.setMaximumSize(p.getPreferredSize());
421
422 add(p);
423 add(Box.createRigidArea(new Dimension(3, 0)));
424 add(volumePane);
425
426 setPreferredSize(new Dimension(270, getPreferredSize().height));
427 setMinimumSize(getPreferredSize());
428 setMaximumSize(getPreferredSize());
429
430 btnInstr.addActionListener(new ActionListener() {
431 public void
432 actionPerformed(ActionEvent e) { channel.loadInstrument(); }
433 });
434
435 final String s = "channel.smallView.showChannelNumbering";
436
437 chnNumberingListener = new PropertyChangeListener() {
438 public void
439 propertyChange(PropertyChangeEvent e) {
440 bShowNumbering = preferences().getBoolProperty(s);
441 channelInfoPane.setShowNumbering(bShowNumbering);
442 }
443 };
444
445 preferences().addPropertyChangeListener(s, chnNumberingListener);
446
447 bShowNumbering = preferences().getBoolProperty(s);
448 channelInfoPane.setShowNumbering(bShowNumbering);
449
450
451 final String s2 = "channel.smallView.showMidiInfo";
452
453 showMidiInfoListener = new PropertyChangeListener() {
454 public void
455 propertyChange(PropertyChangeEvent e) {
456 bShowMidiInfo = preferences().getBoolProperty(s2);
457 channelInfoPane.setShowMidiInfo(bShowMidiInfo);
458 }
459 };
460
461 preferences().addPropertyChangeListener(s2, showMidiInfoListener);
462
463 bShowMidiInfo = preferences().getBoolProperty(s2);
464 channelInfoPane.setShowMidiInfo(bShowMidiInfo);
465
466
467 final String s3 = "channel.smallView.showStreamVoiceCount";
468
469 showStreamVoiceCountListener = new PropertyChangeListener() {
470 public void
471 propertyChange(PropertyChangeEvent e) {
472 boolean b = preferences().getBoolProperty(s3);
473 streamVoiceCountPane.setVisible(b);
474 }
475 };
476
477 preferences().addPropertyChangeListener(s3, showStreamVoiceCountListener);
478
479 boolean b = preferences().getBoolProperty(s3);
480 streamVoiceCountPane.setVisible(b);
481 }
482
483 public void
484 addEnhancedMouseListener(MouseListener l) {
485 removeEnhancedMouseListener(l);
486 for(JComponent c : components) c.addMouseListener(l);
487 }
488
489 public void
490 removeEnhancedMouseListener(MouseListener l) {
491 for(JComponent c : components) c.removeMouseListener(l);
492 }
493
494 protected void
495 updateVolumeInfo() {
496 float f = channel.getChannelInfo().getVolume() * 100.0f;
497 volumePane.updateVolumeInfo((int)f);
498 }
499
500 /**
501 * Updates the number of active disk streams.
502 * @param count The new number of active disk streams.
503 */
504 protected void
505 updateStreamCount(int count) {
506 streamVoiceCountPane.updateStreamCount(count);
507 }
508
509 /**
510 * Updates the number of active voices.
511 * @param count The new number of active voices.
512 */
513 protected void
514 updateVoiceCount(int count) {
515 streamVoiceCountPane.updateVoiceCount(count);
516 }
517
518 protected void
519 updateScreenInfo(SamplerChannel sc) {
520 String s = btnInstr.getToolTipText();
521
522 int status = sc.getInstrumentStatus();
523 if(status >= 0 && status < 100) {
524 btnInstr.setText(i18n.getLabel("ChannelScreen.loadingInstrument", status));
525 if(s != null) btnInstr.setToolTipText(null);
526 } else if(status == -1) {
527 btnInstr.setText(i18n.getButtonLabel("ChannelScreen.btnInstr"));
528 if(s != null) btnInstr.setToolTipText(null);
529 } else if(status < -1) {
530 btnInstr.setText(i18n.getLabel("ChannelScreen.errorLoadingInstrument"));
531 if(s != null) btnInstr.setToolTipText(null);
532 } else {
533 if(sc.getInstrumentName() != null) btnInstr.setText(sc.getInstrumentName());
534 else btnInstr.setText(i18n.getButtonLabel("ChannelScreen.btnInstr"));
535
536 btnInstr.setToolTipText(sc.getInstrumentName());
537 }
538
539 channelInfoPane.updateChannelInfo();
540 }
541
542 public void
543 onDestroy() {
544 String s = "channel.smallView.showChannelNumbering";
545 preferences().removePropertyChangeListener(s, chnNumberingListener);
546
547 s = "channel.smallView.showMidiInfo";
548 preferences().removePropertyChangeListener(s, showMidiInfoListener);
549
550 s = "channel.smallView.showStreamVoiceCount";
551 preferences().removePropertyChangeListener(s, showStreamVoiceCountListener);
552 }
553 }
554
555 private static class ChannelInfoPane extends JPanel {
556 private final Channel channel;
557 private final JLabel lInfo;
558
559 private int channelIndex = -1;
560
561 private boolean showNumbering;
562 private boolean showMidiInfo;
563
564 ChannelInfoPane(Channel channel) {
565 this.channel = channel;
566
567 setOpaque(false);
568 setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
569
570 lInfo = createScreenLabel("");
571 lInfo.setFont(Res.fontScreenMono);
572
573 updateChannelIndex();
574
575 updateLabelLength();
576
577 add(lInfo);
578 }
579
580 private void
581 updateLabelLength() {
582 lInfo.setPreferredSize(null);
583
584 int l = 0;
585 if(getShowNumbering()) l += 4;
586 if(channelIndex > 98) l++;
587 if(getShowMidiInfo()) l += 6;
588
589 StringBuffer sb = new StringBuffer();
590 for(int i = 0; i < l; i++) sb.append("0");
591 lInfo.setText(sb.toString());
592
593 lInfo.setPreferredSize(lInfo.getPreferredSize()); // Don't remove this!
594 lInfo.setMinimumSize(lInfo.getPreferredSize());
595 lInfo.setMaximumSize(lInfo.getPreferredSize());
596 }
597
598 protected void
599 updateChannelInfo() {
600 StringBuffer sb = new StringBuffer();
601
602 if(getShowNumbering()) {
603 if(channelIndex < 9) sb.append(" ");
604 sb.append(channelIndex + 1).append(": ");
605 }
606
607 if(getShowMidiInfo()) {
608 SamplerChannel sc = channel.getChannelInfo();
609 if(sc.getMidiInputDevice() == -1) {
610 sb.append("-/-");
611 } else {
612 sb.append(sc.getMidiInputPort()).append("/");
613
614 if(sc.getMidiInputChannel() == -1) sb.append("All");
615 else sb.append(sc.getMidiInputChannel() + 1);
616 }
617 }
618
619 lInfo.setText(sb.toString());
620 }
621
622 protected void
623 updateChannelIndex() {
624 int i = CC.getSamplerModel().getChannelIndex(channel.getModel());
625
626 boolean b = false;
627 if(i > 98 && channelIndex <= 98) b = true;
628 if(i < 99 && channelIndex >= 99) b = true;
629
630 channelIndex = i;
631 if(b) updateLabelLength();
632
633 if(!getShowNumbering()) return;
634
635 updateChannelInfo();
636 }
637
638 protected boolean
639 getShowNumbering() { return showNumbering; }
640
641 protected void
642 setShowNumbering(boolean b) {
643 if(b == showNumbering) return;
644 showNumbering = b;
645
646 updateLabelLength();
647 updateChannelIndex();
648 }
649
650 protected boolean
651 getShowMidiInfo() { return showMidiInfo; }
652
653 protected void
654 setShowMidiInfo(boolean b) {
655 if(b == showMidiInfo) return;
656 showMidiInfo = b;
657
658 String s = b ? i18n.getLabel("SmallChannelView.ttMidiPortChannel") : null;
659 lInfo.setToolTipText(s);
660
661 updateLabelLength();
662 updateChannelInfo();
663 }
664 }
665
666 private class FxSendsButton extends PixmapButton implements ActionListener {
667 FxSendsButton() {
668 super(Res.gfxFx);
669
670 setRolloverIcon(Res.gfxFxRO);
671
672 addActionListener(this);
673 }
674
675 public void
676 actionPerformed(ActionEvent e) { channel.showFxSendsDialog(); }
677
678 public boolean
679 contains(int x, int y) { return (x > 5 && x < 23) && (y > 5 && y < 16); }
680 }
681 }

  ViewVC Help
Powered by ViewVC