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

Contents of /jsampler/trunk/src/org/jsampler/view/std/JSFxSendsPane.java

Parent Directory Parent Directory | Revision Log Revision Log


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

1 /*
2 * JSampler - a java front-end for LinuxSampler
3 *
4 * Copyright (C) 2005-2008 Grigor Iliev <grigor@grigoriliev.com>
5 *
6 * This file is part of JSampler.
7 *
8 * JSampler is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2
10 * as published by the Free Software Foundation.
11 *
12 * JSampler is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with JSampler; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20 * MA 02111-1307 USA
21 */
22
23 package org.jsampler.view.std;
24
25 import java.awt.BorderLayout;
26 import java.awt.Dimension;
27
28 import java.awt.event.ActionEvent;
29 import java.awt.event.ActionListener;
30
31 import javax.swing.AbstractAction;
32 import javax.swing.Action;
33 import javax.swing.BorderFactory;
34 import javax.swing.Box;
35 import javax.swing.BoxLayout;
36 import javax.swing.DefaultCellEditor;
37 import javax.swing.JButton;
38 import javax.swing.JComboBox;
39 import javax.swing.JLabel;
40 import javax.swing.JPanel;
41 import javax.swing.JScrollPane;
42 import javax.swing.JSlider;
43 import javax.swing.JSplitPane;
44 import javax.swing.JTable;
45 import javax.swing.JToolBar;
46
47 import javax.swing.event.ChangeEvent;
48 import javax.swing.event.ChangeListener;
49 import javax.swing.event.ListSelectionEvent;
50 import javax.swing.event.ListSelectionListener;
51
52 import javax.swing.table.AbstractTableModel;
53 import javax.swing.table.TableColumn;
54 import javax.swing.table.JTableHeader;
55
56 import net.sf.juife.event.TaskEvent;
57 import net.sf.juife.event.TaskListener;
58
59 import org.jsampler.AudioDeviceModel;
60 import org.jsampler.CC;
61 import org.jsampler.HF;
62 import org.jsampler.JSPrefs;
63 import org.jsampler.SamplerChannelModel;
64
65 import org.jsampler.event.EffectSendsAdapter;
66 import org.jsampler.event.EffectSendsEvent;
67 import org.jsampler.event.EffectSendsListener;
68
69
70 import org.jsampler.task.Channel;
71
72 import org.jsampler.view.FxSendTable;
73
74 import org.linuxsampler.lscp.FxSend;
75
76 import static org.jsampler.view.std.StdI18n.i18n;
77
78
79 /**
80 *
81 * @author Grigor Iliev
82 */
83 public class JSFxSendsPane extends JPanel implements ListSelectionListener {
84 private SamplerChannelModel channelModel;
85 private final FxSendTable fxSendsTable;
86
87 protected final Action actionAddFxSend = new AddFxSendAction();
88 protected final Action actionRemoveFxSend = new RemoveFxSendAction();
89
90 private final JComboBox cbMidiCtrls = new JComboBox();
91 private final JSlider slVolume = StdUtils.createVolumeSlider();
92
93 private final JLabel lMidiCtrl = new JLabel(i18n.getLabel("JSFxSendsPane.lMidiCtrl"));
94 private final JLabel lVolume = new JLabel(i18n.getLabel("JSFxSendsPane.lVolume"));
95
96 private final ChannelRoutingTable channelRoutingTable;
97
98 private FxSend fxSend = null;
99
100 /**
101 * Creates a new instance of <code>JSFxSendsPane</code>.
102 *
103 * @throws IllegalArgumentException If <code>model</code> is <code>null</code>.
104 */
105 public
106 JSFxSendsPane(SamplerChannelModel model) {
107 if(model == null)
108 throw new IllegalArgumentException("model should be non-null!");
109
110 channelModel = model;
111 fxSendsTable = new FxSendTable(channelModel);
112 channelRoutingTable = new ChannelRoutingTable();
113
114 setLayout(new BorderLayout());
115
116
117
118 JPanel rightPane = createRightPane();
119
120
121 JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
122 splitPane.setLeftComponent(createLeftPane());
123 splitPane.setRightComponent(rightPane);
124 splitPane.setContinuousLayout(true);
125 add(splitPane);
126
127 channelModel.addEffectSendsListener(getHandler());
128
129 fxSendsTable.getSelectionModel().addListSelectionListener(this);
130
131 if(channelModel.getChannelInfo().getEngine() == null) {
132 actionAddFxSend.setEnabled(false);
133 }
134 if(channelModel.getFxSendCount() == 0) {
135 actionRemoveFxSend.setEnabled(false);
136 } else {
137 fxSendsTable.setSelectedFxSend(channelModel.getFxSend(0));
138 }
139 updateFxSend();
140
141 Dimension d = getMinimumSize();
142 int w = d.width > 500 ? d.width : 500;
143 int h = d.height > 300 ? d.height : 300;
144 setPreferredSize(new Dimension(w, h));
145 splitPane.setDividerLocation(200);
146 }
147
148 protected JSPrefs
149 preferences() { return CC.getViewConfig().preferences(); }
150
151 public SamplerChannelModel
152 getChannelModel() { return channelModel; }
153
154 protected JToolBar
155 createToolBar() {
156 JToolBar tb = new JToolBar();
157 tb.setMaximumSize(new Dimension(Short.MAX_VALUE, tb.getPreferredSize().height));
158 tb.setFloatable(false);
159 tb.setAlignmentX(JPanel.RIGHT_ALIGNMENT);
160
161 tb.add(new JButton(actionAddFxSend));
162 tb.add(new JButton(actionRemoveFxSend));
163
164 return tb;
165 }
166
167 protected JPanel
168 createLeftPane() {
169 JPanel leftPane = new JPanel();
170 leftPane.setLayout(new BorderLayout());
171
172 leftPane.add(createToolBar(), BorderLayout.NORTH);
173 leftPane.add(new JScrollPane(fxSendsTable));
174
175 return leftPane;
176 }
177
178 protected JPanel
179 createRightPane() {
180 for(int i = 0; i < 128; i++) cbMidiCtrls.addItem(new Integer(i));
181
182 cbMidiCtrls.addActionListener(new ActionListener() {
183 public void
184 actionPerformed(ActionEvent e) {
185 if(fxSend == null) return;
186
187 int fxs = fxSend.getFxSendId();
188 int ctrl = cbMidiCtrls.getSelectedIndex();
189
190 if(ctrl == fxSend.getMidiController()) {
191 return;
192 }
193
194 channelModel.setBackendFxSendMidiController(fxs, ctrl);
195 }
196 });
197
198 slVolume.addChangeListener(new ChangeListener() {
199 public void
200 stateChanged(ChangeEvent e) { setVolume(); }
201 });
202
203 JPanel rightPane = new JPanel();
204 rightPane.setLayout(new BorderLayout());
205
206 JPanel p = new JPanel();
207 p.setLayout(new BoxLayout(p, BoxLayout.Y_AXIS));
208
209 JPanel p2 = new JPanel();
210 p2.setLayout(new BoxLayout(p2, BoxLayout.X_AXIS));
211
212 p2.add(lVolume);
213 p2.add(Box.createRigidArea(new Dimension(6, 0)));
214 slVolume.setMinimumSize(slVolume.getPreferredSize());
215 p2.add(slVolume);
216 p2.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
217 p.add(p2);
218
219 p2 = new JPanel();
220
221 p2.setLayout(new BoxLayout(p2, BoxLayout.X_AXIS));
222 p2.add(lMidiCtrl);
223 p2.add(Box.createRigidArea(new Dimension(6, 0)));
224 p2.add(cbMidiCtrls);
225 p2.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
226 //p2.setAlignmentX(LEFT_ALIGNMENT);
227 p.add(p2);
228
229 rightPane.add(p, BorderLayout.NORTH);
230 rightPane.add(new JScrollPane(channelRoutingTable));
231
232 return rightPane;
233 }
234
235 private void
236 setVolume() {
237 if(fxSend == null || slVolume.getValueIsAdjusting()) return;
238
239 int i = (int)(fxSend.getLevel() * 100);
240 if(slVolume.getValue() == i) return;
241
242 float vol = slVolume.getValue();
243 vol /= 100;
244 channelModel.setBackendFxSendLevel(fxSend.getFxSendId(), vol);
245 }
246
247 public void
248 valueChanged(ListSelectionEvent e) {
249 if(e.getValueIsAdjusting()) return;
250
251 fxSend = fxSendsTable.getSelectedFxSend();
252 actionRemoveFxSend.setEnabled(fxSend != null);
253 updateFxSend();
254 }
255
256 private void
257 updateFxSend() {
258 boolean b = (fxSend != null);
259 cbMidiCtrls.setEnabled(b);
260 slVolume.setEnabled(b);
261 channelRoutingTable.setEnabled(b);
262 if(!b) {
263 slVolume.setValue(0);
264 cbMidiCtrls.setSelectedIndex(0);
265 return;
266 }
267
268 cbMidiCtrls.setSelectedIndex(fxSend.getMidiController());
269 slVolume.setValue((int)(fxSend.getLevel() * 100));
270 }
271
272 class AddFxSendAction extends AbstractAction {
273 private int fxSendId = -1;
274
275 AddFxSendAction() {
276 super(i18n.getLabel("JSFxSendsPane.AddFxSendAction"));
277
278 String s = i18n.getLabel("JSFxSendsPane.AddFxSendAction.tt");
279 putValue(SHORT_DESCRIPTION, s);
280 }
281
282 public void
283 actionPerformed(ActionEvent e) {
284 int id = channelModel.getChannelId();
285 final Channel.AddFxSend t = new Channel.AddFxSend(id, 0, "New effect send");
286
287 t.addTaskListener(new TaskListener() {
288 public void
289 taskPerformed(TaskEvent e) {
290 if(t.doneWithErrors()) {
291 fxSendId = -1;
292 return;
293 }
294 setFxSendId(t.getResult());
295 }
296 });
297 CC.getTaskQueue().add(t);
298 }
299
300 public int
301 getFxSendId() { return fxSendId; }
302
303 public void
304 setFxSendId(int id) { fxSendId = id; }
305 }
306
307 class RemoveFxSendAction extends AbstractAction {
308 RemoveFxSendAction() {
309 super(i18n.getLabel("JSFxSendsPane.RemoveFxSendAction"));
310
311 String s = i18n.getLabel("JSFxSendsPane.RemoveFxSendAction.tt");
312 putValue(SHORT_DESCRIPTION, s);
313 }
314
315 public void
316 actionPerformed(ActionEvent e) {
317 FxSend fxs = fxSendsTable.getSelectedFxSend();
318 if(fxs == null) return;
319 channelModel.removeBackendFxSend(fxs.getFxSendId());
320 }
321 }
322
323 class ChannelRoutingTable extends JTable {
324 private String[] columnToolTips = {
325 i18n.getLabel("JSFxSendsPane.ttAudioSrc"),
326 i18n.getLabel("JSFxSendsPane.ttAudioDst"),
327 };
328
329 ChannelRoutingTable() {
330 super(new ChannelRoutingTableModel());
331
332 JComboBox cb = new JComboBox();
333 int devId = channelModel.getChannelInfo().getAudioOutputDevice();
334 AudioDeviceModel adm = CC.getSamplerModel().getAudioDeviceById(devId);
335
336 int chns;
337 if(adm == null) {
338 chns = channelModel.getChannelInfo().getAudioOutputChannels();
339 } else {
340 chns = adm.getDeviceInfo().getAudioChannelCount();
341 }
342
343 for(Integer i = 0; i < chns; i++) cb.addItem(i);
344
345 TableColumn column = getColumnModel().getColumn(1);
346 column.setCellEditor(new DefaultCellEditor(cb));
347 }
348
349 protected JTableHeader
350 createDefaultTableHeader() {
351 return new JTableHeader(columnModel) {
352 public String getToolTipText(java.awt.event.MouseEvent e) {
353 java.awt.Point p = e.getPoint();
354 int i = columnModel.getColumnIndexAtX(p.x);
355 i = columnModel.getColumn(i).getModelIndex();
356 return columnToolTips[i];
357 }
358 };
359 }
360 }
361
362 class ChannelRoutingTableModel extends AbstractTableModel implements ListSelectionListener {
363 private String[] columnNames = {
364 i18n.getLabel("JSFxSendsPane.audioSrc"),
365 i18n.getLabel("JSFxSendsPane.audioDst")
366 };
367
368 ChannelRoutingTableModel() {
369 channelModel.addEffectSendsListener(new EffectSendsAdapter() {
370 /** Invoked when an effect send's setting are changed. */
371 public void
372 effectSendChanged(EffectSendsEvent e) {
373 if(fxSend == null) {
374 fireTableDataChanged();
375 return;
376 }
377
378 if(fxSend.equals(e.getFxSend())) {
379 int l;
380 l = e.getFxSend().getAudioOutputRouting().length;
381 fireTableRowsUpdated(0, l - 1);
382 }
383 }
384 });
385
386 fxSendsTable.getSelectionModel().addListSelectionListener(this);
387 }
388
389 public int
390 getColumnCount() { return columnNames.length; }
391
392 public String
393 getColumnName(int column) { return columnNames[column]; }
394
395 public int
396 getRowCount() {
397 if(fxSend == null) return 0;
398 return fxSend.getAudioOutputRouting().length;
399 }
400
401 public Object
402 getValueAt(int row, int column) {
403 switch(column) {
404 case 0:
405 return row;
406 case 1:
407 return fxSend.getAudioOutputRouting()[row];
408 default: return null;
409 }
410
411 }
412
413 public boolean
414 isCellEditable(int row, int column) {
415 switch(column) {
416 case 0:
417 return false;
418 case 1:
419 return true;
420 default: return false;
421 }
422 }
423
424 public void
425 setValueAt(Object value, int row, int column) {
426 if(column == 0) return;
427 int id = fxSend.getFxSendId();
428 int src = (Integer)getValueAt(row, 0);
429 int dst = (Integer)value;
430 channelModel.setBackendFxSendAudioOutputChannel(id, src, dst);
431 fxSend.getAudioOutputRouting()[row] = dst;
432
433 fireTableCellUpdated(row, column);
434 }
435
436 public void
437 valueChanged(ListSelectionEvent e) {
438 if(e.getValueIsAdjusting()) return;
439
440 fireTableDataChanged();
441 }
442 }
443
444 private final Handler eventHandler = new Handler();
445
446 private Handler
447 getHandler() { return eventHandler; }
448
449 private class Handler implements EffectSendsListener {
450 /** Invoked when a new effect send is added to a sampler channel. */
451 public void
452 effectSendAdded(EffectSendsEvent e) {
453 FxSend fxs = fxSendsTable.getSelectedFxSend();
454 if(fxs == null) return;
455 AddFxSendAction a = (AddFxSendAction)actionAddFxSend;
456 if(fxs.getFxSendId() != a.getFxSendId()) return;
457
458 fxSendsTable.requestFocus();
459 fxSendsTable.editSelectedFxSend();
460 a.setFxSendId(-1);
461 }
462
463 /** Invoked when an effect send is removed from a sampler channel. */
464 public void
465 effectSendRemoved(EffectSendsEvent e) {
466 if(channelModel.getFxSendCount() == 0) return;
467 int id = e.getFxSend().getFxSendId();
468 for(FxSend fxs : channelModel.getFxSends()) {
469 if(fxs.getFxSendId() > id) {
470 fxSendsTable.setSelectedFxSend(fxs);
471 return;
472 }
473 }
474 FxSend fxs = channelModel.getFxSend(channelModel.getFxSendCount() - 1);
475 fxSendsTable.setSelectedFxSend(fxs);
476 }
477
478 /** Invoked when an effect send's setting are changed. */
479 public void
480 effectSendChanged(EffectSendsEvent e) {
481 if(fxSend == null) return;
482 if(fxSend.equals(e.getFxSend())) {
483 fxSend = e.getFxSend();
484 updateFxSend();
485 }
486 }
487 }
488 }

  ViewVC Help
Powered by ViewVC