Nifty TextField on Android

@Momoko_Fan @nehon

The first main problem is that you need an EDITABLE view to be in focus for the native keyboard to display. This forces the use of something like an EditText view to be activated, not the GLSurfaceView that the engine is using to display the game (AndroidInput class). So to fix that, I created an AlertDialog with an EditText so that the user could touch the EditText to get the keyboard to display.



The next main problem is that the native soft keyboard in Android does not produce onKey events for all keys, only the numbers and the non-text keys like Enter or Done. This forces you to implement a second listener on the EditText called a TextWatcher. TextWatchers only supply the CharSequence of the key pressed and the position within the String, not a KeyCode or KeyEvent.



Others have had similar problems when trying to grab the key presses from the soft keyboard and send them to things other than the EditText:

http://stackoverflow.com/questions/4282214/onkeylistener-not-working-on-virtual-keyboard



To get around these issues, I simply grab the completed text and supply the completed text string back to the caller. In this case, the calling method inside my Nifty Screen Controller, which then sets the textfield in the Nifty screen.



There is an alternative in Android called a KeyboardView (http://developer.android.com/reference/android/inputmethodservice/KeyboardView.html) which allows you to define your own keyboard layout via XML and define keycodes to use for each key. It also has it’s own OnKeyboardActionListener that will provide a callback on each key press. It returns the code defined in the XML file and then you can lookup the key and get the Label and Text. Using this method might allow us to create an interface between the keyboard and JME’s onKey method inside AndroidInput, but it will take some work.



I really didn’t see the need to do that since there isn’t much use of the keyboard in a JME game on Android except for text / number entry in the UIF. You can’t really use the soft keyboard for game controls since the soft keyboard will display over the top of the game.



Just my 2 cents.

OK Makes sense. This would work as a preliminary solution.

Is there any way to maybe create an invisible or out of frame EditText and then place the characters inside the actual nifty text?

@Momoko_Fan

It would be possible to hide the EditText. I think you just have to add it under the GLSurfaceView. However, I think it would create a problem of visibility for what you are typing in. The Android OS tries to move the targeted EditText up the screen so that the target and keyboard are both visible. For screen sizes and orientation that do not have enough room, the OS makes the Keyboard full screen and puts in it’s own EditText to allow the user to see what letters they’ve typed in.



Since the Nifty textfield is unknown to Android (the GLSurfaceView and the EditText are the only Android objects visible to Android) it would not be able to shift the Nifty textfield up to ensure it is visible while the keyboard is displayed. I think there would be a lot of cases where the Nifty textfield would be hidden under the keyboard and if the EditText was also hidden behind the GLSurfaceView, then the user would have no way to see what text they have typed in.



I think a potential long term solution would be to have Nifty provide a soft keyboard as a native function, but I don’t know if that is something they would want to do or not. I would also have some concern about the performance on Android phones. The more panels, buttons, textfields you put on a screen, the slower the performance gets on Android and I would be afraid that a full qwerty keyboard would be sluggish on Android phones.



Assuming we go with the AlertDialog box method, to start with at least, is it OK to add a generic interface variable to InputManager so the application (specifically the Screen Controller) can get access to it? I picked InputManager because there was already some code to setup some touch screen specific stuff and this way other platforms can do their own thing to implement a soft keyboard input thing using the same interface variable in InputManager.

I don’t think the InputManager is appropriate for this. It is mostly for mapping game input, e.g. binding triggers like a key for example to a string so you can get events from it. I don’t see the purpose in cluttering it. The context could provide a means to query the user for a string.

@nehon Can you help me figure out where to put the getter in the context so that it is available from the Screen Controller? If it gets put into OGLESContext, then the game code would only compile when the jme-android.jar file is included. I think this would require a getter / setter in JmeContext.java. However, if this is done, then all other platform Contexts would have to be updated to return null when the getter is called. I’m not sure this is what @Momoko_Fan was thinking. I’m afraid I just don’t know enough about the architecture of JME. I can handle all the other changes.

@iwgeric I’m gonna look into this and keep you informed.

@nehon Thanks. I have some changes/improvements to make for the AndroidHarness part to deal with phone life cycle issues (like screen orientation changes while the alert dialog is displayed). I’ll post a new patch file when I’m done with that part.

@iwgeric i made it work in a small example project. It works.

I guess it would require some more integration with nifty to avoid having to request the dialog box to show.

I’m looking further into it.

@nehon Where did you end up putting the interface instead of InputManager? I’ll try to send you some updated code for AndroidHarness in a couple of hours to avoid using “managed” dialog boxes.

I made no change for now, i just integrated your changes to see how it worked.

@nehon

Here is a new patch file for AndroidHarness based on today’s state of the file in SVN (patch files for the other files did not change). It’s much cleaner and does not use Managed DialogBoxes. This works better with screen reorientations and life cycle changes. Let me know if you need anything else.



[java]

This patch file was generated by NetBeans IDE

Following Index: paths are relative to: D:UserspotterecDocumentsjMonkeyProjectsjME3srcandroidcomjme3app

This patch can be applied using context Tools: Patch action on respective folder.

It uses platform neutral UTF-8 encoding and n newlines.

Above lines and this line are ignored by the patching process.

Index: AndroidHarness.java

— AndroidHarness.java Base (BASE)

+++ AndroidHarness.java Locally Modified (Based On LOCAL)

@@ -8,14 +8,18 @@

import android.graphics.drawable.NinePatchDrawable;

import android.opengl.GLSurfaceView;

import android.os.Bundle;

+import android.text.InputType;

import android.view.ViewGroup.LayoutParams;

import android.view.*;

+import android.widget.EditText;

import android.widget.FrameLayout;

import android.widget.ImageView;

import android.widget.TextView;

import com.jme3.audio.AudioRenderer;

import com.jme3.audio.android.AndroidAudioRenderer;

+import com.jme3.input.SoftTextDialogInput;

import com.jme3.input.android.AndroidInput;

+import com.jme3.input.controls.SoftTextDialogInputListener;

import com.jme3.input.controls.TouchListener;

import com.jme3.input.event.TouchEvent;

import com.jme3.system.AppSettings;

@@ -37,7 +41,7 @@

  • @author Kirill
  • @author larynx

    */

    -public class AndroidHarness extends Activity implements TouchListener, DialogInterface.OnClickListener {

    +public class AndroidHarness extends Activity implements TouchListener, DialogInterface.OnClickListener, SoftTextDialogInput {



    protected final static Logger logger = Logger.getLogger(AndroidHarness.class.getName());

    /**

    @@ -395,4 +399,71 @@

    }

    }

    }

    +
  • public void requestDialog(final int id, final String title, final String initialValue, final SoftTextDialogInputListener listener) {
  •    logger.log(Level.INFO, &quot;requestDialog: title: {0}, initialValue: {1}&quot;,<br />
    
  •            new Object[]{title, initialValue});<br />
    

+

  •    this.runOnUiThread(new Runnable() {<br />
    

+

  •        @Override<br />
    
  •        public void run() {<br />
    

+

  •            final FrameLayout layoutTextDialogInput = new FrameLayout(AndroidHarness.this);<br />
    
  •            final EditText editTextDialogInput = new EditText(AndroidHarness.this);<br />
    
  •            editTextDialogInput.setWidth(LayoutParams.FILL_PARENT);<br />
    
  •            editTextDialogInput.setHeight(LayoutParams.FILL_PARENT);<br />
    
  •            editTextDialogInput.setPadding(20, 20, 20, 20);<br />
    
  •            editTextDialogInput.setGravity(Gravity.FILL_HORIZONTAL);<br />
    

+

  •            editTextDialogInput.setText(initialValue);<br />
    

+

  •            switch (id) {<br />
    
  •                case SoftTextDialogInput.TEXT_ENTRY_DIALOG:<br />
    

+

  •                    editTextDialogInput.setInputType(InputType.TYPE_CLASS_TEXT);<br />
    
  •                    break;<br />
    

+

  •                case SoftTextDialogInput.NUMERIC_ENTRY_DIALOG:<br />
    

+

  •                    editTextDialogInput.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL | InputType.TYPE_NUMBER_FLAG_SIGNED);<br />
    
  •                    break;<br />
    

+

  •                case SoftTextDialogInput.NUMERIC_KEYPAD_DIALOG:<br />
    

+

  •                    editTextDialogInput.setInputType(InputType.TYPE_CLASS_PHONE);<br />
    
  •                    break;<br />
    

+

  •                default:<br />
    
  •                    break;<br />
    

}

+

  •            layoutTextDialogInput.addView(editTextDialogInput);<br />
    

+

  •            AlertDialog dialogTextInput = new AlertDialog.Builder(AndroidHarness.this)<br />
    
  •                .setTitle(title)<br />
    
  •                .setView(layoutTextDialogInput)<br />
    
  •                .setPositiveButton(&quot;OK&quot;,<br />
    
  •                    new DialogInterface.OnClickListener() {<br />
    
  •                        public void onClick(DialogInterface dialog, int whichButton) {<br />
    
  •                            /* User clicked OK, send COMPLETE action<br />
    
  •                             * and text */<br />
    
  •                            listener.onSoftText(SoftTextDialogInputListener.COMPLETE, editTextDialogInput.getText().toString());<br />
    
  •                        }<br />
    
  •                    })<br />
    
  •                .setNegativeButton(&quot;Cancel&quot;,<br />
    
  •                    new DialogInterface.OnClickListener() {<br />
    
  •                        public void onClick(DialogInterface dialog, int whichButton) {<br />
    
  •                            /* User clicked CANCEL, send CANCEL action<br />
    
  •                             * and text */<br />
    
  •                                listener.onSoftText(SoftTextDialogInputListener.CANCEL, editTextDialogInput.getText().toString());<br />
    
  •                        }<br />
    
  •                    })<br />
    
  •                .create();<br />
    

