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

Annotation of /jsampler/trunk/src/org/jsampler/view/fantasia/Channel.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1737 - (hide annotations) (download)
Thu May 8 17:26:19 2008 UTC (15 years, 11 months ago) by iliev
File size: 28928 byte(s)
* Major memory optimizations when too many sampler channels are present

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

  ViewVC Help
Powered by ViewVC