Add a language changer

This commit is contained in:
khanhduytran0 2020-11-01 12:20:11 +07:00
parent c4e56b045c
commit dc4ca549d9
4 changed files with 410 additions and 9 deletions

View File

@ -22,7 +22,7 @@
android:screenOrientation="sensorLandscape"
android:label="@string/app_short_name"
android:name=".PojavLoginActivity"
android:configChanges="keyboardHidden|orientation|screenSize">
android:configChanges="keyboardHidden|orientation|screenSize|keyboard|navigation">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
@ -34,39 +34,39 @@
android:theme="@style/MenuDialog"
android:screenOrientation="sensorLandscape"
android:name=".FatalErrorActivity"
android:configChanges="keyboardHidden|orientation|screenSize"/>
android:configChanges="keyboardHidden|orientation|screenSize|keyboard|navigation"/>
<activity
android:screenOrientation="sensorLandscape"
android:name=".MCLauncherActivity"
android:configChanges="keyboardHidden|orientation|screenSize"/>
android:configChanges="keyboardHidden|orientation|screenSize|keyboard|navigation"/>
<activity
android:screenOrientation="sensorLandscape"
android:name=".PojavLauncherActivity"
android:configChanges="keyboardHidden|orientation|screenSize"/>
android:configChanges="keyboardHidden|orientation|screenSize|keyboard|navigation"/>
<activity
android:screenOrientation="sensorLandscape"
android:name=".InstallModActivity"
android:configChanges="keyboardHidden|orientation|screenSize"/>
android:configChanges="keyboardHidden|orientation|screenSize|keyboard|navigation"/>
<activity
android:screenOrientation="sensorLandscape"
android:name=".CustomControlsActivity"
android:configChanges="keyboardHidden|orientation|screenSize"/>
android:configChanges="keyboardHidden|orientation|screenSize|keyboard|navigation"/>
<activity
android:launchMode="standard"
android:multiprocess="true"
android:screenOrientation="sensorLandscape"
android:name=".MainActivity"
android:configChanges="keyboardHidden|orientation|screenSize"/>
android:configChanges="keyboardHidden|orientation|screenSize|keyboard|navigation"/>
<activity
android:screenOrientation="sensorLandscape"
android:name=".prefs.LauncherPreferenceActivity"
android:configChanges="keyboardHidden|orientation|screenSize"/>
android:configChanges="keyboardHidden|orientation|screenSize|keyboard|navigation"/>
</application>
</manifest>

View File

@ -24,6 +24,9 @@ import org.apache.commons.io.*;
import android.support.v7.app.AlertDialog;
import android.system.*;
import android.content.res.*;
import android.text.*;
import android.text.style.*;
public class PojavLoginActivity extends AppCompatActivity
// MineActivity
@ -33,6 +36,7 @@ public class PojavLoginActivity extends AppCompatActivity
private ProgressBar prb;
private CheckBox sRemember, sOffline;
private LinearLayout loginLayout;
private Spinner spinnerChgLang;
private ImageView imageLogo;
private TextView startupTextView;
@ -201,6 +205,7 @@ public class PojavLoginActivity extends AppCompatActivity
setContentView(R.layout.launcher_login_v2);
loginLayout = findViewById(R.id.login_layout_linear);
spinnerChgLang = findViewById(R.id.login_spinner_language);
imageLogo = findViewById(R.id.login_image_logo);
loginLayout.postDelayed(new Runnable(){
@Override
@ -208,6 +213,38 @@ public class PojavLoginActivity extends AppCompatActivity
imageLogo.setTranslationY(loginLayout.getY() - (imageLogo.getHeight() / 2f));
}
}, 100);
String defaultLang = Locale.getDefault().getDisplayName();
SpannableString defaultLangChar = new SpannableString(defaultLang);
defaultLangChar.setSpan(new StyleSpan(android.graphics.Typeface.BOLD), 0, defaultLang.length(),0);
ArrayAdapter<CharSequence> langAdapter = new ArrayAdapter<CharSequence>(this, android.R.layout.simple_spinner_item);
langAdapter.add(defaultLangChar);
for (Locale locale : Locale.getAvailableLocales()) {
langAdapter.add(locale.getDisplayLanguage());
}
langAdapter.setDropDownViewResource(android.R.layout.simple_list_item_single_choice);
spinnerChgLang.setAdapter(langAdapter);
spinnerChgLang.setOnItemSelectedListener(new Spinner.OnItemSelectedListener(){
@Override
public void onItemSelected(AdapterView<?> adapter, View view, int position, long id) {
Locale locale;
if (position == 0) {
locale = Locale.getDefault();
} else {
locale = Locale.getAvailableLocales()[position + 1];
}
Locale.setDefault(locale);
Configuration config = new Configuration();
config.locale = locale;
getBaseContext().getResources().updateConfiguration(config, getBaseContext().getResources().getDisplayMetrics());
}
@Override
public void onNothingSelected(AdapterView<?> adapter) {}
});
edit2 = (EditText) findViewById(R.id.login_edit_email);
edit3 = (EditText) findViewById(R.id.login_edit_password);