+

  •            dialogTextInput.show();<br />
    

+

  •        }<br />
    
  •    });<br />
    
  • }

    +}



    [/java]

cool i’ll check this out

I tested it, that’s strange it does pop the keyboard as soon as the popup shows on my tablet with android 3.2 but not on my phone with android 2.3.



Maybe that’s just a screen size problem…anyway that’s nice.



Now i just have to find a way to make nifty use this automatically when running on android. So the user don’t have to add a controller with an onclick on each text field

I’m doing everything on 2.3.4 with my Motorola Bionic phone. I have to touch the edittext in order to get the keyboard to pop up. I haven’t checked to see if the keyboard pops up automatically on my Motorola Xoom tablet. Maybe a difference in how the OS treats the edittext getting focus.

@nehon

In case you haven’t had time to figure this out yet, I think I have a way to integrate it into Nifty without any user code. Right now, I have a routine in InputSystemJme that figures out the active control on the screen and determines if it is a TextField. I think I can easily expand this to include the call to InputManger to get and display the soft keyboard with a callback.



Should I finish it or did you figure it out already?

To be honest i didn’t have time, go ahead that’s great news!

@nehon

Here is the complete solution that I would propose. No user code is necessary. It only pops up the Android dialog box for entering text if:


  • a touch event or mouse button event triggers

  • Nifty consumes the touch or mouse event

  • the active element is a TextField


It initially populates the dialog box with the current text in the textfield. After the dialog box is dismissed, it takes the text from the dialog box and populates the nifty textfield.

Please let me know what you think.

SoftTextDialogInput
[java]
# This patch file was generated by NetBeans IDE
# Following Index: paths are relative to: D:UserspotterecDocumentsjMonkeyProjectsjME3srccorecomjme3input
# This patch can be applied using context Tools: Patch action on respective folder.
# It uses platform neutral UTF-8 encoding and n newlines.
# Above lines and this line are ignored by the patching process.
Index: SoftTextDialogInput.java
--- SoftTextDialogInput.java Locally New
+++ SoftTextDialogInput.java Locally New
@@ -0,0 +1,13 @@
+package com.jme3.input;
+
+import com.jme3.input.controls.SoftTextDialogInputListener;
+
+public interface SoftTextDialogInput {
+
+ public static int TEXT_ENTRY_DIALOG = 0;
+ public static int NUMERIC_ENTRY_DIALOG = 1;
+ public static int NUMERIC_KEYPAD_DIALOG = 2;
+
+ public void requestDialog(int id, String title, String initialValue, SoftTextDialogInputListener listener);
+
+}

[/java]

SoftTextDialogInputListener
[java]
# This patch file was generated by NetBeans IDE
# Following Index: paths are relative to: D:UserspotterecDocumentsjMonkeyProjectsjME3srccorecomjme3inputcontrols
# This patch can be applied using context Tools: Patch action on respective folder.
# It uses platform neutral UTF-8 encoding and n newlines.
# Above lines and this line are ignored by the patching process.
Index: SoftTextDialogInputListener.java
--- SoftTextDialogInputListener.java Locally New
+++ SoftTextDialogInputListener.java Locally New
@@ -0,0 +1,17 @@
+/*
+ * To change this template, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package com.jme3.input.controls;
+
+/**
+ *
+ * @author potterec
+ */
+public interface SoftTextDialogInputListener extends InputListener {
+ public static int COMPLETE = 0;
+ public static int CANCEL = 1;
+
+ public void onSoftText(int action, String text);
+
+}

[/java]

InputManager
[java]
# This patch file was generated by NetBeans IDE
# Following Index: paths are relative to: D:UserspotterecDocumentsjMonkeyProjectsjME3srccorecomjme3input
# This patch can be applied using context Tools: Patch action on respective folder.
# It uses platform neutral UTF-8 encoding and n newlines.
# Above lines and this line are ignored by the patching process.
Index: InputManager.java
--- InputManager.java Base (BASE)
+++ InputManager.java Locally Modified (Based On LOCAL)
@@ -105,6 +105,7 @@
private ArrayList<RawInputListener> rawListeners = new ArrayList<RawInputListener>();
private RawInputListener[] rawListenerArray = null;
private ArrayList<InputEvent> inputQueue = new ArrayList<InputEvent>();
+ private SoftTextDialogInput softTextDialogInput = null;

private static class Mapping {

@@ -743,6 +744,13 @@
}
}

