/[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 1747 - (show annotations) (download)
Mon Jun 2 04:12:34 2008 UTC (15 years, 10 months ago) by iliev
File size: 17892 byte(s)
* Fantasia: Aligned the numbering of sampler channels > 99

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.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
374 private boolean bShowNumbering;
375 private boolean bShowMidiInfo;
376
377 ChannelScreen(final Channel channel) {
378 super(Res.gfxTextField);
379
380 components.add(this);
381
382 this.channel = channel;
383
384 streamVoiceCountPane = new Channel.StreamVoiceCountPane(channel);
385 components.add(streamVoiceCountPane);
386
387 channelInfoPane = new ChannelInfoPane(channel);
388 volumePane = new Channel.VolumePane(channel);
389 components.add(volumePane);
390
391 setPixmapInsets(pixmapInsets);
392 setBorder(BorderFactory.createEmptyBorder(4, 3, 3, 4));
393
394 setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
395
396 JPanel p = new JPanel();
397 components.add(p);
398 p.setOpaque(false);
399 p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));
400
401 p.add(channelInfoPane);
402
403 btnInstr.setRolloverEnabled(false);
404 btnInstr.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
405 btnInstr.setHorizontalAlignment(btnInstr.LEFT);
406
407 int h = btnInstr.getPreferredSize().height;
408 btnInstr.setPreferredSize(new Dimension(100, h));
409 btnInstr.setMinimumSize(btnInstr.getPreferredSize());
410 btnInstr.setMaximumSize(new Dimension(Short.MAX_VALUE, h));
411 components.add(btnInstr);
412
413 p.add(btnInstr);
414
415 h = p.getPreferredSize().height;
416 p.setPreferredSize(new Dimension(159, h));
417 p.setMinimumSize(p.getPreferredSize());
418 p.setMaximumSize(p.getPreferredSize());
419
420 add(p);
421
422 add(Box.createRigidArea(new Dimension(3, 0)));
423 add(streamVoiceCountPane);
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
452 final String s2 = "channel.smallView.showMidiInfo";
453
454 showMidiInfoListener = new PropertyChangeListener() {
455 public void
456 propertyChange(PropertyChangeEvent e) {
457 bShowMidiInfo = preferences().getBoolProperty(s2);
458 channelInfoPane.setShowMidiInfo(bShowMidiInfo);
459 }
460 };
461
462 preferences().addPropertyChangeListener(s2, showMidiInfoListener);
463
464 bShowMidiInfo = preferences().getBoolProperty(s2);
465 channelInfoPane.setShowMidiInfo(bShowMidiInfo);
466 }
467
468 public void
469 addEnhancedMouseListener(MouseListener l) {
470 removeEnhancedMouseListener(l);
471 for(JComponent c : components) c.addMouseListener(l);
472 }
473
474 public void
475 removeEnhancedMouseListener(MouseListener l) {
476 for(JComponent c : components) c.removeMouseListener(l);
477 }
478
479 protected void
480 updateVolumeInfo() {
481 float f = channel.getChannelInfo().getVolume() * 100.0f;
482 volumePane.updateVolumeInfo((int)f);
483 }
484
485 /**
486 * Updates the number of active disk streams.
487 * @param count The new number of active disk streams.
488 */
489 protected void
490 updateStreamCount(int count) {
491 streamVoiceCountPane.updateStreamCount(count);
492 }
493
494 /**
495 * Updates the number of active voices.
496 * @param count The new number of active voices.
497 */
498 protected void
499 updateVoiceCount(int count) {
500 streamVoiceCountPane.updateVoiceCount(count);
501 }
502
503 protected void
504 updateScreenInfo(SamplerChannel sc) {
505 String s = btnInstr.getToolTipText();
506
507 int status = sc.getInstrumentStatus();
508 if(status >= 0 && status < 100) {
509 btnInstr.setText(i18n.getLabel("ChannelScreen.loadingInstrument", status));
510 if(s != null) btnInstr.setToolTipText(null);
511 } else if(status == -1) {
512 btnInstr.setText(i18n.getButtonLabel("ChannelScreen.btnInstr"));
513 if(s != null) btnInstr.setToolTipText(null);
514 } else if(status < -1) {
515 btnInstr.setText(i18n.getLabel("ChannelScreen.errorLoadingInstrument"));
516 if(s != null) btnInstr.setToolTipText(null);
517 } else {
518 if(sc.getInstrumentName() != null) btnInstr.setText(sc.getInstrumentName());
519 else btnInstr.setText(i18n.getButtonLabel("ChannelScreen.btnInstr"));
520
521 btnInstr.setToolTipText(sc.getInstrumentName());
522 }
523
524 channelInfoPane.updateChannelInfo();
525 }
526
527 public void
528 onDestroy() {
529 String s = "channel.smallView.showChannelNumbering";
530 preferences().removePropertyChangeListener(s, chnNumberingListener);
531
532 s = "channel.smallView.showMidiInfo";
533 preferences().removePropertyChangeListener(s, showMidiInfoListener);
534 }
535 }
536
537 private static class ChannelInfoPane extends JPanel {
538 private final Channel channel;
539 private final JLabel lInfo;
540
541 private int channelIndex = -1;
542
543 private boolean showNumbering;
544 private boolean showMidiInfo;
545
546 ChannelInfoPane(Channel channel) {
547 this.channel = channel;
548
549 setOpaque(false);
550 setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
551
552 lInfo = createScreenLabel("");
553 lInfo.setFont(Res.fontScreenMono);
554 lInfo.setToolTipText(i18n.getLabel("SmallChannelView.ttMidiPortChannel"));
555
556 updateChannelIndex();
557
558 updateLabelLength();
559
560 add(lInfo);
561 }
562
563 private void
564 updateLabelLength() {
565 lInfo.setPreferredSize(null);
566
567 int l = 0;
568 if(getShowNumbering()) l += 4;
569 if(channelIndex > 98) l++;
570 if(getShowMidiInfo()) l += 6;
571
572 StringBuffer sb = new StringBuffer();
573 for(int i = 0; i < l; i++) sb.append("0");
574 lInfo.setText(sb.toString());
575
576 lInfo.setPreferredSize(lInfo.getPreferredSize()); // Don't remove this!
577 lInfo.setMinimumSize(lInfo.getPreferredSize());
578 lInfo.setMaximumSize(lInfo.getPreferredSize());
579 }
580
581 protected void
582 updateChannelInfo() {
583 StringBuffer sb = new StringBuffer();
584
585 if(getShowNumbering()) {
586 if(channelIndex < 9) sb.append(" ");
587 sb.append(channelIndex + 1).append(": ");
588 }
589
590 if(getShowMidiInfo()) {
591 SamplerChannel sc = channel.getChannelInfo();
592 if(sc.getMidiInputDevice() == -1) {
593 sb.append("-/-");
594 } else {
595 sb.append(sc.getMidiInputPort()).append("/");
596
597 if(sc.getMidiInputChannel() == -1) sb.append("All");
598 else sb.append(sc.getMidiInputChannel() + 1);
599 }
600 }
601
602 lInfo.setText(sb.toString());
603 }
604
605 protected void
606 updateChannelIndex() {
607 int i = CC.getSamplerModel().getChannelIndex(channel.getModel());
608
609 boolean b = false;
610 if(i > 98 && channelIndex <= 98) b = true;
611 if(i < 99 && channelIndex >= 99) b = true;
612
613 channelIndex = i;
614 if(b) updateLabelLength();
615
616 if(!getShowNumbering()) return;
617
618 updateChannelInfo();
619 }
620
621 protected boolean
622 getShowNumbering() { return showNumbering; }
623
624 protected void
625 setShowNumbering(boolean b) {
626 if(b == showNumbering) return;
627 showNumbering = b;
628
629 updateLabelLength();
630 updateChannelIndex();
631 }
632
633 protected boolean
634 getShowMidiInfo() { return showMidiInfo; }
635
636 protected void
637 setShowMidiInfo(boolean b) {
638 if(b == showMidiInfo) return;
639 showMidiInfo = b;
640
641 updateLabelLength();
642 updateChannelInfo();
643 }
644 }
645
646 private class FxSendsButton extends PixmapButton implements ActionListener {
647 FxSendsButton() {
648 super(Res.gfxFx);
649
650 setRolloverIcon(Res.gfxFxRO);
651
652 addActionListener(this);
653 }
654
655 public void
656 actionPerformed(ActionEvent e) { channel.showFxSendsDialog(); }
657
658 public boolean
659 contains(int x, int y) { return (x > 5 && x < 23) && (y > 5 && y < 16); }
660 }
661 }

  ViewVC Help
Powered by ViewVC