/[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 1975 - (show annotations) (download)
Mon Aug 3 14:54:18 2009 UTC (14 years, 8 months ago) by iliev
File size: 29095 byte(s)
* preparations for release 0.9

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

  ViewVC Help
Powered by ViewVC