Allow copying java EditText to STK editbox
This commit is contained in:
parent
27f0f8c961
commit
e6d5346e5e
@ -166,7 +166,8 @@ LOCAL_CFLAGS := -I../lib/angelscript/include \
|
|||||||
-DNDEBUG \
|
-DNDEBUG \
|
||||||
-DANDROID_PACKAGE_NAME=\"$(PACKAGE_NAME)\" \
|
-DANDROID_PACKAGE_NAME=\"$(PACKAGE_NAME)\" \
|
||||||
-DANDROID_APP_DIR_NAME=\"$(APP_DIR_NAME)\" \
|
-DANDROID_APP_DIR_NAME=\"$(APP_DIR_NAME)\" \
|
||||||
-DSUPERTUXKART_VERSION=\"$(PROJECT_VERSION)\"
|
-DSUPERTUXKART_VERSION=\"$(PROJECT_VERSION)\" \
|
||||||
|
-DANDROID_PACKAGE_CALLBACK_NAME=$(PACKAGE_CALLBACK_NAME)
|
||||||
LOCAL_CPPFLAGS := -std=gnu++0x
|
LOCAL_CPPFLAGS := -std=gnu++0x
|
||||||
|
|
||||||
LOCAL_STATIC_LIBRARIES := irrlicht bullet enet freetype ifaddrs angelscript \
|
LOCAL_STATIC_LIBRARIES := irrlicht bullet enet freetype ifaddrs angelscript \
|
||||||
|
@ -471,7 +471,22 @@ sed -i "s/targetSdkVersion=\".*\"/targetSdkVersion=\"$TARGET_SDK_VERSION\"/g" \
|
|||||||
sed -i "s/package=\".*\"/package=\"$PACKAGE_NAME\"/g" \
|
sed -i "s/package=\".*\"/package=\"$PACKAGE_NAME\"/g" \
|
||||||
"$DIRNAME/AndroidManifest.xml"
|
"$DIRNAME/AndroidManifest.xml"
|
||||||
|
|
||||||
sed -i "s/package .*/package $PACKAGE_NAME;/g" \
|
sed -i "s/package org.supertuxkart.*/package $PACKAGE_NAME;/g" \
|
||||||
|
"$DIRNAME/src/main/java/STKEditText.java"
|
||||||
|
|
||||||
|
sed -i "s/import org.supertuxkart.*/import $PACKAGE_NAME.STKInputConnection;/g" \
|
||||||
|
"$DIRNAME/src/main/java/STKEditText.java"
|
||||||
|
|
||||||
|
sed -i "s/package org.supertuxkart.*/package $PACKAGE_NAME;/g" \
|
||||||
|
"$DIRNAME/src/main/java/STKInputConnection.java"
|
||||||
|
|
||||||
|
sed -i "s/import org.supertuxkart.*.STKEditText;/import $PACKAGE_NAME.STKEditText;/g" \
|
||||||
|
"$DIRNAME/src/main/java/STKInputConnection.java"
|
||||||
|
|
||||||
|
sed -i "s/package org.supertuxkart.*/package $PACKAGE_NAME;/g" \
|
||||||
|
"$DIRNAME/src/main/java/SuperTuxKartActivity.java"
|
||||||
|
|
||||||
|
sed -i "s/import org.supertuxkart.*/import $PACKAGE_NAME.STKEditText;/g" \
|
||||||
"$DIRNAME/src/main/java/SuperTuxKartActivity.java"
|
"$DIRNAME/src/main/java/SuperTuxKartActivity.java"
|
||||||
|
|
||||||
sed -i "s/versionName=\".*\"/versionName=\"$PROJECT_VERSION\"/g" \
|
sed -i "s/versionName=\".*\"/versionName=\"$PROJECT_VERSION\"/g" \
|
||||||
|
78
android/src/main/java/STKEditText.java
Normal file
78
android/src/main/java/STKEditText.java
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
package org.supertuxkart.stk_dbg;
|
||||||
|
|
||||||
|
import org.supertuxkart.stk_dbg.STKInputConnection;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.text.InputType;
|
||||||
|
import android.view.inputmethod.EditorInfo;
|
||||||
|
import android.view.inputmethod.InputConnection;
|
||||||
|
import android.widget.EditText;
|
||||||
|
|
||||||
|
// We need to extend EditText instead of view to allow copying to our STK
|
||||||
|
// editbox
|
||||||
|
public class STKEditText extends EditText
|
||||||
|
{
|
||||||
|
private int m_composing_start;
|
||||||
|
|
||||||
|
private int m_composing_end;
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
private native static void editText2STKEditbox(String full_text, int start,
|
||||||
|
int end, int composing_start,
|
||||||
|
int composing_end);
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
public STKEditText(Context context)
|
||||||
|
{
|
||||||
|
super(context);
|
||||||
|
setFocusableInTouchMode(true);
|
||||||
|
m_composing_start = 0;
|
||||||
|
m_composing_end = 0;
|
||||||
|
}
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
@Override
|
||||||
|
public InputConnection onCreateInputConnection(EditorInfo out_attrs)
|
||||||
|
{
|
||||||
|
STKInputConnection sic =
|
||||||
|
new STKInputConnection(super.onCreateInputConnection(out_attrs), this);
|
||||||
|
out_attrs.actionLabel = null;
|
||||||
|
out_attrs.inputType = InputType.TYPE_CLASS_TEXT;
|
||||||
|
out_attrs.imeOptions = EditorInfo.IME_ACTION_NEXT |
|
||||||
|
EditorInfo.IME_FLAG_NO_FULLSCREEN |
|
||||||
|
EditorInfo.IME_FLAG_NO_EXTRACT_UI;
|
||||||
|
return sic;
|
||||||
|
}
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
@Override
|
||||||
|
public boolean onCheckIsTextEditor() { return true; }
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
public void resetWhenFocus()
|
||||||
|
{
|
||||||
|
clearComposingText();
|
||||||
|
getText().clear();
|
||||||
|
m_composing_start = m_composing_end = 0;
|
||||||
|
}
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
public void setComposingRegion(int start, int end)
|
||||||
|
{
|
||||||
|
// From doc of InputConnectionWrapper, it says:
|
||||||
|
// Editor authors, be ready to accept a start that is greater than end.
|
||||||
|
if (start != end && start > end)
|
||||||
|
{
|
||||||
|
m_composing_end = start;
|
||||||
|
m_composing_start = end;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_composing_start = start;
|
||||||
|
m_composing_end = end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
public void updateSTKEditBox()
|
||||||
|
{
|
||||||
|
if (!isFocused())
|
||||||
|
return;
|
||||||
|
editText2STKEditbox(getText().toString(), getSelectionStart(),
|
||||||
|
getSelectionEnd(), m_composing_start, m_composing_end);
|
||||||
|
}
|
||||||
|
}
|
68
android/src/main/java/STKInputConnection.java
Normal file
68
android/src/main/java/STKInputConnection.java
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
package org.supertuxkart.stk_dbg;
|
||||||
|
|
||||||
|
import org.supertuxkart.stk_dbg.STKEditText;
|
||||||
|
|
||||||
|
import android.view.inputmethod.InputConnection;
|
||||||
|
import android.view.inputmethod.InputConnectionWrapper;
|
||||||
|
|
||||||
|
public class STKInputConnection extends InputConnectionWrapper
|
||||||
|
{
|
||||||
|
/* The global edittext which will be "copied" to the current focused STK
|
||||||
|
* box. */
|
||||||
|
private STKEditText m_stk_edittext;
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
public STKInputConnection(InputConnection target, STKEditText stk_edittext)
|
||||||
|
{
|
||||||
|
super(target, true/*mutable*/);
|
||||||
|
m_stk_edittext = stk_edittext;
|
||||||
|
}
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
@Override
|
||||||
|
public boolean setComposingText(CharSequence text, int new_cursor_position)
|
||||||
|
{
|
||||||
|
boolean ret = super.setComposingText(text, new_cursor_position);
|
||||||
|
String composing_text = text.toString();
|
||||||
|
String new_text = m_stk_edittext.getText().toString();
|
||||||
|
int composing_start = 0;
|
||||||
|
int composing_end = 0;
|
||||||
|
// Test last char
|
||||||
|
if (!composing_text.isEmpty() && !new_text.isEmpty() &&
|
||||||
|
composing_text.charAt(composing_text.length() - 1) ==
|
||||||
|
new_text.charAt(new_text.length() - 1))
|
||||||
|
{
|
||||||
|
composing_start = new_text.length() - composing_text.length();
|
||||||
|
composing_end = composing_start + composing_text.length();
|
||||||
|
}
|
||||||
|
m_stk_edittext.setComposingRegion(composing_start, composing_end);
|
||||||
|
m_stk_edittext.updateSTKEditBox();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
@Override
|
||||||
|
public boolean finishComposingText()
|
||||||
|
{
|
||||||
|
m_stk_edittext.setComposingRegion(0, 0);
|
||||||
|
m_stk_edittext.updateSTKEditBox();
|
||||||
|
return super.finishComposingText();
|
||||||
|
}
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
@Override
|
||||||
|
public boolean setComposingRegion(int start, int end)
|
||||||
|
{
|
||||||
|
m_stk_edittext.setComposingRegion(start, end);
|
||||||
|
m_stk_edittext.updateSTKEditBox();
|
||||||
|
return super.setComposingRegion(start, end);
|
||||||
|
}
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
@Override
|
||||||
|
public boolean commitText(CharSequence text, int new_cursor_position)
|
||||||
|
{
|
||||||
|
// Usually only a single character, so dismiss composing region
|
||||||
|
boolean ret = super.commitText(text, new_cursor_position);
|
||||||
|
m_stk_edittext.setComposingRegion(0, 0);
|
||||||
|
m_stk_edittext.updateSTKEditBox();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,20 +1,27 @@
|
|||||||
package org.supertuxkart.stk_dbg;
|
package org.supertuxkart.stk_dbg;
|
||||||
|
|
||||||
|
import org.supertuxkart.stk_dbg.STKEditText;
|
||||||
|
|
||||||
import android.app.NativeActivity;
|
import android.app.NativeActivity;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.text.Editable;
|
||||||
|
import android.text.TextWatcher;
|
||||||
import android.view.inputmethod.InputMethodManager;
|
import android.view.inputmethod.InputMethodManager;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
|
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.widget.FrameLayout;
|
||||||
|
|
||||||
public class SuperTuxKartActivity extends NativeActivity
|
public class SuperTuxKartActivity extends NativeActivity
|
||||||
{
|
{
|
||||||
private native void saveFromJavaChars(String chars);
|
private STKEditText m_stk_edittext;
|
||||||
private native void saveKeyboardHeight(int height);
|
|
||||||
|
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
private native void saveKeyboardHeight(int height);
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
private void hideNavBar(View decor_view)
|
private void hideNavBar(View decor_view)
|
||||||
{
|
{
|
||||||
if (Build.VERSION.SDK_INT < 19)
|
if (Build.VERSION.SDK_INT < 19)
|
||||||
@ -27,12 +34,14 @@ public class SuperTuxKartActivity extends NativeActivity
|
|||||||
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
|
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN |
|
||||||
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
|
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION);
|
||||||
}
|
}
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
@Override
|
@Override
|
||||||
public void onCreate(Bundle instance)
|
public void onCreate(Bundle instance)
|
||||||
{
|
{
|
||||||
super.onCreate(instance);
|
super.onCreate(instance);
|
||||||
System.loadLibrary("main");
|
System.loadLibrary("main");
|
||||||
|
m_stk_edittext = null;
|
||||||
|
|
||||||
final View root = getWindow().getDecorView().findViewById(
|
final View root = getWindow().getDecorView().findViewById(
|
||||||
android.R.id.content);
|
android.R.id.content);
|
||||||
root.getViewTreeObserver().addOnGlobalLayoutListener(new
|
root.getViewTreeObserver().addOnGlobalLayoutListener(new
|
||||||
@ -61,26 +70,7 @@ public class SuperTuxKartActivity extends NativeActivity
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
@Override
|
|
||||||
public boolean dispatchKeyEvent(KeyEvent event)
|
|
||||||
{
|
|
||||||
// ACTION_MULTIPLE deprecated in API level Q, it says if the key code
|
|
||||||
// is KEYCODE_UNKNOWN, then this is a sequence of characters as
|
|
||||||
// returned by getCharacters()
|
|
||||||
if (event.getKeyCode() == KeyEvent.KEYCODE_UNKNOWN &&
|
|
||||||
event.getAction() == KeyEvent.ACTION_MULTIPLE)
|
|
||||||
{
|
|
||||||
String chars = event.getCharacters();
|
|
||||||
if (chars != null)
|
|
||||||
{
|
|
||||||
saveFromJavaChars(chars);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return super.dispatchKeyEvent(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onWindowFocusChanged(boolean has_focus)
|
public void onWindowFocusChanged(boolean has_focus)
|
||||||
{
|
{
|
||||||
@ -88,20 +78,88 @@ public class SuperTuxKartActivity extends NativeActivity
|
|||||||
if (has_focus)
|
if (has_focus)
|
||||||
hideNavBar(getWindow().getDecorView());
|
hideNavBar(getWindow().getDecorView());
|
||||||
}
|
}
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
@Override
|
||||||
|
public boolean dispatchKeyEvent(KeyEvent event)
|
||||||
|
{
|
||||||
|
// Called when user change cursor / select all text in native android
|
||||||
|
// keyboard
|
||||||
|
boolean ret = super.dispatchKeyEvent(event);
|
||||||
|
if (m_stk_edittext != null)
|
||||||
|
m_stk_edittext.updateSTKEditBox();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
public void showKeyboard()
|
public void showKeyboard()
|
||||||
{
|
{
|
||||||
InputMethodManager imm = (InputMethodManager)
|
final Context context = this;
|
||||||
getSystemService(Context.INPUT_METHOD_SERVICE);
|
// Need to run in ui thread as it access the view m_stk_edittext
|
||||||
imm.showSoftInput(getWindow().getDecorView(),
|
runOnUiThread(new Runnable()
|
||||||
InputMethodManager.SHOW_FORCED);
|
{
|
||||||
}
|
@Override
|
||||||
|
public void run()
|
||||||
public void hideKeyboard()
|
|
||||||
{
|
{
|
||||||
InputMethodManager imm = (InputMethodManager)
|
InputMethodManager imm = (InputMethodManager)
|
||||||
getSystemService(Context.INPUT_METHOD_SERVICE);
|
getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||||
imm.hideSoftInputFromWindow(
|
|
||||||
getWindow().getDecorView().getWindowToken(), 0);
|
FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(
|
||||||
|
FrameLayout.LayoutParams.WRAP_CONTENT,
|
||||||
|
FrameLayout.LayoutParams.WRAP_CONTENT);
|
||||||
|
if (m_stk_edittext == null)
|
||||||
|
{
|
||||||
|
m_stk_edittext = new STKEditText(context);
|
||||||
|
// For some copy-and-paste text are not done by commitText
|
||||||
|
// in STKInputConnection, so we need an extra watcher
|
||||||
|
m_stk_edittext.addTextChangedListener(new TextWatcher()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onTextChanged(CharSequence s,
|
||||||
|
int start, int before,
|
||||||
|
int count) {}
|
||||||
|
@Override
|
||||||
|
public void beforeTextChanged(CharSequence s,
|
||||||
|
int start, int count,
|
||||||
|
int after) {}
|
||||||
|
@Override
|
||||||
|
public void afterTextChanged(Editable edit)
|
||||||
|
{
|
||||||
|
if (m_stk_edittext != null)
|
||||||
|
m_stk_edittext.updateSTKEditBox();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
addContentView(m_stk_edittext, params);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
m_stk_edittext.setLayoutParams(params);
|
||||||
|
|
||||||
|
m_stk_edittext.resetWhenFocus();
|
||||||
|
m_stk_edittext.setVisibility(View.VISIBLE);
|
||||||
|
m_stk_edittext.requestFocus();
|
||||||
|
|
||||||
|
imm.showSoftInput(m_stk_edittext,
|
||||||
|
InputMethodManager.SHOW_FORCED);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// ------------------------------------------------------------------------
|
||||||
|
public void hideKeyboard()
|
||||||
|
{
|
||||||
|
runOnUiThread(new Runnable()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void run()
|
||||||
|
{
|
||||||
|
if (m_stk_edittext == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_stk_edittext.clearFocus();
|
||||||
|
m_stk_edittext.setVisibility(View.GONE);
|
||||||
|
|
||||||
|
InputMethodManager imm = (InputMethodManager)
|
||||||
|
getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||||
|
imm.hideSoftInputFromWindow(m_stk_edittext.getWindowToken(),
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,6 +23,8 @@
|
|||||||
#include "../../../lib/irrlicht/include/IrrCompileConfig.h"
|
#include "../../../lib/irrlicht/include/IrrCompileConfig.h"
|
||||||
#include "../../../lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.h"
|
#include "../../../lib/irrlicht/source/Irrlicht/CIrrDeviceLinux.h"
|
||||||
|
|
||||||
|
#include <cstdlib>
|
||||||
|
|
||||||
#ifdef ANDROID
|
#ifdef ANDROID
|
||||||
#include "../../../lib/irrlicht/source/Irrlicht/CIrrDeviceAndroid.h"
|
#include "../../../lib/irrlicht/source/Irrlicht/CIrrDeviceAndroid.h"
|
||||||
#endif
|
#endif
|
||||||
@ -69,6 +71,9 @@ CGUIEditBox::CGUIEditBox(const wchar_t* text, bool border,
|
|||||||
// FIXME quick hack to enable mark movement with keyboard and mouse for rtl language,
|
// FIXME quick hack to enable mark movement with keyboard and mouse for rtl language,
|
||||||
// don't know why it's disabled in the first place, because STK fail
|
// don't know why it's disabled in the first place, because STK fail
|
||||||
// to input unicode characters before?
|
// to input unicode characters before?
|
||||||
|
m_from_android_edittext = false;
|
||||||
|
m_composing_start = 0;
|
||||||
|
m_composing_end = 0;
|
||||||
|
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
setDebugName("CGUIEditBox");
|
setDebugName("CGUIEditBox");
|
||||||
@ -261,6 +266,9 @@ bool CGUIEditBox::OnEvent(const SEvent& event)
|
|||||||
#ifndef SERVER_ONLY
|
#ifndef SERVER_ONLY
|
||||||
if (isEnabled())
|
if (isEnabled())
|
||||||
{
|
{
|
||||||
|
// Ignore key input if we only fromAndroidEditText
|
||||||
|
if (m_from_android_edittext && event.EventType == EET_KEY_INPUT_EVENT)
|
||||||
|
return true;
|
||||||
switch(event.EventType)
|
switch(event.EventType)
|
||||||
{
|
{
|
||||||
case EET_GUI_EVENT:
|
case EET_GUI_EVENT:
|
||||||
@ -287,6 +295,9 @@ bool CGUIEditBox::OnEvent(const SEvent& event)
|
|||||||
dl->setTextInputEnabled(false);
|
dl->setTextInputEnabled(false);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
m_from_android_edittext = false;
|
||||||
|
m_composing_start = 0;
|
||||||
|
m_composing_end = 0;
|
||||||
}
|
}
|
||||||
else if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUSED)
|
else if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUSED)
|
||||||
{
|
{
|
||||||
@ -1073,6 +1084,19 @@ void CGUIEditBox::draw()
|
|||||||
// it will return the input pointer if (this->isRTLLanguage()) from Translations::isRTLText
|
// it will return the input pointer if (this->isRTLLanguage()) from Translations::isRTLText
|
||||||
// is false
|
// is false
|
||||||
|
|
||||||
|
// draw composing text underline
|
||||||
|
if (!PasswordBox && focus && m_composing_start != m_composing_end && i == hlineStart)
|
||||||
|
{
|
||||||
|
s = txtLine->subString(0, m_composing_start);
|
||||||
|
s32 underline_begin = font->getDimension(s.c_str()).Width;
|
||||||
|
core::rect<s32> underline = CurrentTextRect;
|
||||||
|
underline.UpperLeftCorner.X += underline_begin;
|
||||||
|
s32 height = underline.LowerRightCorner.Y - underline.UpperLeftCorner.Y;
|
||||||
|
underline.UpperLeftCorner.Y += s32(std::abs(height) * 0.9f);
|
||||||
|
underline.LowerRightCorner.Y -= s32(std::abs(height) * 0.08f);
|
||||||
|
GL32_draw2DRectangle(video::SColor(255, 0, 0, 0), underline);
|
||||||
|
}
|
||||||
|
|
||||||
// draw mark and marked text
|
// draw mark and marked text
|
||||||
if (focus && MarkBegin != MarkEnd && i >= hlineStart && i < hlineStart + hlineCount)
|
if (focus && MarkBegin != MarkEnd && i >= hlineStart && i < hlineStart + hlineCount)
|
||||||
{
|
{
|
||||||
@ -1780,3 +1804,40 @@ void CGUIEditBox::openScreenKeyboard()
|
|||||||
new GUIEngine::ScreenKeyboard(1.0f, 0.40f, this);
|
new GUIEngine::ScreenKeyboard(1.0f, 0.40f, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Real copying is happening in text_box_widget.cpp with static function
|
||||||
|
void CGUIEditBox::fromAndroidEditText(const core::stringw& text, int start,
|
||||||
|
int end, int composing_start,
|
||||||
|
int composing_end)
|
||||||
|
{
|
||||||
|
// When focus of this element is lost, this will be set to false again
|
||||||
|
m_from_android_edittext = true;
|
||||||
|
Text = text;
|
||||||
|
// Prevent invalid start or end
|
||||||
|
if ((unsigned)end > Text.size())
|
||||||
|
{
|
||||||
|
end = (int)Text.size();
|
||||||
|
start = end;
|
||||||
|
}
|
||||||
|
|
||||||
|
CursorPos = end;
|
||||||
|
m_composing_start = 0;
|
||||||
|
m_composing_end = 0;
|
||||||
|
|
||||||
|
if (start != end)
|
||||||
|
setTextMarkers(start, end);
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MarkBegin = 0;
|
||||||
|
MarkEnd = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (composing_start != composing_end)
|
||||||
|
{
|
||||||
|
if (composing_start < 0)
|
||||||
|
composing_start = 0;
|
||||||
|
if (composing_end > end)
|
||||||
|
composing_end = end;
|
||||||
|
m_composing_start = composing_start;
|
||||||
|
m_composing_end = composing_end;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -119,6 +119,8 @@ using namespace gui;
|
|||||||
virtual irr::gui::IGUIFont* getActiveFont() const { return NULL; }
|
virtual irr::gui::IGUIFont* getActiveFont() const { return NULL; }
|
||||||
virtual void setDrawBackground(bool) { }
|
virtual void setDrawBackground(bool) { }
|
||||||
|
|
||||||
|
void fromAndroidEditText(const core::stringw& text, int start, int end,
|
||||||
|
int composing_start, int composing_end);
|
||||||
void openScreenKeyboard();
|
void openScreenKeyboard();
|
||||||
s32 getCursorPosInBox() const { return CursorPos; }
|
s32 getCursorPosInBox() const { return CursorPos; }
|
||||||
s32 getTextCount() const { return (s32)Text.size(); }
|
s32 getTextCount() const { return (s32)Text.size(); }
|
||||||
@ -174,6 +176,13 @@ using namespace gui;
|
|||||||
core::array< s32 > BrokenTextPositions;
|
core::array< s32 > BrokenTextPositions;
|
||||||
|
|
||||||
core::rect<s32> CurrentTextRect, FrameRect; // temporary values
|
core::rect<s32> CurrentTextRect, FrameRect; // temporary values
|
||||||
|
|
||||||
|
s32 m_composing_start;
|
||||||
|
s32 m_composing_end;
|
||||||
|
|
||||||
|
/* If true, this editbox will copy text and selection only from
|
||||||
|
* android edittext, and process only mouse event. */
|
||||||
|
bool m_from_android_edittext;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -228,3 +228,34 @@ EventPropagation TextBoxWidget::leftPressed (const int playerID)
|
|||||||
|
|
||||||
return EVENT_LET;
|
return EVENT_LET;
|
||||||
} // leftPressed
|
} // leftPressed
|
||||||
|
|
||||||
|
// ============================================================================
|
||||||
|
/* This callback will allow copying android edittext data directly to editbox,
|
||||||
|
* which will allow composing text to be auto updated. */
|
||||||
|
#ifdef ANDROID
|
||||||
|
#include "jni.h"
|
||||||
|
|
||||||
|
#if !defined(ANDROID_PACKAGE_CALLBACK_NAME)
|
||||||
|
#error
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define MAKE_EDITTEXT_CALLBACK(x) JNIEXPORT void JNICALL Java_ ## x##_STKEditText_editText2STKEditbox(JNIEnv* env, jobject this_obj, jstring text, jint start, jint end, jint composing_start, jint composing_end)
|
||||||
|
#define ANDROID_EDITTEXT_CALLBACK(PKG_NAME) MAKE_EDITTEXT_CALLBACK(PKG_NAME)
|
||||||
|
|
||||||
|
extern "C"
|
||||||
|
ANDROID_EDITTEXT_CALLBACK(ANDROID_PACKAGE_CALLBACK_NAME)
|
||||||
|
{
|
||||||
|
TextBoxWidget* tb = dynamic_cast<TextBoxWidget*>(getFocusForPlayer(0));
|
||||||
|
if (!tb || text == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const char* utf8_text = env->GetStringUTFChars(text, NULL);
|
||||||
|
if (utf8_text == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
core::stringw to_editbox = StringUtils::utf8ToWide(utf8_text);
|
||||||
|
tb->getIrrlichtElement<MyCGUIEditBox>()->fromAndroidEditText(
|
||||||
|
to_editbox, start, end, composing_start, composing_end);
|
||||||
|
env->ReleaseStringUTFChars(text, utf8_text);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user