+ public void setSoftTextDialogInput(SoftTextDialogInput input) {
+ softTextDialogInput = input;
+ }
+ public SoftTextDialogInput getSoftTextDialogInput() {
+ return softTextDialogInput;
+ }
+
private void processQueue() {
int queueSize = inputQueue.size();
RawInputListener[] array = getRawListenerArray();

[/java]

OGLESContext
[java]
# This patch file was generated by NetBeans IDE
# Following Index: paths are relative to: D:UserspotterecDocumentsjMonkeyProjectsjME3srcandroidcomjme3systemandroid
# This patch can be applied using context Tools: Patch action on respective folder.
# It uses platform neutral UTF-8 encoding and n newlines.
# Above lines and this line are ignored by the patching process.
Index: OGLESContext.java
--- OGLESContext.java Base (BASE)
+++ OGLESContext.java Locally Modified (Based On LOCAL)
@@ -241,6 +241,8 @@
if (app.getInputManager() != null) {
app.getInputManager().addMapping(ESCAPE_EVENT, new TouchTrigger(TouchInput.KEYCODE_BACK));
app.getInputManager().addListener((AndroidHarness) ctx, new String[]{ESCAPE_EVENT});
+
+ app.getInputManager().setSoftTextDialogInput((AndroidHarness)ctx);
}
}


[/java]

AndroidHarness
[java]
# This patch file was generated by NetBeans IDE
# Following Index: paths are relative to: D:UserspotterecDocumentsjMonkeyProjectsjME3srcandroidcomjme3app
# This patch can be applied using context Tools: Patch action on respective folder.
# It uses platform neutral UTF-8 encoding and n newlines.
# Above lines and this line are ignored by the patching process.
Index: AndroidHarness.java
--- AndroidHarness.java Base (BASE)
+++ AndroidHarness.java Locally Modified (Based On LOCAL)
@@ -2,20 +2,26 @@

import android.app.Activity;
import android.app.AlertDialog;
+import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.ActivityInfo;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.NinePatchDrawable;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
+import android.text.InputType;
import android.view.ViewGroup.LayoutParams;
import android.view.*;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.EditText;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import com.jme3.audio.AudioRenderer;
import com.jme3.audio.android.AndroidAudioRenderer;
+import com.jme3.input.SoftTextDialogInput;
import com.jme3.input.android.AndroidInput;
+import com.jme3.input.controls.SoftTextDialogInputListener;
import com.jme3.input.controls.TouchListener;
import com.jme3.input.event.TouchEvent;
import com.jme3.system.AppSettings;
@@ -37,7 +43,7 @@
* @author Kirill
* @author larynx
*/
-public class AndroidHarness extends Activity implements TouchListener, DialogInterface.OnClickListener {
+public class AndroidHarness extends Activity implements TouchListener, DialogInterface.OnClickListener, SoftTextDialogInput {

protected final static Logger logger = Logger.getLogger(AndroidHarness.class.getName());
/**
@@ -395,4 +401,71 @@
}
}
}
+
+ public void requestDialog(final int id, final String title, final String initialValue, final SoftTextDialogInputListener listener) {
+ logger.log(Level.INFO, "requestDialog: title: {0}, initialValue: {1}",
+ new Object[]{title, initialValue});
+
+ this.runOnUiThread(new Runnable() {
+
+ @Override
+ public void run() {
+
+ final FrameLayout layoutTextDialogInput = new FrameLayout(AndroidHarness.this);
+ final EditText editTextDialogInput = new EditText(AndroidHarness.this);
+ editTextDialogInput.setWidth(LayoutParams.FILL_PARENT);
+ editTextDialogInput.setHeight(LayoutParams.FILL_PARENT);
+ editTextDialogInput.setPadding(20, 20, 20, 20);
+ editTextDialogInput.setGravity(Gravity.FILL_HORIZONTAL);
+
+ editTextDialogInput.setText(initialValue);
+
+ switch (id) {
+ case SoftTextDialogInput.TEXT_ENTRY_DIALOG:
+
+ editTextDialogInput.setInputType(InputType.TYPE_CLASS_TEXT);
+ break;
+
+ case SoftTextDialogInput.NUMERIC_ENTRY_DIALOG:
+
+ editTextDialogInput.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL | InputType.TYPE_NUMBER_FLAG_SIGNED);
+ break;
+
+ case SoftTextDialogInput.NUMERIC_KEYPAD_DIALOG:
+
+ editTextDialogInput.setInputType(InputType.TYPE_CLASS_PHONE);
+ break;
+
+ default:
+ break;
}
+
+ layoutTextDialogInput.addView(editTextDialogInput);
+
+ AlertDialog dialogTextInput = new AlertDialog.Builder(AndroidHarness.this)
+ .setTitle(title)
+ .setView(layoutTextDialogInput)
+ .setPositiveButton("OK",
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int whichButton) {
+ /* User clicked OK, send COMPLETE action
+ * and text */
+ listener.onSoftText(SoftTextDialogInputListener.COMPLETE, editTextDialogInput.getText().toString());
+ }
+ })
+ .setNegativeButton("Cancel",
+ new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int whichButton) {
+ /* User clicked CANCEL, send CANCEL action
+ * and text */
+ listener.onSoftText(SoftTextDialogInputListener.CANCEL, editTextDialogInput.getText().toString());
+ }
+ })
+ .create();
+
+ dialogTextInput.show();
+
+ }
+ });
+ }
+}

