/[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 1776 - (show annotations) (download)
Thu Sep 11 18:48:36 2008 UTC (15 years, 6 months ago) by iliev
File size: 18997 byte(s)
* Implemented virtual MIDI keyboard

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

  ViewVC Help
Powered by ViewVC