Add simple settings screen

The first setting is just the keyboard layout, but we'll add lots more
in time (velocity sensitivity). Plus, some synth state (program change
in particular) should persist, and this is a good mechanism.

There are some infelicities: the settings screen doesn't bind the synth
service, so sound pauses. Also, fullscreen is inconsistent and should be
rethought (maybe immersive on KitKat).
master
Raph Levien 11 years ago
parent e90db0e8a4
commit c9fd115563
  1. 3
      android/AndroidManifest.xml
  2. 12
      android/res/values/strings.xml
  3. 9
      android/res/xml/preferences.xml
  4. 58
      android/src/com/levien/synthesizer/android/ui/PianoActivity2.java
  5. 15
      android/src/com/levien/synthesizer/android/ui/SettingsActivity.java
  6. 12
      android/src/com/levien/synthesizer/android/widgets/keyboard/ScrollStripView.java

@ -75,6 +75,9 @@
android:name="com.levien.synthesizer.android.ui.KarplusStrongActivity" android:name="com.levien.synthesizer.android.ui.KarplusStrongActivity"
android:label="@string/karplus_strong" android:label="@string/karplus_strong"
android:screenOrientation="landscape" /> android:screenOrientation="landscape" />
<activity
android:name="com.levien.synthesizer.android.ui.SettingsActivity"
android:label="@string/settings" />
<service android:name=".android.service.SynthesizerService"> <service android:name=".android.service.SynthesizerService">
</service> </service>
</application> </application>

@ -83,4 +83,16 @@
<string name="settings">Settings</string> <string name="settings">Settings</string>
<!-- Preferences -->
<string name="pref_keyboardType">Keyboard Type</string>
<string-array name="pref_keyboardType_entries">
<item>2 Level (Piano)</item>
<item>3 Level</item>
</string-array>
<string-array name="pref_keyboardType_values">
<item>2level</item>
<item>3level</item>
</string-array>
<string name="pref_keyboardType_default">2level</string>
</resources> </resources>

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
<ListPreference
android:key="keyboard_type"
android:title="@string/pref_keyboardType"
android:entries="@array/pref_keyboardType_entries"
android:entryValues="@array/pref_keyboardType_values"
android:defaultValue="@string/pref_keyboardType_default" />
</PreferenceScreen>

