mirror of
https://github.com/mauiaaron/apple2.git
synced 2024-06-25 09:29:28 +00:00
Various improvements to disk management
- Moves disk management form Apple2Activity to Apple2DisksMenu - Handle reading/writing disk images in /sdcard/... - Manage hirerarchical navigation
This commit is contained in:
parent
2008c341d5
commit
2673777be7
|
@ -51,6 +51,10 @@ public abstract class Apple2AbstractMenu implements Apple2MenuView {
|
|||
mActivity.popApple2View(this);
|
||||
}
|
||||
|
||||
public void dismissAll() {
|
||||
this.dismiss();
|
||||
}
|
||||
|
||||
public boolean isShowing() {
|
||||
return mSettingsView.isShown();
|
||||
}
|
||||
|
|
|
@ -14,8 +14,6 @@ package org.deadc0de.apple2ix;
|
|||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Rect;
|
||||
import android.media.AudioManager;
|
||||
import android.os.Build;
|
||||
|
@ -29,19 +27,13 @@ import android.view.ViewGroup;
|
|||
import android.view.ViewTreeObserver;
|
||||
import android.widget.FrameLayout;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class Apple2Activity extends Activity {
|
||||
|
||||
private final static String TAG = "Apple2Activity";
|
||||
private final static int BUF_SZ = 4096;
|
||||
private final static int MAX_FINGERS = 32;// HACK ...
|
||||
|
||||
private String mDataDir = null;
|
||||
private boolean mSetUncaughtExceptionHandler = false;
|
||||
|
||||
private Apple2View mView = null;
|
||||
|
@ -104,70 +96,6 @@ public class Apple2Activity extends Activity {
|
|||
public native void nativeChooseDisk(String path, boolean driveA, boolean readOnly);
|
||||
|
||||
|
||||
// HACK NOTE 2015/02/22 : Apparently native code cannot easily access stuff in the APK ... so copy various resources
|
||||
// out of the APK and into the /data/data/... for ease of access. Because this is FOSS software we don't care about
|
||||
// security or DRM for these assets =)
|
||||
private String _firstTimeInitialization() {
|
||||
|
||||
String dataDir = null;
|
||||
try {
|
||||
PackageManager pm = getPackageManager();
|
||||
PackageInfo pi = pm.getPackageInfo(getPackageName(), 0);
|
||||
dataDir = pi.applicationInfo.dataDir;
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
Log.e(TAG, "" + e);
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
if (Apple2Preferences.PREFS_CONFIGURED.booleanValue(this)) {
|
||||
return dataDir;
|
||||
}
|
||||
|
||||
Log.d(TAG, "First time copying stuff-n-things out of APK for ease-of-NDK access...");
|
||||
|
||||
try {
|
||||
String[] shaders = getAssets().list("shaders");
|
||||
for (String shader : shaders) {
|
||||
_copyFile(dataDir, "shaders", shader);
|
||||
}
|
||||
String[] disks = getAssets().list("disks");
|
||||
for (String disk : disks) {
|
||||
_copyFile(dataDir, "disks", disk);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "problem copying resources : " + e);
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
Log.d(TAG, "Saving default preferences");
|
||||
Apple2Preferences.PREFS_CONFIGURED.saveBoolean(this, true);
|
||||
|
||||
return dataDir;
|
||||
}
|
||||
|
||||
private void _copyFile(String dataDir, String subdir, String assetName)
|
||||
throws IOException {
|
||||
String outputPath = dataDir + File.separator + subdir;
|
||||
Log.d(TAG, "Copying " + subdir + File.separator + assetName + " to " + outputPath + File.separator + assetName + " ...");
|
||||
new File(outputPath).mkdirs();
|
||||
|
||||
InputStream is = getAssets().open(subdir + File.separator + assetName);
|
||||
File file = new File(outputPath + File.separator + assetName);
|
||||
file.setWritable(true);
|
||||
FileOutputStream os = new FileOutputStream(file);
|
||||
|
||||
byte[] buf = new byte[BUF_SZ];
|
||||
while (true) {
|
||||
int len = is.read(buf, 0, BUF_SZ);
|
||||
if (len < 0) {
|
||||
break;
|
||||
}
|
||||
os.write(buf, 0, len);
|
||||
}
|
||||
os.flush();
|
||||
os.close();
|
||||
}
|
||||
|
||||
private void _setCustomExceptionHandler() {
|
||||
if (mSetUncaughtExceptionHandler) {
|
||||
return;
|
||||
|
@ -246,7 +174,7 @@ public class Apple2Activity extends Activity {
|
|||
Log.e(TAG, "onCreate()");
|
||||
|
||||
_setCustomExceptionHandler();
|
||||
mDataDir = _firstTimeInitialization();
|
||||
String dataDir = Apple2DisksMenu.firstTimeAssetsInitialization(this);
|
||||
|
||||
// get device audio parameters for native OpenSLES
|
||||
mSampleRate = DevicePropertyCalculator.getRecommendedSampleRate(this);
|
||||
|
@ -254,7 +182,7 @@ public class Apple2Activity extends Activity {
|
|||
mStereoBufferSize = DevicePropertyCalculator.getRecommendedBufferSize(this, /*isStereo:*/true);
|
||||
Log.d(TAG, "Device sampleRate:" + mSampleRate + " mono bufferSize:" + mMonoBufferSize + " stereo bufferSize:" + mStereoBufferSize);
|
||||
|
||||
nativeOnCreate(mDataDir, mSampleRate, mMonoBufferSize, mStereoBufferSize);
|
||||
nativeOnCreate(dataDir, mSampleRate, mMonoBufferSize, mStereoBufferSize);
|
||||
|
||||
// NOTE: load preferences after nativeOnCreate ... native CPU thread should still be paused
|
||||
Apple2Preferences.loadPreferences(this);
|
||||
|
@ -529,6 +457,19 @@ public class Apple2Activity extends Activity {
|
|||
return mMenuStack.get(lastIndex);
|
||||
}
|
||||
|
||||
public synchronized Apple2MenuView peekApple2View(int index) {
|
||||
int lastIndex = mMenuStack.size() - 1;
|
||||
if (lastIndex < 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
try {
|
||||
return mMenuStack.get(index);
|
||||
} catch (IndexOutOfBoundsException e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public void dismissAllMenus() {
|
||||
if (mMainMenu != null) {
|
||||
mMainMenu.dismiss();
|
||||
|
|
|
@ -11,73 +11,299 @@
|
|||
|
||||
package org.deadc0de.apple2ix;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Environment;
|
||||
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.Button;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.ListView;
|
||||
import android.widget.RadioButton;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FilenameFilter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
|
||||
public class Apple2DisksMenu implements Apple2MenuView {
|
||||
|
||||
private final static String TAG = "Apple2DisksMenu";
|
||||
private static String sDataDir = null;
|
||||
|
||||
private Apple2Activity mActivity = null;
|
||||
private View mDisksView = null;
|
||||
|
||||
private final ArrayList<String> mPathStack = new ArrayList<>();
|
||||
|
||||
private static File sExternalFilesDir = null;
|
||||
private static boolean sExternalStorageAvailable = false;
|
||||
private static boolean sInitializedPath = false;
|
||||
|
||||
public Apple2DisksMenu(Apple2Activity activity) {
|
||||
mActivity = activity;
|
||||
setup();
|
||||
}
|
||||
|
||||
private void setup() {
|
||||
if (!sInitializedPath) {
|
||||
sInitializedPath = true;
|
||||
Apple2Preferences.CURRENT_DISK_PATH.load(mActivity);
|
||||
}
|
||||
|
||||
LayoutInflater inflater = (LayoutInflater) mActivity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
mDisksView = inflater.inflate(R.layout.activity_disks, null, false);
|
||||
|
||||
RadioButton diskA = (RadioButton) mDisksView.findViewById(R.id.radioButton_diskA);
|
||||
diskA.setChecked(true);
|
||||
final Button cancelButton = (Button) mDisksView.findViewById(R.id.cancelButton);
|
||||
cancelButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
Apple2DisksMenu.this.mActivity.dismissAllMenus();
|
||||
}
|
||||
});
|
||||
|
||||
CheckBox readWrite = (CheckBox) mDisksView.findViewById(R.id.checkBox_readWrite);
|
||||
readWrite.setChecked(false);
|
||||
if (!sExternalStorageAvailable) {
|
||||
String storageState = Environment.getExternalStorageState();
|
||||
File externalDir = new File(Environment.getExternalStorageDirectory().getPath() + File.separator + "apple2ix"); // /sdcard/apple2ix
|
||||
sExternalFilesDir = null;
|
||||
sExternalStorageAvailable = storageState.equals(Environment.MEDIA_MOUNTED);
|
||||
if (sExternalStorageAvailable) {
|
||||
sExternalFilesDir = externalDir;
|
||||
boolean made = sExternalFilesDir.mkdirs();
|
||||
if (!made) {
|
||||
Log.d(TAG, "WARNING: could not make directory : " + sExternalFilesDir);
|
||||
}
|
||||
} else {
|
||||
sExternalStorageAvailable = storageState.equals(Environment.MEDIA_MOUNTED_READ_ONLY) && externalDir.exists();
|
||||
sExternalFilesDir = externalDir;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// HACK NOTE 2015/02/22 : Apparently native code cannot easily access stuff in the APK ... so copy various resources
|
||||
// out of the APK and into the /data/data/... for ease of access. Because this is FOSS software we don't care about
|
||||
// security or DRM for these assets =)
|
||||
public static String firstTimeAssetsInitialization(Apple2Activity activity) {
|
||||
|
||||
try {
|
||||
PackageManager pm = activity.getPackageManager();
|
||||
PackageInfo pi = pm.getPackageInfo(activity.getPackageName(), 0);
|
||||
sDataDir = pi.applicationInfo.dataDir;
|
||||
} catch (PackageManager.NameNotFoundException e) {
|
||||
Log.e(TAG, "" + e);
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
if (Apple2Preferences.ASSETS_CONFIGURED.booleanValue(activity)) {
|
||||
return sDataDir;
|
||||
}
|
||||
|
||||
Log.d(TAG, "First time copying stuff-n-things out of APK for ease-of-NDK access...");
|
||||
|
||||
try {
|
||||
String[] shaders = activity.getAssets().list("shaders");
|
||||
for (String shader : shaders) {
|
||||
Apple2DisksMenu.copyFile(activity, "shaders", shader);
|
||||
}
|
||||
String[] disks = activity.getAssets().list("disks");
|
||||
for (String disk : disks) {
|
||||
Apple2DisksMenu.copyFile(activity, "disks", disk);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.e(TAG, "problem copying resources : " + e);
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
Log.d(TAG, "Saving default preferences");
|
||||
Apple2Preferences.ASSETS_CONFIGURED.saveBoolean(activity, true);
|
||||
|
||||
return sDataDir;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// Apple2MenuView interface methods
|
||||
|
||||
public final boolean isCalibrating() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void show() {
|
||||
if (isShowing()) {
|
||||
return;
|
||||
}
|
||||
dynamicSetup();
|
||||
mActivity.pushApple2View(this);
|
||||
}
|
||||
|
||||
public void dismiss() {
|
||||
String path = popPathStack();
|
||||
if (path == null) {
|
||||
mActivity.popApple2View(this);
|
||||
} else {
|
||||
dynamicSetup();
|
||||
ListView disksList = (ListView) mDisksView.findViewById(R.id.listView_settings);
|
||||
disksList.postInvalidate();
|
||||
}
|
||||
}
|
||||
|
||||
public void dismissAll() {
|
||||
mActivity.popApple2View(this);
|
||||
}
|
||||
|
||||
public boolean isShowing() {
|
||||
return mDisksView.isShown();
|
||||
}
|
||||
|
||||
public View getView() {
|
||||
return mDisksView;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// path stack methods
|
||||
|
||||
public String getPathStackJSON() {
|
||||
JSONArray jsonArray = new JSONArray(Arrays.asList(mPathStack.toArray()));
|
||||
return jsonArray.toString();
|
||||
}
|
||||
|
||||
public void setPathStackJSON(String pathStackJSON) {
|
||||
mPathStack.clear();
|
||||
try {
|
||||
JSONArray jsonArray = new JSONArray(pathStackJSON);
|
||||
for (int i = 0, count = jsonArray.length(); i < count; i++) {
|
||||
JSONObject jsonObject = jsonArray.getJSONObject(i);
|
||||
mPathStack.add(jsonObject.toString());
|
||||
}
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void pushPathStack(String path) {
|
||||
mPathStack.add(path);
|
||||
Apple2Preferences.CURRENT_DISK_PATH.saveString(mActivity, getPathStackJSON());
|
||||
}
|
||||
|
||||
public String popPathStack() {
|
||||
if (mPathStack.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
String path = mPathStack.remove(mPathStack.size() - 1);
|
||||
Apple2Preferences.CURRENT_DISK_PATH.saveString(mActivity, getPathStackJSON());
|
||||
return path;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
// internals ...
|
||||
|
||||
private String pathStackAsDirectory() {
|
||||
if (mPathStack.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
StringBuilder pathBuffer = new StringBuilder();
|
||||
for (String component : mPathStack) {
|
||||
pathBuffer.append(component);
|
||||
pathBuffer.append(File.separator);
|
||||
}
|
||||
return pathBuffer.toString();
|
||||
}
|
||||
|
||||
private static void copyFile(Apple2Activity activity, String subdir, String assetName)
|
||||
throws IOException {
|
||||
String outputPath = sDataDir + File.separator + subdir;
|
||||
Log.d(TAG, "Copying " + subdir + File.separator + assetName + " to " + outputPath + File.separator + assetName + " ...");
|
||||
boolean made = new File(outputPath).mkdirs();
|
||||
if (!made) {
|
||||
Log.d(TAG, "WARNING, cannot mkdirs on path : " + outputPath);
|
||||
}
|
||||
|
||||
InputStream is = activity.getAssets().open(subdir + File.separator + assetName);
|
||||
File file = new File(outputPath + File.separator + assetName);
|
||||
boolean madeWriteable = file.setWritable(true);
|
||||
if (!madeWriteable) {
|
||||
Log.d(TAG, "WARNING, cannot make a copied file writeable for asset : " + assetName);
|
||||
}
|
||||
FileOutputStream os = new FileOutputStream(file);
|
||||
|
||||
final int BUF_SZ = 4096;
|
||||
byte[] buf = new byte[BUF_SZ];
|
||||
while (true) {
|
||||
int len = is.read(buf, 0, BUF_SZ);
|
||||
if (len < 0) {
|
||||
break;
|
||||
}
|
||||
os.write(buf, 0, len);
|
||||
}
|
||||
os.flush();
|
||||
os.close();
|
||||
}
|
||||
|
||||
private void dynamicSetup() {
|
||||
|
||||
final ListView disksList = (ListView)mDisksView.findViewById(R.id.listView_settings);
|
||||
final ListView disksList = (ListView) mDisksView.findViewById(R.id.listView_settings);
|
||||
disksList.setEnabled(true);
|
||||
|
||||
String dataDir = mActivity.getDataDir() + File.separator + "disks";
|
||||
File dir = new File(dataDir);
|
||||
String disksDir = pathStackAsDirectory();
|
||||
boolean isRootPath = false;
|
||||
if (disksDir == null) {
|
||||
isRootPath = true;
|
||||
disksDir = sDataDir + File.separator + "disks"; // default path
|
||||
}
|
||||
|
||||
File dir = new File(disksDir);
|
||||
|
||||
final File[] files = dir.listFiles(new FilenameFilter() {
|
||||
public boolean accept(File dir, String name) {
|
||||
name = name.toLowerCase();
|
||||
boolean acceptable = name.endsWith(".dsk") || name.endsWith(".do") || name.endsWith(".po") || name.endsWith(".nib") ||
|
||||
name.endsWith(".dsk.gz") || name.endsWith(".do.gz") || name.endsWith(".po.gz") || name.endsWith(".nib.gz");
|
||||
return acceptable;
|
||||
if (name.equalsIgnoreCase(".")) {
|
||||
return false;
|
||||
}
|
||||
if (name.equalsIgnoreCase("..")) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (name.endsWith(".dsk") || name.endsWith(".do") || name.endsWith(".po") || name.endsWith(".nib") || name.endsWith(".dsk.gz") || name.endsWith(".do.gz") || name.endsWith(".po.gz") || name.endsWith(".nib.gz")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
File file = new File(dir, name);
|
||||
return file.isDirectory();
|
||||
}
|
||||
});
|
||||
|
||||
Arrays.sort(files);
|
||||
int len = files.length;
|
||||
final String[] fileNames = new String[len];
|
||||
final boolean[] isDirectory = new boolean[len];
|
||||
|
||||
for (int i=0; i<files.length; i++) {
|
||||
File file = files[i];
|
||||
fileNames[i] = file.getName();
|
||||
isDirectory[i] = file.isDirectory();
|
||||
final boolean includeExternalStoragePath = (sExternalStorageAvailable && isRootPath);
|
||||
int idx = includeExternalStoragePath ? 1 : 0;
|
||||
final String[] fileNames = new String[files.length + idx];
|
||||
final boolean[] isDirectory = new boolean[files.length + idx];
|
||||
|
||||
if (includeExternalStoragePath) {
|
||||
fileNames[0] = sExternalFilesDir.toString();
|
||||
isDirectory[0] = true;
|
||||
}
|
||||
|
||||
for (File file : files) {
|
||||
isDirectory[idx] = file.isDirectory();
|
||||
fileNames[idx] = file.getName();
|
||||
if (isDirectory[idx]) {
|
||||
fileNames[idx] += File.separator;
|
||||
}
|
||||
++idx;
|
||||
}
|
||||
|
||||
ArrayAdapter<?> adapter = new ArrayAdapter<String>(mActivity, R.layout.a2disk, R.id.a2disk_title, fileNames) {
|
||||
|
@ -85,11 +311,12 @@ public class Apple2DisksMenu implements Apple2MenuView {
|
|||
public boolean areAllItemsEnabled() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
View view = super.getView(position, convertView, parent);
|
||||
|
||||
LinearLayout layout = (LinearLayout)view.findViewById(R.id.a2disk_widget_frame);
|
||||
LinearLayout layout = (LinearLayout) view.findViewById(R.id.a2disk_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();
|
||||
|
@ -105,43 +332,68 @@ public class Apple2DisksMenu implements Apple2MenuView {
|
|||
}
|
||||
};
|
||||
|
||||
final int offset = includeExternalStoragePath ? 1 : 0;
|
||||
disksList.setAdapter(adapter);
|
||||
disksList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
public void onItemClick(AdapterView<?> parent, View view, final int position, long id) {
|
||||
if (isDirectory[position]) {
|
||||
// TODO FIXME ...
|
||||
Log.d(TAG, "Descending to path : " + fileNames[position]);
|
||||
pushPathStack(fileNames[position]);
|
||||
dynamicSetup();
|
||||
ListView disksList = (ListView) mDisksView.findViewById(R.id.listView_settings);
|
||||
disksList.postInvalidate();
|
||||
} else {
|
||||
RadioButton diskA = (RadioButton) mDisksView.findViewById(R.id.radioButton_diskA);
|
||||
CheckBox readWrite = (CheckBox) mDisksView.findViewById(R.id.checkBox_readWrite);
|
||||
Apple2DisksMenu.this.dismiss();
|
||||
mActivity.nativeChooseDisk(files[position].getAbsolutePath(), diskA.isChecked(), !readWrite.isChecked());
|
||||
String title = mActivity.getResources().getString(R.string.header_disks);
|
||||
title = title + " " + fileNames[position];
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(mActivity).setCancelable(true).setMessage(title);
|
||||
LayoutInflater inflater = (LayoutInflater) mActivity.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
final View diskConfirmationView = inflater.inflate(R.layout.a2disk_confirmation, null, false);
|
||||
builder.setView(diskConfirmationView);
|
||||
|
||||
final RadioButton diskA = (RadioButton) diskConfirmationView.findViewById(R.id.radioButton_diskA);
|
||||
diskA.setChecked(Apple2Preferences.CURRENT_DISK_A.booleanValue(mActivity));
|
||||
diskA.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||
Apple2Preferences.CURRENT_DISK_A.saveBoolean(mActivity, isChecked);
|
||||
}
|
||||
});
|
||||
final RadioButton diskB = (RadioButton) diskConfirmationView.findViewById(R.id.radioButton_diskB);
|
||||
diskB.setChecked(!Apple2Preferences.CURRENT_DISK_A.booleanValue(mActivity));
|
||||
|
||||
|
||||
final RadioButton readOnly = (RadioButton) diskConfirmationView.findViewById(R.id.radioButton_readOnly);
|
||||
readOnly.setChecked(Apple2Preferences.CURRENT_DISK_RO.booleanValue(mActivity));
|
||||
readOnly.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||
Apple2Preferences.CURRENT_DISK_RO.saveBoolean(mActivity, isChecked);
|
||||
}
|
||||
});
|
||||
|
||||
final RadioButton readWrite = (RadioButton) diskConfirmationView.findViewById(R.id.radioButton_readWrite);
|
||||
readWrite.setChecked(!Apple2Preferences.CURRENT_DISK_RO.booleanValue(mActivity));
|
||||
|
||||
builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
dialog.dismiss();
|
||||
mActivity.dismissAllMenus();
|
||||
mActivity.nativeChooseDisk(files[position - offset].getAbsolutePath(), diskA.isChecked(), readOnly.isChecked());
|
||||
}
|
||||
});
|
||||
|
||||
builder.show();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public final boolean isCalibrating() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void show() {
|
||||
if (isShowing()) {
|
||||
return;
|
||||
}
|
||||
dynamicSetup();
|
||||
mActivity.pushApple2View(this);
|
||||
}
|
||||
|
||||
public void dismiss() {
|
||||
mActivity.popApple2View(this);
|
||||
}
|
||||
|
||||
public boolean isShowing() {
|
||||
return mDisksView.isShown();
|
||||
}
|
||||
|
||||
public View getView() {
|
||||
return mDisksView;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -87,7 +87,9 @@ public class Apple2JoystickCalibration implements Apple2MenuView {
|
|||
|
||||
public void dismiss() {
|
||||
for (Apple2MenuView apple2MenuView : mViewStack) {
|
||||
mActivity.pushApple2View(apple2MenuView);
|
||||
if (apple2MenuView != this) {
|
||||
mActivity.pushApple2View(apple2MenuView);
|
||||
}
|
||||
}
|
||||
|
||||
Apple2Preferences.nativeSetTouchMenuEnabled(mTouchMenuEnabled);
|
||||
|
@ -97,6 +99,10 @@ public class Apple2JoystickCalibration implements Apple2MenuView {
|
|||
mActivity.popApple2View(this);
|
||||
}
|
||||
|
||||
public void dismissAll() {
|
||||
dismiss();
|
||||
}
|
||||
|
||||
public boolean isShowing() {
|
||||
return mSettingsView.isShown();
|
||||
}
|
||||
|
|
|
@ -210,7 +210,7 @@ public class Apple2JoystickSettingsMenu extends Apple2AbstractMenu {
|
|||
|
||||
@Override
|
||||
public void handleSelection(Apple2Activity activity, Apple2AbstractMenu settingsMenu, boolean isChecked) {
|
||||
ArrayList<Apple2MenuView> viewStack = new ArrayList<Apple2MenuView>();
|
||||
ArrayList<Apple2MenuView> viewStack = new ArrayList<>();
|
||||
{
|
||||
int idx = 0;
|
||||
while (true) {
|
||||
|
|
|
@ -63,7 +63,28 @@ public class Apple2KeypadSettingsMenu extends Apple2AbstractMenu {
|
|||
|
||||
@Override
|
||||
public void handleSelection(final Apple2Activity activity, final Apple2AbstractMenu settingsMenu, boolean isChecked) {
|
||||
//new Apple2KeypadChooser(activity).show();
|
||||
ArrayList<Apple2MenuView> viewStack = new ArrayList<>();
|
||||
{
|
||||
int idx = 0;
|
||||
while (true) {
|
||||
Apple2MenuView apple2MenuView = activity.peekApple2View(idx);
|
||||
if (apple2MenuView == null) {
|
||||
break;
|
||||
}
|
||||
viewStack.add(apple2MenuView);
|
||||
++idx;
|
||||
}
|
||||
}
|
||||
|
||||
Apple2KeypadChooser chooser = new Apple2KeypadChooser(activity, viewStack);
|
||||
|
||||
// show this new view...
|
||||
chooser.show();
|
||||
|
||||
// ...with nothing else underneath 'cept the emulator OpenGL layer
|
||||
for (Apple2MenuView apple2MenuView : viewStack) {
|
||||
activity.popApple2View(apple2MenuView);
|
||||
}
|
||||
}
|
||||
},
|
||||
KEYPAD_CALIBRATE {
|
||||
|
@ -79,7 +100,7 @@ public class Apple2KeypadSettingsMenu extends Apple2AbstractMenu {
|
|||
|
||||
@Override
|
||||
public void handleSelection(Apple2Activity activity, Apple2AbstractMenu settingsMenu, boolean isChecked) {
|
||||
ArrayList<Apple2MenuView> viewStack = new ArrayList<Apple2MenuView>();
|
||||
ArrayList<Apple2MenuView> viewStack = new ArrayList<>();
|
||||
{
|
||||
int idx = 0;
|
||||
while (true) {
|
||||
|
|
|
@ -21,6 +21,8 @@ public interface Apple2MenuView {
|
|||
|
||||
public void dismiss();
|
||||
|
||||
public void dismissAll();
|
||||
|
||||
public View getView();
|
||||
|
||||
public boolean isCalibrating();
|
||||
|
|
|
@ -14,9 +14,12 @@ package org.deadc0de.apple2ix;
|
|||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public enum Apple2Preferences {
|
||||
PREFS_CONFIGURED {
|
||||
ASSETS_CONFIGURED {
|
||||
@Override
|
||||
public void load(Apple2Activity activity) {
|
||||
// ...
|
||||
|
@ -27,6 +30,60 @@ public enum Apple2Preferences {
|
|||
activity.getPreferences(Context.MODE_PRIVATE).edit().putBoolean(toString(), true).apply();
|
||||
}
|
||||
},
|
||||
CURRENT_DISK_PATH {
|
||||
@Override
|
||||
public void load(final Apple2Activity activity) {
|
||||
Apple2MainMenu mainMenu = activity.getMainMenu();
|
||||
if (mainMenu != null) {
|
||||
mainMenu.getDisksMenu().setPathStackJSON(stringValue(activity));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String stringValue(Apple2Activity activity) {
|
||||
return activity.getPreferences(Context.MODE_PRIVATE).getString(toString(), "[]");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveString(Apple2Activity activity, String value) {
|
||||
activity.getPreferences(Context.MODE_PRIVATE).edit().putString(toString(), value).apply();
|
||||
//load(activity);
|
||||
}
|
||||
},
|
||||
CURRENT_DISK_A {
|
||||
@Override
|
||||
public void load(final Apple2Activity activity) {
|
||||
/* ... */
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean booleanValue(Apple2Activity activity) {
|
||||
return activity.getPreferences(Context.MODE_PRIVATE).getBoolean(toString(), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveBoolean(Apple2Activity activity, boolean value) {
|
||||
activity.getPreferences(Context.MODE_PRIVATE).edit().putBoolean(toString(), value).apply();
|
||||
//load(activity);
|
||||
}
|
||||
},
|
||||
CURRENT_DISK_RO {
|
||||
@Override
|
||||
public void load(final Apple2Activity activity) {
|
||||
/* ... */
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean booleanValue(Apple2Activity activity) {
|
||||
return activity.getPreferences(Context.MODE_PRIVATE).getBoolean(toString(), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveBoolean(Apple2Activity activity, boolean value) {
|
||||
activity.getPreferences(Context.MODE_PRIVATE).edit().putBoolean(toString(), value).apply();
|
||||
//load(activity);
|
||||
}
|
||||
},
|
||||
CPU_SPEED_PERCENT {
|
||||
@Override
|
||||
public void load(Apple2Activity activity) {
|
||||
|
@ -368,6 +425,11 @@ public enum Apple2Preferences {
|
|||
throw new RuntimeException("DENIED! You're doing it wrong! =P");
|
||||
}
|
||||
|
||||
public void saveString(Apple2Activity activity, String value) {
|
||||
activity.getPreferences(Context.MODE_PRIVATE).edit().putString(toString(), value).apply();
|
||||
load(activity);
|
||||
}
|
||||
|
||||
public void saveHiresColor(Apple2Activity activity, HiresColor value) {
|
||||
activity.getPreferences(Context.MODE_PRIVATE).edit().putInt(toString(), value.ordinal()).apply();
|
||||
load(activity);
|
||||
|
@ -402,6 +464,10 @@ public enum Apple2Preferences {
|
|||
return (float) activity.getPreferences(Context.MODE_PRIVATE).getInt(toString(), 0);
|
||||
}
|
||||
|
||||
public String stringValue(Apple2Activity activity) {
|
||||
return activity.getPreferences(Context.MODE_PRIVATE).getString(toString(), null);
|
||||
}
|
||||
|
||||
public static void loadPreferences(Apple2Activity activity) {
|
||||
for (Apple2Preferences pref : Apple2Preferences.values()) {
|
||||
pref.load(activity);
|
||||
|
|
|
@ -68,6 +68,10 @@ public class Apple2SplashScreen implements Apple2MenuView {
|
|||
mActivity.popApple2View(this);
|
||||
}
|
||||
|
||||
public void dismissAll() {
|
||||
dismiss();
|
||||
}
|
||||
|
||||
public boolean isShowing() {
|
||||
return mSettingsView.isShown();
|
||||
}
|
||||
|
|
51
Android/app/src/main/res/layout/a2disk_confirmation.xml
Normal file
51
Android/app/src/main/res/layout/a2disk_confirmation.xml
Normal file
|
@ -0,0 +1,51 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:background="@color/black"
|
||||
android:baselineAligned="false"
|
||||
android:orientation="vertical">
|
||||
|
||||
<RadioGroup
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/radioButton_diskA"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/diskA" />
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/radioButton_diskB"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/diskB" />
|
||||
|
||||
</RadioGroup>
|
||||
|
||||
<RadioGroup
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/radioButton_readOnly"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/disk_read_only" />
|
||||
|
||||
<RadioButton
|
||||
android:id="@+id/radioButton_readWrite"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:text="@string/disk_read_write" />
|
||||
|
||||
</RadioGroup>
|
||||
|
||||
</LinearLayout>
|
|
@ -6,39 +6,30 @@
|
|||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent" >
|
||||
|
||||
<TextView
|
||||
android:id="@+id/header_disks"
|
||||
style="?android:attr/listSeparatorTextViewStyle"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/header_disks" />
|
||||
|
||||
<RadioGroup
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
<LinearLayout
|
||||
android:background="@color/black"
|
||||
android:orientation="horizontal"
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
android:baselineAligned="false"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content" >
|
||||
|
||||
<RadioButton
|
||||
<TextView
|
||||
android:id="@+id/header_disks"
|
||||
style="?android:attr/listSeparatorTextViewStyle"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_weight="1"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/diskA"
|
||||
android:id="@+id/radioButton_diskA" />
|
||||
android:text="@string/header_disks" />
|
||||
|
||||
<RadioButton
|
||||
android:layout_weight="1"
|
||||
<Button
|
||||
style="?android:attr/buttonStyleSmall"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/diskB"
|
||||
android:id="@+id/radioButton_diskB" />
|
||||
android:drawableLeft="@android:drawable/ic_menu_close_clear_cancel"
|
||||
android:drawableStart="@android:drawable/ic_menu_close_clear_cancel"
|
||||
android:id="@+id/cancelButton" />
|
||||
|
||||
<CheckBox
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/disk_read_write"
|
||||
android:id="@+id/checkBox_readWrite" />
|
||||
</RadioGroup>
|
||||
</LinearLayout>
|
||||
|
||||
<ListView
|
||||
android:layout_width="fill_parent"
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
<string name="color_interpolated">Interpolated color</string>
|
||||
<string name="diskA">Drive 1</string>
|
||||
<string name="diskB">Drive 2</string>
|
||||
<string name="disk_read_only">Read only</string>
|
||||
<string name="disk_read_write">Read/write</string>
|
||||
<string name="emulation_continue">Continue…</string>
|
||||
<string name="emulation_preferences">Preferences…</string>
|
||||
|
|
Loading…
Reference in New Issue
Block a user