View File

@ -0,0 +1,359 @@
#include <jni.h>
#include <assert.h>
#include "log.h"
#include "utils.h"
int grabCursorX, grabCursorY, lastCursorX, lastCursorY;
JavaVM* firstJavaVM;
JavaVM* secondJavaVM;
JNIEnv* firstJNIEnv;
JNIEnv* secondJNIEnv;
jclass inputBridgeClass_ANDROID, inputBridgeClass_JRE;
jmethodID inputBridgeMethod_ANDROID, inputBridgeMethod_JRE;
jboolean isGrabbing, isUseStackQueueCall;
jint JNI_OnLoad(JavaVM* vm, void* reserved) {
if (dalvikJavaVMPtr == NULL) {
//Save dalvik global JavaVM pointer
dalvikJavaVMPtr = vm;
(*vm)->GetEnv(vm, (void**) &dalvikJNIEnvPtr_ANDROID, JNI_VERSION_1_4);
} else if (dalvikJavaVMPtr != vm) {
runtimeJavaVMPtr = vm;
(*vm)->GetEnv(vm, (void**) &runtimeJNIEnvPtr_JRE, JNI_VERSION_1_4);
}
isGrabbing = JNI_FALSE;
return JNI_VERSION_1_4;
}
// Should be?
void JNI_OnUnload(JavaVM* vm, void* reserved) {
/*
if (dalvikJavaVMPtr == vm) {
} else {
}
DetachCurrentThread(vm);
*/
free(glfwInputEventArr);
}
#define ADD_CALLBACK_WWIN(NAME) \
GLFW_invoke_##NAME##_func* GLFW_invoke_##NAME; \
JNIEXPORT jlong JNICALL Java_org_lwjgl_glfw_GLFW_nglfwSet##NAME##Callback(JNIEnv * env, jclass cls, jlong window, jlong callbackptr) { \
void** oldCallback = &GLFW_invoke_##NAME; \
GLFW_invoke_##NAME = (GLFW_invoke_##NAME##_func*) (uintptr_t) callbackptr; \
return (jlong) (uintptr_t) *oldCallback; \
}
ADD_CALLBACK_WWIN(Char);
ADD_CALLBACK_WWIN(CharMods);
ADD_CALLBACK_WWIN(CursorEnter);
ADD_CALLBACK_WWIN(CursorPos);
ADD_CALLBACK_WWIN(FramebufferSize);
ADD_CALLBACK_WWIN(Key);
ADD_CALLBACK_WWIN(MouseButton);
ADD_CALLBACK_WWIN(Scroll);
ADD_CALLBACK_WWIN(WindowSize);
#undef ADD_CALLBACK_WWIN
void attachThreadIfNeed(bool* isAttached, JNIEnv** secondJNIEnvPtr) {
if (!*isAttached && secondJavaVM) {
(*secondJavaVM)->AttachCurrentThread(secondJavaVM, secondJNIEnvPtr, NULL);
*isAttached = true;
}
secondJNIEnv = *secondJNIEnvPtr;
}
void getJavaInputBridge(jclass* clazz, jmethodID* method) {
if (*method == NULL && secondJNIEnv != NULL) {
*clazz = (*secondJNIEnv)->FindClass(secondJNIEnv, "org/lwjgl/glfw/CallbackBridge");
assert(*clazz != NULL);
*method = (*secondJNIEnv)->GetStaticMethodID(secondJNIEnv, *clazz, "receiveCallback", "(ILjava/lang/String;)V");
assert(*method != NULL);
}
}
void invokeCursorPos(int x, int y) {
if (isGrabbing) {
if (!isPrepareGrabPos) {
grabCursorX += x - lastCursorX;
grabCursorY += y - lastCursorY;
} else {
isPrepareGrabPos = false;
lastCursorX = x;
lastCursorY = y;
return;
}
}
if (!isUseStackQueueCall && GLFW_invoke_CursorPos) {
GLFW_invoke_CursorPos(showingWindow, (double) (isGrabbing ? grabCursorX : x), (double) (isGrabbing ? grabCursorY : y));
}
lastCursorX = x;
lastCursorY = y;
}
void addInputToQueue(GLFWInputEvent event) {
if (glfwInputEventIndex++ >= 100) {
// player type too fast? or fps lower than player tps?
glfwInputEventIndex = 0;
}
glfwInputEventArr[glfwInputEventIndex] = &event;
}
JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeAttachThreadToOther(JNIEnv* env, jclass clazz, jboolean isAndroid, jboolean isUseStackQueue) {
glfwInputEventIndex = -1;
// isUseStackQueueCall = 1;
isUseStackQueueCall = (int) isUseStackQueue;
if (isUseStackQueue) {
isPrepareGrabPos = true;
} else if (isAndroid) {
firstJavaVM = dalvikJavaVMPtr;
firstJNIEnv = dalvikJNIEnvPtr_ANDROID;
secondJavaVM = runtimeJavaVMPtr;
attachThreadIfNeed(&isAndroidThreadAttached, &runtimeJNIEnvPtr_ANDROID);
getJavaInputBridge(&inputBridgeClass_ANDROID, &inputBridgeMethod_ANDROID);
isPrepareGrabPos = true;
} else {
firstJavaVM = runtimeJavaVMPtr;
firstJNIEnv = runtimeJNIEnvPtr_JRE;
secondJavaVM = dalvikJavaVMPtr;
attachThreadIfNeed(&isRuntimeThreadAttached, &dalvikJNIEnvPtr_JRE);
getJavaInputBridge(&inputBridgeClass_JRE, &inputBridgeMethod_JRE);
}
}
JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSetGrabbing(JNIEnv* env, jclass clazz, jboolean grabbing) {
isGrabbing = grabbing;
}
JNIEXPORT jboolean JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeIsGrabbing(JNIEnv* env, jclass clazz) {
return isGrabbing;
}
int diffX, diffY, diffGrabX, diffGrabY, debugTimes;
JNIEXPORT void JNICALL Java_org_lwjgl_glfw_GLFW_nglfwPollEvents(JNIEnv* env, jclass clazz) {
if (!isInputReady) isInputReady = true;
/*
if (debugTimes < 1000) {
debugTimes++;
LOGI("INPUT: IsUseStackQueue=%d, CurrentInputLength=%d, CursorX=%d, CursorY=%d", isUseStackQueueCall, glfwInputEventIndex, lastCursorX, lastCursorY);
}
*/
if (isUseStackQueueCall) {
if (diffX != lastCursorX || diffY != lastCursorY) {
diffX = lastCursorX;
diffY = lastCursorY;
if (GLFW_invoke_CursorPos) {
GLFW_invoke_CursorPos(showingWindow,
isGrabbing ? grabCursorX : lastCursorX,
isGrabbing ? grabCursorY : lastCursorY);
}
}
for (int i = 0; i <= glfwInputEventIndex; i++) {
GLFWInputEvent curr = *glfwInputEventArr[i];
((GLFW_invoke_callback*) curr.trigger)(curr);
// if (debugTimes < 1000) {
// LOGI("INPUT: Got input event %d", curr.type);
// }
/*
switch (curr.type) {
case EVENT_TYPE_CHAR:
if (GLFW_invoke_Char) {
GLFW_invoke_Char(showingWindow, curr.ui1);
}
break;
case EVENT_TYPE_CHAR_MODS:
if (GLFW_invoke_CharMods) {
GLFW_invoke_CharMods(showingWindow, curr.ui1, curr.i2);
}
break;
case EVENT_TYPE_CURSOR_ENTER:
if (GLFW_invoke_CursorEnter) {
GLFW_invoke_CursorEnter(showingWindow, curr.i1);
}
break;
case EVENT_TYPE_FRAMEBUFFER_SIZE:
if (GLFW_invoke_FramebufferSize) {
GLFW_invoke_FramebufferSize(showingWindow, curr.i1, curr.i2);
}
break;
case EVENT_TYPE_KEY:
if (GLFW_invoke_Key) {
GLFW_invoke_Key(showingWindow, curr.i1, curr.i2, curr.i3, curr.i4);
}
break;
case EVENT_TYPE_MOUSE_BUTTON:
if (GLFW_invoke_MouseButton) {
GLFW_invoke_MouseButton(showingWindow, curr.i1, curr.i2, curr.i3);
}
break;
case EVENT_TYPE_SCROLL:
if (GLFW_invoke_Scroll) {
GLFW_invoke_Scroll(showingWindow, curr.d1, curr.d2);
}
break;
case EVENT_TYPE_WINDOW_SIZE:
if (GLFW_invoke_WindowSize) {
GLFW_invoke_WindowSize(showingWindow, curr.i1, curr.i2);
}
break;
default:
LOGW("Unknown GLFW input event: %d", curr.type);
break;
}
*/
}
glfwInputEventIndex = -1;
}
}
JNIEXPORT jboolean JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendChar(JNIEnv* env, jclass clazz, jint codepoint) {
if (GLFW_invoke_Char && isInputReady) {
if (isUseStackQueueCall) {
GLFWInputEvent curr;
curr.trigger = triggerChar;
curr.ui1 = (unsigned int) codepoint;
addInputToQueue(curr);
} else
GLFW_invoke_Char(showingWindow, codepoint);
return JNI_TRUE;
}
return JNI_FALSE;
}
JNIEXPORT jboolean JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendCharMods(JNIEnv* env, jclass clazz, jint codepoint, jint mods) {
if (GLFW_invoke_CharMods && isInputReady) {
if (isUseStackQueueCall) {
GLFWInputEvent curr;
curr.trigger = triggerCharMods;
curr.ui1 = (unsigned int) codepoint;
curr.i2 = mods;
addInputToQueue(curr);
} else
GLFW_invoke_CharMods(showingWindow, codepoint, mods);
return JNI_TRUE;
}
return JNI_FALSE;
}
/*
JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendCursorEnter(JNIEnv* env, jclass clazz, jint entered) {
if (GLFW_invoke_CursorEnter && isInputReady) {
GLFW_invoke_CursorEnter(showingWindow, entered);
}
}
*/
JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendCursorPos(JNIEnv* env, jclass clazz, jint x, jint y) {
if (GLFW_invoke_CursorPos && isInputReady) {
if (!isCursorEntered) {
if (GLFW_invoke_CursorEnter) {
isCursorEntered = true;
if (isUseStackQueueCall) {
GLFWInputEvent curr;
curr.trigger = triggerCursorEnter;
curr.i1 = 1;
addInputToQueue(curr);
} else
GLFW_invoke_CursorEnter(showingWindow, 1);
} else if (isGrabbing) {
// Some Minecraft versions does not use GLFWCursorEnterCallback
// This is a smart check, as Minecraft will not in grab mode if already not.
isCursorEntered = true;
}
}
invokeCursorPos(x, y);
}
}
JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendFramebufferSize(JNIEnv* env, jclass clazz, jint width, jint height) {
if (GLFW_invoke_FramebufferSize && isInputReady) {
if (isUseStackQueueCall) {
GLFWInputEvent curr;
curr.trigger = triggerFramebufferSize;
curr.i1 = width;
curr.i2 = height;
addInputToQueue(curr);
} else
GLFW_invoke_FramebufferSize(showingWindow, width, height);
}
}
JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendKey(JNIEnv* env, jclass clazz, jint key, jint scancode, jint action, jint mods) {
if (GLFW_invoke_Key && isInputReady) {
if (isUseStackQueueCall) {
GLFWInputEvent curr;
curr.trigger = triggerKey;
curr.i1 = key;
curr.i2 = scancode;
curr.i3 = action;
curr.i4 = mods;
addInputToQueue(curr);
} else
GLFW_invoke_Key(showingWindow, key, scancode, action, mods);
}
}
JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendMouseButton(JNIEnv* env, jclass clazz, jint button, jint action, jint mods) {
if (isInputReady) {
if (button == -1) {
// Notify to prepare set new grab pos
isPrepareGrabPos = true;
} else if (GLFW_invoke_MouseButton) {
if (isUseStackQueueCall) {
GLFWInputEvent curr;
curr.trigger = triggerMouseButton;
curr.i1 = button;
curr.i2 = action;
curr.i3 = mods;
addInputToQueue(curr);
} else
GLFW_invoke_MouseButton(showingWindow, button, action, mods);
}
}
}
JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendScroll(JNIEnv* env, jclass clazz, jdouble xoffset, jdouble yoffset) {
if (GLFW_invoke_Scroll && isInputReady) {
if (isUseStackQueueCall) {
GLFWInputEvent curr;
curr.trigger = triggerScroll;
curr.d1 = (double) xoffset;
curr.d2 = (double) yoffset;
addInputToQueue(curr);
} else
GLFW_invoke_Scroll(showingWindow, (double) xoffset, (double) yoffset);
}
}
JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendWindowSize(JNIEnv* env, jclass clazz, jint width, jint height) {
if (GLFW_invoke_WindowSize && isInputReady) {
if (isUseStackQueueCall) {
GLFWInputEvent curr;
curr.trigger = triggerWindowSize;
curr.i1 = width;
curr.i2 = height;
addInputToQueue(curr);
} else
GLFW_invoke_WindowSize(showingWindow, width, height);
}
}
JNIEXPORT void JNICALL Java_org_lwjgl_glfw_GLFW_nglfwSetShowingWindow(JNIEnv* env, jclass clazz, jlong window) {
showingWindow = (long) window;
}

View File

@ -11,6 +11,11 @@
android:adjustViewBounds="true"
android:background="@drawable/sign_in_background"/>
<Spinner
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="@+id/login_spinner_language"/>
<LinearLayout
android:orientation="vertical"
android:layout_width="wrap_content"
@ -62,7 +67,7 @@
android:layout_gravity="left"
android:text="@string/login_offline_label"
android:id="@+id/login_switch_offline"/>
<LinearLayout
android:layout_height="wrap_content"
android:layout_width="wrap_content"