@ -24,12 +24,16 @@ import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.hardware.usb.UsbDevice; import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager; import android.hardware.usb.UsbManager;
import android.os.Build; import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log; import android.util.Log;
import android.view.Menu; import android.view.Menu;
import android.view.MenuItem;
import android.view.View; import android.view.View;
import android.view.WindowManager; import android.view.WindowManager;
import android.widget.AdapterView; import android.widget.AdapterView;
@ -51,7 +55,7 @@ import com.levien.synthesizer.core.midi.MidiListener;
* This version is hacked up to send MIDI to the C++ engine. This needs to * This version is hacked up to send MIDI to the C++ engine. This needs to
* be refactored to make it cleaner. * be refactored to make it cleaner.
*/ */
public class PianoActivity2 extends SynthActivity { public class PianoActivity2 extends SynthActivity implements OnSharedPreferenceChangeListener {
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
Log.d("synth", "activity onCreate " + getIntent()); Log.d("synth", "activity onCreate " + getIntent());
@ -60,9 +64,7 @@ public class PianoActivity2 extends SynthActivity {
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
setContentView(R.layout.piano2); setContentView(R.layout.piano2);
//piano_ = (PianoView)findViewById(R.id.piano);
keyboard_ = (KeyboardView)findViewById(R.id.piano); keyboard_ = (KeyboardView)findViewById(R.id.piano);
keyboard_.setKeyboardSpec(KeyboardSpec.make2Layer());
ScrollStripView scrollStrip_ = (ScrollStripView)findViewById(R.id.scrollstrip); ScrollStripView scrollStrip_ = (ScrollStripView)findViewById(R.id.scrollstrip);
scrollStrip_.bindKeyboard(keyboard_); scrollStrip_.bindKeyboard(keyboard_);
cutoffKnob_ = (KnobView)findViewById(R.id.cutoffKnob); cutoffKnob_ = (KnobView)findViewById(R.id.cutoffKnob);
@ -81,6 +83,16 @@ public class PianoActivity2 extends SynthActivity {
return true; return true;
} }
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.settings:
startActivity(new Intent(this, SettingsActivity.class));
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override @Override
protected void onDestroy() { protected void onDestroy() {
Log.d("synth", "activity onDestroy"); Log.d("synth", "activity onDestroy");
@ -90,16 +102,31 @@ public class PianoActivity2 extends SynthActivity {
super.onDestroy(); super.onDestroy();
} }
@Override
protected void onResume() {
super.onResume();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
prefs.registerOnSharedPreferenceChangeListener(this);
onSharedPreferenceChanged(prefs, "keyboard_type");
}
@Override @Override
protected void onPause() { protected void onPause() {
Log.d("synth", "activity onPause");
super.onPause(); super.onPause();
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(this);
prefs.unregisterOnSharedPreferenceChangeListener(this);
} }
@Override public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
protected void onResume() { if (key.equals("keyboard_type")) {
Log.d("synth", "activity onResume " + getIntent()); String keyboardType = prefs.getString(key, "2level");
super.onResume(); if (keyboardType.equals("2level")) {
keyboard_.setKeyboardSpec(KeyboardSpec.make2Layer());
} else if (keyboardType.equals("3level")) {
keyboard_.setKeyboardSpec(KeyboardSpec.make3Layer());
}
}
} }
@Override @Override
@ -222,11 +249,16 @@ public class PianoActivity2 extends SynthActivity {
// Populate patch names (note: we could update an existing list rather than // Populate patch names (note: we could update an existing list rather than
// creating a new adapter, but it probably wouldn't save all that much). // creating a new adapter, but it probably wouldn't save all that much).
List<String> patchNames = synthesizerService_.getPatchNames(); if (presetSpinner_.getAdapter() == null) {
ArrayAdapter<String> adapter = new ArrayAdapter<String>( // Only set it once, which is a workaround that allows the preset
PianoActivity2.this, android.R.layout.simple_spinner_item, patchNames); // selection to persist for onCreate lifetime. Of course, it should
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); // be persisted for real, instead.
presetSpinner_.setAdapter(adapter); List<String> patchNames = synthesizerService_.getPatchNames();
ArrayAdapter<String> adapter = new ArrayAdapter<String>(
PianoActivity2.this, android.R.layout.simple_spinner_item, patchNames);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
presetSpinner_.setAdapter(adapter);
}
presetSpinner_.setOnItemSelectedListener(new OnItemSelectedListener() { presetSpinner_.setOnItemSelectedListener(new OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {

@ -0,0 +1,15 @@
package com.levien.synthesizer.android.ui;
import android.os.Bundle;
import android.preference.PreferenceActivity;
import com.levien.synthesizer.R;
public class SettingsActivity extends PreferenceActivity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
}
}

@ -83,8 +83,7 @@ public class ScrollStripView extends View {
@Override @Override
public boolean onTouchEvent(MotionEvent event) { public boolean onTouchEvent(MotionEvent event) {
int action = event.getAction(); int actionCode = event.getActionMasked();
int actionCode = action & MotionEvent.ACTION_MASK;
boolean redraw = false; boolean redraw = false;
if (actionCode == MotionEvent.ACTION_DOWN) { if (actionCode == MotionEvent.ACTION_DOWN) {
int pointerId = event.getPointerId(0); int pointerId = event.getPointerId(0);
@ -92,8 +91,7 @@ public class ScrollStripView extends View {
redraw = onTouchDown(pointerId, event.getX()); redraw = onTouchDown(pointerId, event.getX());
} }
} else if (actionCode == MotionEvent.ACTION_POINTER_DOWN) { } else if (actionCode == MotionEvent.ACTION_POINTER_DOWN) {
int pointerIndex = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) int pointerIndex = event.getActionIndex();
>> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
int pointerId = event.getPointerId(pointerIndex); int pointerId = event.getPointerId(pointerIndex);
if (pointerId < 2 && pointerId >= 0) { if (pointerId < 2 && pointerId >= 0) {
redraw = onTouchDown(pointerId, event.getX(pointerIndex)); redraw = onTouchDown(pointerId, event.getX(pointerIndex));
@ -104,8 +102,7 @@ public class ScrollStripView extends View {
onTouchUp(pointerId); onTouchUp(pointerId);
} }
} else if (actionCode == MotionEvent.ACTION_POINTER_UP) { } else if (actionCode == MotionEvent.ACTION_POINTER_UP) {
int pointerIndex = (action & MotionEvent.ACTION_POINTER_INDEX_MASK) int pointerIndex = event.getActionIndex();
>> MotionEvent.ACTION_POINTER_INDEX_SHIFT;
int pointerId = event.getPointerId(pointerIndex); int pointerId = event.getPointerId(pointerIndex);
if (pointerId < 2 && pointerId >= 0) { if (pointerId < 2 && pointerId >= 0) {
onTouchUp(pointerId); onTouchUp(pointerId);
@ -126,8 +123,9 @@ public class ScrollStripView extends View {
} else if (touchDown_[0] && touchDown_[1]) { } else if (touchDown_[0] && touchDown_[1]) {
zoom_ = scaleAtTouch_ * (touchx_[1] - touchx_[0]); zoom_ = scaleAtTouch_ * (touchx_[1] - touchx_[0]);
// TODO: min and max zoom values maybe should depend on screen size // TODO: min and max zoom values maybe should depend on screen size
// Also, zoom range should be on the larger side for 3 level layout
zoom_ = Math.max(1.0f, zoom_); zoom_ = Math.max(1.0f, zoom_);
zoom_ = Math.min(4.0f, zoom_); zoom_ = Math.min(5.0f, zoom_);
offset_ = touchx_[0] + zoom_ / zoomAtTouch_ * deltaAtTouch_; offset_ = touchx_[0] + zoom_ / zoomAtTouch_ * deltaAtTouch_;
redraw = true; redraw = true;
} }

Loading…
Cancel
Save