A more visually-pleasing and functional main menu on Android

This commit is contained in:
Aaron Culliney
2015-03-11 14:42:57 -07:00
parent 2965afe12e
commit 91e7136b8f
4 changed files with 116 additions and 33 deletions

View File

@@ -12,7 +12,9 @@
package org.deadc0de.apple2ix;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
@@ -47,6 +49,8 @@ public class Apple2Activity extends Activity {
private native void nativeOnCreate(String dataDir);
public native void nativeOnResume();
public native void nativeOnPause();
public native void nativeOnQuit();
public native void nativeReboot();
private native void nativeGraphicsInitialized(int width, int height);
private native void nativeGraphicsChanged(int width, int height);
public native void nativeRender();
@@ -170,6 +174,9 @@ public class Apple2Activity extends Activity {
@Override
public boolean onKeyUp(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
maybeQuitApp();
}
nativeOnKeyUp(keyCode, event.getMetaState());
return true;
}
@@ -197,4 +204,30 @@ public class Apple2Activity extends Activity {
public boolean isSoftKeyboardShowing() {
return mSoftKeyboardShowing;
}
public void maybeQuitApp() {
nativeOnPause();
AlertDialog dialog = new AlertDialog.Builder(this).setCancelable(true).setMessage("Quit Apple2ix?").setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
nativeOnQuit();
}
}).setNegativeButton("No", null).create();
dialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
nativeOnResume();
}
});
dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
nativeOnResume();
}
});
dialog.show();
}
}

View File

@@ -12,6 +12,8 @@
package org.deadc0de.apple2ix;
import android.content.Context;
import android.graphics.drawable.BitmapDrawable;
import android.os.Build;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
@@ -70,20 +72,34 @@ public class Apple2MainMenu {
}
});
// WTF ... is there an easier way to dynamically calculate these dimensions?
int totalHeight = 0;
int maxWidth = 0;
for (int i=0; i<adapter.getCount(); i++) {
View view = adapter.getView(i, null, mainMenuView);
view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
totalHeight += view.getMeasuredHeight();
int width = view.getMeasuredWidth();
if (width > maxWidth) {
maxWidth = width;
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.GINGERBREAD_MR1) {
mMainMenuPopup = new PopupWindow(mainPopupContainer, android.app.ActionBar.LayoutParams.WRAP_CONTENT, android.app.ActionBar.LayoutParams.WRAP_CONTENT, true);
} else {
// 2015/03/11 ... there may well be a less hackish way to support Gingerbread, but eh ... diminishing returns
final int TOTAL_MARGINS = 16;
int totalHeight = TOTAL_MARGINS;
int maxWidth = 0;
for (int i = 0; i < adapter.getCount(); i++) {
View view = adapter.getView(i, null, mainMenuView);
view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED), View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
totalHeight += view.getMeasuredHeight();
int width = view.getMeasuredWidth();
if (width > maxWidth) {
maxWidth = width;
}
}
mMainMenuPopup = new PopupWindow(mainPopupContainer, maxWidth+TOTAL_MARGINS, totalHeight, true);
}
mMainMenuPopup = new PopupWindow(mainPopupContainer, maxWidth+MENU_INSET, totalHeight+MENU_INSET, true);
// This kludgery allows touching the outside or back-buttoning to dismiss
mMainMenuPopup.setBackgroundDrawable(new BitmapDrawable());
mMainMenuPopup.setOutsideTouchable(true);
mMainMenuPopup.setOnDismissListener(new PopupWindow.OnDismissListener() {
@Override
public void onDismiss() {
Apple2MainMenu.this.mActivity.nativeOnResume();
}
});
}
public void showDisksMenu() {
@@ -94,10 +110,6 @@ public class Apple2MainMenu {
Log.d(TAG, "showSettings...");
}
public void quitEmulator() {
}
public void show() {
if (mMainMenuPopup.isShowing()) {
return;
@@ -105,23 +117,15 @@ public class Apple2MainMenu {
mActivity.nativeOnPause();
int x = (mActivity.getWidth()-mMainMenuPopup.getWidth())/2;
int y = (mActivity.getHeight()-mMainMenuPopup.getHeight())/2;
mMainMenuPopup.showAtLocation(mParentView, Gravity.NO_GRAVITY, x, y);
mMainMenuPopup.showAtLocation(mParentView, Gravity.CENTER, 0, 0);
}
public void dismiss() {
if (mMainMenuPopup.isShowing()) {
mActivity.nativeOnResume();
mMainMenuPopup.dismiss();
}
}
public void androidBackButton() {
dismiss();
}
public boolean isShowing() {
return mMainMenuPopup.isShowing();
}

View File

@@ -1,14 +1,27 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/main_popup_container"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_centerInParent="true"
android:background="@color/black"
android:orientation="vertical" >
<ListView
android:id="@+id/main_popup_menu"
android:background="@color/black"
android:background="@android:color/background_light"
android:orientation="vertical">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_width="wrap_content">
</ListView>
android:orientation="vertical"
android:layout_margin="2dp"
android:background="@android:color/darker_gray">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical"
android:layout_margin="2dp">
<ListView
android:id="@+id/main_popup_menu"
android:background="@color/black"
android:layout_height="fill_parent"
android:layout_width="fill_parent">
</ListView>
</LinearLayout>
</LinearLayout>
</LinearLayout>

View File

@@ -14,6 +14,8 @@
#include "video/renderer.h"
#include "androidkeys.h"
static bool nativePaused = false;
void Java_org_deadc0de_apple2ix_Apple2Activity_nativeOnCreate(JNIEnv *env, jobject obj, jstring j_dataDir) {
const char *dataDir = (*env)->GetStringUTFChars(env, j_dataDir, 0);
data_dir = strdup(dataDir);
@@ -60,16 +62,27 @@ void Java_org_deadc0de_apple2ix_Apple2Activity_nativeGraphicsInitialized(JNIEnv
}
void Java_org_deadc0de_apple2ix_Apple2Activity_nativeOnResume(JNIEnv *env, jobject obj) {
if (!nativePaused) {
return;
}
nativePaused = false;
LOG("%s", "native onResume...");
pthread_mutex_unlock(&interface_mutex);
}
void Java_org_deadc0de_apple2ix_Apple2Activity_nativeOnPause(JNIEnv *env, jobject obj) {
if (nativePaused) {
return;
}
nativePaused = true;
LOG("%s", "native onPause...");
pthread_mutex_lock(&interface_mutex);
}
void Java_org_deadc0de_apple2ix_Apple2Activity_nativeRender(JNIEnv *env, jobject obj) {
if (nativePaused) {
return;
}
c_keys_handle_input(-1, 0, 0);
#if FPS_LOG
@@ -94,6 +107,26 @@ void Java_org_deadc0de_apple2ix_Apple2Activity_nativeRender(JNIEnv *env, jobject
video_driver_render();
}
void Java_org_deadc0de_apple2ix_Apple2Activity_nativeReboot(JNIEnv *env, jobject obj) {
LOG("%s", "native reboot...");
cpu65_reboot();
}
void Java_org_deadc0de_apple2ix_Apple2Activity_nativeOnQuit(JNIEnv *env, jobject obj) {
LOG("%s", "native quit...");
c_eject_6(0);
c_eject_6(1);
#ifdef AUDIO_ENABLED
speaker_destroy();
MB_Destroy();
#endif
video_shutdown();
exit(0);
}
void Java_org_deadc0de_apple2ix_Apple2Activity_nativeOnKeyDown(JNIEnv *env, jobject obj, jint keyCode, jint metaState) {
#if !TESTING
android_keycode_to_emulator(keyCode, metaState, true);