mirror of
https://github.com/mauiaaron/apple2.git
synced 2025-01-14 03:30:53 +00:00
First cut at audio settings menu
This commit is contained in:
parent
c2fdebd040
commit
37a8985f79
@ -0,0 +1,307 @@
|
||||
/*
|
||||
* Apple // emulator for *nix
|
||||
*
|
||||
* This software package is subject to the GNU General Public License
|
||||
* version 2 or later (your choice) as published by the Free Software
|
||||
* Foundation.
|
||||
*
|
||||
* THERE ARE NO WARRANTIES WHATSOEVER.
|
||||
*
|
||||
*/
|
||||
|
||||
package org.deadc0de.apple2ix;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ListView;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
public class Apple2AudioSettingsMenu {
|
||||
|
||||
private final static String TAG = "Apple2AudioSettingsMenu";
|
||||
|
||||
private Apple2Activity mActivity = null;
|
||||
private View mSettingsView = null;
|
||||
|
||||
public Apple2AudioSettingsMenu(Apple2Activity activity) {
|
||||
mActivity = activity;
|
||||
setup();
|
||||
}
|
||||
|
||||
enum SETTINGS {
|
||||
SPEAKER_ENABLED {
|
||||
@Override public String getTitle(Apple2Activity activity) {
|
||||
return activity.getResources().getString(R.string.speaker_enable);
|
||||
}
|
||||
@Override public String getSummary(Apple2Activity activity) {
|
||||
return activity.getResources().getString(R.string.speaker_enable_summary);
|
||||
}
|
||||
@Override public View getView(final Apple2Activity activity, View convertView) {
|
||||
convertView = _basicView(activity, this, convertView);
|
||||
CheckBox cb = _addCheckbox(activity, this, convertView, true);
|
||||
cb.setEnabled(false);
|
||||
return convertView;
|
||||
}
|
||||
},
|
||||
SPEAKER_VOLUME {
|
||||
@Override public String getTitle(Apple2Activity activity) {
|
||||
return activity.getResources().getString(R.string.speaker_volume);
|
||||
}
|
||||
@Override public String getSummary(Apple2Activity activity) {
|
||||
return activity.getResources().getString(R.string.speaker_volume_summary);
|
||||
}
|
||||
@Override public View getView(final Apple2Activity activity, View convertView) {
|
||||
LayoutInflater inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
convertView = inflater.inflate(R.layout.a2preference_slider, null, false);
|
||||
|
||||
TextView tv = (TextView)convertView.findViewById(R.id.a2preference_slider_summary);
|
||||
tv.setText(getSummary(activity));
|
||||
|
||||
final TextView seekBarValue = (TextView)convertView.findViewById(R.id.a2preference_slider_seekBarValue);
|
||||
|
||||
SeekBar sb = (SeekBar)convertView.findViewById(R.id.a2preference_slider_seekBar);
|
||||
sb.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
if (!fromUser) {
|
||||
return;
|
||||
}
|
||||
seekBarValue.setText("" + progress);
|
||||
Apple2Preferences.SPEAKER_VOLUME.saveVolume(activity, Apple2Preferences.Volume.values()[progress]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||
}
|
||||
});
|
||||
|
||||
sb.setMax(0); // http://stackoverflow.com/questions/10278467/seekbar-not-setting-actual-progress-setprogress-not-working-on-early-android
|
||||
sb.setMax(Apple2Preferences.Volume.MAX.ordinal() - 1);
|
||||
int vol = Apple2Preferences.SPEAKER_VOLUME.intValue(activity);
|
||||
sb.setProgress(vol);
|
||||
seekBarValue.setText("" + vol);
|
||||
return convertView;
|
||||
}
|
||||
},
|
||||
MOCKINGBOARD_ENABLED {
|
||||
@Override
|
||||
public String getTitle(Apple2Activity activity) {
|
||||
return activity.getResources().getString(R.string.mockingboard_enable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSummary(Apple2Activity activity) {
|
||||
return activity.getResources().getString(R.string.mockingboard_enable_summary);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(final Apple2Activity activity, View convertView) {
|
||||
convertView = _basicView(activity, this, convertView);
|
||||
CheckBox cb = _addCheckbox(activity, this, convertView, Apple2Preferences.MOCKINGBOARD_ENABLED.booleanValue(activity));
|
||||
cb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||
Apple2Preferences.MOCKINGBOARD_ENABLED.saveBoolean(activity, isChecked);
|
||||
}
|
||||
});
|
||||
return convertView;
|
||||
}
|
||||
},
|
||||
MOCKINGBOARD_VOLUME {
|
||||
@Override public String getTitle(Apple2Activity activity) {
|
||||
return activity.getResources().getString(R.string.mockingboard_volume);
|
||||
}
|
||||
@Override public String getSummary(Apple2Activity activity) {
|
||||
return activity.getResources().getString(R.string.mockingboard_volume_summary);
|
||||
}
|
||||
@Override public View getView(final Apple2Activity activity, View convertView) {
|
||||
LayoutInflater inflater = (LayoutInflater)activity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
convertView = inflater.inflate(R.layout.a2preference_slider, null, false);
|
||||
|
||||
TextView tv = (TextView)convertView.findViewById(R.id.a2preference_slider_summary);
|
||||
tv.setText(getSummary(activity));
|
||||
|
||||
final TextView seekBarValue = (TextView)convertView.findViewById(R.id.a2preference_slider_seekBarValue);
|
||||
|
||||
SeekBar sb = (SeekBar)convertView.findViewById(R.id.a2preference_slider_seekBar);
|
||||
sb.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||
if (!fromUser) {
|
||||
return;
|
||||
}
|
||||
seekBarValue.setText("" + progress);
|
||||
Apple2Preferences.MOCKINGBOARD_VOLUME.saveVolume(activity, Apple2Preferences.Volume.values()[progress]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||
}
|
||||
});
|
||||
|
||||
sb.setMax(0); // http://stackoverflow.com/questions/10278467/seekbar-not-setting-actual-progress-setprogress-not-working-on-early-android
|
||||
sb.setMax(Apple2Preferences.Volume.MAX.ordinal() - 1);
|
||||
int vol = Apple2Preferences.MOCKINGBOARD_VOLUME.intValue(activity);
|
||||
sb.setProgress(vol);
|
||||
seekBarValue.setText("" + vol);
|
||||
return convertView;
|
||||
}
|
||||
};
|
||||
|
||||
private static View _basicView(Apple2Activity activity, SETTINGS setting, View convertView) {
|
||||
TextView tv = (TextView)convertView.findViewById(R.id.a2preference_title);
|
||||
tv.setText(setting.getTitle(activity));
|
||||
|
||||
tv = (TextView)convertView.findViewById(R.id.a2preference_summary);
|
||||
tv.setText(setting.getSummary(activity));
|
||||
|
||||
LinearLayout layout = (LinearLayout)convertView.findViewById(R.id.a2preference_widget_frame);
|
||||
if (layout.getChildCount() > 0) {
|
||||
// layout cells appear to be reused when scrolling into view ... make sure we start with clear hierarchy
|
||||
layout.removeAllViews();
|
||||
}
|
||||
|
||||
return convertView;
|
||||
}
|
||||
private static ImageView _addPopupIcon(Apple2Activity activity, SETTINGS setting, View convertView) {
|
||||
ImageView imageView = new ImageView(activity);
|
||||
Drawable drawable = activity.getResources().getDrawable(android.R.drawable.ic_menu_edit);
|
||||
imageView.setImageDrawable(drawable);
|
||||
LinearLayout layout = (LinearLayout)convertView.findViewById(R.id.a2preference_widget_frame);
|
||||
layout.addView(imageView);
|
||||
return imageView;
|
||||
}
|
||||
private static CheckBox _addCheckbox(Apple2Activity activity, SETTINGS setting, View convertView, boolean isChecked) {
|
||||
CheckBox checkBox = new CheckBox(activity);
|
||||
checkBox.setChecked(isChecked);
|
||||
LinearLayout layout = (LinearLayout)convertView.findViewById(R.id.a2preference_widget_frame);
|
||||
layout.addView(checkBox);
|
||||
return checkBox;
|
||||
}
|
||||
|
||||
public static final int size = SETTINGS.values().length;
|
||||
|
||||
public abstract String getTitle(Apple2Activity activity);
|
||||
public abstract String getSummary(Apple2Activity activity);
|
||||
|
||||
public void handleSelection(Apple2AudioSettingsMenu settingsMenu, boolean isChecked) {
|
||||
/* ... */
|
||||
}
|
||||
|
||||
public View getView(Apple2Activity activity, View convertView) {
|
||||
return _basicView(activity, this, convertView);
|
||||
}
|
||||
|
||||
public static String[] titles(Apple2Activity activity) {
|
||||
String[] titles = new String[size];
|
||||
int i = 0;
|
||||
for (SETTINGS setting : values()) {
|
||||
titles[i++] = setting.getTitle(activity);
|
||||
}
|
||||
return titles;
|
||||
}
|
||||
}
|
||||
|
||||
private void setup() {
|
||||
LayoutInflater inflater = (LayoutInflater)mActivity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
mSettingsView = inflater.inflate(R.layout.activity_settings, null, false);
|
||||
|
||||
TextView title = (TextView)mSettingsView.findViewById(R.id.header_settings);
|
||||
title.setText(R.string.settings_audio);
|
||||
|
||||
ListView settingsList = (ListView)mSettingsView.findViewById(R.id.listView_settings);
|
||||
settingsList.setEnabled(true);
|
||||
|
||||
// This is a bit of a hack ... we're not using the ArrayAdapter as intended here, simply piggy-backing off its call to getView() to supply a completely custom view. The arguably better way would be to create a custom Apple2SettingsAdapter or something akin to that...
|
||||
ArrayAdapter<?> adapter = new ArrayAdapter<String>(mActivity, R.layout.a2preference, R.id.a2preference_title, SETTINGS.titles(mActivity)) {
|
||||
@Override
|
||||
public boolean areAllItemsEnabled() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEnabled(int position) {
|
||||
if (position < 0 || position >= SETTINGS.size) {
|
||||
throw new ArrayIndexOutOfBoundsException();
|
||||
}
|
||||
return position == SETTINGS.MOCKINGBOARD_ENABLED.ordinal();
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
//View view = super.getView(position, convertView, parent);
|
||||
// ^^^ WHOA ... this is catching an NPE deep in AOSP code on the second time loading the audio menu, WTF?
|
||||
// Methinks it is related to the hack of loading a completely different R.layout.something for certain views...
|
||||
View view = convertView != null ? convertView : super.getView(position, null, parent);
|
||||
SETTINGS setting = SETTINGS.values()[position];
|
||||
return setting.getView(mActivity, view);
|
||||
}
|
||||
};
|
||||
|
||||
settingsList.setAdapter(adapter);
|
||||
settingsList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
SETTINGS setting = SETTINGS.values()[position];
|
||||
LinearLayout layout = (LinearLayout) view.findViewById(R.id.a2preference_widget_frame);
|
||||
if (layout == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
View childView = layout.getChildAt(0);
|
||||
boolean selected = false;
|
||||
if (childView != null && childView instanceof CheckBox) {
|
||||
CheckBox checkBox = (CheckBox) childView;
|
||||
checkBox.setChecked(!checkBox.isChecked());
|
||||
selected = checkBox.isChecked();
|
||||
}
|
||||
setting.handleSelection(Apple2AudioSettingsMenu.this, selected);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void show() {
|
||||
if (isShowing()) {
|
||||
return;
|
||||
}
|
||||
mActivity.nativeOnPause();
|
||||
mActivity.addContentView(mSettingsView, new FrameLayout.LayoutParams(mActivity.getWidth(), mActivity.getHeight()));
|
||||
}
|
||||
|
||||
public void dismiss() {
|
||||
if (isShowing()) {
|
||||
dismissWithoutResume();
|
||||
//mActivity.nativeOnResume(/*isSystemResume:*/false);
|
||||
}
|
||||
}
|
||||
|
||||
public void dismissWithoutResume() {
|
||||
if (isShowing()) {
|
||||
((ViewGroup)mSettingsView.getParent()).removeView(mSettingsView);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isShowing() {
|
||||
return mSettingsView.isShown();
|
||||
}
|
||||
}
|
56
Android/app/src/main/res/layout/a2preference_slider.xml
Normal file
56
Android/app/src/main/res/layout/a2preference_slider.xml
Normal file
@ -0,0 +1,56 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:minHeight="?android:attr/listPreferredItemHeight"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingRight="?android:attr/scrollbarSize">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/preference_margin_left"
|
||||
android:layout_marginStart="@dimen/preference_margin_left"
|
||||
android:layout_marginRight="@dimen/preference_margin_right"
|
||||
android:layout_marginEnd="@dimen/preference_margin_right"
|
||||
android:layout_marginTop="@dimen/preference_margin_top"
|
||||
android:layout_marginBottom="@dimen/preference_margin_bottom"
|
||||
android:layout_weight="1">
|
||||
|
||||
<TextView android:id="@+id/a2preference_slider_summary"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:text="Lorem ipsum dolor sit amet"
|
||||
android:maxLines="4" />
|
||||
|
||||
<LinearLayout android:id="@+id/a2preference_slider_widgets"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_below="@id/a2preference_slider_summary"
|
||||
android:layout_alignLeft="@id/a2preference_slider_summary"
|
||||
android:layout_alignStart="@id/a2preference_slider_summary"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:descendantFocusability="blocksDescendants">
|
||||
|
||||
<SeekBar
|
||||
android:id="@+id/a2preference_slider_seekBar"
|
||||
android:layout_weight="1"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/a2preference_slider_seekBarValue"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="@dimen/preference_margin"
|
||||
android:layout_marginStart="@dimen/preference_margin"
|
||||
android:gravity="center"
|
||||
android:text="0" />
|
||||
</LinearLayout>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</LinearLayout>
|
@ -28,7 +28,7 @@
|
||||
|
||||
<RadioButton
|
||||
android:layout_weight="1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/diskB"
|
||||
android:id="@+id/radioButton_diskB" />
|
||||
|
@ -2,4 +2,9 @@
|
||||
<!-- Default screen margins, per the Android Design guidelines. -->
|
||||
<dimen name="activity_horizontal_margin">16dp</dimen>
|
||||
<dimen name="activity_vertical_margin">16dp</dimen>
|
||||
<dimen name="preference_margin">6dp</dimen>
|
||||
<dimen name="preference_margin_left">15dp</dimen>
|
||||
<dimen name="preference_margin_right">6dp</dimen>
|
||||
<dimen name="preference_margin_top">6dp</dimen>
|
||||
<dimen name="preference_margin_bottom">6dp</dimen>
|
||||
</resources>
|
||||
|
@ -4,15 +4,16 @@
|
||||
<color name="black">#000000</color>
|
||||
<color name="white">#ffffff</color>
|
||||
|
||||
<string name="action_settings">Settings</string>
|
||||
<string name="app_name">Apple2ix</string>
|
||||
<string name="audio_enabled">Enable audio</string>
|
||||
<string name="audio_enabled_summary">(Unimplemented … but hopefully coming soon!)</string>
|
||||
<string name="audio_configure">Configure audio…</string>
|
||||
<string name="audio_configure_summary">Volume, mockingboard, etc</string>
|
||||
<string name="cancel">Cancel</string>
|
||||
<string name="color_bw">Black/white</string>
|
||||
<string name="color_color">Color</string>
|
||||
<string name="color_interpolated">Interpolated color</string>
|
||||
<string name="configure_joystick">Configure emulated joysticks…</string>
|
||||
<string name="configure_joystick_summary">TouchJoy axis and buttons, hitboxes, etc</string>
|
||||
<string name="configure_joystick_summary">Touch/tilt, axis and buttons, etc</string>
|
||||
<string name="configure_video">Configure video…</string>
|
||||
<string name="configure_video_summary">Color settings</string>
|
||||
<string name="diskA">Drive 1</string>
|
||||
@ -35,26 +36,35 @@
|
||||
<string name="menu_settings_summary">General, CPU, Joystick</string>
|
||||
<string name="mockingboard_disabled_title">Mockingboard disabled</string>
|
||||
<string name="mockingboard_disabled_mesg">Mockingboard could not be enabled</string>
|
||||
<string name="mockingboard_enable">Enable Mockingboard</string>
|
||||
<string name="mockingboard_enable_summary">Revision C in Slot 4/5</string>
|
||||
<string name="mockingboard_volume">Mockingboard volume</string>
|
||||
<string name="mockingboard_volume_summary">Set the Mockingboard(s) volume</string>
|
||||
<string name="no">No</string>
|
||||
<string name="ok">OK</string>
|
||||
<string name="quit">Quit emulator…</string>
|
||||
<string name="quit_summary"></string>
|
||||
<string name="quit_really">Quit emulator?</string>
|
||||
<string name="quit_warning">You will lose unsaved progress</string>
|
||||
<string name="reboot">Reboot emulator…</string>
|
||||
<string name="reboot_really">Reboot emulator?</string>
|
||||
<string name="reboot_warning">You will lose unsaved progress</string>
|
||||
<string name="reboot_summary"></string>
|
||||
<string name="reboot_warning">You will lose unsaved progress</string>
|
||||
<string name="spacer"></string>
|
||||
<string name="speaker_disabled_title">Speaker disabled</string>
|
||||
<string name="speaker_disabled_mesg">Speaker could not be enabled</string>
|
||||
<string name="speaker_enable">Enable Speaker</string>
|
||||
<string name="speaker_enable_summary">(Speaker cannot be disabled)</string>
|
||||
<string name="speaker_volume">Speaker volume</string>
|
||||
<string name="speaker_volume_summary">Set the speaker volume</string>
|
||||
<string name="speed_alt">Alternate CPU Speed</string>
|
||||
<string name="speed_cpu">CPU Speed</string>
|
||||
<string name="speed_swipe">Swipe changes emulation speed</string>
|
||||
<string name="speed_swipe_summary">Left/right swiping decreases/increases emulation speed</string>
|
||||
<string name="settings">Apple2ix emulator settings</string>
|
||||
<string name="settings_audio">Apple2ix audio settings</string>
|
||||
<string name="tab_general">General</string>
|
||||
<string name="tab_joystick">Joystick</string>
|
||||
<string name="title_activity_second">SecondActivity</string>
|
||||
<string name="action_settings">Settings</string>
|
||||
|
||||
</resources>
|
||||
|
@ -41,6 +41,8 @@ jboolean Java_org_deadc0de_apple2ix_Apple2Preferences_nativeSetSpeakerEnabled(JN
|
||||
void Java_org_deadc0de_apple2ix_Apple2Preferences_nativeSetSpeakerVolume(JNIEnv *env, jclass cls, jint goesToTen) {
|
||||
LOG("native set speaker volume : %d", goesToTen);
|
||||
assert(goesToTen >= 0);
|
||||
sound_volume = goesToTen;
|
||||
#warning FIXME TODO refactor/remove sound_volume ?
|
||||
speaker_setVolumeZeroToTen(goesToTen);
|
||||
}
|
||||
|
||||
@ -52,6 +54,7 @@ jboolean Java_org_deadc0de_apple2ix_Apple2Preferences_nativeSetMockingboardEnabl
|
||||
if (enabled) {
|
||||
MB_Initialize();
|
||||
}
|
||||
return MB_ISEnabled();
|
||||
}
|
||||
|
||||
void Java_org_deadc0de_apple2ix_Apple2Preferences_nativeSetMockingboardVolume(JNIEnv *env, jclass cls, jint goesToTen) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user