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

Contents of /jsampler/trunk/src/org/jsampler/view/classic/FxSendsPane.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1204 - (show annotations) (download)
Thu May 24 21:43:45 2007 UTC (16 years, 10 months ago) by iliev
File size: 12623 byte(s)
upgrading to version 0.5a

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

  ViewVC Help
Powered by ViewVC