/[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 1286 - (show annotations) (download)
Fri Aug 10 20:24:23 2007 UTC (16 years, 8 months ago) by iliev
File size: 12780 byte(s)
- Updated to version 0.6a. The Fantasia distribution is now
  capable of controlling all features available in LinuxSampler

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

  ViewVC Help
Powered by ViewVC