/[svn]/jsampler/trunk/src/org/jsampler/android/view/AndroidMainFrame.java
ViewVC logotype

Contents of /jsampler/trunk/src/org/jsampler/android/view/AndroidMainFrame.java

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2302 - (show annotations) (download)
Thu Dec 15 23:13:30 2011 UTC (12 years, 4 months ago) by iliev
File size: 12924 byte(s)
* Initial support for Android platforms (only sampler channel
  manipulation for now - see the screenshots on the website)

1 /*
2 * JSampler - a java front-end for LinuxSampler
3 *
4 * Copyright (C) 2011 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.android.view;
24
25 import static org.jsampler.JSPrefs.MANUAL_SERVER_SELECT_ON_STARTUP;
26
27 import java.beans.PropertyChangeListener;
28 import java.beans.PropertyChangeSupport;
29 import java.util.Vector;
30 import java.util.logging.Level;
31
32 import org.jsampler.CC;
33 import org.jsampler.LSConsoleModel;
34 import org.jsampler.SamplerChannelModel;
35 import org.jsampler.Server;
36 import org.jsampler.event.ListSelectionEvent;
37 import org.jsampler.event.ListSelectionListener;
38 import org.jsampler.event.SamplerChannelListEvent;
39 import org.jsampler.event.SamplerChannelListListener;
40 import org.jsampler.view.JSChannel;
41 import org.jsampler.view.JSChannelsPane;
42 import org.jsampler.view.JSMainFrame;
43 import org.jsampler.view.JSViewConfig;
44 import org.jsampler.view.SessionViewConfig.ChannelConfig;
45
46 import android.view.MotionEvent;
47 import android.view.View;
48
49 public abstract class AndroidMainFrame<CP extends AndroidChannelsPane> implements JSMainFrame<CP> {
50 private final PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
51 protected final Vector<CP> chnPaneList = new Vector<CP>();
52 private boolean autoUpdateChannelListUI = true;
53
54 public AndroidMainFrame() {
55 CC.getSamplerModel().addSamplerChannelListListener(new EventHandler());
56 }
57
58 /** Add a PropertyChangeListener for a specific property. */
59 public void
60 addPropertyChangeListener(String propertyName, PropertyChangeListener l) {
61 propertyChangeSupport.addPropertyChangeListener(propertyName, l);
62 }
63
64 /** Remove a PropertyChangeListener for a specific property. */
65 public void
66 removePropertyChangeListener(String propertyName, PropertyChangeListener l) {
67 propertyChangeSupport.removePropertyChangeListener(propertyName, l);
68 }
69
70 /**
71 * Report a bound property update to any registered listeners.
72 * No event is fired if old and new are equal and non-null.
73 */
74 protected void
75 firePropertyChange(String propertyName, Object oldValue, Object newValue) {
76 propertyChangeSupport.firePropertyChange(propertyName, oldValue, newValue);
77 }
78
79 /** Invoked from the main activity's <code>onCreate()</code> method. */
80 public abstract void onCreate();
81
82 /** Returns the main frame's root view. */
83 public abstract View getView();
84
85 public abstract void uninstall();
86
87 public boolean
88 onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { return false; }
89
90 /**
91 * Invoked when this window is about to close.
92 * Don't forget to call <code>super.onWindowClose()</code> at the end,
93 * when override this method.
94 */
95 @Override
96 public void
97 onWindowClose() { CC.cleanExit(); }
98
99 protected Vector<ListSelectionListener> channelsPaneListeners =
100 new Vector<ListSelectionListener>();
101
102 /**
103 * Registers the specified listener for receiving event messages.
104 * @param l The <code>ListSelectionListener</code> to register.
105 */
106 @Override
107 public void
108 addChannelsPaneSelectionListener(ListSelectionListener l) {
109 channelsPaneListeners.add(l);
110 }
111
112 /**
113 * Removes the specified listener.
114 * @param l The <code>ListSelectionListener</code> to remove.
115 */
116 @Override
117 public void
118 removeChannelsPaneSelectionListener(ListSelectionListener l) {
119 channelsPaneListeners.remove(l);
120 }
121
122 protected void
123 fireChannelsPaneSelectionChanged() {
124 int i = getChannelsPaneIndex(getSelectedChannelsPane());
125 ListSelectionEvent e = new ListSelectionEvent(this, i, i, false);
126 for(ListSelectionListener l : channelsPaneListeners) l.valueChanged(e);
127 }
128
129 /**
130 * Returns a list containing all channels' panes added to the view.
131 * @return A list containing all channels' panes added to the view.
132 * @see #addChannelsPane
133 * @see #removeChannelsPane
134 */
135 @Override
136 public Vector<CP>
137 getChannelsPaneList() { return chnPaneList; }
138
139 /**
140 * Return the channels' pane at the specified position.
141 * @param idx The position of the channels' pane to be returned.
142 * @return The channels' pane at the specified position.
143 */
144 @Override
145 public CP
146 getChannelsPane(int idx) { return chnPaneList.get(idx); }
147
148 /**
149 * Adds the specified channels' pane to the view.
150 * @param chnPane The channels' pane to be added.
151 */
152 @Override
153 public void
154 addChannelsPane(CP chnPane) {
155 insertChannelsPane(chnPane, getChannelsPaneCount());
156 }
157
158 /**
159 * Removes the specified channels' pane from the view.
160 * Override this method to remove <code>chnPane</code> from the view,
161 * and don't forget to call <code>super.removeChannelsPane(chnPane);</code>.
162 * @param chnPane The channels' pane to be removed.
163 * @return <code>true</code> if the specified channels' pane
164 * is actually removed from the view, <code>false</code> otherwise.
165 */
166 @Override
167 public boolean
168 removeChannelsPane(CP chnPane) {
169 boolean b = chnPaneList.remove(chnPane);
170 firePropertyChange("channelLaneRemoved", null, chnPane);
171 return b;
172 }
173
174 /**
175 * Gets the current number of channels' panes added to the view.
176 * @return The current number of channels' panes added to the view.
177 */
178 @Override
179 public int
180 getChannelsPaneCount() { return chnPaneList.size(); }
181
182 /**
183 * Returns the index of the specified channels pane, or -1 if
184 * the specified channels pane is not found.
185 */
186 @Override
187 public int
188 getChannelsPaneIndex(CP chnPane) {
189 return chnPaneList.indexOf(chnPane);
190 }
191
192 /**
193 * Gets the LS Console model.
194 * @return The LS Console model or <code>null</code>.
195 */
196 @Override
197 public LSConsoleModel
198 getLSConsoleModel() { return null; }
199
200 private class EventHandler implements SamplerChannelListListener {
201 /**
202 * Invoked when a new sampler channel is created.
203 * @param e A <code>SamplerChannelListEvent</code>
204 * instance providing the event information.
205 */
206 public void
207 channelAdded(SamplerChannelListEvent e) {
208 if(e.getChannelModel() == null) return;
209 Integer id = e.getChannelModel().getChannelId();
210 if(findChannel(id) != null) {
211 CC.getLogger().log(Level.WARNING, "JSMainFrame.channelExist!", id);
212 return;
213 }
214
215 ChannelConfig config = null;
216 JSViewConfig viewConfig = CC.getViewConfig();
217 if(viewConfig != null && viewConfig.getSessionViewConfig() != null) {
218 config = viewConfig.getSessionViewConfig().pollChannelConfig();
219 }
220
221 if(config == null) {
222 getSelectedChannelsPane().addChannel(e.getChannelModel());
223 } else {
224 int i = config.channelsPanel;
225 if(i >= 0 && i < getChannelsPaneCount()) {
226 getChannelsPane(i).addChannel(e.getChannelModel(), config);
227 } else {
228 getSelectedChannelsPane().addChannel(e.getChannelModel(), config);
229 }
230 }
231 }
232
233 /**
234 * Invoked when a sampler channel is removed.
235 * @param e A <code>SamplerChannelListEvent</code>
236 * instance providing the event information.
237 */
238 public void
239 channelRemoved(SamplerChannelListEvent e) {
240 removeChannel(e.getChannelModel().getChannelId());
241 }
242 }
243
244
245 /**
246 * Searches for the first occurrence of a channel with numerical ID <code>id</code>.
247 * @return The first occurrence of a channel with numerical ID <code>id</code> or
248 * <code>null</code> if there is no channel with numerical ID <code>id</code>.
249 */
250 @Override
251 public JSChannel
252 findChannel(int id) {
253 if(id < 0) return null;
254
255 for(JSChannelsPane cp : getChannelsPaneList()) {
256 for(JSChannel c : cp.getChannels()) if(c.getChannelId() == id) return c;
257 }
258
259 return null;
260 }
261
262 /**
263 * Removes the first occurrence of a channel with numerical ID <code>id</code>.
264 * This method is invoked when a sampler channel is removed in the back-end.
265 * @return The removed channel or <code>null</code>
266 * if there is no channel with numerical ID <code>id</code>.
267 */
268 @Override
269 public JSChannel
270 removeChannel(int id) {
271 if(id < 0) return null;
272
273 for(JSChannelsPane cp : getChannelsPaneList()) {
274 for(JSChannel c : cp.getChannels()) {
275 if(c.getChannelId() == id) {
276 cp.removeChannel(c);
277 firePropertyChange("channelRemoved", null, c);
278 return c;
279 }
280 }
281 }
282
283 return null;
284 }
285
286 /**
287 * Gets the zero-based position of the specified sampler channel
288 * in the channels pane, to which the channel is added.
289 * Note that the position may change when adding/removing sampler channels.
290 * @return The zero-based position of the specified sampler channel
291 * in the channels pane, or -1 if the specified channels is not found.
292 */
293 @Override
294 public int
295 getChannelNumber(SamplerChannelModel channel) {
296 if(channel == null) return -1;
297
298 for(int i = 0; i < getChannelsPaneCount(); i++) {
299 JSChannelsPane chnPane = getChannelsPane(i);
300 for(int j = 0; j < chnPane.getChannelCount(); j++) {
301 if(chnPane.getChannel(j).getChannelId() == channel.getChannelId()) {
302 return j;
303 }
304 }
305 }
306
307 return -1;
308 }
309
310 /**
311 * Returns a string in the format <code>channelPaneNumber.channelNumber</code>,
312 * where <code>channelPaneNumber</code> is the one-based number of the channels
313 * pane containing the specified channel and <code>channelNumber</code> is the
314 * one-based number of the channel's position in the channels pane.
315 * Note that this path may change when adding/removing channels/channels panes.
316 * @return The channels path, or <code>null</code> if the specified channels is not found.
317 */
318 @Override
319 public String
320 getChannelPath(SamplerChannelModel channel) {
321 if(channel == null) return null;
322
323 for(int i = 0; i < getChannelsPaneCount(); i++) {
324 JSChannelsPane chnPane = getChannelsPane(i);
325 for(int j = 0; j < chnPane.getChannelCount(); j++) {
326 if(chnPane.getChannel(j).getChannelId() == channel.getChannelId()) {
327 return (i + 1) + "." + (j + 1);
328 }
329 }
330 }
331
332 return null;
333 }
334
335 /**
336 * Gets the zero-based number of the channels pane,
337 * to which the specified sampler channel is added.
338 * Note that the can be moved from one channels pane to another.
339 * @return The zero-based index of the channels pane,
340 * to which the specified sampler channel is added, or
341 * -1 if the specified channels is not found.
342 */
343 @Override
344 public int
345 getChannelsPaneNumber(SamplerChannelModel channel) {
346 if(channel == null) return -1;
347
348 for(int i = 0; i < getChannelsPaneCount(); i++) {
349 JSChannelsPane chnPane = getChannelsPane(i);
350 for(int j = 0; j < chnPane.getChannelCount(); j++) {
351 if(chnPane.getChannel(j).getChannelId() == channel.getChannelId()) {
352 return i;
353 }
354 }
355 }
356
357 return -1;
358 }
359
360 /**
361 * Determines whether the channel list UI should be automatically updated
362 * when channel is added/removed. The default value is <code>true</code>.
363 */
364 @Override
365 public boolean
366 getAutoUpdateChannelListUI() { return autoUpdateChannelListUI; }
367
368 /**
369 * Determines whether the channel list UI should be automatically updated
370 * when channel is added/removed.
371 */
372 @Override
373 public void
374 setAutoUpdateChannelListUI(boolean b) {
375 if(b == autoUpdateChannelListUI) return;
376
377 autoUpdateChannelListUI = b;
378 for(JSChannelsPane cp : getChannelsPaneList()) {
379 cp.setAutoUpdate(b);
380 }
381 }
382
383 /**
384 * Updates the channel list UI.
385 */
386 @Override
387 public void
388 updateChannelListUI() {
389 for(JSChannelsPane cp : getChannelsPaneList()) {
390 cp.updateChannelListUI();
391 }
392 }
393
394 /**
395 * Get the server address to which to connect (asynchronously if needed)
396 * and pass it to <code>r.run()</code>.
397 * If the server should be manually selected, a dialog asking
398 * the user to choose a server is displayed.
399 */
400 @Override
401 public void
402 getServer(CC.Run<Server> r) {
403 getServer(r, CC.preferences().getBoolProperty(MANUAL_SERVER_SELECT_ON_STARTUP));
404
405 }
406
407 /**
408 * Get the server address to which to connect (asynchronously if needed)
409 * and pass it to <code>r.run()</code>.
410 * If the server should be manually selected, a dialog asking
411 * the user to choose a server is displayed.
412 * @param manualSelect Determines whether the server should be manually selected.
413 */
414 @Override
415 public void
416 getServer(CC.Run<Server> r, boolean manualSelect) {
417 r.run(getServer(manualSelect));
418 }
419
420 @Override
421 public Server
422 getServer() { throw new UnsupportedOperationException(); }
423
424 @Override
425 public Server
426 getServer(boolean manualSelect) { throw new UnsupportedOperationException(); }
427 }

  ViewVC Help
Powered by ViewVC