diff --git a/.gitmodules b/.gitmodules
index cf7ba34c..e69de29b 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +0,0 @@
-[submodule "wrapper"]
- path = wrapper
- url = https://github.com/QuestCraftPlusPlus/Wrapper-IL2CPP.git
diff --git a/build.gradle b/build.gradle
index 059d3d66..bacd67e4 100644
--- a/build.gradle
+++ b/build.gradle
@@ -28,6 +28,13 @@ android {
}
buildToolsVersion = "30.0.3"
+ buildFeatures {
+ viewBinding true
+ }
+ compileOptions {
+ sourceCompatibility JavaVersion.VERSION_11
+ targetCompatibility JavaVersion.VERSION_11
+ }
}
build {
@@ -52,5 +59,9 @@ dependencies {
implementation("androidx.core:core:1.13.1")
implementation("com.microsoft.azure:msal4j:1.14.0")
implementation("com.github.Mathias-Boulay:android_gamepad_remapper:2.0.3")
- implementation("blank:unity-classes")
+ implementation 'com.google.android.material:material:1.12.0'
+ implementation 'androidx.appcompat:appcompat:1.7.0'
+ implementation 'androidx.constraintlayout:constraintlayout:2.2.0'
+ implementation 'androidx.navigation:navigation-fragment:2.8.4'
+ implementation 'androidx.navigation:navigation-ui:2.8.4'
}
diff --git a/libs/unity-classes.jar b/libs/unity-classes.jar
deleted file mode 100644
index 650a6e74..00000000
Binary files a/libs/unity-classes.jar and /dev/null differ
diff --git a/settings.gradle b/settings.gradle
index 0dd86d73..ab80b562 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -22,13 +22,9 @@ dependencyResolutionManagement {
maven {
url = uri("https://jitpack.io")
}
- flatDir {
- dirs("libs")
- dirs("wrapper/unityLibrary/libs")
- }
}
}
rootProject.name = "Pojlib"
-include ":jre_lwjgl3glfw", ':wrapper', ':wrapper:launcher', "wrapper:unityLibrary", "wrapper:unityLibrary:xrmanifest.androidlib"
+include ":jre_lwjgl3glfw"
diff --git a/src/main/AndroidManifest.xml b/src/main/AndroidManifest.xml
index 48eed878..9931606d 100644
--- a/src/main/AndroidManifest.xml
+++ b/src/main/AndroidManifest.xml
@@ -1,5 +1,14 @@
+
+
-
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/assets/lwjgl/version b/src/main/assets/lwjgl/version
index d04d82ab..76cb047b 100644
--- a/src/main/assets/lwjgl/version
+++ b/src/main/assets/lwjgl/version
@@ -1 +1 @@
-1729544610054
\ No newline at end of file
+1733683669279
\ No newline at end of file
diff --git a/src/main/java/org/lwjgl/glfw/CallbackBridge.java b/src/main/java/org/lwjgl/glfw/CallbackBridge.java
index 188bb2ae..764b790e 100644
--- a/src/main/java/org/lwjgl/glfw/CallbackBridge.java
+++ b/src/main/java/org/lwjgl/glfw/CallbackBridge.java
@@ -9,7 +9,7 @@
import java.util.ArrayList;
import dalvik.annotation.optimization.CriticalNative;
-import pojlib.UnityPlayerActivity;
+import pojlib.MainActivity;
import pojlib.input.GrabListener;
import pojlib.input.LwjglGlfwKeycode;
@@ -108,12 +108,12 @@ public static boolean isGrabbing() {
public static @Nullable String accessAndroidClipboard(int type, String copy) {
switch (type) {
case CLIPBOARD_COPY:
- UnityPlayerActivity.GLOBAL_CLIPBOARD.setPrimaryClip(ClipData.newPlainText("Copy", copy));
+ MainActivity.GLOBAL_CLIPBOARD.setPrimaryClip(ClipData.newPlainText("Copy", copy));
return null;
case CLIPBOARD_PASTE:
- if (UnityPlayerActivity.GLOBAL_CLIPBOARD.hasPrimaryClip() && UnityPlayerActivity.GLOBAL_CLIPBOARD.getPrimaryClipDescription().hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN)) {
- return UnityPlayerActivity.GLOBAL_CLIPBOARD.getPrimaryClip().getItemAt(0).getText().toString();
+ if (MainActivity.GLOBAL_CLIPBOARD.hasPrimaryClip() && MainActivity.GLOBAL_CLIPBOARD.getPrimaryClipDescription().hasMimeType(ClipDescription.MIMETYPE_TEXT_PLAIN)) {
+ return MainActivity.GLOBAL_CLIPBOARD.getPrimaryClip().getItemAt(0).getText().toString();
} else {
return "";
}
@@ -179,8 +179,8 @@ private static void onGrabStateChanged(final boolean grabbing) {
}
public static void restartUnitySession(Activity activity) {
- UnityPlayerActivity unity = (UnityPlayerActivity) activity;
- unity.reinitUnity();
+// Main unity = (UnityPlayerActivity) activity;
+// unity.reinitUnity();
}
public static void addGrabListener(GrabListener listener) {
diff --git a/src/main/java/pojlib/API.java b/src/main/java/pojlib/API.java
index c7c5eaa8..4ac89f0a 100644
--- a/src/main/java/pojlib/API.java
+++ b/src/main/java/pojlib/API.java
@@ -164,7 +164,7 @@ public static void updateMods(MinecraftInstances instances, MinecraftInstances.I
*/
public static void launchInstance(Activity activity, MinecraftAccount account, MinecraftInstances.Instance instance) {
try {
- UnityPlayerActivity.installLWJGL(activity);
+ MainActivity.installLWJGL(activity);
} catch (IOException e) {
Logger.getInstance().appendToLog("WARN! LWJGL install failed, " + e);
}
diff --git a/src/main/java/pojlib/InstanceHandler.java b/src/main/java/pojlib/InstanceHandler.java
index f9382245..3219ae3a 100644
--- a/src/main/java/pojlib/InstanceHandler.java
+++ b/src/main/java/pojlib/InstanceHandler.java
@@ -172,7 +172,7 @@ public static MinecraftInstances.Instance create(Activity activity, MinecraftIns
String clientClasspath = Installer.installClient(minecraftVersionInfo, gameDir);
String minecraftClasspath = Installer.installLibraries(minecraftVersionInfo, gameDir);
String modLoaderClasspath = Installer.installLibraries(finalModLoaderVersionInfo, gameDir);
- String lwjgl = UnityPlayerActivity.installLWJGL(activity);
+ String lwjgl = MainActivity.installLWJGL(activity);
instance.classpath = clientClasspath + File.pathSeparator + minecraftClasspath + File.pathSeparator + modLoaderClasspath + File.pathSeparator + lwjgl;
diff --git a/src/main/java/pojlib/UnityPlayerActivity.java b/src/main/java/pojlib/MainActivity.java
similarity index 61%
rename from src/main/java/pojlib/UnityPlayerActivity.java
rename to src/main/java/pojlib/MainActivity.java
index 6e9d41b9..5e1e88ab 100644
--- a/src/main/java/pojlib/UnityPlayerActivity.java
+++ b/src/main/java/pojlib/MainActivity.java
@@ -7,56 +7,53 @@
import android.annotation.SuppressLint;
import android.app.Activity;
-import android.app.Activity;
-import android.app.ActivityGroup;
-import android.app.ActivityManager;
import android.content.ClipData;
import android.content.ClipboardManager;
-import android.content.Context;
-import android.content.Intent;
-import android.content.res.Configuration;
+import android.content.pm.ActivityInfo;
import android.os.Build;
import android.os.Bundle;
-import android.os.Process;
-import android.util.DisplayMetrics;
-import android.view.InputDevice;
+
+import com.google.android.material.snackbar.Snackbar;
+
+import androidx.appcompat.app.AppCompatActivity;
+
import android.util.DisplayMetrics;
import android.view.InputDevice;
import android.view.KeyEvent;
import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.view.Window;
import android.view.WindowManager;
-import com.unity3d.player.IUnityPlayerLifecycleEvents;
-import com.unity3d.player.UnityPlayer;
+import androidx.navigation.NavController;
+import androidx.navigation.Navigation;
+import androidx.navigation.ui.AppBarConfiguration;
+import androidx.navigation.ui.NavigationUI;
+import org.checkerframework.framework.qual.Unused;
import org.lwjgl.glfw.CallbackBridge;
import java.io.File;
import java.io.IOException;
-import java.nio.file.Files;
-import java.nio.file.Paths;
import java.util.Objects;
import fr.spse.gamepad_remapper.RemapperManager;
import fr.spse.gamepad_remapper.RemapperView;
+import pojlib.android.databinding.ActivityMainBinding;
+
+import pojlib.android.R;
import pojlib.input.AWTInputBridge;
import pojlib.input.EfficientAndroidLWJGLKeycode;
import pojlib.input.GrabListener;
import pojlib.input.LwjglGlfwKeycode;
import pojlib.input.gamepad.DefaultDataProvider;
import pojlib.input.gamepad.Gamepad;
+import pojlib.util.ConfigUtil;
import pojlib.util.Constants;
import pojlib.util.FileUtil;
-import pojlib.util.Logger;
-import pojlib.util.download.DownloadManager;
-import pojlib.util.download.DownloadUtils;
-public class UnityPlayerActivity extends ActivityGroup implements IUnityPlayerLifecycleEvents, GrabListener
-{
- protected UnityPlayer mUnityPlayer; // don't change the name of this variable; referenced from native code
+public class MainActivity extends AppCompatActivity implements GrabListener {
+
+ private AppBarConfiguration appBarConfiguration;
+ private ActivityMainBinding binding;
public static volatile ClipboardManager GLOBAL_CLIPBOARD;
private Gamepad mGamepad = null;
@@ -64,52 +61,25 @@ public class UnityPlayerActivity extends ActivityGroup implements IUnityPlayerLi
private boolean mLastGrabState = false;
- // Override this in your custom UnityPlayerActivity to tweak the command line arguments passed to the Unity Android Player
- // The command line arguments are passed as a string, separated by spaces
- // UnityPlayerActivity calls this from 'onCreate'
- // Supported: -force-gles20, -force-gles30, -force-gles31, -force-gles31aep, -force-gles32, -force-gles, -force-vulkan
- // See https://docs.unity3d.com/Manual/CommandLineArguments.html
- // @param cmdLine the current command line arguments, may be null
- // @return the modified command line string or null
- private String appendCommandLineArgument(String cmdLine, String arg) {
- if (arg == null || arg.isEmpty())
- return cmdLine;
- else if (cmdLine == null || cmdLine.isEmpty())
- return arg;
- else
- return cmdLine + " " + arg;
- }
-
- protected String updateUnityCommandLineArguments(String cmdLine)
- {
- return appendCommandLineArgument(cmdLine, "-androidChainedSignalHandlerBehavior=disabled");
- }
- // Setup activity layout
- @Override protected void onCreate(Bundle savedInstanceState) {
- requestWindowFeature(Window.FEATURE_NO_TITLE);
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- String cmdLine = updateUnityCommandLineArguments(getIntent().getStringExtra("unity"));
- getIntent().putExtra("unity", cmdLine);
+ binding = ActivityMainBinding.inflate(getLayoutInflater());
+ setContentView(binding.getRoot());
- mUnityPlayer = new UnityPlayer(this, this);
- setContentView(mUnityPlayer);
- mUnityPlayer.setOnHierarchyChangeListener(new ViewGroup.OnHierarchyChangeListener() {
- @Override
- public void onChildViewAdded(View parent, View child) {
- System.out.println("Child added: " + child.toString());
- }
+ ConfigUtil.LoadConfig();
+ setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
+
+ setSupportActionBar(binding.toolbar);
+
+ NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main);
+ appBarConfiguration = new AppBarConfiguration.Builder(navController.getGraph()).build();
+ NavigationUI.setupActionBarWithNavController(this, navController, appBarConfiguration);
- @Override
- public void onChildViewRemoved(View parent, View child) {
- System.out.println("Child removed: " + child.toString());
- }
- });
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
- mUnityPlayer.requestFocus();
- updateWindowSize(this);
GLOBAL_CLIPBOARD = (ClipboardManager) getSystemService(CLIPBOARD_SERVICE);
mInputManager = new RemapperManager(this, new RemapperView.Builder(null)
@@ -129,6 +99,13 @@ public void onChildViewRemoved(View parent, View child) {
.remapDpad(true));
CallbackBridge.nativeSetUseInputStackQueue(true);
+ updateWindowSize(this);
+
+ binding.fab.setOnClickListener(view -> Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
+ .setAnchorView(R.id.fab)
+ .setAction("Action", null).show());
+
+ binding.getRoot().requestFocus();
}
public static String installLWJGL(Activity activity) throws IOException {
@@ -146,16 +123,6 @@ public static String installLWJGL(Activity activity) throws IOException {
return lwjgl.getAbsolutePath();
}
- public void reinitUnity() {
- this.runOnUiThread(() -> {
- Intent start = this.getPackageManager().getLaunchIntentForPackage(getApplicationInfo().packageName);
- start.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
- this.startActivity(start);
- this.finish();
- Process.killProcess(Process.myPid());
- });
- }
-
public static DisplayMetrics getDisplayMetrics(Activity activity) {
DisplayMetrics displayMetrics = new DisplayMetrics();
@@ -173,58 +140,6 @@ public static DisplayMetrics getDisplayMetrics(Activity activity) {
return displayMetrics;
}
- public static DisplayMetrics currentDisplayMetrics;
-
- public static void updateWindowSize(Activity activity) {
- currentDisplayMetrics = getDisplayMetrics(activity);
-
- CallbackBridge.physicalWidth = currentDisplayMetrics.widthPixels;
- CallbackBridge.physicalHeight = currentDisplayMetrics.heightPixels;
- }
-
- public static float dpToPx(float dp) {
- //Better hope for the currentDisplayMetrics to be good
- return dp * currentDisplayMetrics.density;
- }
-
- public static float pxToDp(float px){
- //Better hope for the currentDisplayMetrics to be good
- return px / currentDisplayMetrics.density;
- }
-
- public static void querySystemClipboard() {
- ClipData clipData = GLOBAL_CLIPBOARD.getPrimaryClip();
- if(clipData == null) {
- AWTInputBridge.nativeClipboardReceived(null, null);
- return;
- }
- ClipData.Item firstClipItem = clipData.getItemAt(0);
- //TODO: coerce to HTML if the clip item is styled
- CharSequence clipItemText = firstClipItem.getText();
- if(clipItemText == null) {
- AWTInputBridge.nativeClipboardReceived(null, null);
- return;
- }
- AWTInputBridge.nativeClipboardReceived(clipItemText.toString(), "plain");
- }
-
- public static void putClipboardData(String data, String mimeType) {
- ClipData clipData = null;
- switch(mimeType) {
- case "text/plain":
- clipData = ClipData.newPlainText("AWT Paste", data);
- break;
- case "text/html":
- clipData = ClipData.newHtmlText("AWT Paste", data, data);
- }
- if(clipData != null) GLOBAL_CLIPBOARD.setPrimaryClip(clipData);
- }
-
- private void createGamepad(InputDevice inputDevice) {
- mGamepad = new Gamepad(inputDevice, DefaultDataProvider.INSTANCE);
- }
-
- @SuppressLint("NewApi")
@Override
public boolean dispatchGenericMotionEvent(MotionEvent event) {
int mouseCursorIndex = -1;
@@ -354,7 +269,7 @@ public static boolean sendMouseButtonUnconverted(int button, boolean status) {
@Override
public void onGrabState(boolean isGrabbing) {
- mUnityPlayer.post(()->updateGrabState(isGrabbing));
+ binding.getRoot().post(()->updateGrabState(isGrabbing));
}
// private TouchEventProcessor pickEventProcessor(boolean isGrabbing) {
@@ -369,118 +284,53 @@ private void updateGrabState(boolean isGrabbing) {
// }
}
- @Override
- public boolean onKeyMultiple(int keyCode, int repeatCount, KeyEvent event) {
- return super.onKeyMultiple(keyCode, repeatCount, event);
- }
-
- // When Unity player unloaded move task to background
- @Override public void onUnityPlayerUnloaded() {
- moveTaskToBack(true);
- }
-
- // Callback before Unity player process is killed
- @Override public void onUnityPlayerQuitted() {
- }
-
- @Override protected void onNewIntent(Intent intent)
- {
- // To support deep linking, we need to make sure that the client can get access to
- // the last sent intent. The clients access this through a JNI api that allows them
- // to get the intent set on launch. To update that after launch we have to manually
- // replace the intent with the one caught here.
- setIntent(intent);
- mUnityPlayer.newIntent(intent);
- }
-
- // Quit Unity
- @Override protected void onDestroy ()
- {
- mUnityPlayer.destroy();
- super.onDestroy();
- }
-
- // If the activity is in multi window mode or resizing the activity is allowed we will use
- // onStart/onStop (the visibility callbacks) to determine when to pause/resume.
- // Otherwise it will be done in onPause/onResume as Unity has done historically to preserve
- // existing behavior.
- @Override protected void onStop()
- {
- super.onStop();
-
- mUnityPlayer.pause();
- }
-
- @Override protected void onStart()
- {
- super.onStart();
-
- mUnityPlayer.resume();
- }
-
- // Pause Unity
- @Override protected void onPause()
- {
- super.onPause();
-
- mUnityPlayer.pause();
- }
-
- // Resume Unity
- @Override protected void onResume()
- {
- super.onResume();
+ public static DisplayMetrics currentDisplayMetrics;
- mUnityPlayer.resume();
- }
+ public static void updateWindowSize(Activity activity) {
+ currentDisplayMetrics = getDisplayMetrics(activity);
- // Low Memory Unity
- @Override public void onLowMemory()
- {
- super.onLowMemory();
- mUnityPlayer.lowMemory();
+ CallbackBridge.physicalWidth = currentDisplayMetrics.widthPixels;
+ CallbackBridge.physicalHeight = currentDisplayMetrics.heightPixels;
}
- // Trim Memory Unity
- @Override public void onTrimMemory(int level)
- {
- super.onTrimMemory(level);
- if (level == TRIM_MEMORY_RUNNING_CRITICAL)
- {
- mUnityPlayer.lowMemory();
+ @SuppressLint({})
+ public static void querySystemClipboard() {
+ ClipData clipData = GLOBAL_CLIPBOARD.getPrimaryClip();
+ if(clipData == null) {
+ AWTInputBridge.nativeClipboardReceived(null, null);
+ return;
}
+ ClipData.Item firstClipItem = clipData.getItemAt(0);
+ //TODO: coerce to HTML if the clip item is styled
+ CharSequence clipItemText = firstClipItem.getText();
+ if(clipItemText == null) {
+ AWTInputBridge.nativeClipboardReceived(null, null);
+ return;
+ }
+ AWTInputBridge.nativeClipboardReceived(clipItemText.toString(), "plain");
}
- // This ensures the layout will be correct.
- @Override public void onConfigurationChanged(Configuration newConfig)
- {
- super.onConfigurationChanged(newConfig);
- mUnityPlayer.configurationChanged(newConfig);
+ @SuppressLint({})
+ public static void putClipboardData(String data, String mimeType) {
+ ClipData clipData = null;
+ switch(mimeType) {
+ case "text/plain":
+ clipData = ClipData.newPlainText("AWT Paste", data);
+ break;
+ case "text/html":
+ clipData = ClipData.newHtmlText("AWT Paste", data, data);
+ }
+ if(clipData != null) GLOBAL_CLIPBOARD.setPrimaryClip(clipData);
}
- // Notify Unity of the focus change.
- @Override public void onWindowFocusChanged(boolean hasFocus)
- {
- super.onWindowFocusChanged(hasFocus);
- mUnityPlayer.windowFocusChanged(hasFocus);
+ private void createGamepad(InputDevice inputDevice) {
+ mGamepad = new Gamepad(inputDevice, DefaultDataProvider.INSTANCE);
}
-/* // For some reason the multiple keyevent type is not supported by the ndk.
- // Force event injection by overriding dispatchKeyEvent().
- @Override public boolean dispatchKeyEvent(KeyEvent event)
- {
- if (event.getAction() == KeyEvent.ACTION_MULTIPLE)
- return mUnityPlayer.injectEvent(event);
- return super.dispatchKeyEvent(event);
- }*/
-
- // Pass any events not handled by (unfocused) views straight to UnityPlayer
- @Override public boolean onKeyUp(int keyCode, KeyEvent event) {
- return mUnityPlayer.injectEvent(event);
- }
- @Override public boolean onKeyDown(int keyCode, KeyEvent event) {
- return mUnityPlayer.injectEvent(event);
+ @Override
+ public boolean onSupportNavigateUp() {
+ NavController navController = Navigation.findNavController(this, R.id.nav_host_fragment_content_main);
+ return NavigationUI.navigateUp(navController, appBarConfiguration)
+ || super.onSupportNavigateUp();
}
- @Override public boolean onTouchEvent(MotionEvent event) { return mUnityPlayer.injectEvent(event); }
- /*API12*/ public boolean onGenericMotionEvent(MotionEvent event) { return mUnityPlayer.injectEvent(event); }
}
\ No newline at end of file
diff --git a/src/main/java/pojlib/fragments/FirstFragment.java b/src/main/java/pojlib/fragments/FirstFragment.java
new file mode 100644
index 00000000..d6a3d496
--- /dev/null
+++ b/src/main/java/pojlib/fragments/FirstFragment.java
@@ -0,0 +1,45 @@
+package pojlib.fragments;
+
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.annotation.NonNull;
+import androidx.fragment.app.Fragment;
+import androidx.navigation.fragment.NavHostFragment;
+
+import pojlib.android.R;
+import pojlib.android.databinding.FragmentFirstBinding;
+
+public class FirstFragment extends Fragment {
+
+ private FragmentFirstBinding binding;
+
+ @Override
+ public View onCreateView(
+ @NonNull LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState
+ ) {
+
+ binding = FragmentFirstBinding.inflate(inflater, container, false);
+ return binding.getRoot();
+
+ }
+
+ public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+
+ binding.buttonFirst.setOnClickListener(v ->
+ NavHostFragment.findNavController(FirstFragment.this)
+ .navigate(R.id.action_FirstFragment_to_SecondFragment)
+ );
+ }
+
+ @Override
+ public void onDestroyView() {
+ super.onDestroyView();
+ binding = null;
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/pojlib/fragments/SecondFragment.java b/src/main/java/pojlib/fragments/SecondFragment.java
new file mode 100644
index 00000000..bdc440a0
--- /dev/null
+++ b/src/main/java/pojlib/fragments/SecondFragment.java
@@ -0,0 +1,45 @@
+package pojlib.fragments;
+
+import android.os.Bundle;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+
+import androidx.annotation.NonNull;
+import androidx.fragment.app.Fragment;
+import androidx.navigation.fragment.NavHostFragment;
+
+import pojlib.android.R;
+import pojlib.android.databinding.FragmentSecondBinding;
+
+public class SecondFragment extends Fragment {
+
+ private FragmentSecondBinding binding;
+
+ @Override
+ public View onCreateView(
+ @NonNull LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState
+ ) {
+
+ binding = FragmentSecondBinding.inflate(inflater, container, false);
+ return binding.getRoot();
+
+ }
+
+ public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
+ super.onViewCreated(view, savedInstanceState);
+
+ binding.buttonSecond.setOnClickListener(v ->
+ NavHostFragment.findNavController(SecondFragment.this)
+ .navigate(R.id.action_SecondFragment_to_FirstFragment)
+ );
+ }
+
+ @Override
+ public void onDestroyView() {
+ super.onDestroyView();
+ binding = null;
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/pojlib/input/gamepad/Gamepad.java b/src/main/java/pojlib/input/gamepad/Gamepad.java
index b390f3f2..34a07a7f 100644
--- a/src/main/java/pojlib/input/gamepad/Gamepad.java
+++ b/src/main/java/pojlib/input/gamepad/Gamepad.java
@@ -20,7 +20,7 @@
import static org.lwjgl.glfw.CallbackBridge.sendKeyPress;
import static org.lwjgl.glfw.CallbackBridge.sendMouseButton;
-import static pojlib.UnityPlayerActivity.currentDisplayMetrics;
+import static pojlib.MainActivity.currentDisplayMetrics;
import static pojlib.input.gamepad.GamepadJoystick.DIRECTION_EAST;
import static pojlib.input.gamepad.GamepadJoystick.DIRECTION_NONE;
import static pojlib.input.gamepad.GamepadJoystick.DIRECTION_NORTH;
diff --git a/src/main/jni/awt_bridge.c b/src/main/jni/awt_bridge.c
index 79bb3ca4..c538c469 100644
--- a/src/main/jni/awt_bridge.c
+++ b/src/main/jni/awt_bridge.c
@@ -38,7 +38,7 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) {
dalvikJavaVMPtr = vm;
JNIEnv *env = NULL;
(*vm)->GetEnv(vm, (void**)&env, JNI_VERSION_1_4);
- class_MainActivity = (*env)->NewGlobalRef(env,(*env)->FindClass(env, "pojlib/UnityPlayerActivity"));
+ class_MainActivity = (*env)->NewGlobalRef(env,(*env)->FindClass(env, "pojlib/MainActivity"));
method_OpenLink= (*env)->GetStaticMethodID(env, class_MainActivity, "openLink", "(Ljava/lang/String;)V");
method_OpenPath= (*env)->GetStaticMethodID(env, class_MainActivity, "openLink", "(Ljava/lang/String;)V");
method_QuerySystemClipboard = (*env)->GetStaticMethodID(env, class_MainActivity, "querySystemClipboard", "()V");
diff --git a/src/main/res/layout/activity_main.xml b/src/main/res/layout/activity_main.xml
new file mode 100644
index 00000000..a9c84941
--- /dev/null
+++ b/src/main/res/layout/activity_main.xml
@@ -0,0 +1,33 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/res/layout/content_main.xml b/src/main/res/layout/content_main.xml
new file mode 100644
index 00000000..e416e1c1
--- /dev/null
+++ b/src/main/res/layout/content_main.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/res/layout/fragment_first.xml b/src/main/res/layout/fragment_first.xml
new file mode 100644
index 00000000..44baecd7
--- /dev/null
+++ b/src/main/res/layout/fragment_first.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/res/layout/fragment_second.xml b/src/main/res/layout/fragment_second.xml
new file mode 100644
index 00000000..d074310b
--- /dev/null
+++ b/src/main/res/layout/fragment_second.xml
@@ -0,0 +1,35 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/res/navigation/nav_graph.xml b/src/main/res/navigation/nav_graph.xml
new file mode 100644
index 00000000..7971507d
--- /dev/null
+++ b/src/main/res/navigation/nav_graph.xml
@@ -0,0 +1,28 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/main/res/values-land/dimens.xml b/src/main/res/values-land/dimens.xml
new file mode 100644
index 00000000..22d7f004
--- /dev/null
+++ b/src/main/res/values-land/dimens.xml
@@ -0,0 +1,3 @@
+
+ 48dp
+
\ No newline at end of file
diff --git a/src/main/res/values-night/themes.xml b/src/main/res/values-night/themes.xml
new file mode 100644
index 00000000..32ea07dc
--- /dev/null
+++ b/src/main/res/values-night/themes.xml
@@ -0,0 +1,7 @@
+
+
+
+
\ No newline at end of file
diff --git a/src/main/res/values-v23/themes.xml b/src/main/res/values-v23/themes.xml
new file mode 100644
index 00000000..475e54bc
--- /dev/null
+++ b/src/main/res/values-v23/themes.xml
@@ -0,0 +1,9 @@
+
+
+
+
\ No newline at end of file
diff --git a/src/main/res/values-w1240dp/dimens.xml b/src/main/res/values-w1240dp/dimens.xml
new file mode 100644
index 00000000..d73f4a35
--- /dev/null
+++ b/src/main/res/values-w1240dp/dimens.xml
@@ -0,0 +1,3 @@
+
+ 200dp
+
\ No newline at end of file
diff --git a/src/main/res/values-w600dp/dimens.xml b/src/main/res/values-w600dp/dimens.xml
new file mode 100644
index 00000000..22d7f004
--- /dev/null
+++ b/src/main/res/values-w600dp/dimens.xml
@@ -0,0 +1,3 @@
+
+ 48dp
+
\ No newline at end of file
diff --git a/src/main/res/values/dimens.xml b/src/main/res/values/dimens.xml
new file mode 100644
index 00000000..125df871
--- /dev/null
+++ b/src/main/res/values/dimens.xml
@@ -0,0 +1,3 @@
+
+ 16dp
+
\ No newline at end of file
diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml
new file mode 100644
index 00000000..623fe2e6
--- /dev/null
+++ b/src/main/res/values/strings.xml
@@ -0,0 +1,45 @@
+
+
+
+ First Fragment
+ Second Fragment
+ Next
+ Previous
+
+
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nam in scelerisque sem. Mauris
+ volutpat, dolor id interdum ullamcorper, risus dolor egestas lectus, sit amet mattis purus
+ dui nec risus. Maecenas non sodales nisi, vel dictum dolor. Class aptent taciti sociosqu ad
+ litora torquent per conubia nostra, per inceptos himenaeos. Suspendisse blandit eleifend
+ diam, vel rutrum tellus vulputate quis. Aliquam eget libero aliquet, imperdiet nisl a,
+ ornare ex. Sed rhoncus est ut libero porta lobortis. Fusce in dictum tellus.\n\n
+ Suspendisse interdum ornare ante. Aliquam nec cursus lorem. Morbi id magna felis. Vivamus
+ egestas, est a condimentum egestas, turpis nisl iaculis ipsum, in dictum tellus dolor sed
+ neque. Morbi tellus erat, dapibus ut sem a, iaculis tincidunt dui. Interdum et malesuada
+ fames ac ante ipsum primis in faucibus. Curabitur et eros porttitor, ultricies urna vitae,
+ molestie nibh. Phasellus at commodo eros, non aliquet metus. Sed maximus nisl nec dolor
+ bibendum, vel congue leo egestas.\n\n
+ Sed interdum tortor nibh, in sagittis risus mollis quis. Curabitur mi odio, condimentum sit
+ amet auctor at, mollis non turpis. Nullam pretium libero vestibulum, finibus orci vel,
+ molestie quam. Fusce blandit tincidunt nulla, quis sollicitudin libero facilisis et. Integer
+ interdum nunc ligula, et fermentum metus hendrerit id. Vestibulum lectus felis, dictum at
+ lacinia sit amet, tristique id quam. Cras eu consequat dui. Suspendisse sodales nunc ligula,
+ in lobortis sem porta sed. Integer id ultrices magna, in luctus elit. Sed a pellentesque
+ est.\n\n
+ Aenean nunc velit, lacinia sed dolor sed, ultrices viverra nulla. Etiam a venenatis nibh.
+ Morbi laoreet, tortor sed facilisis varius, nibh orci rhoncus nulla, id elementum leo dui
+ non lorem. Nam mollis ipsum quis auctor varius. Quisque elementum eu libero sed commodo. In
+ eros nisl, imperdiet vel imperdiet et, scelerisque a mauris. Pellentesque varius ex nunc,
+ quis imperdiet eros placerat ac. Duis finibus orci et est auctor tincidunt. Sed non viverra
+ ipsum. Nunc quis augue egestas, cursus lorem at, molestie sem. Morbi a consectetur ipsum, a
+ placerat diam. Etiam vulputate dignissim convallis. Integer faucibus mauris sit amet finibus
+ convallis.\n\n
+ Phasellus in aliquet mi. Pellentesque habitant morbi tristique senectus et netus et
+ malesuada fames ac turpis egestas. In volutpat arcu ut felis sagittis, in finibus massa
+ gravida. Pellentesque id tellus orci. Integer dictum, lorem sed efficitur ullamcorper,
+ libero justo consectetur ipsum, in mollis nisl ex sed nisl. Donec maximus ullamcorper
+ sodales. Praesent bibendum rhoncus tellus nec feugiat. In a ornare nulla. Donec rhoncus
+ libero vel nunc consequat, quis tincidunt nisl eleifend. Cras bibendum enim a justo luctus
+ vestibulum. Fusce dictum libero quis erat maximus, vitae volutpat diam dignissim.
+
+
\ No newline at end of file
diff --git a/src/main/res/values/themes.xml b/src/main/res/values/themes.xml
new file mode 100644
index 00000000..ff9824f5
--- /dev/null
+++ b/src/main/res/values/themes.xml
@@ -0,0 +1,9 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/wrapper b/wrapper
deleted file mode 160000
index 6b9b7a66..00000000
--- a/wrapper
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 6b9b7a66524e644d2b78d0fa621e6ffb61674302