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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1540 - (show annotations) (download)
Mon Dec 3 23:22:02 2007 UTC (16 years, 4 months ago) by iliev
File size: 7166 byte(s)
* Fantasia: by default the volume values are now shown in decibels
* Implemented support for retrieving instrument information
  from instrument files
* Some bugfixes and enhancements

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.Point;
26
27 import java.awt.event.ActionEvent;
28 import java.awt.event.ActionListener;
29 import java.awt.event.FocusAdapter;
30 import java.awt.event.FocusEvent;
31 import java.awt.event.KeyEvent;
32
33 import java.beans.PropertyChangeEvent;
34 import java.beans.PropertyChangeListener;
35
36 import java.util.Vector;
37
38 import javax.swing.AbstractAction;
39 import javax.swing.JComponent;
40 import javax.swing.JSpinner;
41 import javax.swing.JTextField;
42 import javax.swing.KeyStroke;
43 import javax.swing.Popup;
44 import javax.swing.PopupFactory;
45 import javax.swing.SpinnerNumberModel;
46
47
48 import org.jsampler.CC;
49 import org.jsampler.HF;
50 import org.jsampler.JSPrefs;
51
52 import static org.jsampler.view.std.StdPrefs.*;
53
54
55 /**
56 *
57 * @author Grigor Iliev
58 */
59 public class JSVolumeEditorPopup {
60 private final JComponent owner;
61 private Popup popup = null;
62 private final JSpinner spinner = new JSpinner();
63 private boolean decibels = false;
64
65 /* Used to prevent double committing on focus lost and to prevent commiting on cancel. */
66 private boolean shouldCommit = true;
67
68 private final Vector<ActionListener> listeners = new Vector<ActionListener>();
69
70 public static enum VolumeType {
71 MASTER, CHANNEL
72 }
73
74 private VolumeType volumeType;
75
76 /**
77 * Creates a new instance of <code>JSVolumeEditorPopup</code>
78 */
79 public
80 JSVolumeEditorPopup(final JComponent owner, VolumeType volumeType) {
81 if(owner == null) throw new IllegalArgumentException("owner should be non-null");
82 this.owner = owner;
83 this.volumeType = volumeType;
84 java.awt.Dimension d = spinner.getPreferredSize();
85 d.width = 55;
86 spinner.setPreferredSize(d);
87
88 setNumberModel();
89
90 String s;
91 switch(volumeType) {
92 case MASTER: s = MAXIMUM_MASTER_VOLUME; break;
93 case CHANNEL: s = MAXIMUM_CHANNEL_VOLUME; break;
94 default: s = MAXIMUM_CHANNEL_VOLUME;
95 }
96 preferences().addPropertyChangeListener(s, new PropertyChangeListener() {
97 public void
98 propertyChange(PropertyChangeEvent e) {
99 setNumberModel();
100 }
101 });
102
103 s = VOL_MEASUREMENT_UNIT_DECIBEL;
104 preferences().addPropertyChangeListener(s, new PropertyChangeListener() {
105 public void
106 propertyChange(PropertyChangeEvent e) {
107 setNumberModel();
108 }
109 });
110 }
111
112 public void
113 show() {
114 if(popup != null) {
115 popup.hide();
116 }
117
118 shouldCommit = true;
119
120 Point p = owner.getLocationOnScreen();
121 int h = owner.getHeight();
122 popup = PopupFactory.getSharedInstance().getPopup(owner, spinner, p.x, p.y + h);
123 popup.show();
124 JComponent c = spinner.getEditor();
125 ((JSpinner.DefaultEditor)c).getTextField().requestFocus();
126 }
127
128 public void
129 hide() {
130 if(popup == null) return;
131 shouldCommit = false;
132 popup.hide();
133 popup = null;
134 }
135
136 public boolean
137 isVisible() { return popup != null; }
138
139 public void
140 commit() {
141 try { spinner.commitEdit(); }
142 catch(Exception x) { }
143 if(shouldCommit) fireActionEvent();
144 }
145
146 public void
147 setCurrentVolume(float vol) {
148 int volPercentage = (int)(vol * 100);
149 if(decibels) {
150 double d = HF.percentsToDecibels(volPercentage);
151 if(d == Double.NEGATIVE_INFINITY) d = -100;
152 spinner.setValue(d);
153 } else {
154 spinner.setValue(volPercentage);
155 }
156 }
157
158 public float
159 getVolumeFactor() {
160 if(decibels) {
161 double d = (Double)spinner.getValue();
162 return HF.decibelsToFactor(d);
163 } else {
164 int i = (Integer)spinner.getValue();
165 return HF.percentsToFactor(i);
166 }
167 }
168
169 public void
170 addActionListener(ActionListener l) { listeners.add(l); }
171
172 public void
173 removeActionListener(ActionListener l) { listeners.remove(l); }
174
175 private void
176 setNumberModel() {
177 int volPercentage;
178 if(decibels) {
179 volPercentage = HF.decibelsToPercents((Double)spinner.getValue());
180 } else {
181 volPercentage = (Integer)spinner.getValue();
182 }
183
184 String s;
185 switch(volumeType) {
186 case MASTER: s = MAXIMUM_MASTER_VOLUME; break;
187 case CHANNEL: s = MAXIMUM_CHANNEL_VOLUME; break;
188 default: s = MAXIMUM_CHANNEL_VOLUME;
189 }
190
191 int max = preferences().getIntProperty(s);
192 decibels = preferences().getBoolProperty(VOL_MEASUREMENT_UNIT_DECIBEL);
193 SpinnerNumberModel model;
194
195 if(decibels) {
196 double vol = HF.percentsToDecibels(volPercentage);
197 if(vol == Double.NEGATIVE_INFINITY) vol = -100;
198 model = new SpinnerNumberModel(vol, -100, HF.percentsToDecibels(max), 1);
199 spinner.setModel(model);
200 } else {
201 model = new SpinnerNumberModel(volPercentage, 0, max, 1);
202 spinner.setModel(model);
203 }
204
205 reinstallEditorListeners();
206 }
207
208 private FocusAdapter focusListener = new FocusAdapter() {
209 public void
210 focusLost(FocusEvent e) {
211 if(e.getOppositeComponent() == owner) return;
212
213 commit();
214 hide();
215 }
216 };
217
218 private ActionListener actionListener = new ActionListener() {
219 public void
220 actionPerformed(ActionEvent e) {
221 commit();
222 hide();
223 }
224 };
225
226 /** Invoked when the number model of the spinner is changed to reinstall listeners */
227 private void
228 reinstallEditorListeners() {
229 JComponent c = spinner.getEditor();
230 JTextField tf = ((JSpinner.DefaultEditor)c).getTextField();
231
232 tf.removeFocusListener(focusListener); // just in case the text field stays the same
233 tf.addFocusListener(focusListener);
234
235 tf.removeActionListener(actionListener);
236 tf.addActionListener(actionListener);
237
238 tf.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).remove (
239 KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0)
240 );
241
242 tf.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put (
243 KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0),
244 "cancelOp"
245 );
246
247 tf.getActionMap().remove("cancelOp");
248 tf.getActionMap().put ("cancelOp", new AbstractAction() {
249 public void
250 actionPerformed(ActionEvent e) { hide(); }
251 });
252
253 tf.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).remove (
254 KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0)
255 );
256
257 tf.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put (
258 KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0),
259 "commitVolume"
260 );
261
262 tf.getActionMap().remove("commitVolume");
263 tf.getActionMap().put ("commitVolume", new AbstractAction() {
264 public void
265 actionPerformed(ActionEvent e) {
266 commit();
267 hide();
268 }
269 });
270 }
271
272 private void
273 fireActionEvent() {
274 for(ActionListener l : listeners) l.actionPerformed(null);
275 }
276
277 private static JSPrefs
278 preferences() { return CC.getViewConfig().preferences(); }
279 }

  ViewVC Help
Powered by ViewVC