[/java]

InputSystemJme
[java]
# This patch file was generated by NetBeans IDE
# Following Index: paths are relative to: D:UserspotterecDocumentsjMonkeyProjectsjME3srcniftyguicomjme3niftygui
# This patch can be applied using context Tools: Patch action on respective folder.
# It uses platform neutral UTF-8 encoding and n newlines.
# Above lines and this line are ignored by the patching process.
Index: InputSystemJme.java
--- InputSystemJme.java Base (BASE)
+++ InputSystemJme.java Locally Modified (Based On LOCAL)
@@ -35,13 +35,20 @@
import com.jme3.input.InputManager;
import com.jme3.input.KeyInput;
import com.jme3.input.RawInputListener;
+import com.jme3.input.SoftTextDialogInput;
+import com.jme3.input.controls.SoftTextDialogInputListener;
import com.jme3.input.event.*;
import de.lessvoid.nifty.Nifty;
import de.lessvoid.nifty.NiftyInputConsumer;
+import de.lessvoid.nifty.controls.TextField;
+import de.lessvoid.nifty.controls.nullobjects.TextFieldNull;
+import de.lessvoid.nifty.elements.Element;
import de.lessvoid.nifty.tools.resourceloader.NiftyResourceLoader;
import de.lessvoid.nifty.input.keyboard.KeyboardInputEvent;
import de.lessvoid.nifty.spi.input.InputSystem;
import java.util.ArrayList;
+import java.util.logging.Level;
+import java.util.logging.Logger;

public class InputSystemJme implements InputSystem, RawInputListener {

@@ -116,6 +123,10 @@

isDragging = false;
niftyOwnsDragging = false;
+
+ if (consumed)
+ processSoftKeyboard();
+
break;
}
}
@@ -159,6 +170,9 @@
isDragging = true;
niftyOwnsDragging = consumed;
}
+
+ if (consumed)
+ processSoftKeyboard();
}

private void onKeyEventQueued(KeyInputEvent evt, NiftyInputConsumer nic) {
@@ -230,4 +244,31 @@
}


+ private void processSoftKeyboard() {
+ SoftTextDialogInput softTextDialogInput = inputManager.getSoftTextDialogInput();
+ if (softTextDialogInput != null) {
+
+ Element element = nifty.getCurrentScreen().getFocusHandler().getKeyboardFocusElement();
+ if (element != null) {
+ final TextField textField = element.getNiftyControl(TextField.class);
+ if (textField != null && !(textField instanceof TextFieldNull)) {
+ Logger.getLogger(InputSystemJme.class.getName()).log(Level.INFO, "Current TextField: {0}", textField.getId());
+ String initialValue = textField.getText();
+ if (initialValue == null) {
+ initialValue = "";
}
+
+ softTextDialogInput.requestDialog(SoftTextDialogInput.TEXT_ENTRY_DIALOG, "Enter Text", initialValue, new SoftTextDialogInputListener() {
+
+ public void onSoftText(int action, String text) {
+ if (action == SoftTextDialogInputListener.COMPLETE) {
+ textField.setText(text);
+ }
+ }
+ });
+ }
+ }
+ }
+ }
+
+}

[/java]

That’s very nice! I’ll test that asap

@Momoko_Fan what do you think?

@nehon said:
That's very nice! I'll test that asap
@Momoko_Fan what do you think?

If it works it would be very useful
I would avoid adding any code to AndroidHarness and InputManager though, if possible.

@nehon @Momoko_Fan



Here is another version that does not use AndroidHarness or InputManager. I have no idea if this makes good sense for the engine or not, but it is the only other way I could think of to implement the function without using these 2 classes.



Basically, I moved the changes from AndroidHarness into OGLESContext and moved the changes from InputManager into JmeSystemDelagate and JmeSystem.



Here are the patch files based off the current engine a few minutes ago:



SoftTextDialogInput

[java]

This patch file was generated by NetBeans IDE

Following Index: paths are relative to: D:UserspotterecDocumentsjMonkeyProjectsjME3srccorecomjme3input

This patch can be applied using context Tools: Patch action on respective folder.

It uses platform neutral UTF-8 encoding and n newlines.

Above lines and this line are ignored by the patching process.

Index: SoftTextDialogInput.java

— SoftTextDialogInput.java Locally New

+++ SoftTextDialogInput.java Locally New

@@ -0,0 +1,13 @@

+package com.jme3.input;

+

+import com.jme3.input.controls.SoftTextDialogInputListener;

+

