From 7f582a107b959343e532e08fb481d477a70bfacc Mon Sep 17 00:00:00 2001 From: pelya Date: Thu, 4 Nov 2010 19:01:23 +0200 Subject: [PATCH] Added QWERTY on-screen keyboard input, using built-in Android virtual keyboard and EditText widget --- ChangeAppSettings.sh | 3 +- bugs.txt | 13 +-- project/java/EditableSurfaceView.java | 69 ------------ project/java/MainActivity.java | 106 +++++++++++++++++- project/java/Settings.java | 9 +- project/java/Video.java | 27 ++++- project/jni/application/src | 2 +- .../jni/sdl-1.3/include/SDL_screenkeyboard.h | 5 +- .../src/video/android/SDL_androidinput.c | 30 ++++- .../src/video/android/SDL_androidinput.h | 6 + .../src/video/android/SDL_androidvideo.c | 13 +++ .../src/video/android/SDL_androidvideo.h | 1 + .../video/android/SDL_touchscreenkeyboard.c | 67 ++++++++--- 13 files changed, 239 insertions(+), 112 deletions(-) delete mode 100644 project/java/EditableSurfaceView.java diff --git a/ChangeAppSettings.sh b/ChangeAppSettings.sh index 775b62cc3..c22ca39aa 100755 --- a/ChangeAppSettings.sh +++ b/ChangeAppSettings.sh @@ -160,8 +160,9 @@ fi fi if [ -z "$RedefinedKeys" -o -z "$AUTO" ]; then -echo -n "\nRedefine common keys to SDL keysyms: TOUCHSCREEN SEARCH/CALL/DPAD_CENTER VOLUMEUP VOLUMEDOWN MENU BACK CAMERA ENTER DEL" +echo -n "\nRedefine common keys to SDL keysyms: TOUCHSCREEN DPAD_CENTER VOLUMEUP VOLUMEDOWN MENU BACK CAMERA ENTER DEL SEARCH CALL" echo -n "\nMENU and BACK hardware keys and TOUCHSCREEN virtual 'key' are available on all devices, other keys may be absent" +echo -n "\nSEARCH and CALL by default return same keycode as DPAD_CENTER - one of those keys is available on most devices" echo -n "\nThe same key values are used if touchscreen keyboard is enabled, except for MENU and BACK\n($RedefinedKeys)\n: " read var if [ -n "$var" ] ; then diff --git a/bugs.txt b/bugs.txt index ea4c94c23..29bd68ce7 100644 --- a/bugs.txt +++ b/bugs.txt @@ -5,8 +5,6 @@ Known bugs - Fix on-screen keyboard, add more keys and more options, possibility to create custom key layout. -- Add full QWERTY on-screen keyboard. - - Export phone vibrator to SDL - interface is available in SDL 1.3 - HDMI output (HTC Evo and Samsung Epic support that): @@ -24,6 +22,12 @@ UQM gives 5 FPS without such hacks, if I'll implement that FPS will drop to 1-2 plus VideoView will contain some buffer to ensure the playback is smooth, so the data on your TV will lag halfsecond behind the data on the device screen. +- Add a user option to keep aspect ratio of screen (not compile-time option which is already available) + +- Add an option for overlay buttons transparency and button images size. + +- Somehow make this port into main libSDL repository + - OpenTyrian: 1. Navigating game menus downwards with trackball skips events, that does not happen when navigting upwards. @@ -35,8 +39,3 @@ so the data on your TV will lag halfsecond behind the data on the device screen. 2. Add accelerated GFX (even at the cost of GFX bugs, if Melee will work smoothly). 3. Add proper netplay with masterserver and server list instead of "Enter host IP here" dialog. -- Add an option to keep aspect ratio of screen - -- Add an option for overlay buttons transparency. - -- Somehow make this port into main libSDL repository diff --git a/project/java/EditableSurfaceView.java b/project/java/EditableSurfaceView.java deleted file mode 100644 index e22bf593c..000000000 --- a/project/java/EditableSurfaceView.java +++ /dev/null @@ -1,69 +0,0 @@ -// EditableSurfaceView by Angus Lees, taken from ScummVM - -package org.inodes.gus.scummvm; - -import android.content.Context; -import android.text.InputType; -import android.util.AttributeSet; -import android.view.SurfaceView; -import android.view.inputmethod.BaseInputConnection; -import android.view.inputmethod.EditorInfo; -import android.view.inputmethod.InputConnection; -import android.view.inputmethod.InputMethodManager; -import android.view.KeyEvent; - -public class EditableSurfaceView extends SurfaceView { - public EditableSurfaceView(Context context) { - super(context); - } - - public EditableSurfaceView(Context context, AttributeSet attrs) { - super(context, attrs); - } - - public EditableSurfaceView(Context context, AttributeSet attrs, - int defStyle) { - super(context, attrs, defStyle); - } - - @Override - public boolean onCheckIsTextEditor() { - return true; - } - - private class MyInputConnection extends BaseInputConnection { - public MyInputConnection() { - super(EditableSurfaceView.this, false); - } - - @Override - public boolean performEditorAction(int actionCode) { - if (actionCode == EditorInfo.IME_ACTION_DONE) { - InputMethodManager imm = (InputMethodManager) - getContext().getSystemService(Context.INPUT_METHOD_SERVICE); - imm.hideSoftInputFromWindow(getWindowToken(), 0); - } - return super.performEditorAction(actionCode); // Sends enter key - } - - @Override - public boolean sendKeyEvent(KeyEvent event) - { - System.out.println("SDL: MyInputConnection: got key " + event.toString() ); - return true; - } - } - - @Override - public InputConnection onCreateInputConnection(EditorInfo outAttrs) { - outAttrs.initialCapsMode = 0; - outAttrs.initialSelEnd = outAttrs.initialSelStart = -1; - outAttrs.inputType = (InputType.TYPE_CLASS_TEXT | - InputType.TYPE_TEXT_VARIATION_NORMAL | - InputType.TYPE_TEXT_FLAG_AUTO_COMPLETE); - outAttrs.imeOptions = (EditorInfo.IME_ACTION_DONE | - EditorInfo.IME_FLAG_NO_EXTRACT_UI); - - return new MyInputConnection(); - } -} diff --git a/project/java/MainActivity.java b/project/java/MainActivity.java index c987e0138..333d08bb6 100644 --- a/project/java/MainActivity.java +++ b/project/java/MainActivity.java @@ -11,10 +11,19 @@ import android.view.WindowManager; import android.view.View; import android.view.ViewGroup; import android.widget.TextView; +import android.widget.EditText; +import android.text.Editable; import android.widget.Button; import android.widget.ImageView; import android.widget.LinearLayout; +import android.widget.FrameLayout; import android.content.res.Configuration; +import android.app.Notification; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.Intent; +import android.view.View.OnKeyListener; + public class MainActivity extends Activity { @@ -140,7 +149,9 @@ public class MainActivity extends Activity { getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); mGLView = new DemoGLSurfaceView(this); - setContentView(mGLView); + _videoLayout = new FrameLayout(this); + _videoLayout.addView(mGLView); + setContentView(_videoLayout); // Receive keyboard events mGLView.setFocusableInTouchMode(true); mGLView.setFocusable(true); @@ -188,9 +199,55 @@ public class MainActivity extends Activity { System.exit(0); } + public void hideScreenKeyboard() + { + if(_screenKeyboard == null) + return; + String text = _screenKeyboard.getText().toString(); + for(int i = 0; i < text.length(); i++) + { + if( mGLView != null ) + mGLView.nativeTextInput( text.charAt(i), text.codePointAt(i) ); + } + _videoLayout.removeView(_screenKeyboard); + _screenKeyboard = null; + mGLView.setFocusableInTouchMode(true); + mGLView.setFocusable(true); + mGLView.requestFocus(); + }; + + public void showScreenKeyboard() + { + if(_screenKeyboard != null) + return; + class myKeyListener implements OnKeyListener + { + MainActivity _parent; + myKeyListener(MainActivity parent) { _parent = parent; }; + public boolean onKey(View v, int keyCode, KeyEvent event) + { + if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) + { + _parent.hideScreenKeyboard(); + return true; + } + return false; + } + }; + _screenKeyboard = new EditText(this); + _screenKeyboard.setOnKeyListener(new myKeyListener(this)); + _videoLayout.addView(_screenKeyboard); + _screenKeyboard.setFocusableInTouchMode(true); + _screenKeyboard.setFocusable(true); + _screenKeyboard.requestFocus(); + }; + @Override public boolean onKeyDown(int keyCode, final KeyEvent event) { // Overrides Back key to use in our app + if(_screenKeyboard != null) + _screenKeyboard.onKeyDown(keyCode, event); + else if( mGLView != null ) mGLView.nativeKey( keyCode, 1 ); else @@ -206,16 +263,27 @@ public class MainActivity extends Activity { @Override public boolean onKeyUp(int keyCode, final KeyEvent event) { - if( mGLView != null ) - mGLView.nativeKey( keyCode, 0 ); - return true; + if(_screenKeyboard != null) + _screenKeyboard.onKeyUp(keyCode, event); + else + if( mGLView != null ) + mGLView.nativeKey( keyCode, 0 ); + return true; } @Override public boolean dispatchTouchEvent(final MotionEvent ev) { + // ----- DEBUG ----- + //if( ev.getX() < 200.0 && ev.getY() < 50.0 && ev.getAction() == MotionEvent.ACTION_DOWN ) + // showScreenKeyboard(); + // ----- DEBUG ----- + if(_screenKeyboard != null) + _screenKeyboard.dispatchTouchEvent(ev); + else if(mGLView != null) mGLView.onTouchEvent(ev); - else if( _btn != null ) + else + if( _btn != null ) return _btn.dispatchTouchEvent(ev); return true; } @@ -244,14 +312,42 @@ public class MainActivity extends Activity { this.runOnUiThread(cb); } + public void showTaskbarNotification() + { + showTaskbarNotification("SDL application paused", "SDL application", "Application is paused, click to activate"); + } + + // Stolen from SDL port by Mamaich + public void showTaskbarNotification(String text0, String text1, String text2) + { + NotificationManager NotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + Intent intent = new Intent(this, MainActivity.class); + PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, Intent.FLAG_ACTIVITY_NEW_TASK); + Notification n = new Notification(R.drawable.icon, text0, System.currentTimeMillis()); + n.setLatestEventInfo(this, text1, text2, pendingIntent); + NotificationManager.notify(NOTIFY_ID, n); + } + + public void hideTaskbarNotification() + { + NotificationManager NotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + NotificationManager.cancel(NOTIFY_ID); + } + + static int NOTIFY_ID = 12367098; // Random ID + private static DemoGLSurfaceView mGLView = null; private static LoadLibrary mLoadLibraryStub = null; private static AudioThread mAudioThread = null; private static DataDownloader downloader = null; + private TextView _tv = null; private Button _btn = null; private LinearLayout _layout = null; private LinearLayout _layout2 = null; + + private FrameLayout _videoLayout = null; + private EditText _screenKeyboard = null; private boolean sdlInited = false; } diff --git a/project/java/Settings.java b/project/java/Settings.java index 07a1ddf37..49813c3f1 100644 --- a/project/java/Settings.java +++ b/project/java/Settings.java @@ -465,10 +465,11 @@ class Settings if( Globals.UseTouchscreenKeyboard ) { nativeSetTouchscreenKeyboardUsed(); - nativeSetupScreenKeyboard( Globals.TouchscreenKeyboardSize, + nativeSetupScreenKeyboard( Globals.TouchscreenKeyboardSize, Globals.TouchscreenKeyboardTheme, - Globals.AppTouchscreenKeyboardKeysAmount, - Globals.AppTouchscreenKeyboardKeysAmountAutoFire); + Globals.AppTouchscreenKeyboardKeysAmount, + Globals.AppTouchscreenKeyboardKeysAmountAutoFire, + 1, 1); } SetupTouchscreenKeyboardGraphics(p); String lang = new String(Locale.getDefault().getLanguage()); @@ -516,7 +517,7 @@ class Settings private static native void nativeSetJoystickUsed(); private static native void nativeSetMultitouchUsed(); private static native void nativeSetTouchscreenKeyboardUsed(); - private static native void nativeSetupScreenKeyboard(int size, int theme, int nbuttons, int nbuttonsAutoFire); + private static native void nativeSetupScreenKeyboard(int size, int theme, int nbuttons, int nbuttonsAutoFire, int showArrows, int showTextInput); private static native void nativeSetupScreenKeyboardButtons(byte[] img); public static native void nativeSetEnv(final String name, final String value); } diff --git a/project/java/Video.java b/project/java/Video.java index bed3c5982..ce4905f4b 100644 --- a/project/java/Video.java +++ b/project/java/Video.java @@ -173,7 +173,7 @@ abstract class DifferentTouchInput class DemoRenderer extends GLSurfaceView_SDL.Renderer { - public DemoRenderer(Activity _context) + public DemoRenderer(MainActivity _context) { context = _context; } @@ -228,6 +228,22 @@ class DemoRenderer extends GLSurfaceView_SDL.Renderer { return 1; } + public void showScreenKeyboard() // Called from native code + { + class Callback implements Runnable + { + public MainActivity parent; + public void run() + { + parent.showScreenKeyboard(); + } + } + Callback cb = new Callback(); + cb.parent = context; + context.runOnUiThread(cb); + //context.showScreenKeyboard(); + } + public void exitApp() { nativeDone(); }; @@ -239,7 +255,7 @@ class DemoRenderer extends GLSurfaceView_SDL.Renderer { private native void nativeGlContextLost(); public native void nativeGlContextRecreated(); - private Activity context = null; + private MainActivity context = null; private AccelerometerReader accelerometer = null; private EGL10 mEgl = null; @@ -253,7 +269,7 @@ class DemoRenderer extends GLSurfaceView_SDL.Renderer { } class DemoGLSurfaceView extends GLSurfaceView_SDL { - public DemoGLSurfaceView(Activity context) { + public DemoGLSurfaceView(MainActivity context) { super(context); mParent = context; touchInput = DifferentTouchInput.getInstance(); @@ -306,11 +322,14 @@ class DemoGLSurfaceView extends GLSurfaceView_SDL { } DemoRenderer mRenderer; - Activity mParent; + MainActivity mParent; DifferentTouchInput touchInput = null; public static native void nativeMouse( int x, int y, int action, int pointerId, int pressure, int radius ); public static native void nativeKey( int keyCode, int down ); + public static native void nativeTextInput( int ascii, int unicode ); + public static native void initJavaCallbacks(); + } diff --git a/project/jni/application/src b/project/jni/application/src index f36c75d23..57d37d935 120000 --- a/project/jni/application/src +++ b/project/jni/application/src @@ -1 +1 @@ -scummvm \ No newline at end of file +pachi \ No newline at end of file diff --git a/project/jni/sdl-1.3/include/SDL_screenkeyboard.h b/project/jni/sdl-1.3/include/SDL_screenkeyboard.h index 5ce68e369..d3a4474fa 100644 --- a/project/jni/sdl-1.3/include/SDL_screenkeyboard.h +++ b/project/jni/sdl-1.3/include/SDL_screenkeyboard.h @@ -46,7 +46,7 @@ enum { SDL_ANDRIOD_SCREENKEYBOARD_BUTTON_3, SDL_ANDRIOD_SCREENKEYBOARD_BUTTON_4, SDL_ANDRIOD_SCREENKEYBOARD_BUTTON_5, - SDL_ANDRIOD_SCREENKEYBOARD_BUTTON_6, + SDL_ANDRIOD_SCREENKEYBOARD_BUTTON_6, /* Button to show screen keyboard */ SDL_ANDRIOD_SCREENKEYBOARD_BUTTON_MAX = SDL_ANDRIOD_SCREENKEYBOARD_BUTTON_6 }; @@ -69,6 +69,9 @@ extern DECLSPEC int SDLCALL SDL_ANDROID_GetScreenKeyboardShown(); extern DECLSPEC int SDLCALL SDL_ANDROID_GetScreenKeyboardSize(); +/* Show Android on-screen keyboard, and pass entered text back to application when user closes it */ +extern DECLSPEC int SDLCALL SDL_ANDROID_ToggleScreenKeyboardTextInput(); + #ifdef __cplusplus } #endif diff --git a/project/jni/sdl-1.3/src/video/android/SDL_androidinput.c b/project/jni/sdl-1.3/src/video/android/SDL_androidinput.c index 689878375..c8336bfd1 100644 --- a/project/jni/sdl-1.3/src/video/android/SDL_androidinput.c +++ b/project/jni/sdl-1.3/src/video/android/SDL_androidinput.c @@ -143,6 +143,30 @@ JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeKey) ( JNIEnv* env, jobject thiz, jint SDL_SendKeyboardKey( action ? SDL_PRESSED : SDL_RELEASED, TranslateKey(key ,&keysym) ); } +JNIEXPORT void JNICALL +JAVA_EXPORT_NAME(DemoGLSurfaceView_nativeTextInput) ( JNIEnv* env, jobject thiz, jint ascii, jint unicode ) +{ + SDL_keysym keysym; + keysym.scancode = ascii; + keysym.sym = ascii; + keysym.mod = KMOD_NONE; + keysym.unicode = 0; + if ( SDL_TranslateUNICODE ) { + /* Populate the unicode field with the ASCII value */ + keysym.unicode = unicode; + } + +#if SDL_VERSION_ATLEAST(1,3,0) + char text[2]; + text[0]=ascii; + text[1]=0; + SDL_SendKeyboardText(text); +#else + SDL_SendKeyboardKey( SDL_PRESSED, &keysym ); + SDL_SendKeyboardKey( SDL_RELEASED, &keysym ); +#endif +} + static void updateOrientation ( float accX, float accY, float accZ ); @@ -233,9 +257,9 @@ void ANDROID_InitOSKeymap() // TODO: make this configurable keymap[KEYCODE_MENU] = SDL_KEY(SDL_KEY_VAL(SDL_ANDROID_KEYCODE_4)); - keymap[KEYCODE_SEARCH] = SDL_KEY(SDL_KEY_VAL(SDL_ANDROID_KEYCODE_1)); - keymap[KEYCODE_CALL] = SDL_KEY(SDL_KEY_VAL(SDL_ANDROID_KEYCODE_1)); keymap[KEYCODE_DPAD_CENTER] = SDL_KEY(SDL_KEY_VAL(SDL_ANDROID_KEYCODE_1)); + keymap[KEYCODE_SEARCH] = SDL_KEY(SDL_KEY_VAL(SDL_ANDROID_KEYCODE_9)); + keymap[KEYCODE_CALL] = SDL_KEY(SDL_KEY_VAL(SDL_ANDROID_KEYCODE_10)); //keymap[KEYCODE_CALL] = SDL_KEY(RCTRL); //keymap[KEYCODE_DPAD_CENTER] = SDL_KEY(LALT); @@ -724,3 +748,5 @@ void SDL_SYS_JoystickQuit(void) SDL_ANDROID_CurrentJoysticks[i] = NULL; return; } + + diff --git a/project/jni/sdl-1.3/src/video/android/SDL_androidinput.h b/project/jni/sdl-1.3/src/video/android/SDL_androidinput.h index c55f0932e..7bdd77bb6 100644 --- a/project/jni/sdl-1.3/src/video/android/SDL_androidinput.h +++ b/project/jni/sdl-1.3/src/video/android/SDL_androidinput.h @@ -200,5 +200,11 @@ extern int SDL_ANDROID_isTouchscreenKeyboardUsed; #ifndef SDL_ANDROID_KEYCODE_8 #define SDL_ANDROID_KEYCODE_8 DELETE #endif +#ifndef SDL_ANDROID_KEYCODE_9 +#define SDL_ANDROID_KEYCODE_9 SDL_ANDROID_KEYCODE_1 +#endif +#ifndef SDL_ANDROID_KEYCODE_10 +#define SDL_ANDROID_KEYCODE_10 SDL_ANDROID_KEYCODE_1 +#endif #endif diff --git a/project/jni/sdl-1.3/src/video/android/SDL_androidvideo.c b/project/jni/sdl-1.3/src/video/android/SDL_androidvideo.c index 44f92936b..4f048ea25 100644 --- a/project/jni/sdl-1.3/src/video/android/SDL_androidvideo.c +++ b/project/jni/sdl-1.3/src/video/android/SDL_androidvideo.c @@ -55,7 +55,9 @@ static JNIEnv* JavaEnv = NULL; static jclass JavaRendererClass = NULL; static jobject JavaRenderer = NULL; static jmethodID JavaSwapBuffers = NULL; +static jmethodID JavaShowScreenKeyboard = NULL; static int glContextLost = 0; +static int showScreenKeyboardDeferred = 0; static void appPutToBackgroundCallbackDefault(void) { @@ -85,6 +87,11 @@ int SDL_ANDROID_CallJavaSwapBuffers() SDL_ANDROID_VideoContextRecreated(); appRestoredCallback(); } + if( showScreenKeyboardDeferred ) + { + showScreenKeyboardDeferred = 0; + (*JavaEnv)->CallVoidMethod( JavaEnv, JavaRenderer, JavaShowScreenKeyboard ); + } return 1; } @@ -151,6 +158,11 @@ JAVA_EXPORT_NAME(DemoRenderer_nativeGlContextRecreated) ( JNIEnv* env, jobject #endif } +void SDL_ANDROID_CallJavaShowScreenKeyboard() +{ + showScreenKeyboardDeferred = 1; +} + JNIEXPORT void JNICALL JAVA_EXPORT_NAME(DemoRenderer_nativeInitJavaCallbacks) ( JNIEnv* env, jobject thiz ) { @@ -159,6 +171,7 @@ JAVA_EXPORT_NAME(DemoRenderer_nativeInitJavaCallbacks) ( JNIEnv* env, jobject t JavaRendererClass = (*JavaEnv)->GetObjectClass(JavaEnv, thiz); JavaSwapBuffers = (*JavaEnv)->GetMethodID(JavaEnv, JavaRendererClass, "swapBuffers", "()I"); + JavaShowScreenKeyboard = (*JavaEnv)->GetMethodID(JavaEnv, JavaRendererClass, "showScreenKeyboard", "()V"); ANDROID_InitOSKeymap(); diff --git a/project/jni/sdl-1.3/src/video/android/SDL_androidvideo.h b/project/jni/sdl-1.3/src/video/android/SDL_androidvideo.h index 506a55979..ffa560f7e 100644 --- a/project/jni/sdl-1.3/src/video/android/SDL_androidvideo.h +++ b/project/jni/sdl-1.3/src/video/android/SDL_androidvideo.h @@ -32,6 +32,7 @@ extern int SDL_ANDROID_sWindowHeight; extern int SDL_ANDROID_sFakeWindowWidth; // SDL 1.2 only extern int SDL_ANDROID_sFakeWindowHeight; // SDL 1.2 only extern int SDL_ANDROID_CallJavaSwapBuffers(); +extern void SDL_ANDROID_CallJavaShowScreenKeyboard(); extern int SDL_ANDROID_drawTouchscreenKeyboard(); extern void SDL_ANDROID_VideoContextLost(); extern void SDL_ANDROID_VideoContextRecreated(); diff --git a/project/jni/sdl-1.3/src/video/android/SDL_touchscreenkeyboard.c b/project/jni/sdl-1.3/src/video/android/SDL_touchscreenkeyboard.c index 4e8d0b62b..63760a4d8 100644 --- a/project/jni/sdl-1.3/src/video/android/SDL_touchscreenkeyboard.c +++ b/project/jni/sdl-1.3/src/video/android/SDL_touchscreenkeyboard.c @@ -55,13 +55,12 @@ FONT_BTN1 = 4, FONT_BTN2 = 5, FONT_BTN3 = 6, FONT_BTN4 = 7 static GLshort fontGL[sizeof(font)/sizeof(font[0])][FONT_MAX_LINES_PER_CHAR * 4 + 1]; enum { FONT_CHAR_LINES_COUNT = FONT_MAX_LINES_PER_CHAR * 4 }; -enum { MAX_BUTTONS = SDL_ANDRIOD_SCREENKEYBOARD_BUTTON_MAX, MAX_BUTTONS_AUTOFIRE = 2 } ; // Max amount of custom buttons +enum { MAX_BUTTONS = SDL_ANDRIOD_SCREENKEYBOARD_BUTTON_MAX, MAX_BUTTONS_AUTOFIRE = 2, BUTTON_TEXT_INPUT = MAX_BUTTONS - 1 } ; // Max amount of custom buttons int SDL_ANDROID_isTouchscreenKeyboardUsed = 0; static int touchscreenKeyboardTheme = 0; static int touchscreenKeyboardShown = 1; static int AutoFireButtonsNum = 0; -static int nbuttons = 4; static int buttonsize = 1; static SDL_Rect arrows, buttons[MAX_BUTTONS], buttonsAutoFireRect[MAX_BUTTONS_AUTOFIRE]; @@ -242,8 +241,10 @@ int SDL_ANDROID_drawTouchscreenKeyboard() 255, 255, SDL_GetKeyboardState(NULL)[SDL_KEY(DOWN)] ? 255 : 0, 128 ); // Draw buttons - for( i = 0; i < nbuttons; i++ ) + for( i = 0; i < MAX_BUTTONS; i++ ) { + if( ! buttons[i].h || ! buttons[i].w ) + continue; drawCharWireframe( FONT_BTN1 + i, buttons[i].x + buttons[i].w / 2, buttons[i].y + buttons[i].h / 2, ( i < AutoFireButtonsNum ? ButtonAutoFireRot[i] * 0x10000 : 0 ), ( i < AutoFireButtonsNum && ButtonAutoFire[i] ) ? 0 : 255, 255, SDL_GetKeyboardState(NULL)[buttonKeysyms[i]] ? 255 : 0, 128 ); } @@ -270,8 +271,10 @@ int SDL_ANDROID_drawTouchscreenKeyboard() drawCharTex( &arrowImages[4], NULL, &arrows, 255, 255, 255, 128 / blendFactor ); } - for( i = 0; i < nbuttons; i++ ) + for( i = 0; i < MAX_BUTTONS; i++ ) { + if( ! buttons[i].h || ! buttons[i].w ) + continue; if( i < AutoFireButtonsNum ) { if( ButtonAutoFire[i] == 1 && SDL_GetTicks() - ButtonAutoFireDecay[i] > 1000 ) @@ -411,15 +414,20 @@ int SDL_ANDROID_processTouchscreenKeyboard(int x, int y, int action, int pointer } } - for( i = 0; i < nbuttons; i++ ) + for( i = 0; i < MAX_BUTTONS; i++ ) { + if( ! buttons[i].h || ! buttons[i].w ) + continue; if( InsideRect( &buttons[i], x, y) ) { processed = 1; if( pointerInButtonRect[i] == -1 ) { pointerInButtonRect[i] = pointerId; - SDL_SendKeyboardKey( SDL_PRESSED, GetKeysym(buttonKeysyms[i], &keysym) ); + if( i == BUTTON_TEXT_INPUT ) + SDL_ANDROID_ToggleScreenKeyboardTextInput(); + else + SDL_SendKeyboardKey( SDL_PRESSED, GetKeysym(buttonKeysyms[i], &keysym) ); if( i < AutoFireButtonsNum ) { ButtonAutoFire[i] = 0; @@ -465,8 +473,10 @@ int SDL_ANDROID_processTouchscreenKeyboard(int x, int y, int action, int pointer oldArrows = 0; } } - for( i = 0; i < nbuttons; i++ ) + for( i = 0; i < MAX_BUTTONS; i++ ) { + if( ! buttons[i].h || ! buttons[i].w ) + continue; if( pointerInButtonRect[i] == pointerId ) { processed = 1; @@ -477,7 +487,8 @@ int SDL_ANDROID_processTouchscreenKeyboard(int x, int y, int action, int pointer } else { - SDL_SendKeyboardKey( SDL_RELEASED, GetKeysym(buttonKeysyms[i] ,&keysym) ); + if( i != BUTTON_TEXT_INPUT ) + SDL_SendKeyboardKey( SDL_RELEASED, GetKeysym(buttonKeysyms[i] ,&keysym) ); } if( i < AutoFireButtonsNum ) { @@ -571,7 +582,8 @@ int SDL_ANDROID_processTouchscreenKeyboard(int x, int y, int action, int pointer pointerInButtonRect[i] = -1; if( !ButtonAutoFire[i] ) { - SDL_SendKeyboardKey( SDL_RELEASED, GetKeysym(buttonKeysyms[i] ,&keysym) ); + if( i != BUTTON_TEXT_INPUT ) + SDL_SendKeyboardKey( SDL_RELEASED, GetKeysym(buttonKeysyms[i] ,&keysym) ); } else { @@ -625,15 +637,18 @@ int SDL_ANDROID_processTouchscreenKeyboard(int x, int y, int action, int pointer } } } - for( i = AutoFireButtonsNum; i < nbuttons; i++ ) + for( i = AutoFireButtonsNum; i < MAX_BUTTONS; i++ ) { + if( ! buttons[i].h || ! buttons[i].w ) + continue; if( pointerInButtonRect[i] == pointerId ) { processed = 1; if( ! InsideRect( &buttons[i], x, y ) ) { pointerInButtonRect[i] = -1; - SDL_SendKeyboardKey( SDL_RELEASED, GetKeysym(buttonKeysyms[i] ,&keysym) ); + if( i != BUTTON_TEXT_INPUT ) + SDL_SendKeyboardKey( SDL_RELEASED, GetKeysym(buttonKeysyms[i] ,&keysym) ); } } } @@ -643,14 +658,13 @@ int SDL_ANDROID_processTouchscreenKeyboard(int x, int y, int action, int pointer }; JNIEXPORT void JNICALL -JAVA_EXPORT_NAME(Settings_nativeSetupScreenKeyboard) ( JNIEnv* env, jobject thiz, jint size, jint theme, jint _nbuttons, jint nbuttonsAutoFire ) +JAVA_EXPORT_NAME(Settings_nativeSetupScreenKeyboard) ( JNIEnv* env, jobject thiz, jint size, jint theme, jint _nbuttons, jint nbuttonsAutoFire, jint showArrows, jint showTextInput ) { int i, ii; int nbuttons1row, nbuttons2row; - nbuttons = _nbuttons; touchscreenKeyboardTheme = theme; - if( nbuttons > MAX_BUTTONS ) - nbuttons = MAX_BUTTONS; + if( _nbuttons > MAX_BUTTONS ) + _nbuttons = MAX_BUTTONS; AutoFireButtonsNum = nbuttonsAutoFire; if( AutoFireButtonsNum > MAX_BUTTONS_AUTOFIRE ) AutoFireButtonsNum = MAX_BUTTONS_AUTOFIRE; @@ -672,7 +686,7 @@ JAVA_EXPORT_NAME(Settings_nativeSetupScreenKeyboard) ( JNIEnv* env, jobject thi buttons[0].y = SDL_ANDROID_sWindowHeight - buttons[0].h; // Row of secondary buttons to the upper-right - nbuttons1row = MIN(nbuttons, 4); + nbuttons1row = 4; for( i = 1; i < nbuttons1row; i++ ) { buttons[i].w = SDL_ANDROID_sWindowWidth / (nbuttons1row - 1) / (size + 2); @@ -682,7 +696,7 @@ JAVA_EXPORT_NAME(Settings_nativeSetupScreenKeyboard) ( JNIEnv* env, jobject thi } // Row of secondary buttons to the upper-left above arrows - nbuttons2row = MIN(nbuttons, 7); + nbuttons2row = MAX_BUTTONS; for( i = 4; i < nbuttons2row; i++ ) { buttons[i].w = SDL_ANDROID_sWindowWidth / (nbuttons2row - 4) / (size + 2); @@ -697,7 +711,7 @@ JAVA_EXPORT_NAME(Settings_nativeSetupScreenKeyboard) ( JNIEnv* env, jobject thi prepareFontCharWireframe(FONT_UP, arrows.w / 2, arrows.h / 2); prepareFontCharWireframe(FONT_DOWN, arrows.w / 2, arrows.h / 2); - for( i = 0; i < nbuttons; i++ ) + for( i = 0; i < MAX_BUTTONS; i++ ) { prepareFontCharWireframe(FONT_BTN1 + i, MIN(buttons[i].h, buttons[i].w), MIN(buttons[i].h, buttons[i].w)); } @@ -735,6 +749,17 @@ JAVA_EXPORT_NAME(Settings_nativeSetupScreenKeyboard) ( JNIEnv* env, jobject thi buttons[6].w = 30; buttons[6].h = 30; } + + if( !showArrows ) + { + arrows.w = 0; + arrows.h = 0; + } + for( i = 0; i < MAX_BUTTONS; i++ ) + { + if( i >= _nbuttons && ( i == BUTTON_TEXT_INPUT && !showTextInput ) ) + buttons[i].w = buttons[i].h = 0; + } for( i = 0; i < sizeof(pointerInButtonRect)/sizeof(pointerInButtonRect[0]); i++ ) { @@ -923,3 +948,9 @@ int SDL_ANDROID_GetScreenKeyboardSize() { return buttonsize; }; + +int SDL_ANDROID_ToggleScreenKeyboardTextInput() +{ + SDL_ANDROID_CallJavaShowScreenKeyboard(); + return 1; +};