/[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 1743 - (show annotations) (download)
Sat May 31 23:04:01 2008 UTC (15 years, 10 months ago) by iliev
File size: 28801 byte(s)
* Renamed the column labels in the Channel Routing dialog: The column
  representing the sampler channel's audio channels is "Audio In" and
  the column representing the audio device's channels is "Audio Out"
* Remember the last used tab in the Preferences dialog
* Fantasia: The sampler channels are now referenced by their position
  in the list, not by their ID
* Fantasia: Implemented options to show the channel number and/or the MIDI
  input port/channel on the sampler channel screen when using Small View
  (choose Edit/Preferences, then click the `Channels' tab)
* Fantasia: Migrated to substance 5

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

  ViewVC Help
Powered by ViewVC