+public interface SoftTextDialogInput {

+

  • public static int TEXT_ENTRY_DIALOG = 0;
  • public static int NUMERIC_ENTRY_DIALOG = 1;
  • public static int NUMERIC_KEYPAD_DIALOG = 2;

    +
  • public void requestDialog(int id, String title, String initialValue, SoftTextDialogInputListener listener);

    +

    +}



    [/java]



    SoftTextDialogInputListener

    [java]

This patch file was generated by NetBeans IDE

Following Index: paths are relative to: D:UserspotterecDocumentsjMonkeyProjectsjME3srccorecomjme3inputcontrols

This patch can be applied using context Tools: Patch action on respective folder.

It uses platform neutral UTF-8 encoding and n newlines.

Above lines and this line are ignored by the patching process.

Index: SoftTextDialogInputListener.java

— SoftTextDialogInputListener.java Locally New

+++ SoftTextDialogInputListener.java Locally New

@@ -0,0 +1,17 @@

+/*

    • To change this template, choose Tools | Templates
    • and open the template in the editor.
  • */

    +package com.jme3.input.controls;

    +

    +/**
  • *
    • @author potterec
  • */

    +public interface SoftTextDialogInputListener extends InputListener {
  • public static int COMPLETE = 0;
  • public static int CANCEL = 1;

    +
  • public void onSoftText(int action, String text);

    +

    +}



    [/java]



    JmeSystemDelegate

    [java]

This patch file was generated by NetBeans IDE

Following Index: paths are relative to: D:UserspotterecDocumentsjMonkeyProjectsjME3srccorecomjme3system

This patch can be applied using context Tools: Patch action on respective folder.

It uses platform neutral UTF-8 encoding and n newlines.

Above lines and this line are ignored by the patching process.

Index: JmeSystemDelegate.java

— JmeSystemDelegate.java Base (BASE)

+++ JmeSystemDelegate.java Locally Modified (Based On LOCAL)

@@ -33,6 +33,7 @@



import com.jme3.asset.AssetManager;

import com.jme3.audio.AudioRenderer;

+import com.jme3.input.SoftTextDialogInput;

import java.io.File;

import java.io.InputStream;

import java.net.URL;

@@ -48,6 +49,7 @@

protected boolean initialized = false;

protected boolean lowPermissions = false;

protected File storageFolder = null;

  • protected SoftTextDialogInput softTextDialogInput = null;



    public synchronized File getStorageFolder() {

    if (lowPermissions) {

    @@ -87,6 +89,13 @@

    return lowPermissions;

    }


  • public void setSoftTextDialogInput(SoftTextDialogInput input) {
  •    softTextDialogInput = input;<br />
    
  • }
  • public SoftTextDialogInput getSoftTextDialogInput() {
  •    return softTextDialogInput;<br />
    
  • }

    +

    public abstract AssetManager newAssetManager(URL configFile);



    public abstract AssetManager newAssetManager();



    [/java]



    JmeSystem

    [java]

This patch file was generated by NetBeans IDE

Following Index: paths are relative to: D:UserspotterecDocumentsjMonkeyProjectsjME3srccorecomjme3system

This patch can be applied using context Tools: Patch action on respective folder.

It uses platform neutral UTF-8 encoding and n newlines.

Above lines and this line are ignored by the patching process.

Index: JmeSystem.java

— JmeSystem.java Base (BASE)

+++ JmeSystem.java Locally Modified (Based On LOCAL)

@@ -33,6 +33,7 @@



import com.jme3.asset.AssetManager;

import com.jme3.audio.AudioRenderer;

+import com.jme3.input.SoftTextDialogInput;

import java.io.File;

import java.io.InputStream;

import java.net.URL;

@@ -82,6 +83,16 @@

return systemDelegate.isLowPermissions();

}


  • public static void setSoftTextDialogInput(SoftTextDialogInput input) {
  •    checkDelegate();<br />
    
  •    systemDelegate.setSoftTextDialogInput(input);<br />
    
  • }

    +
  • public static SoftTextDialogInput getSoftTextDialogInput() {
  •    checkDelegate();<br />
    
  •    return systemDelegate.getSoftTextDialogInput();<br />
    
  • }

    +

    public static AssetManager newAssetManager(URL configFile) {

    checkDelegate();

    return systemDelegate.newAssetManager(configFile);



    [/java]



    OGLESContext

    [java]

This patch file was generated by NetBeans IDE

Following Index: paths are relative to: D:UserspotterecDocumentsjMonkeyProjectsjME3srcandroidcomjme3systemandroid

This patch can be applied using context Tools: Patch action on respective folder.

It uses platform neutral UTF-8 encoding and n newlines.

Above lines and this line are ignored by the patching process.

Index: OGLESContext.java

— OGLESContext.java Base (BASE)

+++ OGLESContext.java Locally Modified (Based On LOCAL)

@@ -32,26 +32,37 @@

package com.jme3.system.android;



import android.app.Activity;

+import android.app.AlertDialog;

import android.content.Context;

+import android.content.DialogInterface;

import android.opengl.GLSurfaceView;

+import android.text.InputType;

+import android.view.Gravity;

import android.view.SurfaceHolder;

+import android.view.ViewGroup.LayoutParams;

+import android.widget.EditText;

+import android.widget.FrameLayout;

import com.jme3.app.AndroidHarness;

import com.jme3.app.Application;

import com.jme3.input.JoyInput;

import com.jme3.input.KeyInput;

import com.jme3.input.MouseInput;

+import com.jme3.input.SoftTextDialogInput;

import com.jme3.input.TouchInput;

import com.jme3.input.android.AndroidInput;

+import com.jme3.input.controls.SoftTextDialogInputListener;

import com.jme3.input.controls.TouchTrigger;

import com.jme3.input.dummy.DummyKeyInput;

import com.jme3.input.dummy.DummyMouseInput;

import com.jme3.renderer.android.OGLESShaderRenderer;

import com.jme3.system.AppSettings;

import com.jme3.system.JmeContext;

+import com.jme3.system.JmeSystem;

import com.jme3.system.SystemListener;

import com.jme3.system.Timer;

import com.jme3.system.android.AndroidConfigChooser.ConfigType;

import java.util.concurrent.atomic.AtomicBoolean;

+import java.util.logging.Level;

import java.util.logging.Logger;

import javax.microedition.khronos.egl.EGL10;

import javax.microedition.khronos.egl.EGLConfig;

@@ -59,7 +70,7 @@

import javax.microedition.khronos.egl.EGLDisplay;

import javax.microedition.khronos.opengles.GL10;



-public class OGLESContext implements JmeContext, GLSurfaceView.Renderer {

+public class OGLESContext implements JmeContext, GLSurfaceView.Renderer, SoftTextDialogInput {



private static final Logger logger = Logger.getLogger(OGLESContext.class.getName());

protected final AtomicBoolean created = new AtomicBoolean(false);

@@ -244,6 +255,8 @@

}

}


  •    JmeSystem.setSoftTextDialogInput(this);<br />
    

+

needClose.set(false);

renderable.set(true);

}

