mirror of https://github.com/axmolengine/axmol.git
CCIMEDispatcher works on android.
This commit is contained in:
parent
85027c40ca
commit
252f3efe1a
|
@ -2,17 +2,145 @@ package org.cocos2dx.lib;
|
|||
|
||||
import android.content.Context;
|
||||
import android.opengl.GLSurfaceView;
|
||||
import android.os.Bundle;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.inputmethod.CompletionInfo;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.view.inputmethod.ExtractedText;
|
||||
import android.view.inputmethod.ExtractedTextRequest;
|
||||
import android.view.inputmethod.InputConnection;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
|
||||
class Cocos2dxInputConnection implements InputConnection {
|
||||
|
||||
@Override
|
||||
public boolean beginBatchEdit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean clearMetaKeyStates(int states) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean commitCompletion(CompletionInfo text) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean commitText(CharSequence text, int newCursorPosition) {
|
||||
if (null != mView) {
|
||||
final String insertText = text.toString();
|
||||
mView.insertText(insertText);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteSurroundingText(int leftLength, int rightLength) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean endBatchEdit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean finishComposingText() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCursorCapsMode(int reqModes) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExtractedText getExtractedText(ExtractedTextRequest request,
|
||||
int flags) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getTextAfterCursor(int n, int flags) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getTextBeforeCursor(int n, int flags) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean performContextMenuAction(int id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean performEditorAction(int editorAction) {
|
||||
if (null != mView) {
|
||||
final String insertText = "\n";
|
||||
mView.insertText(insertText);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean performPrivateCommand(String action, Bundle data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean reportFullscreenMode(boolean enabled) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean sendKeyEvent(KeyEvent event) {
|
||||
if (null != mView) {
|
||||
switch (event.getKeyCode()) {
|
||||
|
||||
case KeyEvent.KEYCODE_DEL:
|
||||
mView.deleteBackward();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setComposingText(CharSequence text, int newCursorPosition) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setSelection(int start, int end) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setGLSurfaceView(Cocos2dxGLSurfaceView view) {
|
||||
mView = view;
|
||||
}
|
||||
|
||||
private Cocos2dxGLSurfaceView mView;
|
||||
}
|
||||
|
||||
public class Cocos2dxGLSurfaceView extends GLSurfaceView {
|
||||
private static final String TAG = Cocos2dxGLSurfaceView.class
|
||||
.getCanonicalName();
|
||||
|
||||
static private Cocos2dxGLSurfaceView mainView;
|
||||
|
||||
private static final String TAG = Cocos2dxGLSurfaceView.class.getCanonicalName();
|
||||
private Cocos2dxRenderer mRenderer;
|
||||
private final boolean debug = false;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// for initialize
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
public Cocos2dxGLSurfaceView(Context context) {
|
||||
super(context);
|
||||
initView();
|
||||
|
@ -27,8 +155,86 @@ public class Cocos2dxGLSurfaceView extends GLSurfaceView {
|
|||
mRenderer = new Cocos2dxRenderer();
|
||||
setFocusableInTouchMode(true);
|
||||
setRenderer(mRenderer);
|
||||
mainView = this;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// for text input
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public static void openIMEKeyboard() {
|
||||
if (null == mainView) {
|
||||
return;
|
||||
}
|
||||
InputMethodManager imm = (InputMethodManager)mainView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
if (imm == null) {
|
||||
return;
|
||||
}
|
||||
imm.showSoftInput(mainView, InputMethodManager.SHOW_IMPLICIT);
|
||||
}
|
||||
|
||||
public static void closeIMEKeyboard() {
|
||||
if (null != mainView) {
|
||||
Log.d("Cocos2dxGLSurfaceView", "closeIMEKeyboard");
|
||||
}
|
||||
InputMethodManager imm = (InputMethodManager)mainView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
if (imm == null) {
|
||||
return;
|
||||
}
|
||||
imm.hideSoftInputFromWindow(mainView.getWindowToken(), 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCheckIsTextEditor() {
|
||||
if (null == mainView)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private Cocos2dxInputConnection ic;
|
||||
@Override
|
||||
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
|
||||
if (onCheckIsTextEditor()) {
|
||||
|
||||
outAttrs.inputType = EditorInfo.TYPE_CLASS_TEXT;
|
||||
outAttrs.imeOptions = EditorInfo.IME_NULL;
|
||||
outAttrs.initialSelStart = -1;
|
||||
outAttrs.initialSelEnd = -1;
|
||||
outAttrs.initialCapsMode = 0;
|
||||
|
||||
if (null == ic)
|
||||
{
|
||||
ic = new Cocos2dxInputConnection();
|
||||
ic.setGLSurfaceView(this);
|
||||
}
|
||||
return ic;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void insertText(final String text) {
|
||||
queueEvent(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mRenderer.handleInsertText(text);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void deleteBackward() {
|
||||
queueEvent(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mRenderer.handleDeleteBackward();
|
||||
}
|
||||
});
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// for touch event
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public boolean onTouchEvent(final MotionEvent event) {
|
||||
// these data are used in ACTION_MOVE and ACTION_CANCEL
|
||||
final int pointerNumber = event.getPointerCount();
|
||||
|
|
|
@ -67,12 +67,26 @@ public class Cocos2dxRenderer implements GLSurfaceView.Renderer {
|
|||
public static void setAnimationInterval(double interval){
|
||||
animationInterval = (long)(interval * NANOSECONDSPERSECOND);
|
||||
}
|
||||
|
||||
private static native void nativeTouchesBegin(int id, float x, float y);
|
||||
private static native void nativeTouchesEnd(int id, float x, float y);
|
||||
private static native void nativeTouchesMove(int[] id, float[] x, float[] y);
|
||||
private static native void nativeTouchesCancel(int[] id, float[] x, float[] y);
|
||||
private static native boolean nativeKeyDown(int keyCode);
|
||||
private static native boolean nativeKeyDown(int keyCode);
|
||||
private static native void nativeRender();
|
||||
private static native void nativeInit(int w, int h);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// handle input method edit message
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void handleInsertText(final String text) {
|
||||
nativeInsertText(text);
|
||||
}
|
||||
|
||||
public void handleDeleteBackward() {
|
||||
nativeDeleteBackward();
|
||||
}
|
||||
|
||||
private static native void nativeInsertText(String text);
|
||||
private static native void nativeDeleteBackward();
|
||||
}
|
||||
|
|
|
@ -82,6 +82,8 @@ support/image_support/TGAlib.cpp \
|
|||
support/zip_support/ZipUtils.cpp \
|
||||
support/zip_support/ioapi.cpp \
|
||||
support/zip_support/unzip.cpp \
|
||||
text_input_node/CCIMEDispatcher.cpp \
|
||||
text_input_node/CCTextFieldTTF.cpp \
|
||||
textures/CCTexture2D.cpp \
|
||||
textures/CCTextureAtlas.cpp \
|
||||
textures/CCTextureCache.cpp \
|
||||
|
@ -135,4 +137,4 @@ LOCAL_LDLIBS := -L$(LOCAL_PATH)/platform/third_party/android/libraries \
|
|||
# define the macro to compile through support/zip_support/ioapi.c
|
||||
LOCAL_CFLAGS := -DUSE_FILE32API
|
||||
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
include $(BUILD_SHARED_LIBRARY)
|
||||
|
|
|
@ -28,6 +28,7 @@ THE SOFTWARE.
|
|||
#include "CCDirector.h"
|
||||
#include "ccMacros.h"
|
||||
#include "CCTouchDispatcher.h"
|
||||
#include "Cocos2dJni.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
|
@ -127,21 +128,21 @@ void CCEGLView::setContentScaleFactor(float contentScaleFactor)
|
|||
|
||||
void CCEGLView::setViewPortInPoints(float x, float y, float w, float h)
|
||||
{
|
||||
if (m_bNotHVGA)
|
||||
{
|
||||
float factor = m_fScreenScaleFactor / CC_CONTENT_SCALE_FACTOR();
|
||||
glViewport((GLint)(x * factor) + m_rcViewPort.origin.x,
|
||||
(GLint)(y * factor) + m_rcViewPort.origin.y,
|
||||
(GLint)(w * factor),
|
||||
(GLint)(h * factor));
|
||||
}
|
||||
else
|
||||
{
|
||||
glViewport((GLint)x,
|
||||
(GLint)y,
|
||||
(GLint)w,
|
||||
(GLint)h);
|
||||
}
|
||||
if (m_bNotHVGA)
|
||||
{
|
||||
float factor = m_fScreenScaleFactor / CC_CONTENT_SCALE_FACTOR();
|
||||
glViewport((GLint)(x * factor) + m_rcViewPort.origin.x,
|
||||
(GLint)(y * factor) + m_rcViewPort.origin.y,
|
||||
(GLint)(w * factor),
|
||||
(GLint)(h * factor));
|
||||
}
|
||||
else
|
||||
{
|
||||
glViewport((GLint)x,
|
||||
(GLint)y,
|
||||
(GLint)w,
|
||||
(GLint)h);
|
||||
}
|
||||
}
|
||||
|
||||
CCEGLView& CCEGLView::sharedOpenGLView()
|
||||
|
@ -157,15 +158,21 @@ float CCEGLView::getScreenScaleFactor()
|
|||
|
||||
CCRect CCEGLView::getViewPort()
|
||||
{
|
||||
if (m_bNotHVGA)
|
||||
{
|
||||
return m_rcViewPort;
|
||||
}
|
||||
else
|
||||
{
|
||||
CCRect rect(0, 0, 0, 0);
|
||||
return rect;
|
||||
}
|
||||
if (m_bNotHVGA)
|
||||
{
|
||||
return m_rcViewPort;
|
||||
}
|
||||
else
|
||||
{
|
||||
CCRect rect(0, 0, 0, 0);
|
||||
return rect;
|
||||
}
|
||||
}
|
||||
|
||||
void CCEGLView::setIMEKeyboardState(bool bOpen)
|
||||
{
|
||||
|
||||
setKeyboardStateJNI((int)bOpen);
|
||||
}
|
||||
|
||||
} // end of namespace cocos2d
|
||||
|
|
|
@ -60,6 +60,7 @@ public:
|
|||
void setViewPortInPoints(float x, float y, float w, float h);
|
||||
CCRect getViewPort();
|
||||
float getScreenScaleFactor();
|
||||
void setIMEKeyboardState(bool bOpen);
|
||||
|
||||
// static function
|
||||
/**
|
||||
|
|
|
@ -29,6 +29,7 @@ THE SOFTWARE.
|
|||
#include "CCTouchDispatcher.h"
|
||||
#include "CCFileUtils.h"
|
||||
#include "CCGeometry.h"
|
||||
#include "CCIMEDispatcher.h"
|
||||
#include "platform/android/CCAccelerometer_android.h"
|
||||
#include <android/log.h>
|
||||
|
||||
|
@ -43,24 +44,73 @@ using namespace cocos2d;
|
|||
|
||||
extern "C"
|
||||
{
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// java vm helper function
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define MAX_TOUCHES 5
|
||||
static CCTouch *s_pTouches[MAX_TOUCHES] = { NULL };
|
||||
JavaVM *gJavaVM = NULL;
|
||||
|
||||
// handle accelerometer changes
|
||||
jint JNI_OnLoad(JavaVM *vm, void *reserved)
|
||||
{
|
||||
gJavaVM = vm;
|
||||
return JNI_VERSION_1_4;
|
||||
}
|
||||
|
||||
void Java_org_cocos2dx_lib_Cocos2dxAccelerometer_onSensorChanged(JNIEnv* env, jobject thiz, jfloat x, jfloat y, jfloat z, jlong timeStamp)
|
||||
{
|
||||
// We need to invert to make it compatible with iOS.
|
||||
CCRect rcRect = CCEGLView::sharedOpenGLView().getViewPort();
|
||||
float fScreenScaleFactor = CCEGLView::sharedOpenGLView().getScreenScaleFactor();
|
||||
cocos2d::CCAccelerometer::sharedAccelerometer()->update((x - rcRect.origin.x) / fScreenScaleFactor,
|
||||
(y - rcRect.origin.y) / fScreenScaleFactor,
|
||||
z,
|
||||
timeStamp);
|
||||
}
|
||||
struct TMethodJNI
|
||||
{
|
||||
JNIEnv * env;
|
||||
jclass classID;
|
||||
jmethodID methodID;
|
||||
};
|
||||
static bool getMethodID(struct TMethodJNI& t, const char *className, const char *methodName, const char *paramCode)
|
||||
{
|
||||
bool ret = 0;
|
||||
do
|
||||
{
|
||||
if (gJavaVM->GetEnv((void**)&t.env, JNI_VERSION_1_4) != JNI_OK)
|
||||
{
|
||||
LOGD("Failed to get the environment using GetEnv()");
|
||||
break;
|
||||
}
|
||||
|
||||
// handle touch event
|
||||
if (gJavaVM->AttachCurrentThread(&t.env, 0) < 0)
|
||||
{
|
||||
LOGD("Failed to get the environment using AttachCurrentThread()");
|
||||
break;
|
||||
}
|
||||
|
||||
t.classID = t.env->FindClass(className);
|
||||
if (! t.classID)
|
||||
{
|
||||
LOGD("Failed to find class of %s", className);
|
||||
break;
|
||||
}
|
||||
|
||||
t.methodID = t.env->GetStaticMethodID(t.classID, methodName, paramCode);
|
||||
if (! t.methodID)
|
||||
{
|
||||
LOGD("Failed to find method id of %s", methodName);
|
||||
break;
|
||||
}
|
||||
ret = true;
|
||||
} while (0);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// native renderer
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#define MAX_TOUCHES 5
|
||||
static CCTouch *s_pTouches[MAX_TOUCHES] = { NULL };
|
||||
|
||||
void Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeRender(JNIEnv* env)
|
||||
{
|
||||
cocos2d::CCDirector::sharedDirector()->mainLoop();
|
||||
}
|
||||
|
||||
// handle touch event
|
||||
void Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeTouchesBegin(JNIEnv* env, jobject thiz, jint id, jfloat x, jfloat y)
|
||||
{
|
||||
CCRect rcRect = CCEGLView::sharedOpenGLView().getViewPort();
|
||||
|
@ -196,6 +246,21 @@ extern "C"
|
|||
return JNI_FALSE;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// handle accelerometer changes
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Java_org_cocos2dx_lib_Cocos2dxAccelerometer_onSensorChanged(JNIEnv* env, jobject thiz, jfloat x, jfloat y, jfloat z, jlong timeStamp)
|
||||
{
|
||||
// We need to invert to make it compatible with iOS.
|
||||
CCRect rcRect = CCEGLView::sharedOpenGLView().getViewPort();
|
||||
float fScreenScaleFactor = CCEGLView::sharedOpenGLView().getScreenScaleFactor();
|
||||
cocos2d::CCAccelerometer::sharedAccelerometer()->update((x - rcRect.origin.x) / fScreenScaleFactor,
|
||||
(y - rcRect.origin.y) / fScreenScaleFactor,
|
||||
z,
|
||||
timeStamp);
|
||||
}
|
||||
|
||||
void Java_org_cocos2dx_lib_Cocos2dxActivity_nativeSetPaths(JNIEnv* env, jobject thiz, jstring apkPath)
|
||||
{
|
||||
const char* str;
|
||||
|
@ -207,72 +272,29 @@ extern "C"
|
|||
}
|
||||
}
|
||||
|
||||
// record the java vm
|
||||
|
||||
JavaVM *gJavaVM = NULL;
|
||||
jclass classOfCocos2dxActivity = 0;
|
||||
JNIEnv *env = 0;
|
||||
|
||||
jint JNI_OnLoad(JavaVM *vm, void *reserved)
|
||||
{
|
||||
gJavaVM = vm;
|
||||
return JNI_VERSION_1_4;
|
||||
}
|
||||
|
||||
static jmethodID getMethodID(const char *methodName, const char *paramCode)
|
||||
{
|
||||
jmethodID ret = 0;
|
||||
|
||||
// get jni environment and java class for Cocos2dxActivity
|
||||
if (gJavaVM->GetEnv((void**)&env, JNI_VERSION_1_4) != JNI_OK)
|
||||
{
|
||||
LOGD("Failed to get the environment using GetEnv()");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (gJavaVM->AttachCurrentThread(&env, 0) < 0)
|
||||
{
|
||||
LOGD("Failed to get the environment using AttachCurrentThread()");
|
||||
return 0;
|
||||
}
|
||||
|
||||
classOfCocos2dxActivity = env->FindClass("org/cocos2dx/lib/Cocos2dxActivity");
|
||||
if (! classOfCocos2dxActivity)
|
||||
{
|
||||
LOGD("Failed to find class of org/cocos2dx/lib/Cocos2dxActivity");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (env != 0 && classOfCocos2dxActivity != 0)
|
||||
{
|
||||
ret = env->GetStaticMethodID(classOfCocos2dxActivity, methodName, paramCode);
|
||||
}
|
||||
|
||||
if (! ret)
|
||||
{
|
||||
LOGD("get method id of %s error", methodName);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void enableAccelerometerJNI()
|
||||
{
|
||||
jmethodID methodID = getMethodID("enableAccelerometer", "()V");
|
||||
|
||||
if (methodID)
|
||||
TMethodJNI t;
|
||||
if (getMethodID(t
|
||||
, "org/cocos2dx/lib/Cocos2dxActivity"
|
||||
, "enableAccelerometer"
|
||||
, "()V"))
|
||||
{
|
||||
env->CallStaticVoidMethod(classOfCocos2dxActivity, methodID);
|
||||
t.env->CallStaticVoidMethod(t.classID, t.methodID);
|
||||
}
|
||||
}
|
||||
|
||||
void disableAccelerometerJNI()
|
||||
{
|
||||
jmethodID methodID = getMethodID("disableAccelerometer", "()V");
|
||||
TMethodJNI t;
|
||||
|
||||
if (methodID)
|
||||
if (getMethodID(t
|
||||
, "org/cocos2dx/lib/Cocos2dxActivity"
|
||||
, "disableAccelerometer"
|
||||
, "()V"))
|
||||
{
|
||||
env->CallStaticVoidMethod(classOfCocos2dxActivity, methodID);
|
||||
t.env->CallStaticVoidMethod(t.classID, t.methodID);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -283,30 +305,58 @@ extern "C"
|
|||
return;
|
||||
}
|
||||
|
||||
jmethodID methodID = getMethodID("showMessageBox", "(Ljava/lang/String;Ljava/lang/String;)V");
|
||||
|
||||
if (methodID)
|
||||
TMethodJNI t;
|
||||
if (getMethodID(t
|
||||
, "org/cocos2dx/lib/Cocos2dxActivity"
|
||||
, "showMessageBox"
|
||||
, "(Ljava/lang/String;Ljava/lang/String;)V"))
|
||||
{
|
||||
jstring StringArg1;
|
||||
|
||||
if (! pszTitle)
|
||||
{
|
||||
StringArg1 = env->NewStringUTF("");
|
||||
StringArg1 = t.env->NewStringUTF("");
|
||||
}
|
||||
else
|
||||
{
|
||||
StringArg1 = env->NewStringUTF(pszTitle);
|
||||
StringArg1 = t.env->NewStringUTF(pszTitle);
|
||||
}
|
||||
|
||||
jstring StringArg2 = env->NewStringUTF(pszMsg);
|
||||
env->CallStaticVoidMethod(classOfCocos2dxActivity, methodID, StringArg1, StringArg2);
|
||||
jstring StringArg2 = t.env->NewStringUTF(pszMsg);
|
||||
t.env->CallStaticVoidMethod(t.classID, t.methodID, StringArg1, StringArg2);
|
||||
}
|
||||
}
|
||||
|
||||
// native renderer
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
// handle IME message
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeRender(JNIEnv* env)
|
||||
{
|
||||
cocos2d::CCDirector::sharedDirector()->mainLoop();
|
||||
}
|
||||
void setKeyboardStateJNI(int bOpen)
|
||||
{
|
||||
TMethodJNI t;
|
||||
jint open = bOpen;
|
||||
if (getMethodID(t
|
||||
, "org/cocos2dx/lib/Cocos2dxGLSurfaceView"
|
||||
, (bOpen) ? "openIMEKeyboard" : "closeIMEKeyboard"
|
||||
, "()V"))
|
||||
{
|
||||
t.env->CallStaticVoidMethod(t.classID, t.methodID);
|
||||
}
|
||||
}
|
||||
|
||||
void Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeInsertText(JNIEnv* env, jobject thiz, jstring text)
|
||||
{
|
||||
jboolean isCopy = 0;
|
||||
const char* pszText = env->GetStringUTFChars(text, &isCopy);
|
||||
if (isCopy)
|
||||
{
|
||||
cocos2d::CCIMEDispatcher::sharedDispatcher()->dispatchInsertText(pszText, strlen(pszText));
|
||||
env->ReleaseStringUTFChars(text, pszText);
|
||||
}
|
||||
}
|
||||
|
||||
void Java_org_cocos2dx_lib_Cocos2dxRenderer_nativeDeleteBackward(JNIEnv* env, jobject thiz)
|
||||
{
|
||||
cocos2d::CCIMEDispatcher::sharedDispatcher()->dispatchDeleteBackward();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -33,6 +33,7 @@ extern "C"
|
|||
void enableAccelerometerJNI();
|
||||
void disableAccelerometerJNI();
|
||||
void showMessageBoxJNI(const char * pszMsg, const char * pszTitle);
|
||||
void setKeyboardStateJNI(int bOpen);
|
||||
}
|
||||
|
||||
#endif // __ANDROID_COCOS2D_JNI_H__
|
||||
|
|
|
@ -319,6 +319,10 @@ LRESULT CCEGLView::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
|
|||
{
|
||||
CCIMEDispatcher::sharedDispatcher()->dispatchDeleteBackward();
|
||||
}
|
||||
else if (VK_RETURN == wParam)
|
||||
{
|
||||
CCIMEDispatcher::sharedDispatcher()->dispatchInsertText("\n", 1);
|
||||
}
|
||||
else if (VK_TAB == wParam)
|
||||
{
|
||||
// tab input
|
||||
|
@ -327,13 +331,19 @@ LRESULT CCEGLView::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
|
|||
{
|
||||
// ESC input
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
char szUtf8[8] = {0};
|
||||
int nLen = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)&wParam, 1, szUtf8, sizeof(szUtf8), NULL, NULL);
|
||||
else if (wParam < 128)
|
||||
{
|
||||
// ascii char
|
||||
CCIMEDispatcher::sharedDispatcher()->dispatchInsertText((const char *)&wParam, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
char szUtf8[8] = {0};
|
||||
int nLen = WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)&wParam, 1, szUtf8, sizeof(szUtf8), NULL, NULL);
|
||||
|
||||
CCIMEDispatcher::sharedDispatcher()->dispatchInsertText(szUtf8, nLen);
|
||||
CCIMEDispatcher::sharedDispatcher()->dispatchInsertText(szUtf8, nLen);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -155,9 +155,29 @@ void CCTextFieldTTF::detatchWithIME()
|
|||
|
||||
void CCTextFieldTTF::insertText(const char * text, int len)
|
||||
{
|
||||
std::string sInsert(text, len);
|
||||
|
||||
// insert \n means input end
|
||||
int nPos = sInsert.find('\n');
|
||||
if (sInsert.npos != nPos)
|
||||
{
|
||||
len = nPos;
|
||||
sInsert.erase(nPos);
|
||||
}
|
||||
if (len <= 0)
|
||||
{
|
||||
// close keyboard
|
||||
CCEGLView * pGlView = CCDirector::sharedDirector()->getOpenGLView();
|
||||
if (pGlView)
|
||||
{
|
||||
pGlView->setIMEKeyboardState(false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
m_bLock = true;
|
||||
std::string sText(*m_pInputText);
|
||||
sText.append(text, len);
|
||||
sText.append(sInsert);
|
||||
m_pLens->push_back((unsigned short)len);
|
||||
setString(sText.c_str());
|
||||
m_bLock = false;
|
||||
|
|
|
@ -2,17 +2,145 @@ package org.cocos2dx.lib;
|
|||
|
||||
import android.content.Context;
|
||||
import android.opengl.GLSurfaceView;
|
||||
import android.os.Bundle;
|
||||
import android.util.AttributeSet;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.inputmethod.CompletionInfo;
|
||||
import android.view.inputmethod.EditorInfo;
|
||||
import android.view.inputmethod.ExtractedText;
|
||||
import android.view.inputmethod.ExtractedTextRequest;
|
||||
import android.view.inputmethod.InputConnection;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
|
||||
class Cocos2dxInputConnection implements InputConnection {
|
||||
|
||||
@Override
|
||||
public boolean beginBatchEdit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean clearMetaKeyStates(int states) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean commitCompletion(CompletionInfo text) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean commitText(CharSequence text, int newCursorPosition) {
|
||||
if (null != mView) {
|
||||
final String insertText = text.toString();
|
||||
mView.insertText(insertText);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteSurroundingText(int leftLength, int rightLength) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean endBatchEdit() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean finishComposingText() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getCursorCapsMode(int reqModes) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ExtractedText getExtractedText(ExtractedTextRequest request,
|
||||
int flags) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getTextAfterCursor(int n, int flags) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public CharSequence getTextBeforeCursor(int n, int flags) {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean performContextMenuAction(int id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean performEditorAction(int editorAction) {
|
||||
if (null != mView) {
|
||||
final String insertText = "\n";
|
||||
mView.insertText(insertText);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean performPrivateCommand(String action, Bundle data) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean reportFullscreenMode(boolean enabled) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean sendKeyEvent(KeyEvent event) {
|
||||
if (null != mView) {
|
||||
switch (event.getKeyCode()) {
|
||||
|
||||
case KeyEvent.KEYCODE_DEL:
|
||||
mView.deleteBackward();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setComposingText(CharSequence text, int newCursorPosition) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean setSelection(int start, int end) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public void setGLSurfaceView(Cocos2dxGLSurfaceView view) {
|
||||
mView = view;
|
||||
}
|
||||
|
||||
private Cocos2dxGLSurfaceView mView;
|
||||
}
|
||||
|
||||
public class Cocos2dxGLSurfaceView extends GLSurfaceView {
|
||||
private static final String TAG = Cocos2dxGLSurfaceView.class
|
||||
.getCanonicalName();
|
||||
|
||||
static private Cocos2dxGLSurfaceView mainView;
|
||||
|
||||
private static final String TAG = Cocos2dxGLSurfaceView.class.getCanonicalName();
|
||||
private Cocos2dxRenderer mRenderer;
|
||||
private final boolean debug = false;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// for initialize
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
public Cocos2dxGLSurfaceView(Context context) {
|
||||
super(context);
|
||||
initView();
|
||||
|
@ -27,8 +155,86 @@ public class Cocos2dxGLSurfaceView extends GLSurfaceView {
|
|||
mRenderer = new Cocos2dxRenderer();
|
||||
setFocusableInTouchMode(true);
|
||||
setRenderer(mRenderer);
|
||||
mainView = this;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// for text input
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public static void openIMEKeyboard() {
|
||||
if (null == mainView) {
|
||||
return;
|
||||
}
|
||||
InputMethodManager imm = (InputMethodManager)mainView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
if (imm == null) {
|
||||
return;
|
||||
}
|
||||
imm.showSoftInput(mainView, InputMethodManager.SHOW_IMPLICIT);
|
||||
}
|
||||
|
||||
public static void closeIMEKeyboard() {
|
||||
if (null != mainView) {
|
||||
Log.d("Cocos2dxGLSurfaceView", "closeIMEKeyboard");
|
||||
}
|
||||
InputMethodManager imm = (InputMethodManager)mainView.getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
if (imm == null) {
|
||||
return;
|
||||
}
|
||||
imm.hideSoftInputFromWindow(mainView.getWindowToken(), 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCheckIsTextEditor() {
|
||||
if (null == mainView)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private Cocos2dxInputConnection ic;
|
||||
@Override
|
||||
public InputConnection onCreateInputConnection(EditorInfo outAttrs) {
|
||||
if (onCheckIsTextEditor()) {
|
||||
|
||||
outAttrs.inputType = EditorInfo.TYPE_CLASS_TEXT;
|
||||
outAttrs.imeOptions = EditorInfo.IME_NULL;
|
||||
outAttrs.initialSelStart = -1;
|
||||
outAttrs.initialSelEnd = -1;
|
||||
outAttrs.initialCapsMode = 0;
|
||||
|
||||
if (null == ic)
|
||||
{
|
||||
ic = new Cocos2dxInputConnection();
|
||||
ic.setGLSurfaceView(this);
|
||||
}
|
||||
return ic;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public void insertText(final String text) {
|
||||
queueEvent(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mRenderer.handleInsertText(text);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void deleteBackward() {
|
||||
queueEvent(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mRenderer.handleDeleteBackward();
|
||||
}
|
||||
});
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// for touch event
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public boolean onTouchEvent(final MotionEvent event) {
|
||||
// these data are used in ACTION_MOVE and ACTION_CANCEL
|
||||
final int pointerNumber = event.getPointerCount();
|
||||
|
|
|
@ -67,12 +67,26 @@ public class Cocos2dxRenderer implements GLSurfaceView.Renderer {
|
|||
public static void setAnimationInterval(double interval){
|
||||
animationInterval = (long)(interval * NANOSECONDSPERSECOND);
|
||||
}
|
||||
|
||||
private static native void nativeTouchesBegin(int id, float x, float y);
|
||||
private static native void nativeTouchesEnd(int id, float x, float y);
|
||||
private static native void nativeTouchesMove(int[] id, float[] x, float[] y);
|
||||
private static native void nativeTouchesCancel(int[] id, float[] x, float[] y);
|
||||
private static native boolean nativeKeyDown(int keyCode);
|
||||
private static native boolean nativeKeyDown(int keyCode);
|
||||
private static native void nativeRender();
|
||||
private static native void nativeInit(int w, int h);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
// handle input method edit message
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
public void handleInsertText(final String text) {
|
||||
nativeInsertText(text);
|
||||
}
|
||||
|
||||
public void handleDeleteBackward() {
|
||||
nativeDeleteBackward();
|
||||
}
|
||||
|
||||
private static native void nativeInsertText(String text);
|
||||
private static native void nativeDeleteBackward();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue