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

Annotation of /jsampler/trunk/src/org/jsampler/android/view/classic/MainFrame.java

Parent Directory Parent Directory | Revision Log Revision Log


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

1 iliev 2302 /*
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.classic;
24    
25     import java.beans.PropertyChangeEvent;
26     import java.beans.PropertyChangeListener;
27    
28     import org.jsampler.CC;
29     import org.jsampler.HF;
30     import org.jsampler.JSPrefs;
31     import org.jsampler.Server;
32     import org.jsampler.android.AHF;
33     import org.jsampler.android.JSamplerActivity;
34     import org.jsampler.android.R;
35     import org.jsampler.android.view.AndroidChannelsPane;
36     import org.jsampler.android.view.AndroidMainFrame;
37     import org.jsampler.event.SamplerAdapter;
38     import org.jsampler.event.SamplerEvent;
39    
40     import android.content.Context;
41     import android.os.Parcelable;
42     import android.support.v4.view.PagerAdapter;
43     import android.support.v4.view.ViewPager;
44     import android.util.Log;
45     import android.view.LayoutInflater;
46     import android.view.MotionEvent;
47     import android.view.View;
48     import android.widget.ImageButton;
49     import android.widget.SeekBar;
50     import android.widget.TextView;
51     import android.widget.ViewFlipper;
52    
53     import static org.jsampler.JSPrefs.MAXIMUM_MASTER_VOLUME;
54     import static org.jsampler.JSPrefs.VOL_MEASUREMENT_UNIT_DECIBEL;
55     import static org.jsampler.android.view.AndroidI18n.i18n;
56     import static org.jsampler.android.view.classic.ClassicPrefs.preferences;
57     import static org.jsampler.android.JSamplerActivity.*;
58    
59     public class MainFrame extends AndroidMainFrame<AndroidChannelsPane> {
60     private static final int FLING_MIN_DISTANCE = 100;
61    
62     private View view = null;
63     private ViewFlipper panesFlipper;
64     private ViewPager lanesPager;
65    
66     public MainFrame() {
67    
68     }
69    
70     @Override
71     public void
72     onCreate() {
73     LayoutInflater inflater =
74     (LayoutInflater)AHF.getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
75     view = inflater.inflate(R.layout.classic_main, null);
76    
77     ChannelLanesPagerAdapter lanesPagerAdapter = new ChannelLanesPagerAdapter();
78     lanesPager = (ViewPager)view.findViewById(R.id.main_channel_lane_pager);
79     lanesPager.setAdapter(lanesPagerAdapter);
80    
81     panesFlipper = (ViewFlipper)view.findViewById(R.id.main_flipper);
82     panesFlipper.setDisplayedChild(1);
83     updateMainTitle();
84    
85     installListeners();
86     updateVolume();
87    
88     ChannelsPane cp = new ChannelsPane();
89     cp.setTitle("Channel Lane 1");
90     addChannelsPane(cp);
91    
92     addChannelsPane(new ChannelsPane("Channel Lane 2"));
93     setSelectedChannelsPane(cp);
94     }
95    
96     public void
97     uninstall() {
98     uninstallListeners();
99     }
100    
101     @Override
102     public View
103     getView() { return view; }
104    
105     @Override
106     public boolean
107     onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
108     /*ViewFlipper flipper = getFlipper();
109    
110     if(Math.abs(e1.getX() - e2.getX()) > Math.abs(e1.getY() - e2.getY())) {
111     if(Math.abs(e1.getX() - e2.getX()) < FLING_MIN_DISTANCE) return false;
112     if(e1.getX() - e2.getX() > 0) { // right to left
113     flipper.setInAnimation(AHF.inFromRightAnimation());
114     flipper.setOutAnimation(AHF.outToLeftAnimation());
115     flipper.showNext();
116     } else { // left to right
117     flipper.setInAnimation(AHF.inFromLeftAnimation());
118     flipper.setOutAnimation(AHF.outToRightAnimation());
119     flipper.showPrevious();
120     }
121     return true;
122     } else {
123     if(e1.getY() - e2.getY() > 0) { // up
124    
125     } else { // down
126    
127     }
128     }*/
129     return false;
130     }
131    
132     public boolean
133     onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
134    
135     return false;
136     }
137    
138     @Override
139     public void setVisible(boolean b) {
140    
141     }
142    
143     private void
144     installListeners() {
145     SeekBar sliderVolume = (SeekBar)view.findViewById(R.id.main_slider_volume);
146     int i = CC.preferences().getIntProperty(MAXIMUM_MASTER_VOLUME);
147     sliderVolume.setMax(i);
148     CC.preferences().addPropertyChangeListener(MAXIMUM_MASTER_VOLUME, getHandler());
149    
150     sliderVolume.setOnSeekBarChangeListener(getHandler());
151    
152     CC.getSamplerModel().addSamplerListener(getHandler());
153    
154     CC.preferences().addPropertyChangeListener(VOL_MEASUREMENT_UNIT_DECIBEL, getHandler());
155    
156     ImageButton btn = (ImageButton)view.findViewById(R.id.classic_main_flip_back);
157     btn.setOnClickListener(new View.OnClickListener() {
158     public void onClick(View v) {
159     panesFlipper.setInAnimation(AHF.inFromLeftAnimation());
160     panesFlipper.setOutAnimation(AHF.outToRightAnimation());
161     panesFlipper.showPrevious();
162     updateMainTitle();
163     }
164     });
165    
166     btn = (ImageButton)view.findViewById(R.id.classic_main_flip_forward);
167     btn.setOnClickListener(new View.OnClickListener() {
168     public void onClick(View v) {
169     panesFlipper.setInAnimation(AHF.inFromRightAnimation());
170     panesFlipper.setOutAnimation(AHF.outToLeftAnimation());
171     panesFlipper.showNext();
172     updateMainTitle();
173     }
174     });
175     }
176    
177     private void
178     uninstallListeners() {
179     CC.preferences().removePropertyChangeListener(MAXIMUM_MASTER_VOLUME, getHandler());
180     CC.getSamplerModel().removeSamplerListener(getHandler());
181     CC.preferences().removePropertyChangeListener(VOL_MEASUREMENT_UNIT_DECIBEL, getHandler());
182    
183     ImageButton btn = (ImageButton)view.findViewById(R.id.classic_main_flip_back);
184     btn.setOnClickListener(null);
185    
186     btn = (ImageButton)view.findViewById(R.id.classic_main_flip_forward);
187     btn.setOnClickListener(null);
188    
189     SeekBar sliderVolume = (SeekBar)view.findViewById(R.id.main_slider_volume);
190     sliderVolume.setOnSeekBarChangeListener(null);
191     }
192    
193     private void
194     updateMainTitle() {
195     TextView text = (TextView)view.findViewById(R.id.main_title);
196     switch(panesFlipper.getDisplayedChild()) {
197     case 0:
198     text.setText(i18n.getLabel("MainFrame.titleMidiDevices"));
199     break;
200     case 1:
201     text.setText(i18n.getLabel("MainFrame.titleSamplerChannels"));
202     break;
203     case 2:
204     text.setText(i18n.getLabel("MainFrame.titleAudioDevices"));
205     break;
206     default:
207     text.setText("");
208     }
209     }
210    
211     private void
212     updateVolume() {
213     SeekBar sliderVolume = (SeekBar)view.findViewById(R.id.main_slider_volume);
214     sliderVolume.setProgress((int)(CC.getSamplerModel().getVolume() * 100));
215     }
216    
217     private void
218     setVolume(boolean isAdjusting) {
219     SeekBar sliderVolume = (SeekBar)view.findViewById(R.id.main_slider_volume);
220     TextView tvVolume = (TextView)view.findViewById(R.id.main_text_volume);
221     int volume = sliderVolume.getProgress();
222    
223     tvVolume.setText(HF.getVolumeString(volume));
224    
225     if(isAdjusting) return;
226    
227     int vol = (int)(CC.getSamplerModel().getVolume() * 100);
228    
229     if(vol == sliderVolume.getProgress()) return;
230    
231     /*
232     * If the model's volume is not equal to the slider
233     * value we assume that the change is due to user input.
234     * So we must update the volume at the backend too.
235     */
236     float v = sliderVolume.getProgress();
237     v /= 100;
238     CC.getSamplerModel().setBackendVolume(v);
239     }
240    
241     EventHandler handler = new EventHandler();
242    
243     private EventHandler
244     getHandler() { return handler; }
245    
246     private class EventHandler extends SamplerAdapter
247     implements SeekBar.OnSeekBarChangeListener, PropertyChangeListener {
248    
249     @Override
250     public void
251     volumeChanged(SamplerEvent e) { updateVolume(); }
252    
253     @Override
254     public void
255     onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
256     setVolume(true);
257     }
258    
259     @Override
260     public void
261     onStopTrackingTouch(SeekBar seekBar) { setVolume(false); }
262    
263     @Override
264     public void
265     onStartTrackingTouch(SeekBar seekBar) { }
266    
267     @Override
268     public void
269     propertyChange(PropertyChangeEvent e) {
270     if (VOL_MEASUREMENT_UNIT_DECIBEL.equals(e.getPropertyName())) {
271     setVolume(true);
272     } else if (MAXIMUM_MASTER_VOLUME.equals(e.getPropertyName())) {
273     int j = CC.preferences().getIntProperty(MAXIMUM_MASTER_VOLUME);
274     SeekBar sliderVolume = (SeekBar)view.findViewById(R.id.main_slider_volume);
275     sliderVolume.setMax(j);
276     }
277    
278     }
279     }
280    
281     /**
282     * Gets the channels' pane that is currently shown,
283     * or has the focus if more than one channels' panes are shown.
284     * If the GUI implementation has only one pane containing sampler channels,
285     * than this method should always return that pane (the channels' pane
286     * with index 0).
287     * @return The selected channels' pane.
288     */
289     @Override
290     public AndroidChannelsPane
291     getSelectedChannelsPane() {
292     return getChannelsPane(lanesPager.getCurrentItem());
293     }
294    
295     /**
296     * Sets the channels' pane to be selected.
297     * Note that all registered listeners should be notified
298     * when the selection is changed.
299     * @param pane The channels' pane to be shown.
300     * @see #fireChannelsPaneSelectionChanged
301     */
302     @Override
303     public void
304     setSelectedChannelsPane(AndroidChannelsPane pane) {
305     int idx = getChannelsPaneIndex(pane);
306     if(idx == -1) {
307     Log.w("setSelectedChannelsPane", "Channel lane not found!");
308     return;
309     }
310     lanesPager.setCurrentItem(idx, true);
311     }
312    
313     /**
314     * Inserts the specified channels' pane at the specified position
315     * in the view and in the channels' pane list.
316     * Where and how this pane will be shown depends on the view/GUI implementation.
317     * Note that some GUI implementation may have only one pane containing sampler channels.
318     * @param pane The channels' pane to be inserted.
319     * @param idx Specifies the position of the channels' pane.
320     * @see #getChannelsPaneList
321     */
322     @Override
323     public void insertChannelsPane(AndroidChannelsPane pane, int idx) {
324     chnPaneList.insertElementAt(pane, idx);
325     lanesPager.getAdapter().notifyDataSetChanged();
326     lanesPager.setCurrentItem(idx, true);
327    
328     /*ViewFlipper flipper = getFlipper();
329    
330     if(idx < 0 || flipper.getChildCount() < idx) {
331     Log.w("classic.MainFrame.insertChannelsPane", "Incorrect lane position: " + idx);
332     flipper.addView(pane.getView());
333     } else {
334     flipper.addView(pane.getView(), idx);
335     }
336    
337     flipper.setDisplayedChild(idx);*/
338     firePropertyChange("channelLaneAdded", null, pane);
339     }
340    
341     /**
342     * Invoked on startup when no JSampler home directory is specified
343     * or the specified JSampler home directory doesn't exist.
344     * This method should ask the user to specify a JSampler
345     * home directory and then set the specified JSampler home directory using
346     * {@link org.jsampler.CC#setJSamplerHome} method.
347     * @see org.jsampler.CC#getJSamplerHome
348     * @see org.jsampler.CC#setJSamplerHome
349     */
350     @Override
351     public void installJSamplerHome() {
352     AHF.getActivity().showDialog(JSamplerActivity.DLG_CHOOSE_HOME_DIR);
353     }
354    
355     /** Shows a detailed error information about the specified exception. */
356     @Override
357     public void showDetailedErrorMessage(String err, String details) {
358    
359     }
360    
361     @Override
362     public void handleConnectionFailure() {
363    
364     }
365    
366     /**
367     * Gets the server address to which to connect. If the server should be
368     * manually selected, a dialog asking the user to choose a server is displayed.
369     * @param manualSelect Determines whether the server should be manually selected.
370     */
371     @Override
372     public void getServer(final CC.Run<Server> r, boolean manualSelect) {
373     if(!manualSelect) {
374     int i = preferences().getIntProperty(JSPrefs.SERVER_INDEX);
375     int size = CC.getServerList().getServerCount();
376     if(size == 0) r.run(null);
377     else if(i >= size) r.run(CC.getServerList().getServer(0));
378     else r.run(CC.getServerList().getServer(i));
379     return;
380     }
381    
382     AHF.getActivity().startLocalActivity(new Requestor<Server>(CHOOSE_BACKEND_REQUEST) {
383     public void
384     onResult(Server res) { r.run(res); }
385     });
386     }
387    
388     /**
389     * Sends the specified script to the backend.
390     * @param script The file name of the script to run.
391     */
392     @Override
393     public void runScript(String script) {
394    
395     }
396    
397     private class ChannelLanesPagerAdapter extends PagerAdapter {
398     public int
399     getCount() { return getChannelsPaneCount(); }
400    
401     public void startUpdate(View container) { }
402     public void finishUpdate(View container) { }
403    
404     public Object
405     instantiateItem(View container, int position) {
406     View view = getChannelsPane(position).getView();
407     ((ViewPager)container).addView(view, 0);
408     return view;
409     }
410    
411     public void
412     destroyItem(View container, int position, Object object) {
413     ((ViewPager)container).removeView((View)object);
414     }
415    
416     public void
417     setPrimaryItem(View container, int position, Object object) {
418     setSelectedChannelsPane(getChannelsPane(position));
419     }
420    
421     public boolean
422     isViewFromObject(View view, Object object) { return view == object; }
423    
424     public Parcelable
425     saveState() { return null; }
426    
427     public void
428     restoreState(Parcelable state, ClassLoader loader) { }
429     }
430     }

  ViewVC Help
Powered by ViewVC