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

Contents of /jsampler/trunk/src/org/jsampler/view/fantasia/Channel.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: 29157 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.Container;
26 import java.awt.Dimension;
27 import java.awt.Rectangle;
28
29 import java.awt.event.ActionEvent;
30 import java.awt.event.ActionListener;
31 import java.awt.event.MouseAdapter;
32 import java.awt.event.MouseEvent;
33
34 import java.beans.PropertyChangeEvent;
35 import java.beans.PropertyChangeListener;
36
37 import java.text.NumberFormat;
38
39 import javax.swing.AbstractAction;
40 import javax.swing.Action;
41 import javax.swing.BoxLayout;
42 import javax.swing.ButtonGroup;
43 import javax.swing.ImageIcon;
44 import javax.swing.JButton;
45 import javax.swing.JComponent;
46 import javax.swing.JLabel;
47 import javax.swing.JMenuItem;
48 import javax.swing.JPanel;
49 import javax.swing.JPopupMenu;
50 import javax.swing.JRadioButtonMenuItem;
51 import javax.swing.JScrollPane;
52 import javax.swing.JToolBar;
53
54 import org.jdesktop.swingx.JXCollapsiblePane;
55
56 import org.jsampler.CC;
57 import org.jsampler.HF;
58 import org.jsampler.SamplerChannelModel;
59
60 import org.jsampler.event.SamplerChannelEvent;
61 import org.jsampler.event.SamplerChannelListEvent;
62 import org.jsampler.event.SamplerChannelListListener;
63 import org.jsampler.event.SamplerChannelListener;
64
65 import org.jsampler.view.JSChannel;
66 import org.jsampler.view.JSChannelsPane;
67
68 import org.jsampler.view.fantasia.basic.PixmapToggleButton;
69
70 import org.jsampler.view.std.JSChannelOutputRoutingDlg;
71 import org.jsampler.view.std.JSFxSendsDlg;
72 import org.jsampler.view.std.JSFxSendsPane;
73 import org.jsampler.view.std.JSInstrumentChooser;
74 import org.jsampler.view.std.JSVolumeEditorPopup;
75
76 import org.linuxsampler.lscp.SamplerChannel;
77
78 import static org.jsampler.view.fantasia.FantasiaI18n.i18n;
79 import static org.jsampler.view.fantasia.FantasiaPrefs.*;
80 import static org.jsampler.view.fantasia.FantasiaUtils.*;
81 import static org.jsampler.view.std.JSVolumeEditorPopup.VolumeType;
82
83
84 /**
85 *
86 * @author Grigor Iliev
87 */
88 public class Channel extends JSChannel {
89 private final JXCollapsiblePane mainPane;
90 private final ChannelOptionsPane optionsPane = new ChannelOptionsPane();
91
92 private final ViewTracker viewTracker;
93
94 private JSFxSendsDlg fxSendsDlg = null;
95
96 private final ContextMenu contextMenu;
97
98 private boolean selected = false;
99
100 private AnimatedPorpetyListener animatedPorpetyListener = new AnimatedPorpetyListener();
101
102 class AnimatedPorpetyListener implements PropertyChangeListener {
103 public void
104 propertyChange(PropertyChangeEvent e) {
105 mainPane.setAnimated(preferences().getBoolProperty(ANIMATED));
106 }
107 }
108
109 ////////////////////////////////
110 // ******* Mouse tracker *******
111 ////////////////////////////////
112 private static int mouseOverChannelId = -1;
113 private static boolean mousePressed = false;
114
115 private static ActionListener guiListener = null;
116
117 private static Channel oldMouseOverChannel = null;
118 private static Channel newMouseOverChannel = null;
119
120
121 private static void
122 mouseMoved() {
123 //TODO: do this for all channels panes
124 JSChannelsPane cp = CC.getMainFrame().getChannelsPane(0);
125 for(int i = 0; i < cp.getChannelCount(); i++) {
126 mouseMoved((Channel)cp.getChannel(i));
127 }
128
129 if(oldMouseOverChannel == newMouseOverChannel) return;
130
131 if(oldMouseOverChannel != null) oldMouseOverChannel.mouseExited();
132
133 if(newMouseOverChannel != null) {
134 mouseOverChannelId = newMouseOverChannel.getChannelId();
135 newMouseOverChannel.mouseEntered();
136 }
137
138 oldMouseOverChannel = newMouseOverChannel = null;
139 }
140
141 private static void
142 mouseMoved(Channel c) {
143 int id = c.getChannelId();
144 if(c.mainPane.getMousePosition(true) != null) {
145 newMouseOverChannel = c;
146 } else if(id == mouseOverChannelId) {
147 oldMouseOverChannel = c;
148 }
149 }
150
151 ////////////////////////////////
152
153
154 /**
155 * Creates a new instance of <code>Channel</code> using the specified
156 * non-<code>null</code> channel model.
157 * @param model The model to be used by this channel.
158 * @throws IllegalArgumentException If the model is <code>null</code>.
159 */
160 public
161 Channel(SamplerChannelModel model) {
162 this(model, null);
163 }
164
165 /**
166 * Creates a new instance of <code>Channel</code> using the specified
167 * non-<code>null</code> channel model.
168 * @param model The model to be used by this channel.
169 * @param listener A listener which is notified when the newly created
170 * channel is fully expanded on the screen.
171 * @throws IllegalArgumentException If the model is <code>null</code>.
172 */
173 public
174 Channel(SamplerChannelModel model, final ActionListener listener) {
175 super(model);
176
177 setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
178 optionsPane.setAlignmentX(JPanel.CENTER_ALIGNMENT);
179
180 mainPane = new JXCollapsiblePane();
181 viewTracker = new ViewTracker();
182 contextMenu = new ContextMenu();
183
184 mainPane.getContentPane().setLayout (
185 new BoxLayout(mainPane.getContentPane(), BoxLayout.Y_AXIS)
186 );
187
188 int viewIdx = preferences().getIntProperty(DEFAULT_CHANNEL_VIEW);
189 if(viewIdx == 0) {
190 viewTracker.setView(new SmallChannelView(Channel.this));
191 } else if(viewIdx == 1) {
192 viewTracker.setView(new NormalChannelView(Channel.this));
193 } else {
194 viewTracker.setView(new NormalChannelView(Channel.this));
195 }
196
197 setOpaque(false);
198
199 getModel().addSamplerChannelListener(getHandler());
200
201 updateChannelInfo();
202
203 add(mainPane);
204
205 if(listener != null) {
206 final String s = JXCollapsiblePane.ANIMATION_STATE_KEY;
207 mainPane.addPropertyChangeListener(s, new PropertyChangeListener() {
208 public void
209 propertyChange(PropertyChangeEvent e) {
210 if(e.getNewValue() == "expanded") {
211 // TODO: this should be done regardles the listener != null?
212 mainPane.removePropertyChangeListener(s, this);
213 ///////
214 listener.actionPerformed(null);
215 ensureChannelIsVisible();
216 } else if(e.getNewValue() == "expanding/collapsing") {
217 ensureChannelIsVisible();
218 }
219 }
220 });
221 }
222
223 mainPane.setAnimated(false);
224 mainPane.setCollapsed(true);
225 mainPane.setAnimated(preferences().getBoolProperty(ANIMATED));
226 mainPane.setCollapsed(false);
227
228 preferences().addPropertyChangeListener(ANIMATED, animatedPorpetyListener);
229
230 if(listener != null) {
231 javax.swing.SwingUtilities.invokeLater(new Runnable() {
232 public void
233 run() { listener.actionPerformed(null); }
234 });
235 }
236
237 CC.getSamplerModel().addSamplerChannelListListener(getHandler());
238
239 installGuiListener();
240 }
241
242 private static void
243 installGuiListener() {
244 if(guiListener != null) return;
245
246 guiListener = new ActionListener() {
247 public void
248 actionPerformed(ActionEvent e) {
249 mouseMoved();
250 }
251 };
252
253 ((MainFrame)CC.getMainFrame()).getGuiTimer().addActionListener(guiListener);
254 }
255
256 private void
257 mouseEntered() {
258 viewTracker.mouseEntered();
259 }
260
261 private void
262 mouseExited() {
263 viewTracker.mouseExited();
264 }
265
266 private void
267 ensureChannelIsVisible() {
268 Container p = getParent();
269 JScrollPane sp = null;
270 while(p != null) {
271 if(p instanceof JScrollPane) {
272 sp = (JScrollPane)p;
273 break;
274 }
275 p = p.getParent();
276 }
277 if(sp == null) return;
278 int h = sp.getViewport().getView().getHeight();
279 sp.getViewport().scrollRectToVisible(new Rectangle(0, h - 2, 1, 1));
280 }
281
282 /**
283 * Determines whether the channel is selected.
284 * @return <code>true</code> if the channel is selected, <code>false</code> otherwise.
285 */
286 @Override
287 public boolean
288 isSelected() { return selected; }
289
290 /**
291 * Sets the selection state of this channel.
292 * This method is invoked when the selection state of the channel has changed.
293 * @param select Specifies the new selection state of this channel;
294 * <code>true</code> to select the channel, <code>false</code> otherwise.
295 */
296 @Override
297 public void
298 setSelected(boolean select) {
299
300 selected = select;
301 }
302
303 /** Shows the channel properties. */
304 public void
305 expandChannel() { expandChannel(optionsPane.isAnimated()); }
306
307 /** Shows the channel properties. */
308 public void
309 expandChannel(boolean animated) {
310 boolean b = optionsPane.isAnimated();
311 optionsPane.setAnimated(animated);
312 viewTracker.getCurrentView().expandChannel();
313 optionsPane.setAnimated(b);
314 }
315
316 /**
317 * Updates the channel settings. This method is invoked when changes to the
318 * channel were made.
319 */
320 private void
321 updateChannelInfo() {
322 viewTracker.getCurrentView().updateChannelInfo();
323 }
324
325 public void
326 loadInstrument() {
327 JSInstrumentChooser dlg = FantasiaUtils.createInstrumentChooser(CC.getMainFrame());
328 dlg.setVisible(true);
329
330 if(!dlg.isCancelled()) {
331 SamplerChannelModel m = getModel();
332 m.loadBackendInstrument(dlg.getInstrumentFile(), dlg.getInstrumentIndex());
333 }
334 }
335
336 public void
337 fallbackToOriginalView() {
338 viewTracker.fallbackToOriginalView();
339 }
340
341 public boolean
342 isUsingOriginalView() {
343 return viewTracker.isUsingOriginalView();
344 }
345
346 protected void
347 onDestroy() {
348 CC.getSamplerModel().removeSamplerChannelListListener(getHandler());
349 preferences().removePropertyChangeListener(ANIMATED, animatedPorpetyListener);
350 if(fxSendsDlg != null) fxSendsDlg.dispose();
351 viewTracker.onDestroy();
352 }
353
354 public void
355 remove() {
356 if(!mainPane.isAnimated()) {
357 CC.getSamplerModel().removeBackendChannel(getChannelId());
358 return;
359 }
360
361 String s = JXCollapsiblePane.ANIMATION_STATE_KEY;
362 mainPane.addPropertyChangeListener(s, getHandler());
363 mainPane.setCollapsed(true);
364 }
365
366 public void
367 showOptionsPane(boolean show) { optionsPane.showOptionsPane(show); }
368
369 public void
370 showFxSendsDialog() {
371 if(fxSendsDlg != null && fxSendsDlg.isVisible()) {
372 fxSendsDlg.toFront();
373 return;
374 }
375
376 fxSendsDlg = new JSFxSendsDlg(new FxSendsPane(getModel()));
377 fxSendsDlg.setVisible(true);
378 }
379
380 private final EventHandler eventHandler = new EventHandler();
381
382 private EventHandler
383 getHandler() { return eventHandler; }
384
385 private class EventHandler implements SamplerChannelListener,
386 SamplerChannelListListener, PropertyChangeListener {
387 /**
388 * Invoked when changes are made to a sampler channel.
389 * @param e A <code>SamplerChannelEvent</code> instance
390 * containing event information.
391 */
392 @Override
393 public void
394 channelChanged(SamplerChannelEvent e) { updateChannelInfo(); }
395
396 /**
397 * Invoked when the number of active disk streams has changed.
398 * @param e A <code>SamplerChannelEvent</code> instance
399 * containing event information.
400 */
401 @Override
402 public void
403 streamCountChanged(SamplerChannelEvent e) {
404 viewTracker.getCurrentView().updateStreamCount(getModel().getStreamCount());
405 }
406
407 /**
408 * Invoked when the number of active voices has changed.
409 * @param e A <code>SamplerChannelEvent</code> instance
410 * containing event information.
411 */
412 @Override
413 public void
414 voiceCountChanged(SamplerChannelEvent e) {
415 viewTracker.getCurrentView().updateVoiceCount(getModel().getVoiceCount());
416 }
417
418 /**
419 * Invoked when a new sampler channel is created.
420 * @param e A <code>SamplerChannelListEvent</code>
421 * instance providing the event information.
422 */
423 @Override
424 public void
425 channelAdded(SamplerChannelListEvent e) { }
426
427 /**
428 * Invoked when a sampler channel is removed.
429 * @param e A <code>SamplerChannelListEvent</code>
430 * instance providing the event information.
431 */
432 @Override
433 public void
434 channelRemoved(SamplerChannelListEvent e) {
435 // Some cleanup when the channel is removed.
436 if(e.getChannelModel().getChannelId() == getChannelId()) {
437 onDestroy();
438 }
439 }
440
441 @Override
442 public void
443 propertyChange(PropertyChangeEvent e) {
444 if(e.getNewValue() == "collapsed") {
445 CC.getSamplerModel().removeBackendChannel(getChannelId());
446 }
447 }
448 }
449
450 public ViewTracker
451 getViewTracker() { return viewTracker; }
452
453 class ViewTracker extends MouseAdapter implements PropertyChangeListener {
454 private ChannelView originalView;
455 private ChannelView mouseOverView;
456 private ChannelView currentView;
457
458 private ChannelView.Type mouseOverViewType = null;
459
460 ViewTracker() {
461
462
463 updateMouseOverViewType();
464
465 String s = DIFFERENT_CHANNEL_VIEW_ON_MOUSE_OVER;
466 preferences().addPropertyChangeListener(s, this);
467
468 s = CHANNEL_VIEW_ON_MOUSE_OVER;
469 preferences().addPropertyChangeListener(s, this);
470 }
471
472 public boolean
473 isUsingOriginalView() {
474 return currentView == originalView;
475 }
476
477 private void
478 installListeners() {
479
480 }
481
482 private void
483 uninstallListeners() {
484
485 }
486
487 private void
488 updateMouseOverViewType() {
489 if(mouseOverView != null) {
490 mouseOverView.removeEnhancedMouseListener(this);
491 }
492
493 mouseOverView = null;
494
495 boolean b;
496 b = preferences().getBoolProperty(DIFFERENT_CHANNEL_VIEW_ON_MOUSE_OVER);
497 if(!b) {
498 mouseOverViewType = null;
499 uninstallListeners();
500 return;
501 }
502
503 int i = preferences().getIntProperty(CHANNEL_VIEW_ON_MOUSE_OVER);
504
505 switch(i) {
506 case 0: mouseOverViewType = ChannelView.Type.SMALL; break;
507 case 1: mouseOverViewType = ChannelView.Type.NORMAL; break;
508 default:mouseOverViewType = null;
509 }
510
511 if(mouseOverViewType != null) {
512 installListeners();
513 }
514 }
515
516 public ChannelView
517 getMouseOverView() {
518 if(mouseOverViewType == null) return null;
519
520 if(mouseOverView == null) {
521 Channel channel = Channel.this;
522
523 switch(mouseOverViewType) {
524 case SMALL: mouseOverView = new SmallChannelView(channel); break;
525 case NORMAL: mouseOverView = new NormalChannelView(channel); break;
526 default: mouseOverView = new NormalChannelView(channel);
527 }
528
529 mouseOverView.addEnhancedMouseListener(this);
530 }
531
532 return mouseOverView;
533 }
534
535 public ChannelView
536 getCurrentView() { return currentView; }
537
538 public ChannelView
539 getOriginalView() { return originalView; }
540
541 public void
542 setView(ChannelView view) {
543 setView(view, true);
544 }
545
546 public void
547 setView(ChannelView view, boolean manual) {
548 boolean selected = false;
549 if(currentView != null) selected = currentView.isOptionsButtonSelected();
550
551 if(manual) {
552 if(originalView != null) {
553 originalView.removeEnhancedMouseListener(this);
554 }
555
556 if(originalView != currentView) destroyOriginalView();
557 if(currentView != null && currentView.getType() == view.getType()) {
558 originalView = currentView;
559 originalView.addEnhancedMouseListener(this);
560 destroyView(view);
561 return;
562 }
563
564 removeCurrentView();
565
566 originalView = view;
567 originalView.addEnhancedMouseListener(this);
568 currentView = view;
569 } else {
570 if(view.getType() == getCurrentView().getType()) {
571 destroyView(view);
572 return;
573 }
574
575 removeCurrentView();
576 currentView = view;
577 }
578
579 currentView.setOptionsButtonSelected(selected);
580
581 updateView();
582 }
583
584 private void
585 updateView() {
586 ChannelOptionsView view = getCurrentView().getChannelOptionsView();
587 if(view != null) optionsPane.setContentPane(view.getComponent());
588
589 updateChannelInfo();
590
591 mainPane.add(getCurrentView().getComponent());
592 mainPane.add(optionsPane);
593 mainPane.validate();
594 mainPane.revalidate();
595 mainPane.repaint();
596 }
597
598 public void
599 fallbackToOriginalView() {
600 if(currentView == originalView) return;
601
602 boolean selected = false;
603 if(currentView != null) selected = currentView.isOptionsButtonSelected();
604
605 removeCurrentView();
606 currentView = originalView;
607 currentView.setOptionsButtonSelected(selected);
608
609 updateView();
610 }
611
612 private void
613 removeCurrentView() { removeView(currentView); }
614
615 private void
616 destroyCurrentView() { destroyView(currentView); }
617
618 private void
619 removeOriginalView() { removeView(originalView); }
620
621 private void
622 destroyOriginalView() { destroyView(originalView); }
623
624 private void
625 removeView(ChannelView view) {
626 if(view == null) return;
627
628 mainPane.remove(view.getComponent());
629 mainPane.remove(optionsPane);
630
631 destroyView(view);
632 }
633
634 private void
635 destroyView(ChannelView view) {
636 if(view == null) return;
637
638 view.uninstallView();
639
640 view = null;
641 }
642
643 public boolean
644 isMouseOverEnabled() { return mouseOverViewType != null; }
645
646 private void
647 mouseEntered() {
648 if(!isMouseOverEnabled()) return;
649 if(getCurrentView().getType() == getMouseOverView().getType()) return;
650
651 JSChannel[] channels = CC.getMainFrame().getChannelsPane(0).getChannels();
652 for(JSChannel c : channels) {
653 if(c == Channel.this) continue;
654
655 Channel chn = (Channel)c;
656 if(!(chn).isUsingOriginalView()) chn.fallbackToOriginalView();
657 }
658
659 setView(getMouseOverView(), false);
660 }
661
662 private void
663 mouseExited() {
664 if(!isMouseOverEnabled()) return;
665 if(getCurrentView().getType() == originalView.getType()) return;
666
667 fallbackToOriginalView();
668 }
669
670 @Override
671 public void
672 mouseEntered(MouseEvent e) {
673 guiListener.actionPerformed(null);
674 }
675
676 @Override
677 public void
678 mouseExited(MouseEvent e) {
679 guiListener.actionPerformed(null);
680 }
681
682 @Override
683 public void
684 mousePressed(MouseEvent e) {
685 mousePressed = true;
686 }
687
688 @Override
689 public void
690 mouseReleased(MouseEvent e) {
691 mousePressed = false;
692 }
693
694 public void
695 onDestroy() {
696 destroyCurrentView();
697 destroyOriginalView();
698
699 uninstallListeners();
700
701 if(currentView != null) {
702 currentView.removeEnhancedMouseListener(this);
703 }
704
705 if(mouseOverView != null) {
706 mouseOverView.removeEnhancedMouseListener(this);
707 }
708
709 String s = DIFFERENT_CHANNEL_VIEW_ON_MOUSE_OVER;
710 preferences().removePropertyChangeListener(s, this);
711
712 s = CHANNEL_VIEW_ON_MOUSE_OVER;
713 preferences().removePropertyChangeListener(s, this);
714 }
715
716 @Override
717 public void
718 propertyChange(PropertyChangeEvent e) {
719 updateMouseOverViewType();
720 }
721 }
722
723 class EditInstrumentAction extends AbstractAction implements SamplerChannelListener {
724 EditInstrumentAction() {
725 super(i18n.getMenuLabel("channels.editInstrument"));
726 channelChanged(null);
727 getModel().addSamplerChannelListener(this);
728 }
729
730 @Override
731 public void
732 actionPerformed(ActionEvent e) {
733 CC.getSamplerModel().editBackendInstrument(getChannelId());
734 }
735
736 @Override
737 public void
738 channelChanged(SamplerChannelEvent e) {
739 boolean b = getChannelInfo().getInstrumentStatus() == 100;
740 setEnabled(b);
741 }
742
743 @Override
744 public void
745 streamCountChanged(SamplerChannelEvent e) { }
746
747 @Override
748 public void
749 voiceCountChanged(SamplerChannelEvent e) { }
750 }
751
752 class FxSendsAction extends AbstractAction {
753 FxSendsAction() {
754 super(i18n.getMenuLabel("channels.fxSends"));
755 }
756
757 @Override
758 public void
759 actionPerformed(ActionEvent e) {
760 showFxSendsDialog();
761 }
762 }
763
764 class ChannelRoutingAction extends AbstractAction implements SamplerChannelListener {
765 ChannelRoutingAction() {
766 super(i18n.getMenuLabel("channels.channelRouting"));
767 channelChanged(null);
768 getModel().addSamplerChannelListener(this);
769 }
770
771 @Override
772 public void
773 actionPerformed(ActionEvent e) {
774 SamplerChannel c = getChannelInfo();
775 new JSChannelOutputRoutingDlg(CC.getMainFrame(), c).setVisible(true);
776 }
777
778 @Override
779 public void
780 channelChanged(SamplerChannelEvent e) {
781 boolean b = getChannelInfo().getAudioOutputDevice() != -1;
782 setEnabled(b);
783 }
784
785 @Override
786 public void
787 streamCountChanged(SamplerChannelEvent e) { }
788
789 @Override
790 public void
791 voiceCountChanged(SamplerChannelEvent e) { }
792 }
793
794 class SetSmallViewAction extends AbstractAction {
795 SetSmallViewAction() {
796 super(i18n.getMenuLabel("channels.smallView"));
797 }
798
799 @Override
800 public void
801 actionPerformed(ActionEvent e) {
802 viewTracker.setView(new SmallChannelView(Channel.this));
803 }
804 }
805
806 class SetNormalViewAction extends AbstractAction {
807 SetNormalViewAction() {
808 super(i18n.getMenuLabel("channels.normalView"));
809 }
810
811 @Override
812 public void
813 actionPerformed(ActionEvent e) {
814 viewTracker.setView(new NormalChannelView(Channel.this));
815 }
816 }
817
818 public ContextMenu
819 getContextMenu() { return contextMenu; }
820
821 class ContextMenu extends MouseAdapter {
822 private JPopupMenu menu = null;
823
824 protected JRadioButtonMenuItem rbmiSmallView;
825 protected JRadioButtonMenuItem rbmiNormalView;
826
827 ContextMenu() {
828
829 }
830
831 private void
832 createMenu() {
833 menu = new JPopupMenu();
834 menu.add(new JMenuItem(new EditInstrumentAction()));
835 menu.addSeparator();
836
837 rbmiSmallView = new JRadioButtonMenuItem(new SetSmallViewAction());
838 rbmiNormalView = new JRadioButtonMenuItem(new SetNormalViewAction());
839 if(viewTracker.getOriginalView() instanceof SmallChannelView) {
840 rbmiSmallView.setSelected(true);
841 } else if(viewTracker.getOriginalView() instanceof NormalChannelView) {
842 rbmiNormalView.setSelected(true);
843 }
844
845 ButtonGroup group = new ButtonGroup();
846 group.add(rbmiSmallView);
847 group.add(rbmiNormalView);
848
849 menu.add(rbmiSmallView);
850 menu.add(rbmiNormalView);
851
852 menu.addSeparator();
853 menu.add(new JMenuItem(new FxSendsAction()));
854 menu.add(new JMenuItem(new ChannelRoutingAction()));
855 }
856
857 private JPopupMenu
858 getMenu() {
859 if(menu == null) createMenu();
860 return menu;
861 }
862
863 @Override
864 public void
865 mousePressed(MouseEvent e) {
866 if(e.isPopupTrigger()) show(e);
867 }
868
869 @Override
870 public void
871 mouseReleased(MouseEvent e) {
872 if(e.isPopupTrigger()) show(e);
873 }
874
875 void
876 show(MouseEvent e) {
877 getMenu().show(e.getComponent(), e.getX(), e.getY());
878 }
879 }
880
881 class FxSendsPane extends JSFxSendsPane {
882 FxSendsPane(SamplerChannelModel model) {
883 super(model);
884
885 actionAddFxSend.putValue(Action.SMALL_ICON, Res.iconNew16);
886 actionRemoveFxSend.putValue(Action.SMALL_ICON, Res.iconDelete16);
887 }
888
889 @Override
890 protected JToolBar
891 createToolBar() {
892 JToolBar tb = new JToolBar();
893 Dimension d = new Dimension(Short.MAX_VALUE, tb.getPreferredSize().height);
894 tb.setMaximumSize(d);
895 tb.setFloatable(false);
896 tb.setAlignmentX(JPanel.RIGHT_ALIGNMENT);
897
898 tb.add(new ToolbarButton(actionAddFxSend));
899 tb.add(new ToolbarButton(actionRemoveFxSend));
900
901 return tb;
902 }
903 }
904
905 public static class StreamVoiceCountPane extends JPanel {
906 private final Channel channel;
907
908 private final JLabel lStreams = createScreenLabel(" --");
909 private final JLabel lSlash = createScreenLabel("/");
910 private final JLabel lVoices = createScreenLabel("-- ");
911
912 public
913 StreamVoiceCountPane(Channel channel) {
914 this.channel = channel;
915
916 setOpaque(false);
917 setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
918 lStreams.setFont(Res.fontScreenMono);
919 lStreams.setHorizontalAlignment(JLabel.RIGHT);
920 lStreams.setToolTipText(i18n.getLabel("Channel.streamVoiceCount"));
921
922 Dimension d = lStreams.getPreferredSize();
923 lStreams.setMinimumSize(d);
924 lStreams.setPreferredSize(d);
925 lStreams.setMaximumSize(d);
926 add(lStreams);
927
928 lSlash.setFont(Res.fontScreenMono);
929 lSlash.setToolTipText(i18n.getLabel("Channel.streamVoiceCount"));
930 add(lSlash);
931
932 lVoices.setFont(Res.fontScreenMono);
933 lVoices.setToolTipText(i18n.getLabel("Channel.streamVoiceCount"));
934
935 d = lStreams.getPreferredSize();
936 lVoices.setMinimumSize(d);
937 lVoices.setPreferredSize(d);
938 lVoices.setMaximumSize(d);
939 add(lVoices);
940
941 lStreams.addMouseListener(channel.getContextMenu());
942 lSlash.addMouseListener(channel.getContextMenu());
943 lVoices.addMouseListener(channel.getContextMenu());
944 }
945
946 public void
947 updateStreamCount(int count) {
948 lStreams.setText(count == 0 ? " --" : String.valueOf(count));
949 }
950
951 public void
952 updateVoiceCount(int count) {
953 lVoices.setText(count == 0 ? "-- " : String.valueOf(count));
954 }
955 }
956
957 public static class VolumePane extends JPanel {
958 private final Channel channel;
959 private final JButton btnVolume = createScreenButton("");
960 private JSVolumeEditorPopup popupVolume;
961
962 private static NumberFormat numberFormat = NumberFormat.getInstance();
963 static { numberFormat.setMaximumFractionDigits(1); }
964
965 public
966 VolumePane(final Channel channel) {
967 this.channel = channel;
968 setOpaque(false);
969 setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
970
971 btnVolume.setIcon(Res.iconVolume14);
972 btnVolume.setIconTextGap(2);
973 btnVolume.setAlignmentX(RIGHT_ALIGNMENT);
974 btnVolume.setHorizontalAlignment(btnVolume.LEFT);
975 updateVolumeInfo(100);
976 Dimension d = btnVolume.getPreferredSize();
977 d.width = 57;
978 btnVolume.setPreferredSize(d);
979 btnVolume.setMinimumSize(d);
980
981 add(btnVolume);
982
983 btnVolume.addActionListener(new ActionListener() {
984 public void
985 actionPerformed(ActionEvent e) {
986 if(popupVolume.isVisible()) {
987 popupVolume.commit();
988 popupVolume.hide();
989 } else {
990 float vol = channel.getModel().getChannelInfo().getVolume();
991 popupVolume.setCurrentVolume(vol);
992 popupVolume.show();
993 }
994 }
995 });
996
997 popupVolume = new JSVolumeEditorPopup(btnVolume, VolumeType.CHANNEL);
998
999 popupVolume.addActionListener(new ActionListener() {
1000 public void
1001 actionPerformed(ActionEvent e) {
1002 channel.getModel().setBackendVolume(popupVolume.getVolumeFactor());
1003 }
1004 });
1005
1006 btnVolume.addMouseListener(channel.getContextMenu());
1007 }
1008
1009 public void
1010 updateVolumeInfo(int volume) {
1011 if(CC.getViewConfig().isMeasurementUnitDecibel()) {
1012 String s = numberFormat.format(HF.percentsToDecibels(volume));
1013 btnVolume.setText(s + "dB");
1014 } else {
1015 btnVolume.setText(String.valueOf(volume) + "%");
1016 }
1017 }
1018 }
1019
1020 public static class PowerButton extends PixmapToggleButton implements ActionListener {
1021 private final Channel channel;
1022
1023 PowerButton(Channel channel) {
1024 this(channel, Res.gfxPowerOff, Res.gfxPowerOn);
1025 }
1026
1027 PowerButton(Channel channel, ImageIcon defaultIcon, ImageIcon selectedIcon) {
1028 super(defaultIcon, selectedIcon);
1029
1030 this.channel = channel;
1031
1032 setSelected(true);
1033 addActionListener(this);
1034 setToolTipText(i18n.getButtonLabel("Channel.ttRemoveChannel"));
1035 }
1036
1037 @Override
1038 public void
1039 actionPerformed(ActionEvent e) {
1040 boolean b = preferences().getBoolProperty(CONFIRM_CHANNEL_REMOVAL);
1041 if(b) {
1042 String s = i18n.getMessage("Channel.remove?", channel.getChannelId());
1043 if(!HF.showYesNoDialog(channel, s)) {
1044 setSelected(true);
1045 return;
1046 }
1047 }
1048 channel.remove();
1049 }
1050
1051 @Override
1052 public boolean
1053 contains(int x, int y) { return (x - 11)*(x - 11) + (y - 11)*(y - 11) < 71; }
1054 }
1055
1056 public static class OptionsButton extends PixmapToggleButton
1057 implements ActionListener, PropertyChangeListener {
1058
1059 private final Channel channel;
1060
1061 OptionsButton(Channel channel) {
1062 super(Res.gfxOptionsOff, Res.gfxOptionsOn);
1063
1064 this.channel = channel;
1065
1066 setRolloverIcon(Res.gfxOptionsOffRO);
1067 this.setRolloverSelectedIcon(Res.gfxOptionsOnRO);
1068 addActionListener(this);
1069 setToolTipText(i18n.getButtonLabel("Channel.ttShowOptions"));
1070 }
1071
1072 @Override
1073 public void
1074 actionPerformed(ActionEvent e) {
1075 ChannelView view = channel.viewTracker.getCurrentView();
1076
1077 if(isSelected() && view.getChannelOptionsView() == null) {
1078 view.installChannelOptionsView();
1079 JComponent c = view.getChannelOptionsView().getComponent();
1080 channel.optionsPane.setContentPane(c);
1081 }
1082
1083 channel.showOptionsPane(isSelected());
1084
1085 String s;
1086 if(isSelected()) s = i18n.getButtonLabel("Channel.ttHideOptions");
1087 else s = i18n.getButtonLabel("Channel.ttShowOptions");
1088
1089 setToolTipText(s);
1090
1091 s = JXCollapsiblePane.ANIMATION_STATE_KEY;
1092 channel.optionsPane.addPropertyChangeListener(s, this);
1093 }
1094
1095 @Override
1096 public void
1097 propertyChange(PropertyChangeEvent e) {
1098 if(e.getNewValue() == "collapsed") {
1099 ChannelView view = channel.viewTracker.getCurrentView();
1100 view.uninstallChannelOptionsView();
1101 channel.optionsPane.setContentPane(new JPanel());
1102 }
1103 }
1104
1105 public void
1106 onDestroy() {
1107 String s = JXCollapsiblePane.ANIMATION_STATE_KEY;
1108 channel.optionsPane.removePropertyChangeListener(s, this);
1109 }
1110
1111 @Override
1112 public boolean
1113 contains(int x, int y) { return super.contains(x, y) & y < 13; }
1114 }
1115 }
1116
1117 class ChannelOptionsPane extends JXCollapsiblePane {
1118 ChannelOptionsPane() {
1119 setAnimated(false);
1120 setCollapsed(true);
1121 setAnimated(preferences().getBoolProperty(ANIMATED));
1122
1123 preferences().addPropertyChangeListener(ANIMATED, new PropertyChangeListener() {
1124 public void
1125 propertyChange(PropertyChangeEvent e) {
1126 setAnimated(preferences().getBoolProperty(ANIMATED));
1127 }
1128 });
1129 }
1130
1131 public void
1132 showOptionsPane(boolean show) { setCollapsed(!show); }
1133 }

  ViewVC Help
Powered by ViewVC