/[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 1785 - (show annotations) (download)
Tue Oct 7 00:07:14 2008 UTC (15 years, 6 months ago) by iliev
File size: 19358 byte(s)
* Fantasia: Implemented multiple channels panels
* Fantasia: Refactoring - all basic UI components moved to
  org.jsampler.view.fantasia.basic package

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

  ViewVC Help
Powered by ViewVC