@@ -442,4 +455,72 @@

public int getClientOpenGLESVersion() {

return clientOpenGLESVersion;

}

+

  • public void requestDialog(final int id, final String title, final String initialValue, final SoftTextDialogInputListener listener) {
  •    logger.log(Level.INFO, &quot;requestDialog: title: {0}, initialValue: {1}&quot;,<br />
    
  •            new Object[]{title, initialValue});<br />
    

+

  •    JmeAndroidSystem.getActivity().runOnUiThread(new Runnable() {<br />
    

+

  •        @Override<br />
    
  •        public void run() {<br />
    

+

  •            final FrameLayout layoutTextDialogInput = new FrameLayout(JmeAndroidSystem.getActivity());<br />
    
  •            final EditText editTextDialogInput = new EditText(JmeAndroidSystem.getActivity());<br />
    
  •            editTextDialogInput.setWidth(LayoutParams.FILL_PARENT);<br />
    
  •            editTextDialogInput.setHeight(LayoutParams.FILL_PARENT);<br />
    
  •            editTextDialogInput.setPadding(20, 20, 20, 20);<br />
    
  •            editTextDialogInput.setGravity(Gravity.FILL_HORIZONTAL);<br />
    

+

  •            editTextDialogInput.setText(initialValue);<br />
    

+

  •            switch (id) {<br />
    
  •                case SoftTextDialogInput.TEXT_ENTRY_DIALOG:<br />
    

+

  •                    editTextDialogInput.setInputType(InputType.TYPE_CLASS_TEXT);<br />
    
  •                    break;<br />
    

+

  •                case SoftTextDialogInput.NUMERIC_ENTRY_DIALOG:<br />
    

+

  •                    editTextDialogInput.setInputType(InputType.TYPE_CLASS_NUMBER | InputType.TYPE_NUMBER_FLAG_DECIMAL | InputType.TYPE_NUMBER_FLAG_SIGNED);<br />
    
  •                    break;<br />
    

+

  •                case SoftTextDialogInput.NUMERIC_KEYPAD_DIALOG:<br />
    

+

  •                    editTextDialogInput.setInputType(InputType.TYPE_CLASS_PHONE);<br />
    
  •                    break;<br />
    

+

  •                default:<br />
    
  •                    break;<br />
    

}

+

  •            layoutTextDialogInput.addView(editTextDialogInput);<br />
    

+

  •            AlertDialog dialogTextInput = new AlertDialog.Builder(JmeAndroidSystem.getActivity())<br />
    
  •                .setTitle(title)<br />
    
  •                .setView(layoutTextDialogInput)<br />
    
  •                .setPositiveButton(&quot;OK&quot;,<br />
    
  •                    new DialogInterface.OnClickListener() {<br />
    
  •                        public void onClick(DialogInterface dialog, int whichButton) {<br />
    
  •                            /* User clicked OK, send COMPLETE action<br />
    
  •                             * and text */<br />
    
  •                            listener.onSoftText(SoftTextDialogInputListener.COMPLETE, editTextDialogInput.getText().toString());<br />
    
  •                        }<br />
    
  •                    })<br />
    
  •                .setNegativeButton(&quot;Cancel&quot;,<br />
    
  •                    new DialogInterface.OnClickListener() {<br />
    
  •                        public void onClick(DialogInterface dialog, int whichButton) {<br />
    
  •                            /* User clicked CANCEL, send CANCEL action<br />
    
  •                             * and text */<br />
    
  •                                listener.onSoftText(SoftTextDialogInputListener.CANCEL, editTextDialogInput.getText().toString());<br />
    
  •                        }<br />
    
  •                    })<br />
    
  •                .create();<br />
    

+

  •            dialogTextInput.show();<br />
    

+

  •        }<br />
    
  •    });<br />
    
  • }

    +

    +}



    [/java]



    InputSystemJme

    [java]

