/[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 1737 - (show annotations) (download)
Thu May 8 17:26:19 2008 UTC (15 years, 11 months ago) by iliev
File size: 22032 byte(s)
* Major memory optimizations when too many sampler channels are present

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 import java.awt.event.MouseListener;
35
36 import java.beans.PropertyChangeEvent;
37 import java.beans.PropertyChangeListener;
38
39 import java.util.Vector;
40
41 import javax.swing.Action;
42 import javax.swing.BorderFactory;
43 import javax.swing.Box;
44 import javax.swing.BoxLayout;
45 import javax.swing.JButton;
46 import javax.swing.JComponent;
47 import javax.swing.JLabel;
48 import javax.swing.JMenuItem;
49 import javax.swing.JPanel;
50 import javax.swing.JPopupMenu;
51
52 import javax.swing.event.ChangeEvent;
53 import javax.swing.event.ChangeListener;
54
55 import net.sf.juife.Dial;
56 import net.sf.juife.JuifeUtils;
57
58 import org.jsampler.CC;
59 import org.jsampler.HF;
60 import org.jsampler.SamplerChannelModel;
61
62 import org.jvnet.substance.SubstanceImageCreator;
63
64 import org.linuxsampler.lscp.SamplerChannel;
65 import org.linuxsampler.lscp.SamplerEngine;
66
67 import static org.jsampler.view.fantasia.FantasiaI18n.i18n;
68 import static org.jsampler.view.fantasia.FantasiaPrefs.*;
69 import static org.jsampler.view.fantasia.FantasiaUtils.*;
70
71 /**
72 *
73 * @author Grigor Iliev
74 */
75 public class NormalChannelView extends PixmapPane implements ChannelView {
76 private final Channel channel;
77 private ChannelOptionsView channelOptionsView = null;
78
79 private final EnhancedDial dialVolume = new EnhancedDial();
80 private final ChannelScreen screen;
81
82 private final Channel.PowerButton btnPower;
83 private final MuteButton btnMute = new MuteButton();
84 private final SoloButton btnSolo = new SoloButton();
85 private final Channel.OptionsButton btnOptions;
86
87 private final Vector<JComponent> components = new Vector<JComponent>();
88
89
90 /** Creates a new instance of <code>NormalChannelView</code> */
91 public
92 NormalChannelView(Channel channel) {
93 super(Res.gfxChannel);
94 setPixmapInsets(new Insets(3, 3, 3, 3));
95
96 components.add(this);
97
98 this.channel = channel;
99
100 btnPower = new Channel.PowerButton(channel);
101 components.add(btnPower);
102 btnOptions = new Channel.OptionsButton(channel);
103 components.add(btnOptions);
104
105 screen = new ChannelScreen(channel);
106 setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
107
108 btnPower.setAlignmentY(JPanel.TOP_ALIGNMENT);
109
110 JPanel tb = new JPanel();
111 components.add(tb);
112 tb.setBorder(BorderFactory.createEmptyBorder(3, 3, 0, 4));
113 tb.setLayout(new BoxLayout(tb, BoxLayout.X_AXIS));
114 tb.setOpaque(false);
115 tb.setAlignmentY(JPanel.TOP_ALIGNMENT);
116 tb.add(btnPower);
117 tb.setPreferredSize(new Dimension(tb.getPreferredSize().width, 58));
118 tb.setMinimumSize(tb.getPreferredSize());
119 tb.setMaximumSize(tb.getPreferredSize());
120 add(tb);
121
122 //p.add(Box.createRigidArea(new Dimension(4, 0)));
123
124 add(createVSeparator());
125
126 //p.add(Box.createRigidArea(new Dimension(3, 0)));
127
128 JPanel p2 = new JPanel();
129 components.add(p2);
130 p2.setOpaque(false);
131 p2.setLayout(new BoxLayout(p2, BoxLayout.Y_AXIS));
132 p2.setAlignmentY(JPanel.TOP_ALIGNMENT);
133 p2.setBorder(BorderFactory.createEmptyBorder(5, 3, 0, 2));
134 p2.add(screen);
135 add(p2);
136
137 add(createVSeparator());
138
139 p2 = new JPanel();
140 components.add(p2);
141 p2.setOpaque(false);
142 p2.setLayout(new BoxLayout(p2, BoxLayout.Y_AXIS));
143 p2.setAlignmentY(JPanel.TOP_ALIGNMENT);
144 p2.setBorder(BorderFactory.createEmptyBorder(4, 0, 0, 0));
145
146 JLabel l = new JLabel(Res.gfxMuteTitle);
147 components.add(l);
148 p2.add(l);
149 components.add(btnMute);
150 p2.add(btnMute);
151
152 l = new JLabel(Res.gfxSoloTitle);
153 components.add(l);
154 p2.add(l);
155
156 components.add(btnSolo);
157 p2.add(btnSolo);
158
159 add(p2);
160
161 add(createVSeparator());
162
163 p2 = new JPanel();
164 components.add(p2);
165 p2.setOpaque(false);
166 p2.setLayout(new BoxLayout(p2, BoxLayout.Y_AXIS));
167 p2.setAlignmentY(JPanel.TOP_ALIGNMENT);
168 p2.setBorder(BorderFactory.createEmptyBorder(4, 0, 0, 0));
169 l = new JLabel(Res.gfxVolumeTitle);
170 components.add(l);
171 l.setAlignmentX(JPanel.CENTER_ALIGNMENT);
172 l.setBorder(BorderFactory.createEmptyBorder(0, 0, 2, 0));
173 p2.add(l);
174
175 components.add(dialVolume);
176 dialVolume.setDialPixmap(Res.gfxVolumeDial, 30, 330);
177 dialVolume.setAlignmentX(JPanel.CENTER_ALIGNMENT);
178 p2.add(dialVolume);
179 add(p2);
180
181 add(createVSeparator());
182
183 p2 = new JPanel();
184 components.add(p2);
185 p2.setOpaque(false);
186 p2.setLayout(new BoxLayout(p2, BoxLayout.Y_AXIS));
187 p2.setAlignmentY(JPanel.TOP_ALIGNMENT);
188 p2.setBorder(BorderFactory.createEmptyBorder(27, 0, 0, 0));
189 l = new JLabel(Res.gfxOptionsTitle);
190 components.add(l);
191 l.setAlignmentX(JPanel.CENTER_ALIGNMENT);
192 l.setBorder(BorderFactory.createEmptyBorder(0, 0, 2, 0));
193 p2.add(l);
194
195 p2.add(Box.createRigidArea(new Dimension(0, 3)));
196
197 btnOptions.setAlignmentX(JPanel.CENTER_ALIGNMENT);
198 p2.add(btnOptions);
199 add(p2);
200
201
202 setPreferredSize(new Dimension(420, 60));
203 setMinimumSize(getPreferredSize());
204 setMaximumSize(getPreferredSize());
205 //p.setBorder(BorderFactory.createEmptyBorder(1, 0, 1, 0));
206
207 setAlignmentX(JPanel.CENTER_ALIGNMENT);
208
209 installView();
210 }
211
212 //////////////////////////////////////////////
213 // Implementation of the ChannelView interface
214 //////////////////////////////////////////////
215
216 public Type
217 getType() { return Type.NORMAL; }
218
219 public JComponent
220 getComponent() { return this; }
221
222 public void
223 installView() {
224 String vmud = VOL_MEASUREMENT_UNIT_DECIBEL;
225 preferences().addPropertyChangeListener(vmud, new PropertyChangeListener() {
226 public void
227 propertyChange(PropertyChangeEvent e) {
228 boolean b;
229 b = preferences().getBoolProperty(VOL_MEASUREMENT_UNIT_DECIBEL);
230 screen.updateVolumeInfo(dialVolume.getValue());
231 }
232 });
233
234 screen.installListeners();
235
236 addEnhancedMouseListener(channel.getContextMenu());
237 }
238
239 public void
240 uninstallView() {
241 screen.onDestroy();
242 btnOptions.onDestroy();
243 uninstallChannelOptionsView();
244 //removeEnhancedMouseListener(channel.getContextMenu());
245 }
246
247 public void
248 installChannelOptionsView() {
249 if(channelOptionsView != null) return;
250
251 channelOptionsView = new NormalChannelOptionsView(channel);
252 channelOptionsView.installView();
253
254 }
255
256 public void
257 uninstallChannelOptionsView() {
258 if(channelOptionsView == null) return;
259 channelOptionsView.uninstallView();
260 channelOptionsView = null;
261 }
262
263 public ChannelOptionsView
264 getChannelOptionsView() { return channelOptionsView; }
265
266 public void
267 updateChannelInfo() {
268 SamplerChannel sc = channel.getChannelInfo();
269
270 screen.updateScreenInfo(sc);
271 float f = sc.getVolume() * 100.0f;
272 screen.updateVolumeInfo((int)f);
273 updateMuteIcon(sc);
274
275 if(sc.isSoloChannel()) btnSolo.setIcon(Res.gfxSoloOn);
276 else btnSolo.setIcon(Res.gfxSoloOff);
277 dialVolume.setValue((int)(sc.getVolume() * 100));
278
279 boolean b = sc.getEngine() != null;
280 dialVolume.setEnabled(b);
281 btnSolo.setEnabled(b);
282 btnMute.setEnabled(b);
283
284 if(getChannelOptionsView() != null) getChannelOptionsView().updateChannelInfo();
285 }
286
287 public void
288 updateStreamCount(int count) { screen.updateStreamCount(count); }
289
290 public void
291 updateVoiceCount(int count) { screen.updateVoiceCount(count); }
292
293 public void
294 expandChannel() {
295 if(btnOptions.isSelected()) return;
296 btnOptions.doClick();
297 }
298
299 public boolean
300 isOptionsButtonSelected() { return btnOptions.isSelected(); }
301
302 public void
303 setOptionsButtonSelected(boolean b) {
304 btnOptions.setSelected(b);
305 }
306
307 public void
308 addEnhancedMouseListener(MouseListener l) {
309 removeEnhancedMouseListener(l);
310
311 for(JComponent c : components) c.addMouseListener(l);
312 screen.addEnhancedMouseListener(l);
313 }
314
315 public void
316 removeEnhancedMouseListener(MouseListener l) {
317 for(JComponent c : components) c.removeMouseListener(l);
318 screen.removeEnhancedMouseListener(l);
319 }
320
321 //////////////////////////////////////////////
322
323
324 /**
325 * Updates the mute button with the proper icon regarding to information obtained
326 * from <code>channel</code>.
327 * @param channel A <code>SamplerChannel</code> instance containing the new settings
328 * for this channel.
329 */
330 private void
331 updateMuteIcon(SamplerChannel channel) {
332 if(channel.isMutedBySolo()) btnMute.setIcon(Res.gfxMutedBySolo);
333 else if(channel.isMuted()) btnMute.setIcon(Res.gfxMuteOn);
334 else btnMute.setIcon(Res.gfxMuteOff);
335 }
336
337 /** Invoked when the user changes the volume */
338 private void
339 setVolume() {
340 screen.updateVolumeInfo(dialVolume.getValue());
341
342 if(dialVolume.getValueIsAdjusting()) return;
343
344 int vol = (int)(channel.getChannelInfo().getVolume() * 100);
345
346 if(vol == dialVolume.getValue()) return;
347
348 /*
349 * If the model's volume is not equal to the dial knob
350 * value we assume that the change is due to user input.
351 * So we must update the volume at the backend too.
352 */
353 float volume = dialVolume.getValue();
354 volume /= 100;
355 channel.getModel().setBackendVolume(volume);
356 }
357
358 private JPanel
359 createVSeparator() {
360 PixmapPane p = new PixmapPane(Res.gfxVLine);
361 p.setAlignmentY(JPanel.TOP_ALIGNMENT);
362 p.setPreferredSize(new Dimension(2, 60));
363 p.setMinimumSize(p.getPreferredSize());
364 p.setMaximumSize(p.getPreferredSize());
365 return p;
366 }
367
368 private class EnhancedDial extends Dial {
369 EnhancedDial() {
370 super(0, 100, 0);
371
372 setMouseHandlerMode(MouseHandlerMode.LEFT_TO_RIGHT_AND_DOWN_TO_UP);
373
374 int i = preferences().getIntProperty(MAXIMUM_CHANNEL_VOLUME);
375 setMaximum(i);
376 String mcv = MAXIMUM_CHANNEL_VOLUME;
377 preferences().addPropertyChangeListener(mcv, new PropertyChangeListener() {
378 public void
379 propertyChange(PropertyChangeEvent e) {
380 int j = preferences().getIntProperty(MAXIMUM_CHANNEL_VOLUME);
381 setMaximum(j);
382 }
383 });
384
385 addMouseListener(new MouseAdapter() {
386 public void
387 mouseClicked(MouseEvent e) {
388 if(e.getButton() == e.BUTTON3) {
389 setValue(getMaximum() / 2);
390 return;
391 }
392
393 if(e.getButton() != e.BUTTON1) return;
394
395 if(e.getClickCount() < 2) return;
396 setValue(getValueByPoint(e.getPoint()));
397 }
398 });
399
400 addChangeListener(new ChangeListener() {
401 public void
402 stateChanged(ChangeEvent e) { setVolume(); }
403 });
404 }
405 }
406
407
408 private class MuteButton extends PixmapButton implements ActionListener {
409 MuteButton() {
410 super(Res.gfxMuteOff);
411 //setDisabledIcon(Res.gfxMuteSoloDisabled);
412 setDisabledIcon (
413 SubstanceImageCreator.makeTransparent(this, Res.gfxMuteOff, 0.4)
414 );
415 addActionListener(this);
416 }
417
418 public void
419 actionPerformed(ActionEvent e) {
420 SamplerChannel sc = channel.getChannelInfo();
421 boolean b = true;
422
423 /*
424 * Changing the mute button icon now instead of
425 * leaving the work to the notification mechanism of the LinuxSampler.
426 */
427 if(sc.isMuted() && !sc.isMutedBySolo()) {
428 b = false;
429 boolean hasSolo = CC.getSamplerModel().hasSoloChannel();
430
431 if(sc.isSoloChannel() || !hasSolo) setIcon(Res.gfxMuteOff);
432 else setIcon(Res.gfxMutedBySolo);
433 } else setIcon(Res.gfxMuteOn);
434
435 channel.getModel().setBackendMute(b);
436 }
437
438 public boolean
439 contains(int x, int y) { return (x > 5 && x < 23) && (y > 5 && y < 16); }
440 }
441
442 private class SoloButton extends PixmapButton implements ActionListener {
443 SoloButton() {
444 super(Res.gfxSoloOff);
445 //setDisabledIcon(Res.gfxMuteSoloDisabled);
446 setDisabledIcon (
447 SubstanceImageCreator.makeTransparent(this, Res.gfxSoloOff, 0.4)
448 );
449 addActionListener(this);
450 }
451
452 public void
453 actionPerformed(ActionEvent e) {
454 SamplerChannel sc = channel.getChannelInfo();
455 boolean b = !sc.isSoloChannel();
456
457 /*
458 * Changing the solo button icon (and related) now instead of
459 * leaving the work to the notification mechanism of the LinuxSampler.
460 */
461 if(b) {
462 setIcon(Res.gfxSoloOn);
463 if(sc.isMutedBySolo()) btnMute.setIcon(Res.gfxMuteOff);
464 } else {
465 setIcon(Res.gfxSoloOff);
466 if(!sc.isMuted() && CC.getSamplerModel().getSoloChannelCount() > 1)
467 btnMute.setIcon(Res.gfxMutedBySolo);
468 }
469
470 channel.getModel().setBackendSolo(b);
471 }
472
473 public boolean
474 contains(int x, int y) { return (x > 5 && x < 23) && (y > 5 && y < 16); }
475 }
476 }
477
478
479 class ChannelScreen extends PixmapPane {
480 private final Channel channel;
481
482 private final InstrumentPane instrumentPane;
483
484 private final Channel.StreamVoiceCountPane streamVoiceCountPane;
485
486 private final Channel.VolumePane volumePane;
487
488 private JButton btnInstr =
489 createScreenButton(i18n.getButtonLabel("ChannelScreen.btnInstr"));
490
491 private final JButton btnEditInstr =
492 createScreenButton(i18n.getButtonLabel("ChannelScreen.btnEditInstr"));
493 private final ScreenButtonBg sbbEditInstr = new ScreenButtonBg(btnEditInstr);
494
495 private final JButton btnFxSends =
496 createScreenButton(i18n.getButtonLabel("ChannelScreen.btnFxSends"));
497
498 private final JButton btnEngine
499 = createScreenButton(i18n.getButtonLabel("ChannelScreen.btnEngine"));
500
501 private final JPopupMenu menuEngines = new JPopupMenu();
502
503 private final ActionListener guiListener;
504
505 private final Vector<JComponent> components = new Vector<JComponent>();
506
507 ChannelScreen(final Channel channel) {
508 super(Res.gfxChannelScreen);
509 setPixmapInsets(new Insets(6, 6, 6, 6));
510 setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
511
512 components.add(this);
513
514 this.channel = channel;
515
516 streamVoiceCountPane = new Channel.StreamVoiceCountPane(channel);
517 components.add(streamVoiceCountPane);
518
519 volumePane = new Channel.VolumePane(channel);
520 components.add(volumePane);
521
522 setOpaque(false);
523
524 setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
525
526 btnInstr.setAlignmentX(CENTER_ALIGNMENT);
527 btnInstr.setRolloverEnabled(false);
528 btnInstr.setBorder(BorderFactory.createEmptyBorder(3, 0, 0, 0));
529 components.add(btnInstr);
530
531 instrumentPane = new InstrumentPane();
532 components.add(instrumentPane);
533 add(instrumentPane);
534
535 JPanel p = new JPanel();
536 components.add(p);
537 p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));
538 p.setAlignmentX(CENTER_ALIGNMENT);
539 p.setBorder(BorderFactory.createEmptyBorder(5, 2, 0, 0));
540
541 components.add(btnFxSends);
542 btnFxSends.setToolTipText(i18n.getButtonLabel("ChannelScreen.btnFxSends.tt"));
543 btnFxSends.addActionListener(new ActionListener() {
544 public void
545 actionPerformed(ActionEvent e) {
546 channel.showFxSendsDialog();
547 }
548 });
549
550 p.add(btnFxSends);
551
552 //p.add(Box.createRigidArea(new Dimension(6, 0)));
553 p.add(Box.createGlue());
554
555 components.add(btnEngine);
556 btnEngine.setIcon(Res.iconEngine12);
557 btnEngine.setIconTextGap(1);
558 p.add(btnEngine);
559 //p.add(new Label("|"));
560
561 //p.add(Box.createRigidArea(new Dimension(6, 0)));
562
563 //p.add(btnReset);
564
565 p.add(Box.createGlue());
566
567 p.add(streamVoiceCountPane);
568 p.add(volumePane);
569
570 p.setPreferredSize(new Dimension(260, p.getPreferredSize().height));
571 p.setMinimumSize(p.getPreferredSize());
572 p.setMaximumSize(p.getPreferredSize());
573
574 //btnInstr.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
575 p.setOpaque(false);
576 add(p);
577
578
579 setPreferredSize(new Dimension(270, 48));
580 setMinimumSize(getPreferredSize());
581 setMaximumSize(getPreferredSize());
582
583 createEngineMenu();
584
585 guiListener = new ActionListener() {
586 public void
587 actionPerformed(ActionEvent e) {
588 if(getMousePosition(true) != null) {
589 getHandler().mouseEntered(null);
590 } else {
591 getHandler().mouseExited(null);
592 }
593 }
594 };
595 }
596
597 public void
598 addEnhancedMouseListener(MouseListener l) {
599 removeEnhancedMouseListener(l);
600 for(JComponent c : components) c.addMouseListener(l);
601 }
602
603 public void
604 removeEnhancedMouseListener(MouseListener l) {
605 for(JComponent c : components) c.removeMouseListener(l);
606 }
607
608 protected void
609 onDestroy() { uninstallListeners(); }
610
611 private void
612 createEngineMenu() {
613 for(final SamplerEngine engine : CC.getSamplerModel().getEngines()) {
614 JMenuItem mi = new JMenuItem(engine.getName() + " engine");
615 mi.setToolTipText(engine.getDescription());
616
617 mi.addActionListener(new ActionListener() {
618 public void
619 actionPerformed(ActionEvent e) {
620 channel.getModel().setBackendEngineType(engine.getName());
621 }
622 });
623
624 menuEngines.add(mi);
625 }
626 }
627
628 protected void
629 installListeners() {
630 btnInstr.addActionListener(new ActionListener() {
631 public void
632 actionPerformed(ActionEvent e) { channel.loadInstrument(); }
633 });
634
635 btnEditInstr.addActionListener(new ActionListener() {
636 public void
637 actionPerformed(ActionEvent e) {
638 CC.getSamplerModel().editBackendInstrument(channel.getChannelId());
639 }
640 });
641
642 btnEngine.addActionListener(new ActionListener() {
643 public void
644 actionPerformed(ActionEvent e) {
645 int y = btnEngine.getHeight() + 1;
646 menuEngines.show(btnEngine, 0, y);
647 }
648 });
649
650 addMouseListener(getHandler());
651 addHierarchyListener(getHandler());
652
653 ((MainFrame)CC.getMainFrame()).getGuiTimer().addActionListener(guiListener);
654 }
655
656 private void
657 uninstallListeners() {
658 ((MainFrame)CC.getMainFrame()).getGuiTimer().removeActionListener(guiListener);
659 }
660
661 protected void
662 updateScreenInfo(SamplerChannel sc) {
663 int status = sc.getInstrumentStatus();
664 if(status >= 0 && status < 100) {
665 btnInstr.setText(i18n.getLabel("ChannelScreen.loadingInstrument", status));
666 } else if(status == -1) {
667 btnInstr.setText(i18n.getButtonLabel("ChannelScreen.btnInstr"));
668 } else if(status < -1) {
669 btnInstr.setText(i18n.getLabel("ChannelScreen.errorLoadingInstrument"));
670 } else {
671 if(sc.getInstrumentName() != null) btnInstr.setText(sc.getInstrumentName());
672 else btnInstr.setText(i18n.getButtonLabel("ChannelScreen.btnInstr"));
673 }
674
675 instrumentPane.update();
676
677 if(sc.getEngine() != null) {
678 String s = sc.getEngine().getName();
679 s += " engine";
680 if(!s.equals(btnEngine.getText())) {
681 btnEngine.setText(s);
682 btnEngine.setToolTipText(sc.getEngine().getDescription());
683 }
684 }
685
686 }
687
688 protected void
689 updateVolumeInfo(int volume) {
690 volumePane.updateVolumeInfo(volume);
691 }
692
693 /**
694 * Updates the number of active disk streams.
695 * @param count The new number of active disk streams.
696 */
697 protected void
698 updateStreamCount(int count) {
699 streamVoiceCountPane.updateStreamCount(count);
700 }
701
702 /**
703 * Updates the number of active voices.
704 * @param count The new number of active voices.
705 */
706 protected void
707 updateVoiceCount(int count) {
708 streamVoiceCountPane.updateVoiceCount(count);
709 }
710
711 class InstrumentPane extends JPanel {
712 private final JPanel leftPane = new JPanel();
713 private final JPanel rightPane = new JPanel();
714
715 InstrumentPane() {
716 setOpaque(false);
717 setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
718 add(leftPane);
719 add(btnInstr);
720 add(rightPane);
721 add(sbbEditInstr);
722 btnEditInstr.setToolTipText(i18n.getLabel("ChannelScreen.btnEditInstr.tt"));
723 sbbEditInstr.setVisible(false);
724 setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 6));
725
726 update();
727 }
728
729 public void
730 update() {
731 int a = btnInstr.getMinimumSize().width;
732 int b = 0;
733 if(sbbEditInstr.isVisible()) b = sbbEditInstr.getPreferredSize().width;
734
735 int max = 254 - b;
736 if(a > max) a = max;
737
738 int h = btnInstr.getPreferredSize().height;
739 btnInstr.setPreferredSize(new Dimension(a, h));
740 h = btnInstr.getMaximumSize().height;
741 btnInstr.setMaximumSize(new Dimension(a, h));
742
743
744 int i = (254 - btnInstr.getPreferredSize().width) / 2;
745
746 int j = i;
747 if(sbbEditInstr.isVisible()) j -= sbbEditInstr.getPreferredSize().width;
748 if(i < 0 || j < 0) i = j = 0;
749
750 Dimension d = new Dimension(i, 1);
751 leftPane.setMinimumSize(d);
752 leftPane.setPreferredSize(d);
753 leftPane.setMaximumSize(d);
754
755 d = new Dimension(j, 1);
756 rightPane.setMinimumSize(d);
757 rightPane.setPreferredSize(d);
758 rightPane.setMaximumSize(d);
759
760 validate();
761 }
762 }
763
764 static class ScreenButtonBg extends PixmapPane {
765 ScreenButtonBg(JButton btn) {
766 super(Res.gfxScreenBtnBg);
767 setPixmapInsets(new Insets(4, 4, 4, 4));
768 setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
769 setBorder(BorderFactory.createEmptyBorder(0, 7, 0, 7));
770 add(btn);
771 setPreferredSize(new Dimension(getPreferredSize().width, 13));
772 }
773
774 public Dimension
775 getPreferredSize() {
776 return new Dimension(super.getPreferredSize().width, 13);
777 }
778 }
779
780
781 private final EventHandler eventHandler = new EventHandler();
782
783 private EventHandler
784 getHandler() { return eventHandler; }
785
786 private class EventHandler extends MouseAdapter implements HierarchyListener {
787 public void
788 mouseEntered(MouseEvent e) {
789 if(channel.getChannelInfo().getInstrumentStatus() != 100) return;
790
791 if(!sbbEditInstr.isVisible()) {
792 sbbEditInstr.setVisible(true);
793 instrumentPane.update();
794 }
795 }
796
797 public void
798 mouseExited(MouseEvent e) {
799 if(getMousePosition(true) != null) return;
800 if(sbbEditInstr.isVisible()) {
801 sbbEditInstr.setVisible(false);
802 instrumentPane.update();
803 }
804 }
805
806 /** Called when the hierarchy has been changed. */
807 public void
808 hierarchyChanged(HierarchyEvent e) {
809 if((e.getChangeFlags() & e.SHOWING_CHANGED) == e.SHOWING_CHANGED) {
810 if(getMousePosition() == null) mouseExited(null);
811 else mouseEntered(null);
812 }
813 }
814 }
815 }

  ViewVC Help
Powered by ViewVC