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

Contents of /jsampler/trunk/src/org/jsampler/view/fantasia/SmallChannelView.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1737 - (show annotations) (download)
Thu May 8 17:26:19 2008 UTC (15 years, 11 months ago) by iliev
File size: 13944 byte(s)
* Major memory optimizations when too many sampler channels are present

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.fantasia;
24
25 import java.awt.Dimension;
26 import java.awt.Insets;
27
28 import java.awt.event.ActionEvent;
29 import java.awt.event.ActionListener;
30 import java.awt.event.MouseListener;
31
32 import java.beans.PropertyChangeEvent;
33 import java.beans.PropertyChangeListener;
34
35 import java.util.Vector;
36
37 import javax.swing.BorderFactory;
38 import javax.swing.Box;
39 import javax.swing.BoxLayout;
40 import javax.swing.JButton;
41 import javax.swing.JComponent;
42 import javax.swing.JLabel;
43 import javax.swing.JPanel;
44
45 import org.jsampler.CC;
46
47 import org.jvnet.substance.SubstanceImageCreator;
48
49 import org.linuxsampler.lscp.SamplerChannel;
50
51 import static org.jsampler.view.fantasia.FantasiaI18n.i18n;
52 import static org.jsampler.view.fantasia.FantasiaPrefs.*;
53 import static org.jsampler.view.fantasia.FantasiaUtils.*;
54
55
56 /**
57 *
58 * @author Grigor Iliev
59 */
60 public class SmallChannelView extends PixmapPane implements ChannelView {
61 private final Channel channel;
62 private ChannelOptionsView channelOptionsView = null;
63
64 private final ChannelScreen screen;
65 private final Channel.PowerButton btnPower;
66 private final MuteButton btnMute = new MuteButton();
67 private final SoloButton btnSolo = new SoloButton();
68 private final Channel.OptionsButton btnOptions;
69
70 private final Vector<JComponent> components = new Vector<JComponent>();
71
72
73 /** Creates a new instance of <code>SmallChannelView</code> */
74 public
75 SmallChannelView(Channel channel) {
76 super(Res.gfxDeviceBg);
77 setPixmapInsets(new Insets(1, 1, 1, 1));
78
79 components.add(this);
80
81 this.channel = channel;
82
83 screen = new ChannelScreen(channel);
84
85 btnPower = new Channel.PowerButton(channel);
86 components.add(btnPower);
87
88 btnOptions = new Channel.OptionsButton(channel);
89 components.add(btnOptions);
90
91 setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
92
93 setBorder(BorderFactory.createEmptyBorder(1, 3, 0, 11));
94
95 add(btnPower);
96 add(Box.createRigidArea(new Dimension(4, 0)));
97
98 add(createVSeparator());
99 add(Box.createRigidArea(new Dimension(3, 0)));
100
101 add(screen);
102
103 add(Box.createRigidArea(new Dimension(2, 0)));
104 add(createVSeparator());
105 add(new FxSendsButton());
106
107 add(createVSeparator());
108 add(Box.createRigidArea(new Dimension(1, 0)));
109
110 components.add(btnMute);
111 components.add(btnSolo);
112
113 add(btnMute);
114 add(btnSolo);
115
116 add(Box.createRigidArea(new Dimension(1, 0)));
117 add(createVSeparator());
118 add(Box.createRigidArea(new Dimension(8, 0)));
119
120 add(btnOptions);
121
122 setPreferredSize(new Dimension(420, 22));
123 setMinimumSize(getPreferredSize());
124 setMaximumSize(getPreferredSize());
125
126 installView();
127 }
128
129 //////////////////////////////////////////////
130 // Implementation of the ChannelView interface
131 //////////////////////////////////////////////
132
133 public Type
134 getType() { return Type.SMALL; }
135
136 public JComponent
137 getComponent() { return this; }
138
139 public void
140 installView() {
141 String vmud = VOL_MEASUREMENT_UNIT_DECIBEL;
142 preferences().addPropertyChangeListener(vmud, new PropertyChangeListener() {
143 public void
144 propertyChange(PropertyChangeEvent e) {
145 boolean b;
146 b = preferences().getBoolProperty(VOL_MEASUREMENT_UNIT_DECIBEL);
147 screen.updateVolumeInfo();
148 }
149 });
150
151 addEnhancedMouseListener(channel.getContextMenu());
152 }
153
154 public void
155 uninstallView() {
156 //removeEnhancedMouseListener(channel.getContextMenu());
157 btnOptions.onDestroy();
158 uninstallChannelOptionsView();
159 }
160
161 public void
162 installChannelOptionsView() {
163 if(channelOptionsView != null) return;
164
165 channelOptionsView = new NormalChannelOptionsView(channel);
166 channelOptionsView.installView();
167
168 }
169
170 public void
171 uninstallChannelOptionsView() {
172 if(channelOptionsView == null) return;
173 channelOptionsView.uninstallView();
174 channelOptionsView = null;
175 }
176
177 public ChannelOptionsView
178 getChannelOptionsView() { return channelOptionsView; }
179
180 public void
181 updateChannelInfo() {
182 SamplerChannel sc = channel.getChannelInfo();
183
184 screen.updateScreenInfo(sc);
185 screen.updateVolumeInfo();
186 updateMuteIcon(sc);
187
188 if(sc.isSoloChannel()) btnSolo.setIcon(Res.gfxSoloSmallOn);
189 else btnSolo.setIcon(Res.gfxSoloSmallOff);
190
191 boolean b = sc.getEngine() != null;
192 btnSolo.setEnabled(b);
193 btnMute.setEnabled(b);
194
195 if(getChannelOptionsView() != null) getChannelOptionsView().updateChannelInfo();
196 }
197
198 public void
199 updateStreamCount(int count) { screen.updateStreamCount(count); }
200
201 public void
202 updateVoiceCount(int count) { screen.updateVoiceCount(count); }
203
204 public void
205 expandChannel() {
206 if(btnOptions.isSelected()) return;
207 btnOptions.doClick();
208 }
209
210 public boolean
211 isOptionsButtonSelected() { return btnOptions.isSelected(); }
212
213 public void
214 setOptionsButtonSelected(boolean b) {
215 btnOptions.setSelected(b);
216 }
217
218 public void
219 addEnhancedMouseListener(MouseListener l) {
220 removeEnhancedMouseListener(l);
221
222 for(JComponent c : components) c.addMouseListener(l);
223 screen.addEnhancedMouseListener(l);
224 }
225
226 public void
227 removeEnhancedMouseListener(MouseListener l) {
228 for(JComponent c : components) c.removeMouseListener(l);
229 screen.removeEnhancedMouseListener(l);
230 }
231
232 //////////////////////////////////////////////
233
234
235 /**
236 * Updates the mute button with the proper icon regarding to information obtained
237 * from <code>channel</code>.
238 * @param channel A <code>SamplerChannel</code> instance containing the new settings
239 * for this channel.
240 */
241 private void
242 updateMuteIcon(SamplerChannel channel) {
243 if(channel.isMutedBySolo()) btnMute.setIcon(Res.gfxMutedBySoloSmall);
244 else if(channel.isMuted()) btnMute.setIcon(Res.gfxMuteSmallOn);
245 else btnMute.setIcon(Res.gfxMuteSmallOff);
246 }
247
248 protected JPanel
249 createVSeparator() {
250 PixmapPane p = new PixmapPane(Res.gfxVLine);
251 p.setOpaque(false);
252 p.setPreferredSize(new Dimension(2, 22));
253 p.setMinimumSize(p.getPreferredSize());
254 p.setMaximumSize(p.getPreferredSize());
255 return p;
256 }
257
258
259 private class MuteButton extends PixmapButton implements ActionListener {
260 MuteButton() {
261 super(Res.gfxMuteSmallOff);
262 setDisabledIcon (
263 SubstanceImageCreator.makeTransparent(this, Res.gfxMuteSmallOff, 0.4)
264 );
265 addActionListener(this);
266 }
267
268 public void
269 actionPerformed(ActionEvent e) {
270 SamplerChannel sc = channel.getChannelInfo();
271 boolean b = true;
272
273 /*
274 * Changing the mute button icon now instead of
275 * leaving the work to the notification mechanism of the LinuxSampler.
276 */
277 if(sc.isMuted() && !sc.isMutedBySolo()) {
278 b = false;
279 boolean hasSolo = CC.getSamplerModel().hasSoloChannel();
280
281 if(sc.isSoloChannel() || !hasSolo) setIcon(Res.gfxMuteSmallOff);
282 else setIcon(Res.gfxMutedBySoloSmall);
283 } else setIcon(Res.gfxMuteSmallOn);
284
285 channel.getModel().setBackendMute(b);
286 }
287
288 //public boolean
289 //contains(int x, int y) { return (x > 5 && x < 23) && (y > 5 && y < 16); }
290 }
291
292 private class SoloButton extends PixmapButton implements ActionListener {
293 SoloButton() {
294 super(Res.gfxSoloSmallOff);
295 //setDisabledIcon(Res.gfxMuteSoloDisabled);
296 setDisabledIcon (
297 SubstanceImageCreator.makeTransparent(this, Res.gfxSoloSmallOff, 0.4)
298 );
299 addActionListener(this);
300 }
301
302 public void
303 actionPerformed(ActionEvent e) {
304 SamplerChannel sc = channel.getChannelInfo();
305 boolean b = !sc.isSoloChannel();
306
307 /*
308 * Changing the solo button icon (and related) now instead of
309 * leaving the work to the notification mechanism of the LinuxSampler.
310 */
311 if(b) {
312 setIcon(Res.gfxSoloSmallOn);
313 if(sc.isMutedBySolo()) btnMute.setIcon(Res.gfxMuteSmallOff);
314 } else {
315 setIcon(Res.gfxSoloSmallOff);
316 if(!sc.isMuted() && CC.getSamplerModel().getSoloChannelCount() > 1)
317 btnMute.setIcon(Res.gfxMutedBySoloSmall);
318 }
319
320 channel.getModel().setBackendSolo(b);
321 }
322
323 //public boolean
324 //contains(int x, int y) { return (x > 5 && x < 23) && (y > 5 && y < 16); }
325 }
326
327 static class ChannelScreen extends PixmapPane {
328 private final Channel channel;
329
330 //private final ChannelInfoPane channelInfoPane;
331
332 private final Channel.StreamVoiceCountPane streamVoiceCountPane;
333
334
335 private final Channel.VolumePane volumePane;
336
337 private JButton btnInstr =
338 createScreenButton(i18n.getButtonLabel("ChannelScreen.btnInstr"));
339
340
341 private static Insets pixmapInsets = new Insets(5, 5, 4, 5);
342
343 private final Vector<JComponent> components = new Vector<JComponent>();
344
345 ChannelScreen(final Channel channel) {
346 super(Res.gfxTextField);
347
348 components.add(this);
349
350 this.channel = channel;
351
352 streamVoiceCountPane = new Channel.StreamVoiceCountPane(channel);
353 components.add(streamVoiceCountPane);
354
355 //channelInfoPane = new ChannelInfoPane(channel);
356 volumePane = new Channel.VolumePane(channel);
357 components.add(volumePane);
358
359 setPixmapInsets(pixmapInsets);
360 setBorder(BorderFactory.createEmptyBorder(4, 3, 3, 4));
361
362 setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
363
364 JPanel p = new JPanel();
365 components.add(p);
366 p.setOpaque(false);
367 p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));
368
369 //p.add(channelInfoPane);
370
371 btnInstr.setRolloverEnabled(false);
372 btnInstr.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
373 btnInstr.setHorizontalAlignment(btnInstr.LEFT);
374
375 int h = btnInstr.getPreferredSize().height;
376 btnInstr.setPreferredSize(new Dimension(100, h));
377 btnInstr.setMinimumSize(btnInstr.getPreferredSize());
378 btnInstr.setMaximumSize(new Dimension(Short.MAX_VALUE, h));
379 components.add(btnInstr);
380
381 p.add(btnInstr);
382
383 h = p.getPreferredSize().height;
384 p.setPreferredSize(new Dimension(159, h));
385 p.setMinimumSize(p.getPreferredSize());
386 p.setMaximumSize(p.getPreferredSize());
387
388 add(p);
389
390 add(Box.createRigidArea(new Dimension(3, 0)));
391 add(streamVoiceCountPane);
392 add(volumePane);
393
394 setPreferredSize(new Dimension(270, getPreferredSize().height));
395 setMinimumSize(getPreferredSize());
396 setMaximumSize(getPreferredSize());
397
398 btnInstr.addActionListener(new ActionListener() {
399 public void
400 actionPerformed(ActionEvent e) { channel.loadInstrument(); }
401 });
402 }
403
404 public void
405 addEnhancedMouseListener(MouseListener l) {
406 removeEnhancedMouseListener(l);
407 for(JComponent c : components) c.addMouseListener(l);
408 }
409
410 public void
411 removeEnhancedMouseListener(MouseListener l) {
412 for(JComponent c : components) c.removeMouseListener(l);
413 }
414
415 protected void
416 updateVolumeInfo() {
417 float f = channel.getChannelInfo().getVolume() * 100.0f;
418 volumePane.updateVolumeInfo((int)f);
419 }
420
421 /**
422 * Updates the number of active disk streams.
423 * @param count The new number of active disk streams.
424 */
425 protected void
426 updateStreamCount(int count) {
427 streamVoiceCountPane.updateStreamCount(count);
428 }
429
430 /**
431 * Updates the number of active voices.
432 * @param count The new number of active voices.
433 */
434 protected void
435 updateVoiceCount(int count) {
436 streamVoiceCountPane.updateVoiceCount(count);
437 }
438
439 protected void
440 updateScreenInfo(SamplerChannel sc) {
441 int status = sc.getInstrumentStatus();
442 if(status >= 0 && status < 100) {
443 btnInstr.setText(i18n.getLabel("ChannelScreen.loadingInstrument", status));
444 } else if(status == -1) {
445 btnInstr.setText(i18n.getButtonLabel("ChannelScreen.btnInstr"));
446 } else if(status < -1) {
447 btnInstr.setText(i18n.getLabel("ChannelScreen.errorLoadingInstrument"));
448 } else {
449 if(sc.getInstrumentName() != null) btnInstr.setText(sc.getInstrumentName());
450 else btnInstr.setText(i18n.getButtonLabel("ChannelScreen.btnInstr"));
451 }
452
453 //channelInfoPane.updateChannelInfo();
454 }
455 }
456
457 private static class ChannelInfoPane extends JPanel {
458 private final Channel channel;
459 private final JLabel lInfo;
460
461 ChannelInfoPane(Channel channel) {
462 this.channel = channel;
463
464 setOpaque(false);
465 setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
466
467 lInfo = createScreenLabel("");
468 lInfo.setFont(Res.fontScreenMono);
469 lInfo.setText("1234");
470 lInfo.setPreferredSize(lInfo.getPreferredSize()); // Don't remove this!
471 lInfo.setMinimumSize(lInfo.getPreferredSize());
472 lInfo.setMaximumSize(lInfo.getPreferredSize());
473
474 updateChannelInfo();
475
476 add(lInfo);
477
478 setPreferredSize(getPreferredSize()); // Don't remove this!
479 setMinimumSize(getPreferredSize());
480 setMaximumSize(getPreferredSize());
481 }
482
483 protected void
484 updateChannelInfo() {
485 String s = channel.getChannelId() < 10 ? " " : "";
486 s += String.valueOf(channel.getChannelId()) + ":";
487
488 /*SamplerChannel sc = channel.getChannelInfo();
489 s += sc.getMidiInputPort() + "/";
490
491 if(sc.getMidiInputChannel() == -1) s += "All";
492 else s += sc.getMidiInputChannel() + 1;*/
493 lInfo.setText(s);
494 }
495 }
496
497 private class FxSendsButton extends PixmapButton implements ActionListener {
498 FxSendsButton() {
499 super(Res.gfxFx);
500
501 setRolloverIcon(Res.gfxFxRO);
502
503 addActionListener(this);
504 }
505
506 public void
507 actionPerformed(ActionEvent e) { channel.showFxSendsDialog(); }
508
509 public boolean
510 contains(int x, int y) { return (x > 5 && x < 23) && (y > 5 && y < 16); }
511 }
512 }

  ViewVC Help
Powered by ViewVC