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

Contents of /jsampler/trunk/src/org/jsampler/view/SamplerTreeModel.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2200 - (show annotations) (download)
Sun Jul 3 22:01:16 2011 UTC (12 years, 9 months ago) by iliev
File size: 34636 byte(s)
* added support for exporting effects to LSCP script
* Sampler Browser (work in progress): initial
  implementation of sampler channels

1 /*
2 * JSampler - a java front-end for LinuxSampler
3 *
4 * Copyright (C) 2011 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 package org.jsampler.view;
23
24 import java.beans.PropertyChangeEvent;
25 import java.beans.PropertyChangeListener;
26 import java.beans.PropertyChangeSupport;
27 import java.util.Enumeration;
28 import java.util.Vector;
29 import javax.swing.SwingConstants;
30 import javax.swing.SwingUtilities;
31 import javax.swing.event.TreeModelEvent;
32 import javax.swing.event.TreeModelListener;
33 import javax.swing.tree.TreeModel;
34 import javax.swing.tree.TreeNode;
35 import javax.swing.tree.TreePath;
36
37 import org.jsampler.AudioDeviceModel;
38 import org.jsampler.CC;
39 import org.jsampler.EffectChain;
40 import org.jsampler.EffectInstance;
41 import org.jsampler.SamplerChannelModel;
42 import org.jsampler.event.AudioDeviceEvent;
43 import org.jsampler.event.AudioDeviceListener;
44 import org.jsampler.event.EffectChainEvent;
45 import org.jsampler.event.EffectChainListener;
46 import org.jsampler.event.EffectInstanceEvent;
47 import org.jsampler.event.EffectInstanceListener;
48 import org.jsampler.event.EffectSendsEvent;
49 import org.jsampler.event.EffectSendsListener;
50 import org.jsampler.event.ListEvent;
51 import org.jsampler.event.ListListener;
52
53 import org.linuxsampler.lscp.Effect;
54 import org.linuxsampler.lscp.EffectParameter;
55 import org.linuxsampler.lscp.FxSend;
56
57 import static org.jsampler.JSI18n.i18n;
58
59 /**
60 *
61 * @author Grigor Iliev
62 */
63 public class SamplerTreeModel extends AbstractTreeModel {
64 private final SamplerTreeNode root = new SamplerTreeNode(this);
65
66 private final SamplerChannelDirTreeNode samplerChannels;
67 private final AudioDevicesTreeNode audioDevices;
68 private final InternalEffectsTreeNode internalEffects;
69
70 public
71 SamplerTreeModel() {
72 audioDevices = new AudioDevicesTreeNode(this, root); // should be created before samplerChannels
73
74 for(AudioDeviceModel a : CC.getSamplerModel().getAudioDevices()) {
75 audioDevices.addChild(new AudioDeviceTreeNode(this, audioDevices, a));
76 a.addAudioDeviceListener(getHandler());
77 }
78
79 CC.getSamplerModel().addAudioDeviceListListener(getHandler());
80
81 root.addChild(audioDevices);
82
83 samplerChannels = new SamplerChannelDirTreeNode(this, root);
84 root.insertChild(samplerChannels, root.getIndex(audioDevices));
85
86 internalEffects = new InternalEffectsTreeNode(this, root);
87 root.addChild(internalEffects);
88 for(int i = 0; i < CC.getSamplerModel().getEffects().getEffectCount(); i++) {
89 Effect fx = CC.getSamplerModel().getEffects().getEffect(i);
90 internalEffects.addChild(new InternalEffectTreeNode(internalEffects, fx));
91 }
92 }
93
94 @Override
95 public Object
96 getRoot() { return root; }
97
98 @Override
99 public void
100 valueForPathChanged(TreePath path, Object newValue) {
101
102 }
103 ///////
104
105
106 private final EventHandler eventHandler = new EventHandler();
107
108 private EventHandler
109 getHandler() { return eventHandler; }
110
111 private class EventHandler implements ListListener<AudioDeviceModel>, AudioDeviceListener {
112
113
114 /** Invoked when a new entry is added to a list. */
115 @Override
116 public void
117 entryAdded(final ListEvent<AudioDeviceModel> e) {
118 e.getEntry().addAudioDeviceListener(getHandler());
119 AudioDeviceTreeNode node =
120 new AudioDeviceTreeNode(SamplerTreeModel.this, audioDevices, e.getEntry());
121 audioDevices.addChild(node);
122 fireNodeInserted(node, audioDevices.getIndex(node));
123
124 root.firePropertyChange("SamplerTreeModel.update", null, null);
125 audioDevices.firePropertyChange("SamplerTreeModel.update", null, null);
126 }
127
128 /** Invoked when an entry is removed from a list. */
129 @Override
130 public void
131 entryRemoved(ListEvent<AudioDeviceModel> e) {
132 TreeNode node = audioDevices.getChildById(e.getEntry().getDeviceId());
133 int i = audioDevices.getIndex(node);
134 if(i == -1) return;
135
136 audioDevices.removeChildAt(i);
137 fireNodeRemoved(audioDevices, node, i);
138
139 e.getEntry().removeAudioDeviceListener(getHandler());
140
141 root.firePropertyChange("SamplerTreeModel.update", null, null);
142 audioDevices.firePropertyChange("SamplerTreeModel.update", null, null);
143 }
144
145 @Override
146 public void
147 settingsChanged(AudioDeviceEvent e) {
148 audioDevices.firePropertyChange("SamplerTreeModel.update", null, null);
149
150 TreeNodeBase node =
151 audioDevices.getChildById(e.getAudioDeviceModel().getDeviceId());
152
153 if(node != null) {
154 node.firePropertyChange("SamplerTreeModel.update", null, null);
155 }
156 }
157
158 /** Invoked when a new send effect chain is added to the audio device. */
159 @Override
160 public void
161 sendEffectChainAdded(AudioDeviceEvent e) {
162 AudioDeviceTreeNode node =
163 audioDevices.getChildById(e.getAudioDeviceModel().getDeviceId());
164
165 if(node == null) {
166 CC.getLogger().warning("Missing audio device node. This is a bug!");
167 return;
168 }
169
170 SendEffectChainsTreeNode chainsNode = node.getSendEffectChainsNode();
171
172 SendEffectChainTreeNode child = new SendEffectChainTreeNode (
173 SamplerTreeModel.this, chainsNode, e.getEffectChain()
174 );
175
176 chainsNode.addChild(child);
177 fireNodeInserted(child, chainsNode.getIndex(child));
178
179 node.firePropertyChange("SamplerTreeModel.update", null, null);
180 chainsNode.firePropertyChange("SamplerTreeModel.update", null, null);
181 }
182
183 /** Invoked when when a send effect chain is removed from the audio device. */
184 @Override
185 public void
186 sendEffectChainRemoved(AudioDeviceEvent e) {
187 AudioDeviceTreeNode node =
188 audioDevices.getChildById(e.getAudioDeviceModel().getDeviceId());
189
190 if(node == null) {
191 CC.getLogger().warning("Missing audio device node. This is a bug!");
192 return;
193 }
194
195 SendEffectChainsTreeNode chainsNode = node.getSendEffectChainsNode();
196
197 SendEffectChainTreeNode child = chainsNode.getChildById(e.getEffectChain().getChainId());
198 if(child == null) {
199 CC.getLogger().warning("Missing send effect chain node. This is a bug!");
200 return;
201 }
202
203 child.uninstall();
204
205 int idx = chainsNode.getIndex(child);
206 chainsNode.removeChildAt(idx);
207 fireNodeRemoved(chainsNode, child, idx);
208
209 node.firePropertyChange("SamplerTreeModel.update", null, null);
210 chainsNode.firePropertyChange("SamplerTreeModel.update", null, null);
211 }
212 }
213
214 public static abstract class TreeNodeBase<T extends TreeNodeBase>
215 extends PropertyChangeSupport implements TreeNode {
216
217 public TreeNodeBase() { super(new Object()); }
218
219 public abstract T getChildAt(int index);
220 public abstract boolean isLeaf();
221 public abstract void uninstall();
222
223 public boolean
224 isLink() { return false; }
225
226 public TreeNodeBase
227 getLink() { return null; }
228
229 public void edit() { }
230
231 public int
232 getId() { return -1; }
233
234 /** Gets the number of columns for the corresponding table model. */
235 public int
236 getColumnCount() { return 1; }
237
238 /** Gets the number of rows for the corresponding table model. */
239 public int
240 getRowCount() { return 1; }
241
242 /**
243 * Gets the value for the cell at <code>row</code> and
244 * <code>col</code> for the corresponding table model.
245 */
246 public Object
247 getValueAt(int row, int col) { return "Not implemented yet"; }
248
249 /** Gets the name of the column for the corresponding table model. */
250 public String
251 getColumnName(int col) { return " "; }
252
253 /** Gets the number of items this node contains. */
254 public int
255 getItemCount() { return getRowCount(); }
256
257 public String
258 getItemCountString() { return String.valueOf(getItemCount()); }
259
260 /** Determines the alignment for the cells in the specified column. */
261 public int
262 getHorizontalAlignment(int column) {
263 return column == 0 ? SwingConstants.LEFT : SwingConstants.CENTER;
264 }
265 }
266
267 public static class AbstractTreeNode<T extends TreeNodeBase> extends TreeNodeBase<T> {
268 protected AbstractTreeModel treeModel;
269 private TreeNodeBase parent;
270 private Vector<T> children = new Vector<T>();
271
272 public
273 AbstractTreeNode(AbstractTreeModel treeModel) { this(treeModel, null); }
274
275 public
276 AbstractTreeNode(AbstractTreeModel treeModel, TreeNodeBase parent) {
277 this.parent = parent;
278 this.treeModel = treeModel;
279 }
280
281 // Tree node model methods
282 @Override
283 public T
284 getChildAt(int index) { return children.get(index); }
285
286 @Override
287 public int
288 getChildCount() { return children.size(); }
289
290 @Override
291 public TreeNodeBase
292 getParent() { return parent; }
293
294 @Override
295 public int
296 getIndex(TreeNode node) { return children.indexOf(node); }
297
298 @Override
299 public boolean
300 getAllowsChildren() { return true; }
301
302 @Override
303 public boolean
304 isLeaf() { return false; }
305
306 @Override
307 public Enumeration
308 children() { return children.elements(); }
309 ///////
310
311 public void
312 addChild(T child) { children.add(child); }
313 ///////
314
315 public void
316 insertChild(T child, int index) { children.insertElementAt(child, index); }
317
318 public T
319 removeChildAt(int index) { return children.remove(index); }
320
321 public void
322 removeAllChildren() {
323 children.removeAllElements();
324 }
325
326 public T
327 getChildById(int id) {
328 if(id == -1) return null;
329
330 for(int i = 0; i < getChildCount(); i++) {
331 if(getChildAt(i).getId() == id) return getChildAt(i);
332 }
333
334 return null;
335 }
336
337 public void
338 removeAndUninstallAllChildren() {
339 for(int i = getChildCount() - 1; i >= 0; i--) {
340 T child = getChildAt(i);
341 removeChildAt(i);
342 child.uninstall();
343 }
344 }
345
346 public void
347 uninstall() {
348 removeAndUninstallAllChildren();
349 treeModel = null;
350 parent = null;
351 }
352 }
353
354 public static class AbstractTreeLeaf<T extends TreeNodeBase> extends TreeNodeBase<T> {
355 private T parent;
356
357 public
358 AbstractTreeLeaf() { this(null); }
359
360 public
361 AbstractTreeLeaf(T parent) {this.parent = parent; }
362
363 // Tree node model methods
364 @Override
365 public T
366 getChildAt(int index) { return null; }
367
368 @Override
369 public int
370 getChildCount() { return 0; }
371
372 @Override
373 public T
374 getParent() { return parent; }
375
376 @Override
377 public int
378 getIndex(TreeNode node) { return -1; }
379
380 @Override
381 public boolean
382 getAllowsChildren() { return false; }
383
384 @Override
385 public boolean
386 isLeaf() { return true; }
387
388 @Override
389 public Enumeration
390 children() { return null; }
391 ///////
392
393 public void
394 uninstall() { parent = null; }
395 }
396
397 public static class StandardTreeNode<T extends TreeNodeBase> extends AbstractTreeNode<T> {
398 public
399 StandardTreeNode(AbstractTreeModel treeModel) { this(treeModel, null); }
400
401 public
402 StandardTreeNode(AbstractTreeModel treeModel, TreeNodeBase parent) {
403 super(treeModel, parent);
404 }
405
406 /** Gets the number of columns for the corresponding table model. */
407 @Override
408 public int
409 getColumnCount() { return 3; }
410
411 /** Gets the number of rows for the corresponding table model. */
412 @Override
413 public int
414 getRowCount() { return getChildCount(); }
415
416 /**
417 * Gets the value for the cell at <code>row</code> and
418 * <code>col</code> for the corresponding table model.
419 */
420 @Override
421 public Object
422 getValueAt(int row, int col) {
423 if(col == 0) return getChildAt(row);
424 if(col == 1) return getChildAt(row).getItemCountString();
425 return "";
426 }
427
428 /** Gets the name of the column for the corresponding table model. */
429 @Override
430 public String
431 getColumnName(int col) {
432 if(col == 0) return i18n.getLabel("SamplerTreeModel.tableColumn.name");
433 if(col == 1) return i18n.getLabel("SamplerTreeModel.tableColumn.itemCount");
434 return " ";
435 }
436 }
437
438 public static class SamplerTreeNode extends StandardTreeNode {
439 public
440 SamplerTreeNode(SamplerTreeModel treeModel) {
441 super(treeModel);
442 }
443
444 @Override
445 public String
446 toString() { return i18n.getLabel("SamplerTreeNode.toString"); }
447 }
448
449 public static class SamplerChannelDirTreeNode
450 extends StandardTreeNode<ChannelLaneTreeNode>
451 implements PropertyChangeListener {
452 public
453 SamplerChannelDirTreeNode(SamplerTreeModel treeModel, TreeNodeBase parent) {
454 super(treeModel, parent);
455
456 updateChildren();
457
458 CC.getMainFrame().addPropertyChangeListener(this);
459 }
460
461 @Override
462 public void
463 propertyChange(PropertyChangeEvent e) {
464 if (
465 e.getPropertyName() == "channelLaneAdded" ||
466 e.getPropertyName() == "channelLaneInserted" ||
467 e.getPropertyName() == "channelLaneRemoved"
468 ) {
469 updateChildren();
470 firePropertyChange("SamplerTreeModel.update", null, null);
471 getParent().firePropertyChange("SamplerTreeModel.update", null, null);
472 }
473 }
474
475 private void
476 updateChildren() {
477 removeAndUninstallAllChildren();
478
479 for(int i = 0; i < CC.getMainFrame().getChannelsPaneCount(); i++) {
480 JSChannelsPane lane = CC.getMainFrame().getChannelsPane(i);
481 addChild(new ChannelLaneTreeNode(treeModel, this, lane));
482 }
483 }
484
485 @Override
486 public void
487 uninstall() {
488 CC.getMainFrame().removePropertyChangeListener(this);
489
490 super.uninstall();
491 }
492
493 @Override
494 public String
495 toString() { return i18n.getLabel("SamplerChannelDirTreeNode.toString"); }
496 }
497
498 public static class ChannelLaneTreeNode extends StandardTreeNode<SamplerChannelTreeNode>
499 implements PropertyChangeListener {
500
501 private JSChannelsPane lane;
502
503 public
504 ChannelLaneTreeNode (
505 AbstractTreeModel treeModel, TreeNodeBase parent, JSChannelsPane lane
506 ) {
507 super(treeModel, parent);
508 this.lane = lane;
509
510 updateChildren();
511
512 lane.addPropertyChangeListener(this);
513 }
514
515 public JSChannelsPane
516 getLane() { return lane; }
517
518 /** Gets the number of columns for the corresponding table model. */
519 @Override
520 public int
521 getColumnCount() { return 3; }
522
523 /** Gets the number of rows for the corresponding table model. */
524 @Override
525 public int
526 getRowCount() { return getChildCount(); }
527
528 /**
529 * Gets the value for the cell at <code>row</code> and
530 * <code>col</code> for the corresponding table model.
531 */
532 @Override
533 public Object
534 getValueAt(int row, int col) {
535 if(col == 0) return getChildAt(row);
536 if(col == 1) {
537 Object o = getChildAt(row).getChannel().getChannelInfo().getEngine();
538 if(o == null) o = i18n.getLabel("ChannelLaneTreeNode.noEngine");
539 return o;
540 }
541 return "";
542 }
543
544 /** Gets the name of the column for the corresponding table model. */
545 @Override
546 public String
547 getColumnName(int col) {
548 if(col == 0) return i18n.getLabel("SamplerTreeModel.tableColumn.chn");
549 if(col == 1) return i18n.getLabel("SamplerTreeModel.tableColumn.engine");
550 return " ";
551 }
552
553 @Override
554 public void
555 propertyChange(PropertyChangeEvent e) {
556 if (
557 e.getPropertyName() == "channelAdded" ||
558 e.getPropertyName() == "channelsAdded" ||
559 e.getPropertyName() == "channelRemoved" ||
560 e.getPropertyName() == "channelsRemoved"
561 ) {
562 updateChildren();
563 firePropertyChange("SamplerTreeModel.update", null, null);
564 getParent().firePropertyChange("SamplerTreeModel.update", null, null);
565 }
566
567 if(e.getPropertyName() == "channelsPositionChanged") {
568 updateChildren();
569 firePropertyChange("SamplerTreeModel.update", null, null);
570 }
571 }
572
573 private void
574 updateChildren() {
575 removeAndUninstallAllChildren();
576
577 for(int i = 0; i < lane.getChannelCount(); i++) {
578 SamplerChannelModel chn = lane.getChannel(i).getModel();
579 addChild(new SamplerChannelTreeNode(treeModel, this, chn));
580 }
581
582 treeModel.fireNodeStructureChanged(this);
583 }
584
585 @Override
586 public void
587 uninstall() {
588 lane.removePropertyChangeListener(this);
589 lane = null;
590
591 super.uninstall();
592 }
593
594 @Override
595 public String
596 toString() { return lane.getTitle(); }
597 }
598
599 public static class SamplerChannelTreeNode extends StandardTreeNode {
600 private SamplerChannelModel channel;
601
602 public
603 SamplerChannelTreeNode (
604 AbstractTreeModel treeModel, TreeNodeBase parent, SamplerChannelModel chn
605 ) {
606 super(treeModel, parent);
607 channel = chn;
608 addChild(new FxSendDirTreeNode(treeModel, this, chn));
609 }
610
611 public SamplerChannelModel
612 getChannel() { return channel; }
613
614 public int
615 getId() { return getChannel().getChannelId(); }
616
617 @Override
618 public void
619 uninstall() {
620 super.uninstall();
621 channel = null; // might be needed by the children to uninstall properly
622 }
623
624 @Override
625 public String
626 toString() {
627 String s = CC.getMainFrame().getChannelPath(channel);
628 return i18n.getLabel("SamplerChannelTreeNode.toString", s);
629 }
630 }
631
632 public static class FxSendDirTreeNode
633 extends StandardTreeNode<FxSendTreeNode>
634 implements EffectSendsListener {
635
636 private SamplerChannelModel channel;
637
638 public
639 FxSendDirTreeNode (
640 AbstractTreeModel treeModel, TreeNodeBase parent, SamplerChannelModel chn
641 ) {
642 super(treeModel, parent);
643 channel = chn;
644
645 for(FxSend fx : chn.getFxSends()) {
646 addChild(new FxSendTreeNode(treeModel, this, fx));
647 }
648
649 chn.addEffectSendsListener(this);
650 }
651
652 public SamplerChannelModel
653 getChannel() { return channel; }
654
655 @Override
656 public void
657 effectSendAdded(EffectSendsEvent e) {
658 FxSendTreeNode node = new FxSendTreeNode(treeModel, this, e.getFxSend());
659 addChild(node);
660 treeModel.fireNodeInserted(node, getIndex(node));
661 firePropertyChange("SamplerTreeModel.update", null, null);
662 getParent().firePropertyChange("SamplerTreeModel.update", null, null);
663 }
664
665 @Override
666 public void
667 effectSendRemoved(EffectSendsEvent e) {
668 final FxSendTreeNode child = getChildById(e.getFxSend().getFxSendId());
669 int i = getIndex(child);
670 if(i == -1) return;
671
672 removeChildAt(i);
673 treeModel.fireNodeRemoved(this, child, i);
674 firePropertyChange("SamplerTreeModel.update", null, null);
675 getParent().firePropertyChange("SamplerTreeModel.update", null, null);
676
677 /* To avoid ConcurrentModificationException. */
678 SwingUtilities.invokeLater(new Runnable() {
679 public void
680 run() { child.uninstall(); }
681 });
682 ///////
683 }
684
685 @Override
686 public void
687 effectSendChanged(EffectSendsEvent e) {
688 FxSendTreeNode node = getChildById(e.getFxSend().getFxSendId());
689 node.setFxSend(e.getFxSend());
690
691 treeModel.fireNodeChanged(node, getIndex(node));
692
693 firePropertyChange("SamplerTreeModel.update", null, null);
694 }
695
696 @Override
697 public void
698 uninstall() {
699 channel.removeEffectSendsListener(this);
700 super.uninstall();
701 channel = null; // might be needed by the children to uninstall properly
702 }
703
704 @Override
705 public String
706 toString() { return i18n.getLabel("FxSendDirTreeNode.toString"); }
707 }
708
709 public static class FxSendTreeNode extends StandardTreeNode<DestEffectDirTreeNode> {
710 private FxSend fxSend;
711 private DestEffectDirTreeNode destEffectDir;
712
713 public
714 FxSendTreeNode(AbstractTreeModel treeModel, TreeNodeBase parent, FxSend fxSend) {
715 super(treeModel, parent);
716 this.fxSend = fxSend;
717
718 destEffectDir = new DestEffectDirTreeNode(treeModel, this, fxSend);
719 addChild(destEffectDir);
720 }
721
722 public SamplerChannelModel
723 getChannel() { return ((FxSendDirTreeNode)getParent()).getChannel(); }
724
725 public FxSend
726 getFxSend() { return fxSend; }
727
728 public void
729 setFxSend(FxSend fxSend) {
730 this.fxSend = fxSend;
731 destEffectDir.setFxSend(fxSend);
732 }
733
734 public int
735 getId() { return fxSend.getFxSendId(); }
736
737 @Override
738 public void
739 uninstall() {
740 fxSend = null;
741 super.uninstall();
742 }
743
744 @Override
745 public String
746 toString() { return fxSend != null ? fxSend.getName(): super.toString(); }
747 }
748
749 public static class DestEffectDirTreeNode extends AbstractTreeNode<DestEffectTreeNode> {
750 public
751 DestEffectDirTreeNode(AbstractTreeModel treeModel, TreeNodeBase parent, FxSend fxSend) {
752 super(treeModel, parent);
753
754 addChild(new DestEffectTreeNode(this, fxSend));
755 }
756
757 public void
758 setFxSend(FxSend fxSend) { getChildAt(0).setFxSend(fxSend); }
759
760 /** Gets the number of columns for the corresponding table model. */
761 @Override
762 public int
763 getColumnCount() { return 3; }
764
765 /** Gets the number of rows for the corresponding table model. */
766 @Override
767 public int
768 getRowCount() { return getChildCount(); }
769
770 /**
771 * Gets the value for the cell at <code>row</code> and
772 * <code>col</code> for the corresponding table model.
773 */
774 @Override
775 public Object
776 getValueAt(int row, int col) {
777 if(col == 0) return getChildAt(row);
778 if(col == 1) return getChildAt(row).getEffectInstanceString();
779 return "";
780 }
781
782 /** Gets the name of the column for the corresponding table model. */
783 @Override
784 public String
785 getColumnName(int col) {
786 if(col == 0) return i18n.getLabel("SamplerTreeModel.tableColumn.destChain");
787 if(col == 1) return i18n.getLabel("SamplerTreeModel.tableColumn.destFx");
788 return " ";
789 }
790
791 @Override
792 public String
793 toString() { return i18n.getLabel("DestEffectDirTreeNode.toString"); }
794 }
795
796 public static class DestEffectTreeNode extends AbstractTreeLeaf<DestEffectDirTreeNode>
797 implements EffectSendsListener {
798
799 private SendEffectChainTreeNode chain;
800 private FxSend fxSend;
801
802 public
803 DestEffectTreeNode(DestEffectDirTreeNode parent, FxSend fxSend) {
804 super(parent);
805
806 setFxSend(fxSend);
807
808 /* To avoid ConcurrentModificationException because
809 * this method is created due to effect sends event. */
810 SwingUtilities.invokeLater(new Runnable() {
811 public void
812 run() { getChannel().addEffectSendsListener(DestEffectTreeNode.this); }
813 });
814 ///////
815 }
816
817 public SamplerChannelModel
818 getChannel() { return ((FxSendTreeNode)getParent().getParent()).getChannel(); }
819
820 public FxSend
821 getFxSend() { return fxSend; }
822
823 public void
824 setFxSend(FxSend fxSend) {
825 this.fxSend = fxSend;
826
827 int d = getChannel().getChannelInfo().getAudioOutputDevice();
828 int c = fxSend.getDestChainId();
829 SamplerTreeModel m = (SamplerTreeModel)getParent().treeModel;
830 chain = m.audioDevices.getSendEffectChainNodeById(d, c);
831 }
832
833 public SendEffectChainTreeNode
834 getEffectChain() { return chain; }
835
836 public EffectInstance
837 getEffectInstance() {
838 if(chain == null) return null;
839 return chain.getEffectChain().getEffectInstance(fxSend.getDestChainPos());
840 }
841
842 public String
843 getEffectInstanceString() {
844 if(chain == null) return "";
845 int i = fxSend.getDestChainPos();
846 String s = chain.getEffectChain().getEffectInstance(i).getInfo().getDescription();
847 return String.valueOf(i) + " (" + s + ")";
848 }
849
850 public AudioDeviceModel
851 getAudioDevice() {
852 int dev = getChannel().getChannelInfo().getAudioOutputDevice();
853 if(dev == -1) return null;
854 return CC.getSamplerModel().getAudioDeviceById(dev);
855 }
856
857 @Override
858 public boolean
859 isLink() { return true; }
860
861 @Override
862 public TreeNodeBase
863 getLink() {
864 if(chain == null) return null;
865 return chain.getChildAt(fxSend.getDestChainPos());
866 }
867
868 @Override
869 public void
870 effectSendAdded(EffectSendsEvent e) { }
871
872 @Override
873 public void
874 effectSendRemoved(EffectSendsEvent e) { }
875
876 @Override
877 public void
878 effectSendChanged(EffectSendsEvent e) {
879 if(e.getFxSend().getFxSendId() != getFxSend().getFxSendId()) return;
880 firePropertyChange("SamplerTreeModel.update", null, null);
881 }
882
883 @Override
884 public void
885 uninstall() {
886 getChannel().removeEffectSendsListener(this);
887 fxSend = null;
888 chain = null;
889
890 super.uninstall();
891 }
892
893 @Override
894 public String
895 toString() {
896 Object o = getEffectChain();
897 return o == null ? i18n.getLabel("DestEffectTreeNode.noFx") : o.toString();
898 }
899 }
900
901 public static class AudioDevicesTreeNode extends AbstractTreeNode<AudioDeviceTreeNode> {
902 public
903 AudioDevicesTreeNode(SamplerTreeModel treeModel, TreeNodeBase parent) {
904 super(treeModel, parent);
905 }
906
907 public SendEffectChainTreeNode
908 getSendEffectChainNodeById(int devId, int chainId) {
909 AudioDeviceTreeNode node = getChildById(devId);
910 if(node == null) return null;
911 return node.getSendEffectChainNodeById(chainId);
912 }
913
914 /** Gets the number of columns for the corresponding table model. */
915 @Override
916 public int
917 getColumnCount() { return 5; }
918
919 /** Gets the number of rows for the corresponding table model. */
920 @Override
921 public int
922 getRowCount() { return getChildCount(); }
923
924 /**
925 * Gets the value for the cell at <code>row</code> and
926 * <code>col</code> for the corresponding table model.
927 */
928 @Override
929 public Object
930 getValueAt(int row, int col) {
931 AudioDeviceModel m = getChildAt(row).getAudioDevice();
932 if(col == 0) return getChildAt(row);
933 if(col == 1) return m.getDeviceInfo().getDriverName();
934 if(col == 2) return m.getDeviceInfo().getSampleRate();
935 if(col == 3) return m.getDeviceInfo().getChannelCount();
936 return "";
937 }
938
939 /** Gets the name of the column for the corresponding table model. */
940 @Override
941 public String
942 getColumnName(int col) {
943 if(col == 0) return i18n.getLabel("SamplerTreeModel.tableColumn.dev");
944 if(col == 1) return i18n.getLabel("SamplerTreeModel.tableColumn.drv");
945 if(col == 2) return i18n.getLabel("SamplerTreeModel.tableColumn.smplrate");
946 if(col == 3) return i18n.getLabel("SamplerTreeModel.tableColumn.chns");
947 return " ";
948 }
949
950 @Override
951 public String
952 toString() { return i18n.getLabel("AudioDevicesTreeNode.toString"); }
953 }
954
955 public static class AudioDeviceTreeNode extends StandardTreeNode {
956 private AudioDeviceModel audioDevice;
957 private SendEffectChainsTreeNode effectChains;
958
959 public
960 AudioDeviceTreeNode (
961 AbstractTreeModel treeModel, TreeNodeBase parent, AudioDeviceModel audioDevice
962 ) {
963 super(treeModel, parent);
964 this.audioDevice = audioDevice;
965
966 effectChains = new SendEffectChainsTreeNode(treeModel, this, audioDevice);
967 addChild(effectChains);
968 }
969
970 public AudioDeviceModel
971 getAudioDevice() { return audioDevice; }
972
973 @Override
974 public int
975 getId() { return audioDevice.getDeviceId(); }
976
977 public SendEffectChainsTreeNode
978 getSendEffectChainsNode() { return effectChains; }
979
980 public SendEffectChainTreeNode
981 getSendEffectChainNodeById(int id) {
982 return getSendEffectChainsNode().getChildById(id);
983 }
984
985 @Override
986 public void
987 uninstall() {
988 audioDevice = null;
989 effectChains = null;
990 super.uninstall();
991 }
992
993 @Override
994 public String
995 toString() { return i18n.getLabel("AudioDeviceTreeNode.toString", getId()); }
996 }
997
998 public static class SendEffectChainsTreeNode extends StandardTreeNode<SendEffectChainTreeNode> {
999 private AudioDeviceModel audioDevice;
1000
1001 public
1002 SendEffectChainsTreeNode (
1003 AbstractTreeModel treeModel, TreeNodeBase parent, AudioDeviceModel audioDevice
1004 ) {
1005 super(treeModel, parent);
1006 this.audioDevice = audioDevice;
1007
1008 for(int i = 0; i < audioDevice.getSendEffectChainCount(); i++) {
1009 EffectChain chain = audioDevice.getSendEffectChain(i);
1010 addChild(new SendEffectChainTreeNode(treeModel, this, chain));
1011 }
1012 }
1013
1014 public AudioDeviceModel
1015 getAudioDevice() { return audioDevice; }
1016
1017 public int
1018 getAudioDeviceId() { return audioDevice.getDeviceId(); }
1019
1020 @Override
1021 public void
1022 uninstall() {
1023 audioDevice = null;
1024 super.uninstall();
1025 }
1026
1027 @Override
1028 public String
1029 toString() { return i18n.getLabel("SendEffectChainsTreeNode.toString"); }
1030 }
1031
1032 public static class SendEffectChainTreeNode extends AbstractTreeNode<EffectInstanceTreeNode>
1033 implements EffectChainListener {
1034 private EffectChain chain;
1035
1036 public
1037 SendEffectChainTreeNode (
1038 AbstractTreeModel treeModel, SendEffectChainsTreeNode parent, EffectChain chain
1039 ) {
1040 super(treeModel, parent);
1041 this.chain = chain;
1042 chain.addEffectChainListener(this);
1043 updateEffectInstanceList();
1044 }
1045 ///////
1046
1047 public EffectChain
1048 getEffectChain() { return chain; }
1049
1050 @Override
1051 public int
1052 getId() { return chain.getChainId(); }
1053
1054 /**
1055 * Gets the audio device to which the
1056 * send effect chain represented by this tree node belongs.
1057 */
1058 public AudioDeviceModel
1059 getAudioDevice() { return ((SendEffectChainsTreeNode)getParent()).getAudioDevice(); }
1060
1061 /** Gets the number of columns for the corresponding table model. */
1062 @Override
1063 public int
1064 getColumnCount() { return 5; }
1065
1066 /** Gets the number of rows for the corresponding table model. */
1067 @Override
1068 public int
1069 getRowCount() { return getChildCount(); }
1070
1071 /**
1072 * Gets the value for the cell at <code>row</code> and
1073 * <code>col</code> for the corresponding table model.
1074 */
1075 @Override
1076 public Object
1077 getValueAt(int row, int col) {
1078 EffectInstance e = getChildAt(row).effectInstance;
1079 if(col == 0) return getChildAt(row);
1080 if(col == 1) return e.getInfo().getSystem();
1081 if(col == 2) return e.getInfo().getModule();
1082 if(col == 3) return e.getInfo().getName();
1083 return "";
1084 }
1085
1086 /** Gets the name of the column for the corresponding table model. */
1087 @Override
1088 public String
1089 getColumnName(int col) {
1090 if(col == 0) return i18n.getLabel("SamplerTreeModel.tableColumn.effect");
1091 if(col == 1) return i18n.getLabel("SamplerTreeModel.tableColumn.type");
1092 if(col == 2) return i18n.getLabel("SamplerTreeModel.tableColumn.file");
1093 if(col == 3) return i18n.getLabel("SamplerTreeModel.tableColumn.id");
1094 return " ";
1095 }
1096
1097 @Override
1098 public int
1099 getHorizontalAlignment(int column) {
1100 return column == 1 ? SwingConstants.CENTER : SwingConstants.LEFT;
1101 }
1102
1103 @Override
1104 public void
1105 uninstall() {
1106 chain.removeEffectChainListener(this);
1107 chain = null;
1108 super.uninstall();
1109 }
1110
1111 @Override
1112 public String
1113 toString() { return i18n.getLabel("SendEffectChainTreeNode.toString", chain.getChainId()); }
1114
1115 @Override
1116 public void
1117 effectInstanceListChanged(EffectChainEvent e) {
1118 updateEffectInstanceList();
1119 treeModel.fireNodeStructureChanged(this);
1120
1121 firePropertyChange("SamplerTreeModel.update", null, null);
1122 getParent().firePropertyChange("SamplerTreeModel.update", null, null);
1123 }
1124
1125 private void
1126 updateEffectInstanceList() {
1127 removeAndUninstallAllChildren();
1128
1129 for(int i = 0; i < chain.getEffectInstanceCount(); i++) {
1130 EffectInstance ei = chain.getEffectInstance(i);
1131 addChild(new EffectInstanceTreeNode(treeModel, this, ei));
1132 }
1133 }
1134 }
1135
1136 public static class EffectInstanceTreeNode extends AbstractTreeNode implements EffectInstanceListener {
1137 private EffectInstance effectInstance;
1138 private EffectParameter[] params;
1139
1140 public
1141 EffectInstanceTreeNode (
1142 AbstractTreeModel treeModel, SendEffectChainTreeNode parent, EffectInstance ei
1143 ) {
1144 super(treeModel, parent);
1145 effectInstance = ei;
1146 params = ei.getInfo().getParameters();
1147
1148 effectInstance.addEffectInstanceListener(this);
1149 }
1150
1151 @Override
1152 public void
1153 uninstall() {
1154 effectInstance.removeEffectInstanceListener(this);
1155 effectInstance = null;
1156 params = null;
1157 super.uninstall();
1158 }
1159
1160 @Override
1161 public SendEffectChainTreeNode
1162 getParent() { return (SendEffectChainTreeNode)super.getParent(); }
1163
1164 public int
1165 getInstanceId() { return effectInstance.getInstanceId(); }
1166
1167 /** Gets the number of columns for the corresponding table model. */
1168 @Override
1169 public int
1170 getColumnCount() { return 3; }
1171
1172 /** Gets the number of rows for the corresponding table model. */
1173 @Override
1174 public int
1175 getRowCount() { return params.length; }
1176
1177 /**
1178 * Gets the value for the cell at <code>row</code> and
1179 * <code>col</code> for the corresponding table model.
1180 */
1181 @Override
1182 public Object
1183 getValueAt(int row, int col) {
1184 if(col == 0) return effectInstance.getInfo().getParameter(row);
1185 if(col == 1) return effectInstance.getInfo().getParameter(row).getValue();
1186 return "";
1187 }
1188
1189 /** Gets the name of the column for the corresponding table model. */
1190 @Override
1191 public String
1192 getColumnName(int col) {
1193 if(col == 0) return i18n.getLabel("SamplerTreeModel.tableColumn.name");
1194 if(col == 1) return i18n.getLabel("SamplerTreeModel.tableColumn.value");
1195 return " ";
1196 }
1197
1198 @Override
1199 public int
1200 getHorizontalAlignment(int column) {
1201 return column == 1 ? SwingConstants.RIGHT : SwingConstants.LEFT;
1202 }
1203
1204 @Override
1205 public void
1206 effectInstanceChanged(EffectInstanceEvent e) {
1207 firePropertyChange("SamplerTreeModel.update", null, null);
1208 }
1209
1210 @Override
1211 public String
1212 toString() { return effectInstance.getInfo().getDescription(); }
1213 }
1214
1215 public static class InternalEffectsTreeNode extends AbstractTreeNode<InternalEffectTreeNode> {
1216 public
1217 InternalEffectsTreeNode(SamplerTreeModel treeModel, TreeNodeBase parent) {
1218 super(treeModel, parent);
1219 }
1220
1221 /** Gets the number of columns for the corresponding table model. */
1222 @Override
1223 public int
1224 getColumnCount() { return 5; }
1225
1226 /** Gets the number of rows for the corresponding table model. */
1227 @Override
1228 public int
1229 getRowCount() { return getChildCount(); }
1230
1231 /**
1232 * Gets the value for the cell at <code>row</code> and
1233 * <code>col</code> for the corresponding table model.
1234 */
1235 @Override
1236 public Object
1237 getValueAt(int row, int col) {
1238 Effect e = getChildAt(row).effect;
1239 if(col == 0) return getChildAt(row);
1240 if(col == 1) return e.getSystem();
1241 if(col == 2) return e.getModule();
1242 if(col == 3) return e.getName();
1243 return "";
1244 }
1245
1246 /** Gets the name of the column for the corresponding table model. */
1247 @Override
1248 public String
1249 getColumnName(int col) {
1250 if(col == 0) return i18n.getLabel("SamplerTreeModel.tableColumn.effect");
1251 if(col == 1) return i18n.getLabel("SamplerTreeModel.tableColumn.type");
1252 if(col == 2) return i18n.getLabel("SamplerTreeModel.tableColumn.file");
1253 if(col == 3) return i18n.getLabel("SamplerTreeModel.tableColumn.id");
1254 return " ";
1255 }
1256
1257 @Override
1258 public int
1259 getHorizontalAlignment(int column) {
1260 return column == 1 ? SwingConstants.CENTER : SwingConstants.LEFT;
1261 }
1262
1263 @Override
1264 public String
1265 toString() { return i18n.getLabel("InternalEffectsTreeNode.toString"); }
1266 }
1267
1268 public static class InternalEffectTreeNode extends AbstractTreeLeaf {
1269 private final Effect effect;
1270
1271 public
1272 InternalEffectTreeNode(TreeNodeBase parent, Effect effect) {
1273 super(parent);
1274 this.effect = effect;
1275 }
1276
1277 @Override
1278 public String
1279 toString() { return effect.getDescription(); }
1280 }
1281
1282 }

  ViewVC Help
Powered by ViewVC