This patch file was generated by NetBeans IDE

Following Index: paths are relative to: D:UserspotterecDocumentsjMonkeyProjectsjME3srcniftyguicomjme3niftygui

This patch can be applied using context Tools: Patch action on respective folder.

It uses platform neutral UTF-8 encoding and n newlines.

Above lines and this line are ignored by the patching process.

Index: InputSystemJme.java

— InputSystemJme.java Base (BASE)

+++ InputSystemJme.java Locally Modified (Based On LOCAL)

@@ -35,13 +35,21 @@

import com.jme3.input.InputManager;

import com.jme3.input.KeyInput;

import com.jme3.input.RawInputListener;

+import com.jme3.input.SoftTextDialogInput;

+import com.jme3.input.controls.SoftTextDialogInputListener;

import com.jme3.input.event.*;

+import com.jme3.system.JmeSystem;

import de.lessvoid.nifty.Nifty;

import de.lessvoid.nifty.NiftyInputConsumer;

+import de.lessvoid.nifty.controls.TextField;

+import de.lessvoid.nifty.controls.nullobjects.TextFieldNull;

+import de.lessvoid.nifty.elements.Element;

import de.lessvoid.nifty.tools.resourceloader.NiftyResourceLoader;

import de.lessvoid.nifty.input.keyboard.KeyboardInputEvent;

import de.lessvoid.nifty.spi.input.InputSystem;

import java.util.ArrayList;

+import java.util.logging.Level;

+import java.util.logging.Logger;



public class InputSystemJme implements InputSystem, RawInputListener {



@@ -116,6 +124,10 @@



isDragging = false;

niftyOwnsDragging = false;

+

  •           if (consumed)<br />
    
  •               processSoftKeyboard();<br />
    

+

break;

}

}

@@ -159,6 +171,9 @@

isDragging = true;

niftyOwnsDragging = consumed;

}

+

  •    if (consumed)<br />
    
  •        processSoftKeyboard();<br />
    

}



private void onKeyEventQueued(KeyInputEvent evt, NiftyInputConsumer nic) {

@@ -230,4 +245,31 @@

}




  • private void processSoftKeyboard() {
  •    SoftTextDialogInput softTextDialogInput = JmeSystem.getSoftTextDialogInput();<br />
    
  •    if (softTextDialogInput != null) {<br />
    

+

  •        Element element = nifty.getCurrentScreen().getFocusHandler().getKeyboardFocusElement();<br />
    
  •        if (element != null) {<br />
    
  •            final TextField textField = element.getNiftyControl(TextField.class);<br />
    
  •            if (textField != null &amp;&amp; !(textField instanceof TextFieldNull)) {<br />
    
  •                Logger.getLogger(InputSystemJme.class.getName()).log(Level.INFO, &quot;Current TextField: {0}&quot;, textField.getId());<br />
    
  •                String initialValue = textField.getText();<br />
    
  •                if (initialValue == null) {<br />
    
  •                    initialValue = &quot;&quot;;<br />
    

}

+

  •                softTextDialogInput.requestDialog(SoftTextDialogInput.TEXT_ENTRY_DIALOG, &quot;Enter Text&quot;, initialValue, new SoftTextDialogInputListener() {<br />
    

+

  •                    public void onSoftText(int action, String text) {<br />
    
  •                        if (action == SoftTextDialogInputListener.COMPLETE) {<br />
    
  •                            textField.setText(text);<br />
    
  •                        }<br />
    
  •                    }<br />
    
  •                });<br />
    
  •            }<br />
    
  •        }<br />
    
  •    }<br />
    
  • }

    +

    +}



    [/java]
2 Likes