/[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 1144 - (show annotations) (download)
Mon Apr 2 21:39:15 2007 UTC (17 years ago) by iliev
File size: 12333 byte(s)
- upgrading to version 0.4a

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

  ViewVC Help
Powered by ViewVC