mirror of
https://github.com/AngelAuraMC/Amethyst-Android.git
synced 2025-09-19 01:27:18 -04:00
Merge branch 'v3_openjdk' into v3-virgl
This commit is contained in:
commit
cc6c6ab14c
15
README.md
15
README.md
@ -19,7 +19,7 @@
|
|||||||
- [Credits & Third party components and their licenses](#credits--third-party-components-and-their-licenses)
|
- [Credits & Third party components and their licenses](#credits--third-party-components-and-their-licenses)
|
||||||
|
|
||||||
## Introduction
|
## Introduction
|
||||||
PojavLauncher is a Minecraft: Java Edition launcher for Android and iOS based on [Boardwalk](https://github.com/zhuowei/Boardwalk). This launcher can launch almost all available Minecraft versions (from rd-132211 to 1.18 snapshots (kinda), including Combat Test versions. Modding via Forge and Fabric are also supported. This repository contains source code for Android. For iOS/iPadOS, check out [PojavLauncher_iOS](https://github.com/PojavLauncherTeam/PojavLauncher_iOS).
|
PojavLauncher is a Minecraft: Java Edition launcher for Android and iOS based on [Boardwalk](https://github.com/zhuowei/Boardwalk). This launcher can launch almost all available Minecraft versions (from rd-132211 to 1.18 snapshots (kinda)), including Combat Test versions. Modding via Forge (up to 1.16.5) and Fabric are also supported. This repository contains source code for Android. For iOS/iPadOS, check out [PojavLauncher_iOS](https://github.com/PojavLauncherTeam/PojavLauncher_iOS).
|
||||||
|
|
||||||
## Building
|
## Building
|
||||||
To get started, you can just get prebuilt app from [stable release](https://github.com/PojavLauncherTeam/PojavLauncher/releases) or [automatic builds](https://github.com/PojavLauncherTeam/PojavLauncher/actions). If you want to build after launcher code changes, follow steps below.
|
To get started, you can just get prebuilt app from [stable release](https://github.com/PojavLauncherTeam/PojavLauncher/releases) or [automatic builds](https://github.com/PojavLauncherTeam/PojavLauncher/actions). If you want to build after launcher code changes, follow steps below.
|
||||||
@ -80,13 +80,13 @@ cp jre_lwjgl3glfw/build/libs/jre_lwjgl3glfw-3.2.3.jar app_pojavlauncher/src/main
|
|||||||
- [ ] More...
|
- [ ] More...
|
||||||
|
|
||||||
## Known Issues
|
## Known Issues
|
||||||
- Minecraft `21w10a` or newer are currently not yet supported due to the new GLSL usage.
|
- Minecraft `21w10a` or newer are currently not yet supported due to the new GLSL usage. Fortunately, a workaround is provided and built into the launcher.
|
||||||
- In 1.16 and up spawn eggs banners are white (you can fix this by switching renderer
|
- In 1.16 and up, spawn eggs banners are white (you can fix this by switching renderer
|
||||||
to `gl4es 1.1.5`, only works on 1.16 and up, do not use under this version)
|
to `gl4es 1.1.5`, only works on 1.16 and up, do not use under this version, as the texture
|
||||||
- Controller mods aren't working
|
will bug out when hit a mob)
|
||||||
|
- Controller mods aren't working.
|
||||||
- Random crashes could happen very often on Android 5.x during game load or join world.
|
- Random crashes could happen very often on Android 5.x during game load or join world.
|
||||||
- With big modpacks textures could be messed up
|
- With big modpacks textures could be messed up
|
||||||
- If you're using gl4es 1.1.5 on 1.16 and lower texture will bug out when hit a mob
|
|
||||||
- probably more, that's why we have a bug tracker ;)
|
- probably more, that's why we have a bug tracker ;)
|
||||||
|
|
||||||
## License
|
## License
|
||||||
@ -96,7 +96,7 @@ to `gl4es 1.1.5`, only works on 1.16 and up, do not use under this version)
|
|||||||
Contributions are welcome! We welcome any type of contribution, not only code.
|
Contributions are welcome! We welcome any type of contribution, not only code.
|
||||||
Any code change should be submitted as a pull request. The description should explain what the code does and give steps to execute it.
|
Any code change should be submitted as a pull request. The description should explain what the code does and give steps to execute it.
|
||||||
|
|
||||||
## Credits & Third party components and their licenses
|
## Credits & Third party components and their licenses (if available)
|
||||||
- [Boardwalk](https://github.com/zhuowei/Boardwalk) (JVM Launcher): Unknown License/[Apache License 2.0](https://github.com/zhuowei/Boardwalk/blob/master/LICENSE) or GNU GPLv2.
|
- [Boardwalk](https://github.com/zhuowei/Boardwalk) (JVM Launcher): Unknown License/[Apache License 2.0](https://github.com/zhuowei/Boardwalk/blob/master/LICENSE) or GNU GPLv2.
|
||||||
- Android Support Libraries: [Apache License 2.0](https://android.googlesource.com/platform/prebuilts/maven_repo/android/+/master/NOTICE.txt).
|
- Android Support Libraries: [Apache License 2.0](https://android.googlesource.com/platform/prebuilts/maven_repo/android/+/master/NOTICE.txt).
|
||||||
- [GL4ES](https://github.com/PojavLauncherTeam/gl4es): [MIT License](https://github.com/ptitSeb/gl4es/blob/master/LICENSE).<br>
|
- [GL4ES](https://github.com/PojavLauncherTeam/gl4es): [MIT License](https://github.com/ptitSeb/gl4es/blob/master/LICENSE).<br>
|
||||||
@ -108,4 +108,3 @@ Any code change should be submitted as a pull request. The description should ex
|
|||||||
- [xHook](https://github.com/iqiyi/xHook) (Used for exit code trapping): [MIT and BSD-style licenses](https://github.com/iqiyi/xHook/blob/master/LICENSE).
|
- [xHook](https://github.com/iqiyi/xHook) (Used for exit code trapping): [MIT and BSD-style licenses](https://github.com/iqiyi/xHook/blob/master/LICENSE).
|
||||||
- [libepoxy](https://github.com/anholt/libepoxy): [MIT License](https://github.com/anholt/libepoxy/blob/master/COPYING).
|
- [libepoxy](https://github.com/anholt/libepoxy): [MIT License](https://github.com/anholt/libepoxy/blob/master/COPYING).
|
||||||
- [virglrenderer](https://github.com/PojavLauncherTeam/virglrenderer): [MIT License](https://gitlab.freedesktop.org/virgl/virglrenderer/-/blob/master/COPYING).
|
- [virglrenderer](https://github.com/PojavLauncherTeam/virglrenderer): [MIT License](https://gitlab.freedesktop.org/virgl/virglrenderer/-/blob/master/COPYING).
|
||||||
|
|
||||||
|
@ -118,13 +118,13 @@ dependencies {
|
|||||||
// implementation 'com.wu-man:android-bsf-api:3.1.3'
|
// implementation 'com.wu-man:android-bsf-api:3.1.3'
|
||||||
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
|
||||||
implementation 'androidx.preference:preference:1.1.1'
|
implementation 'androidx.preference:preference:1.1.1'
|
||||||
implementation 'androidx.appcompat:appcompat:1.3.0'
|
implementation 'androidx.appcompat:appcompat:1.3.1'
|
||||||
implementation 'androidx.legacy:legacy-preference-v14:1.0.0'
|
implementation 'androidx.legacy:legacy-preference-v14:1.0.0'
|
||||||
implementation 'com.google.android.material:material:1.4.0'
|
implementation 'com.google.android.material:material:1.4.0'
|
||||||
implementation 'androidx.annotation:annotation:1.2.0'
|
implementation 'androidx.annotation:annotation:1.2.0'
|
||||||
implementation 'androidx.browser:browser:1.3.0'
|
implementation 'androidx.browser:browser:1.3.0'
|
||||||
|
|
||||||
implementation "androidx.constraintlayout:constraintlayout:2.0.4"
|
implementation "androidx.constraintlayout:constraintlayout:2.1.1"
|
||||||
|
|
||||||
implementation 'com.github.martin-stone:hsv-alpha-color-picker-android:3.0.1'
|
implementation 'com.github.martin-stone:hsv-alpha-color-picker-android:3.0.1'
|
||||||
implementation 'com.github.duanhong169:checkerboarddrawable:1.0.2'
|
implementation 'com.github.duanhong169:checkerboarddrawable:1.0.2'
|
||||||
|
Binary file not shown.
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,7 @@
|
|||||||
package net.kdt.pojavlaunch;
|
package net.kdt.pojavlaunch;
|
||||||
|
|
||||||
|
import static net.kdt.pojavlaunch.Tools.getFileName;
|
||||||
|
|
||||||
import android.app.*;
|
import android.app.*;
|
||||||
import android.content.*;
|
import android.content.*;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
@ -28,12 +30,10 @@ import org.apache.commons.io.IOUtils;
|
|||||||
|
|
||||||
public abstract class BaseLauncherActivity extends BaseActivity {
|
public abstract class BaseLauncherActivity extends BaseActivity {
|
||||||
public Button mPlayButton;
|
public Button mPlayButton;
|
||||||
public ConsoleFragment mConsoleView;
|
|
||||||
public CrashFragment mCrashView;
|
|
||||||
public ProgressBar mLaunchProgress;
|
public ProgressBar mLaunchProgress;
|
||||||
public Spinner mVersionSelector;
|
public Spinner mVersionSelector;
|
||||||
public MultiRTConfigDialog mRuntimeConfigDialog;
|
public MultiRTConfigDialog mRuntimeConfigDialog;
|
||||||
public TextView mLaunchTextStatus, mTextVersion;
|
public TextView mLaunchTextStatus;
|
||||||
|
|
||||||
public JMinecraftVersionList mVersionList;
|
public JMinecraftVersionList mVersionList;
|
||||||
public MinecraftDownloaderTask mTask;
|
public MinecraftDownloaderTask mTask;
|
||||||
@ -45,52 +45,24 @@ public abstract class BaseLauncherActivity extends BaseActivity {
|
|||||||
|
|
||||||
public abstract void statusIsLaunching(boolean isLaunching);
|
public abstract void statusIsLaunching(boolean isLaunching);
|
||||||
|
|
||||||
public void mcaccLogout(View view) {
|
|
||||||
//PojavProfile.reset();
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
public void launcherMenu(View view) {
|
* Used by the custom control button from the layout_main_v4
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(this);
|
* @param view The view triggering the function
|
||||||
builder.setTitle(R.string.mcl_options);
|
*/
|
||||||
builder.setItems(R.array.mcl_options, new DialogInterface.OnClickListener(){
|
public void launchCustomControlsActivity(View view){
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onClick(DialogInterface p1, int p2)
|
|
||||||
{
|
|
||||||
switch (p2) {
|
|
||||||
case 0: // Mod installer
|
|
||||||
installMod(false);
|
|
||||||
break;
|
|
||||||
case 1: // Mod installer with java args
|
|
||||||
installMod(true);
|
|
||||||
break;
|
|
||||||
case 2: // Custom controls
|
|
||||||
startActivity(new Intent(BaseLauncherActivity.this, CustomControlsActivity.class));
|
startActivity(new Intent(BaseLauncherActivity.this, CustomControlsActivity.class));
|
||||||
break;
|
|
||||||
case 3: { // About
|
|
||||||
final AlertDialog.Builder aboutB = new AlertDialog.Builder(BaseLauncherActivity.this);
|
|
||||||
aboutB.setTitle(R.string.mcl_option_about);
|
|
||||||
try {
|
|
||||||
aboutB.setMessage(Html.fromHtml(String.format(Tools.read(getAssets().open("about_en.txt")),
|
|
||||||
Tools.APP_NAME,
|
|
||||||
BuildConfig.VERSION_NAME,
|
|
||||||
"3.2.3")
|
|
||||||
));
|
|
||||||
} catch (Exception e) {
|
|
||||||
throw new RuntimeException(e);
|
|
||||||
}
|
}
|
||||||
aboutB.setPositiveButton(android.R.string.ok, null);
|
|
||||||
AlertDialog aboutDialog = aboutB.show();
|
/**
|
||||||
TextView aboutTv = aboutDialog.findViewById(android.R.id.message);
|
* Used by the install button from the layout_main_v4
|
||||||
aboutTv.setMovementMethod(LinkMovementMethod.getInstance());
|
* @param view The view triggering the function
|
||||||
} break;
|
*/
|
||||||
}
|
public void installJarFile(View view){
|
||||||
}
|
installMod(false);
|
||||||
});
|
|
||||||
builder.show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static final int RUN_MOD_INSTALLER = 2050;
|
public static final int RUN_MOD_INSTALLER = 2050;
|
||||||
private void installMod(boolean customJavaArgs) {
|
private void installMod(boolean customJavaArgs) {
|
||||||
if (customJavaArgs) {
|
if (customJavaArgs) {
|
||||||
@ -101,14 +73,11 @@ public abstract class BaseLauncherActivity extends BaseActivity {
|
|||||||
final EditText edit = new EditText(this);
|
final EditText edit = new EditText(this);
|
||||||
edit.setSingleLine();
|
edit.setSingleLine();
|
||||||
edit.setHint("-jar/-cp /path/to/file.jar ...");
|
edit.setHint("-jar/-cp /path/to/file.jar ...");
|
||||||
builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener(){
|
builder.setPositiveButton(android.R.string.ok, (di, i) -> {
|
||||||
@Override
|
|
||||||
public void onClick(DialogInterface di, int i) {
|
|
||||||
Intent intent = new Intent(BaseLauncherActivity.this, JavaGUILauncherActivity.class);
|
Intent intent = new Intent(BaseLauncherActivity.this, JavaGUILauncherActivity.class);
|
||||||
intent.putExtra("skipDetectMod", true);
|
intent.putExtra("skipDetectMod", true);
|
||||||
intent.putExtra("javaArgs", edit.getText().toString());
|
intent.putExtra("javaArgs", edit.getText().toString());
|
||||||
startActivity(intent);
|
startActivity(intent);
|
||||||
}
|
|
||||||
});
|
});
|
||||||
dialog = builder.create();
|
dialog = builder.create();
|
||||||
dialog.setView(edit);
|
dialog.setView(edit);
|
||||||
@ -132,7 +101,7 @@ public abstract class BaseLauncherActivity extends BaseActivity {
|
|||||||
v.setEnabled(false);
|
v.setEnabled(false);
|
||||||
mTask = new MinecraftDownloaderTask(this);
|
mTask = new MinecraftDownloaderTask(this);
|
||||||
mTask.execute(mProfile.selectedVersion);
|
mTask.execute(mProfile.selectedVersion);
|
||||||
mCrashView.resetCrashLog = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -160,20 +129,18 @@ public abstract class BaseLauncherActivity extends BaseActivity {
|
|||||||
decorView.setSystemUiVisibility(uiOptions);
|
decorView.setSystemUiVisibility(uiOptions);
|
||||||
System.out.println("call to onResume; E");
|
System.out.println("call to onResume; E");
|
||||||
}
|
}
|
||||||
|
|
||||||
SharedPreferences.OnSharedPreferenceChangeListener listRefreshListener = null;
|
SharedPreferences.OnSharedPreferenceChangeListener listRefreshListener = null;
|
||||||
@Override
|
@Override
|
||||||
protected void onResumeFragments() {
|
protected void onResumeFragments() {
|
||||||
super.onResumeFragments();
|
super.onResumeFragments();
|
||||||
if(listRefreshListener == null) {
|
if(listRefreshListener == null) {
|
||||||
final BaseLauncherActivity thiz = this;
|
final BaseLauncherActivity thiz = this;
|
||||||
listRefreshListener = new SharedPreferences.OnSharedPreferenceChangeListener() {
|
listRefreshListener = (sharedPreferences, key) -> {
|
||||||
@Override
|
|
||||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
|
||||||
if(key.startsWith("vertype_")) {
|
if(key.startsWith("vertype_")) {
|
||||||
System.out.println("Verlist update needed!");
|
System.out.println("Verlist update needed!");
|
||||||
new RefreshVersionListTask(thiz).execute();
|
new RefreshVersionListTask(thiz).execute();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
LauncherPreferences.DEFAULT_PREF.registerOnSharedPreferenceChangeListener(listRefreshListener);
|
LauncherPreferences.DEFAULT_PREF.registerOnSharedPreferenceChangeListener(listRefreshListener);
|
||||||
@ -181,76 +148,11 @@ public abstract class BaseLauncherActivity extends BaseActivity {
|
|||||||
System.out.println("call to onResumeFragments");
|
System.out.println("call to onResumeFragments");
|
||||||
mRuntimeConfigDialog = new MultiRTConfigDialog();
|
mRuntimeConfigDialog = new MultiRTConfigDialog();
|
||||||
mRuntimeConfigDialog.prepare(this);
|
mRuntimeConfigDialog.prepare(this);
|
||||||
try{
|
|
||||||
final ProgressDialog barrier = new ProgressDialog(this);
|
|
||||||
barrier.setMessage(getString(R.string.global_waiting));
|
|
||||||
barrier.setProgressStyle(barrier.STYLE_SPINNER);
|
|
||||||
barrier.setCancelable(false);
|
|
||||||
barrier.show();
|
|
||||||
|
|
||||||
new Thread(new Runnable(){
|
//TODO ADD CRASH CHECK AND FOCUS
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
while (mConsoleView == null) {
|
|
||||||
try {
|
|
||||||
Thread.sleep(20);
|
|
||||||
} catch (Throwable th) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
Thread.sleep(100);
|
|
||||||
} catch (Throwable th) {}
|
|
||||||
|
|
||||||
runOnUiThread(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run()
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
mConsoleView.putLog("");
|
|
||||||
barrier.dismiss();
|
|
||||||
} catch (Throwable th) {
|
|
||||||
startActivity(getIntent());
|
|
||||||
finish();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}).start();
|
|
||||||
|
|
||||||
File lastCrashFile = Tools.lastFileModified(Tools.DIR_HOME_CRASH);
|
|
||||||
if(CrashFragment.isNewCrash(lastCrashFile) || !mCrashView.getLastCrash().isEmpty()){
|
|
||||||
mCrashView.resetCrashLog = false;
|
|
||||||
initTabs(2);
|
|
||||||
|
|
||||||
} /*else throw new Exception();*/
|
|
||||||
} catch(Throwable e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
}
|
|
||||||
System.out.println("call to onResumeFragments; E");
|
System.out.println("call to onResumeFragments; E");
|
||||||
}
|
}
|
||||||
public static String getFileName(Context ctx, Uri uri) {
|
|
||||||
String result = null;
|
|
||||||
if (uri.getScheme().equals("content")) {
|
|
||||||
Cursor cursor = ctx.getContentResolver().query(uri, null, null, null, null);
|
|
||||||
try {
|
|
||||||
if (cursor != null && cursor.moveToFirst()) {
|
|
||||||
result = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
|
|
||||||
}
|
|
||||||
} finally {
|
|
||||||
cursor.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (result == null) {
|
|
||||||
result = uri.getPath();
|
|
||||||
int cut = result.lastIndexOf('/');
|
|
||||||
if (cut != -1) {
|
|
||||||
result = result.substring(cut + 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
@Override
|
@Override
|
||||||
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
|
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
|
||||||
super.onActivityResult(requestCode,resultCode,data);
|
super.onActivityResult(requestCode,resultCode,data);
|
||||||
@ -260,8 +162,11 @@ public abstract class BaseLauncherActivity extends BaseActivity {
|
|||||||
barrier.setProgressStyle(barrier.STYLE_SPINNER);
|
barrier.setProgressStyle(barrier.STYLE_SPINNER);
|
||||||
barrier.setCancelable(false);
|
barrier.setCancelable(false);
|
||||||
barrier.show();
|
barrier.show();
|
||||||
|
|
||||||
|
// Install the runtime
|
||||||
if (requestCode == MultiRTConfigDialog.MULTIRT_PICK_RUNTIME) {
|
if (requestCode == MultiRTConfigDialog.MULTIRT_PICK_RUNTIME) {
|
||||||
if (data != null) {
|
if (data == null) return;
|
||||||
|
|
||||||
final Uri uri = data.getData();
|
final Uri uri = data.getData();
|
||||||
Thread t = new Thread(() -> {
|
Thread t = new Thread(() -> {
|
||||||
try {
|
try {
|
||||||
@ -271,22 +176,21 @@ public abstract class BaseLauncherActivity extends BaseActivity {
|
|||||||
() -> barrier.setMessage(BaseLauncherActivity.this.getString(resid, stuff))));
|
() -> barrier.setMessage(BaseLauncherActivity.this.getString(resid, stuff))));
|
||||||
MultiRTUtils.postPrepare(BaseLauncherActivity.this, name);
|
MultiRTUtils.postPrepare(BaseLauncherActivity.this, name);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
Tools.showError(BaseLauncherActivity.this
|
Tools.showError(BaseLauncherActivity.this, e);
|
||||||
, e);
|
|
||||||
}
|
}
|
||||||
BaseLauncherActivity.this.runOnUiThread(new Runnable() {
|
BaseLauncherActivity.this.runOnUiThread(() -> {
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
barrier.dismiss();
|
barrier.dismiss();
|
||||||
mRuntimeConfigDialog.refresh();
|
mRuntimeConfigDialog.refresh();
|
||||||
mRuntimeConfigDialog.dialog.show();
|
mRuntimeConfigDialog.dialog.show();
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
t.start();
|
t.start();
|
||||||
}
|
}
|
||||||
} else if (requestCode == RUN_MOD_INSTALLER) {
|
|
||||||
if (data != null) {
|
// Run a mod installer
|
||||||
|
if (requestCode == RUN_MOD_INSTALLER) {
|
||||||
|
if (data == null) return;
|
||||||
|
|
||||||
final Uri uri = data.getData();
|
final Uri uri = data.getData();
|
||||||
barrier.setMessage(BaseLauncherActivity.this.getString(R.string.multirt_progress_caching));
|
barrier.setMessage(BaseLauncherActivity.this.getString(R.string.multirt_progress_caching));
|
||||||
Thread t = new Thread(()->{
|
Thread t = new Thread(()->{
|
||||||
@ -308,14 +212,8 @@ public abstract class BaseLauncherActivity extends BaseActivity {
|
|||||||
});
|
});
|
||||||
t.start();
|
t.start();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Catching touch exception
|
}
|
||||||
@Override
|
|
||||||
public boolean onTouchEvent(MotionEvent event) {
|
|
||||||
return super.onTouchEvent(event);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract void initTabs(int pageIndex);
|
protected abstract void initTabs(int pageIndex);
|
||||||
|
@ -48,8 +48,9 @@ public class BaseMainActivity extends LoggableActivity {
|
|||||||
public float scaleFactor = 1;
|
public float scaleFactor = 1;
|
||||||
public double sensitivityFactor;
|
public double sensitivityFactor;
|
||||||
private final int fingerStillThreshold = (int) Tools.dpToPx(9);
|
private final int fingerStillThreshold = (int) Tools.dpToPx(9);
|
||||||
|
private final int fingerScrollThreshold = (int) Tools.dpToPx(6);
|
||||||
private float initialX, initialY;
|
private float initialX, initialY;
|
||||||
private int scrollInitialX, scrollInitialY;
|
private float scrollLastInitialX, scrollLastInitialY;
|
||||||
private float prevX, prevY;
|
private float prevX, prevY;
|
||||||
private int currentPointerID;
|
private int currentPointerID;
|
||||||
|
|
||||||
@ -62,8 +63,8 @@ public class BaseMainActivity extends LoggableActivity {
|
|||||||
switch (msg.what) {
|
switch (msg.what) {
|
||||||
case MSG_LEFT_MOUSE_BUTTON_CHECK:
|
case MSG_LEFT_MOUSE_BUTTON_CHECK:
|
||||||
if(LauncherPreferences.PREF_DISABLE_GESTURES) break;
|
if(LauncherPreferences.PREF_DISABLE_GESTURES) break;
|
||||||
int x = CallbackBridge.mouseX;
|
float x = CallbackBridge.mouseX;
|
||||||
int y = CallbackBridge.mouseY;
|
float y = CallbackBridge.mouseY;
|
||||||
if (CallbackBridge.isGrabbing() &&
|
if (CallbackBridge.isGrabbing() &&
|
||||||
Math.abs(initialX - x) < fingerStillThreshold &&
|
Math.abs(initialX - x) < fingerStillThreshold &&
|
||||||
Math.abs(initialY - y) < fingerStillThreshold) {
|
Math.abs(initialY - y) < fingerStillThreshold) {
|
||||||
@ -96,8 +97,9 @@ public class BaseMainActivity extends LoggableActivity {
|
|||||||
private TextView textLog;
|
private TextView textLog;
|
||||||
private ScrollView contentScroll;
|
private ScrollView contentScroll;
|
||||||
private ToggleButton toggleLog;
|
private ToggleButton toggleLog;
|
||||||
private GestureDetector gestureDetector;
|
|
||||||
private DoubleTapDetector doubleTapDetector;
|
private TapDetector singleTapDetector;
|
||||||
|
private TapDetector doubleTapDetector;
|
||||||
|
|
||||||
private TextView debugText;
|
private TextView debugText;
|
||||||
private NavigationView.OnNavigationItemSelectedListener gameActionListener;
|
private NavigationView.OnNavigationItemSelectedListener gameActionListener;
|
||||||
@ -164,8 +166,9 @@ public class BaseMainActivity extends LoggableActivity {
|
|||||||
System.out.println("WidthHeight: " + windowWidth + ":" + windowHeight);
|
System.out.println("WidthHeight: " + windowWidth + ":" + windowHeight);
|
||||||
|
|
||||||
|
|
||||||
gestureDetector = new GestureDetector(this, new SingleTapConfirm());
|
|
||||||
doubleTapDetector = new DoubleTapDetector();
|
singleTapDetector = new TapDetector(1, TapDetector.DETECTION_METHOD_BOTH);
|
||||||
|
doubleTapDetector = new TapDetector(2, TapDetector.DETECTION_METHOD_DOWN);
|
||||||
|
|
||||||
|
|
||||||
// Menu
|
// Menu
|
||||||
@ -262,7 +265,7 @@ public class BaseMainActivity extends LoggableActivity {
|
|||||||
float mouseX = mousePointer.getX();
|
float mouseX = mousePointer.getX();
|
||||||
float mouseY = mousePointer.getY();
|
float mouseY = mousePointer.getY();
|
||||||
|
|
||||||
if (gestureDetector.onTouchEvent(event)) {
|
if (singleTapDetector.onTouchEvent(event)) {
|
||||||
mouse_x = (mouseX * scaleFactor);
|
mouse_x = (mouseX * scaleFactor);
|
||||||
mouse_y = (mouseY * scaleFactor);
|
mouse_y = (mouseY * scaleFactor);
|
||||||
CallbackBridge.sendCursorPos(mouse_x, mouse_y);
|
CallbackBridge.sendCursorPos(mouse_x, mouse_y);
|
||||||
@ -273,8 +276,8 @@ public class BaseMainActivity extends LoggableActivity {
|
|||||||
} else {
|
} else {
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case MotionEvent.ACTION_POINTER_DOWN: // 5
|
case MotionEvent.ACTION_POINTER_DOWN: // 5
|
||||||
scrollInitialX = CallbackBridge.mouseX;
|
scrollLastInitialX = event.getX();
|
||||||
scrollInitialY = CallbackBridge.mouseY;
|
scrollLastInitialY = event.getY();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case MotionEvent.ACTION_DOWN:
|
case MotionEvent.ACTION_DOWN:
|
||||||
@ -285,10 +288,15 @@ public class BaseMainActivity extends LoggableActivity {
|
|||||||
|
|
||||||
case MotionEvent.ACTION_MOVE: // 2
|
case MotionEvent.ACTION_MOVE: // 2
|
||||||
|
|
||||||
if (!CallbackBridge.isGrabbing() && event.getPointerCount() == 2 && !LauncherPreferences.PREF_DISABLE_GESTURES) { //Scrolling feature
|
if (!CallbackBridge.isGrabbing() && event.getPointerCount() >= 2 && !LauncherPreferences.PREF_DISABLE_GESTURES) { //Scrolling feature
|
||||||
CallbackBridge.sendScroll( Tools.pxToDp(CallbackBridge.mouseX - scrollInitialX)/30, Tools.pxToDp(CallbackBridge.mouseY - scrollInitialY)/30);
|
int hScroll = ((int) (event.getX() - scrollLastInitialX)) / fingerScrollThreshold;
|
||||||
scrollInitialX = CallbackBridge.mouseX;
|
int vScroll = ((int) (event.getY() - scrollLastInitialY)) / fingerScrollThreshold;
|
||||||
scrollInitialY = CallbackBridge.mouseY;
|
|
||||||
|
if(vScroll != 0 || hScroll != 0){
|
||||||
|
CallbackBridge.sendScroll(hScroll, vScroll);
|
||||||
|
scrollLastInitialX = event.getX();
|
||||||
|
scrollLastInitialY = event.getY();
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if(currentPointerID == event.getPointerId(0)) {
|
if(currentPointerID == event.getPointerId(0)) {
|
||||||
mouseX = Math.max(0, Math.min(displayMetrics.widthPixels, mouseX + (x - prevX) * LauncherPreferences.PREF_MOUSESPEED));
|
mouseX = Math.max(0, Math.min(displayMetrics.widthPixels, mouseX + (x - prevX) * LauncherPreferences.PREF_MOUSESPEED));
|
||||||
@ -354,7 +362,7 @@ public class BaseMainActivity extends LoggableActivity {
|
|||||||
mouse_x = (e.getX() * scaleFactor);
|
mouse_x = (e.getX() * scaleFactor);
|
||||||
mouse_y = (e.getY() * scaleFactor);
|
mouse_y = (e.getY() * scaleFactor);
|
||||||
//One android click = one MC click
|
//One android click = one MC click
|
||||||
if(gestureDetector.onTouchEvent(e)){
|
if(singleTapDetector.onTouchEvent(e)){
|
||||||
CallbackBridge.putMouseEventWithCoords(rightOverride ? (byte) 1 : (byte) 0, (int)mouse_x, (int)mouse_y);
|
CallbackBridge.putMouseEventWithCoords(rightOverride ? (byte) 1 : (byte) 0, (int)mouse_x, (int)mouse_y);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -424,8 +432,8 @@ public class BaseMainActivity extends LoggableActivity {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case MotionEvent.ACTION_POINTER_DOWN: // 5
|
case MotionEvent.ACTION_POINTER_DOWN: // 5
|
||||||
scrollInitialX = CallbackBridge.mouseX;
|
scrollLastInitialX = e.getX();
|
||||||
scrollInitialY = CallbackBridge.mouseY;
|
scrollLastInitialY = e.getY();
|
||||||
//Checking if we are pressing the hotbar to select the item
|
//Checking if we are pressing the hotbar to select the item
|
||||||
hudKeyHandled = handleGuiBar((int)e.getX(e.getPointerCount()-1), (int) e.getY(e.getPointerCount()-1));
|
hudKeyHandled = handleGuiBar((int)e.getX(e.getPointerCount()-1), (int) e.getY(e.getPointerCount()-1));
|
||||||
if(hudKeyHandled != -1){
|
if(hudKeyHandled != -1){
|
||||||
@ -440,10 +448,17 @@ public class BaseMainActivity extends LoggableActivity {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case MotionEvent.ACTION_MOVE:
|
case MotionEvent.ACTION_MOVE:
|
||||||
if (!CallbackBridge.isGrabbing() && e.getPointerCount() == 2 && !LauncherPreferences.PREF_DISABLE_GESTURES) { //Scrolling feature
|
if (!CallbackBridge.isGrabbing() && e.getPointerCount() >= 2 && !LauncherPreferences.PREF_DISABLE_GESTURES) { //Scrolling feature
|
||||||
CallbackBridge.sendScroll(Tools.pxToDp(mouse_x - scrollInitialX)/30 , Tools.pxToDp(mouse_y - scrollInitialY)/30);
|
int hScroll = ((int) (e.getX() - scrollLastInitialX)) / fingerScrollThreshold;
|
||||||
scrollInitialX = (int)mouse_x;
|
int vScroll = ((int) (e.getY() - scrollLastInitialY)) / fingerScrollThreshold;
|
||||||
scrollInitialY = (int)mouse_y;
|
|
||||||
|
if(vScroll != 0 || hScroll != 0){
|
||||||
|
CallbackBridge.sendScroll(hScroll, vScroll);
|
||||||
|
scrollLastInitialX = e.getX();
|
||||||
|
scrollLastInitialY = e.getY();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
} else if (!CallbackBridge.isGrabbing() && e.getPointerCount() == 1) { //Touch hover
|
} else if (!CallbackBridge.isGrabbing() && e.getPointerCount() == 1) { //Touch hover
|
||||||
CallbackBridge.sendCursorPos(mouse_x, mouse_y);
|
CallbackBridge.sendCursorPos(mouse_x, mouse_y);
|
||||||
prevX = e.getX();
|
prevX = e.getX();
|
||||||
|
@ -1,67 +0,0 @@
|
|||||||
package net.kdt.pojavlaunch;
|
|
||||||
|
|
||||||
import android.view.MotionEvent;
|
|
||||||
|
|
||||||
import static android.view.MotionEvent.ACTION_DOWN;
|
|
||||||
import static android.view.MotionEvent.ACTION_POINTER_DOWN;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Class aiming at better detecting double tap events for EVERY POINTER
|
|
||||||
* Only uses the least amount of events possible,
|
|
||||||
* since we aren't guaranteed to have all events in order
|
|
||||||
*/
|
|
||||||
public class DoubleTapDetector {
|
|
||||||
|
|
||||||
private final static int DOUBLE_TAP_MIN_DELTA_MS = 50;
|
|
||||||
private final static int DOUBLE_TAP_MAX_DELTA_MS = 300;
|
|
||||||
private final static int DOUBLE_TAP_SLOP_SQUARE_PX = (int) Math.pow(Tools.dpToPx(100), 2);
|
|
||||||
|
|
||||||
private long mLastEventTime = 0;
|
|
||||||
private float mLastX = 9999;
|
|
||||||
private float mLastY = 9999;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A function to call when you have a touch event.
|
|
||||||
* @param e The MotionEvent to inspect
|
|
||||||
* @return whether or not a double tap happened for a pointer
|
|
||||||
*/
|
|
||||||
public boolean onTouchEvent(MotionEvent e){
|
|
||||||
int eventAction = e.getActionMasked();
|
|
||||||
int pointerIndex;
|
|
||||||
|
|
||||||
//Get the pointer index we want to look at
|
|
||||||
if(eventAction == ACTION_DOWN) pointerIndex = 0;
|
|
||||||
else if(eventAction == ACTION_POINTER_DOWN) pointerIndex = e.getActionIndex();
|
|
||||||
else return false;
|
|
||||||
|
|
||||||
float eventX = e.getX(pointerIndex);
|
|
||||||
float eventY = e.getY(pointerIndex);
|
|
||||||
long eventTime = e.getEventTime();
|
|
||||||
|
|
||||||
long deltaTime = eventTime - mLastEventTime;
|
|
||||||
if(deltaTime > DOUBLE_TAP_MIN_DELTA_MS && deltaTime < DOUBLE_TAP_MAX_DELTA_MS){
|
|
||||||
int deltaX = (int) mLastX - (int) eventX;
|
|
||||||
int deltaY = (int) mLastY - (int) eventY;
|
|
||||||
if((deltaX*deltaX + deltaY*deltaY) < DOUBLE_TAP_SLOP_SQUARE_PX){
|
|
||||||
//Then I guess there is a double tap :thonk:
|
|
||||||
resetDoubleTapState();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mLastEventTime = eventTime;
|
|
||||||
mLastX = eventX;
|
|
||||||
mLastY = eventY;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Reset the double tap values.
|
|
||||||
*/
|
|
||||||
private void resetDoubleTapState(){
|
|
||||||
mLastEventTime = 0;
|
|
||||||
mLastX = 9999;
|
|
||||||
mLastY = 9999;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -49,8 +49,8 @@ public class JavaGUILauncherActivity extends LoggableActivity implements View.On
|
|||||||
public void handleMessage(Message msg) {
|
public void handleMessage(Message msg) {
|
||||||
switch (msg.what) {
|
switch (msg.what) {
|
||||||
case MSG_LEFT_MOUSE_BUTTON_CHECK: {
|
case MSG_LEFT_MOUSE_BUTTON_CHECK: {
|
||||||
int x = CallbackBridge.mouseX;
|
float x = CallbackBridge.mouseX;
|
||||||
int y = CallbackBridge.mouseY;
|
float y = CallbackBridge.mouseY;
|
||||||
if (CallbackBridge.isGrabbing() &&
|
if (CallbackBridge.isGrabbing() &&
|
||||||
Math.abs(initialX - x) < fingerStillThreshold &&
|
Math.abs(initialX - x) < fingerStillThreshold &&
|
||||||
Math.abs(initialY - y) < fingerStillThreshold) {
|
Math.abs(initialY - y) < fingerStillThreshold) {
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
package net.kdt.pojavlaunch;
|
package net.kdt.pojavlaunch;
|
||||||
|
|
||||||
|
import static android.os.Build.VERSION_CODES.P;
|
||||||
|
import static net.kdt.pojavlaunch.Tools.ignoreNotch;
|
||||||
|
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_HIDE_SIDEBAR;
|
||||||
|
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_NOTCH_SIZE;
|
||||||
|
|
||||||
import android.animation.ValueAnimator;
|
import android.animation.ValueAnimator;
|
||||||
import android.content.SharedPreferences;
|
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
import android.graphics.Color;
|
import android.graphics.Color;
|
||||||
import android.graphics.Typeface;
|
import android.graphics.Typeface;
|
||||||
@ -9,115 +13,127 @@ import android.os.Build;
|
|||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.support.design.widget.VerticalTabLayout.ViewPagerAdapter;
|
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.AdapterView;
|
import android.widget.AdapterView;
|
||||||
import android.widget.ArrayAdapter;
|
import android.widget.ArrayAdapter;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ImageView;
|
||||||
import android.widget.Spinner;
|
import android.widget.Spinner;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
|
||||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||||
import androidx.constraintlayout.widget.Guideline;
|
import androidx.constraintlayout.widget.Guideline;
|
||||||
import androidx.viewpager.widget.ViewPager;
|
import androidx.fragment.app.Fragment;
|
||||||
|
import androidx.fragment.app.FragmentActivity;
|
||||||
|
import androidx.viewpager2.adapter.FragmentStateAdapter;
|
||||||
|
import androidx.viewpager2.widget.ViewPager2;
|
||||||
|
|
||||||
|
import net.kdt.pojavlaunch.extra.ExtraCore;
|
||||||
|
import net.kdt.pojavlaunch.extra.ExtraListener;
|
||||||
import net.kdt.pojavlaunch.fragments.ConsoleFragment;
|
import net.kdt.pojavlaunch.fragments.ConsoleFragment;
|
||||||
import net.kdt.pojavlaunch.fragments.CrashFragment;
|
import net.kdt.pojavlaunch.fragments.CrashFragment;
|
||||||
import net.kdt.pojavlaunch.fragments.LauncherFragment;
|
import net.kdt.pojavlaunch.fragments.LauncherFragment;
|
||||||
import net.kdt.pojavlaunch.prefs.LauncherPreferenceFragment;
|
|
||||||
import net.kdt.pojavlaunch.prefs.LauncherPreferences;
|
import net.kdt.pojavlaunch.prefs.LauncherPreferences;
|
||||||
|
import net.kdt.pojavlaunch.prefs.screens.LauncherPreferenceFragment;
|
||||||
import net.kdt.pojavlaunch.value.MinecraftAccount;
|
import net.kdt.pojavlaunch.value.MinecraftAccount;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static android.os.Build.VERSION_CODES.P;
|
|
||||||
import static net.kdt.pojavlaunch.Tools.ignoreNotch;
|
|
||||||
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_HIDE_SIDEBAR;
|
|
||||||
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_IGNORE_NOTCH;
|
|
||||||
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_NOTCH_SIZE;
|
|
||||||
|
|
||||||
public class PojavLauncherActivity extends BaseLauncherActivity
|
public class PojavLauncherActivity extends BaseLauncherActivity
|
||||||
{
|
{
|
||||||
|
|
||||||
private ViewPager viewPager;
|
// An equivalent ViewPager2 adapter class
|
||||||
|
private static class ScreenSlidePagerAdapter extends FragmentStateAdapter {
|
||||||
|
public ScreenSlidePagerAdapter(FragmentActivity fa) {
|
||||||
|
super(fa);
|
||||||
|
}
|
||||||
|
|
||||||
private TextView tvUsernameView, tvConnectStatus;
|
@Override
|
||||||
|
public Fragment createFragment(int position) {
|
||||||
|
if (position == 0) return new LauncherFragment();
|
||||||
|
if (position == 1) return new ConsoleFragment();
|
||||||
|
if (position == 2) return new CrashFragment();
|
||||||
|
if (position == 3) return new LauncherPreferenceFragment();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private TextView tvConnectStatus;
|
||||||
private Spinner accountSelector;
|
private Spinner accountSelector;
|
||||||
private ViewPagerAdapter viewPageAdapter;
|
private ViewPager2 viewPager;
|
||||||
private final Button[] Tabs = new Button[4];
|
private final Button[] Tabs = new Button[4];
|
||||||
private View selected;
|
private View selectedTab;
|
||||||
|
private ImageView accountFaceImageView;
|
||||||
|
|
||||||
private Button logoutBtn; // MineButtons
|
private Button logoutBtn; // MineButtons
|
||||||
|
private ExtraListener backPreferenceListener;
|
||||||
|
|
||||||
public PojavLauncherActivity() {
|
public PojavLauncherActivity() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
setContentView(R.layout.launcher_main_v4);
|
setContentView(R.layout.launcher_main_v4);
|
||||||
|
|
||||||
|
//Boilerplate linking/initialisation
|
||||||
if (BuildConfig.DEBUG) {
|
|
||||||
Toast.makeText(this, "Launcher process id: " + android.os.Process.myPid(), Toast.LENGTH_LONG).show();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
viewPager = findViewById(R.id.launchermainTabPager);
|
viewPager = findViewById(R.id.launchermainTabPager);
|
||||||
selected = findViewById(R.id.viewTabSelected);
|
selectedTab = findViewById(R.id.viewTabSelected);
|
||||||
|
tvConnectStatus = findViewById(R.id.launchermain_text_accountstatus);
|
||||||
mConsoleView = new ConsoleFragment();
|
accountFaceImageView = findViewById(R.id.launchermain_account_image);
|
||||||
mCrashView = new CrashFragment();
|
accountSelector = findViewById(R.id.launchermain_spinner_account);
|
||||||
|
mVersionSelector = findViewById(R.id.launchermain_spinner_version);
|
||||||
viewPageAdapter = new ViewPagerAdapter(getSupportFragmentManager());
|
mLaunchProgress = findViewById(R.id.progressDownloadBar);
|
||||||
viewPageAdapter.addFragment(new LauncherFragment(), 0, getString(R.string.mcl_tab_news));
|
mLaunchTextStatus = findViewById(R.id.progressDownloadText);
|
||||||
viewPageAdapter.addFragment(mConsoleView, 0, getString(R.string.mcl_tab_console));
|
logoutBtn = findViewById(R.id.installJarButton);
|
||||||
viewPageAdapter.addFragment(mCrashView, 0, getString(R.string.mcl_tab_crash));
|
mPlayButton = findViewById(R.id.launchermainPlayButton);
|
||||||
viewPageAdapter.addFragment(new LauncherPreferenceFragment(), 0, getString(R.string.mcl_option_settings));
|
|
||||||
|
|
||||||
viewPager.addOnPageChangeListener(new ViewPager.OnPageChangeListener() {
|
|
||||||
@Override
|
|
||||||
public void onPageSelected(int position) {
|
|
||||||
setTabActive(position);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPageScrollStateChanged(int state) {
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
viewPager.setAdapter(viewPageAdapter);
|
|
||||||
|
|
||||||
tvConnectStatus = (TextView) findViewById(R.id.launchermain_text_accountstatus);
|
|
||||||
tvUsernameView = (TextView) findViewById(R.id.launchermain_text_welcome);
|
|
||||||
mTextVersion = (TextView) findViewById(R.id.launcherMainVersionView);
|
|
||||||
|
|
||||||
//The following line is used to make this TextView horizontally scroll if the version name is larger than the view
|
|
||||||
mTextVersion.setSelected(true);
|
|
||||||
|
|
||||||
Tabs[0] = findViewById(R.id.btnTab1);
|
Tabs[0] = findViewById(R.id.btnTab1);
|
||||||
Tabs[1] = findViewById(R.id.btnTab2);
|
Tabs[1] = findViewById(R.id.btnTab2);
|
||||||
Tabs[2] = findViewById(R.id.btnTab3);
|
Tabs[2] = findViewById(R.id.btnTab3);
|
||||||
Tabs[3] = findViewById(R.id.btnTab4);
|
Tabs[3] = findViewById(R.id.btnTab4);
|
||||||
|
|
||||||
|
|
||||||
pickAccount();
|
if (BuildConfig.DEBUG) {
|
||||||
|
Toast.makeText(this, "Launcher process id: " + android.os.Process.myPid(), Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Setup the viewPager to slide across fragments
|
||||||
|
viewPager.setAdapter(new ScreenSlidePagerAdapter(this));
|
||||||
|
viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
|
||||||
|
@Override
|
||||||
|
public void onPageSelected(int position) {
|
||||||
|
setTabActive(position);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
initTabs(0);
|
||||||
|
|
||||||
|
//Setup listener to the backPreference system
|
||||||
|
backPreferenceListener = new ExtraListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onValueSet(String key, String value) {
|
||||||
|
if(value.equals("true")){
|
||||||
|
onBackPressed();
|
||||||
|
ExtraCore.setValue(key, "false");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
ExtraCore.addExtraListener("back_preference", backPreferenceListener);
|
||||||
|
|
||||||
|
|
||||||
final List<String> accountList = new ArrayList<String>();
|
// Try to load the temporary account
|
||||||
final MinecraftAccount tempProfile = PojavProfile.getTempProfileContent(this);
|
final List<String> accountList = new ArrayList<>();
|
||||||
|
final MinecraftAccount tempProfile = PojavProfile.getTempProfileContent();
|
||||||
if (tempProfile != null) {
|
if (tempProfile != null) {
|
||||||
accountList.add(tempProfile.username);
|
accountList.add(tempProfile.username);
|
||||||
}
|
}
|
||||||
@ -125,10 +141,12 @@ public class PojavLauncherActivity extends BaseLauncherActivity
|
|||||||
accountList.add(s.substring(0, s.length() - 5));
|
accountList.add(s.substring(0, s.length() - 5));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Setup account spinner
|
||||||
|
pickAccount();
|
||||||
ArrayAdapter<String> adapterAcc = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, accountList);
|
ArrayAdapter<String> adapterAcc = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, accountList);
|
||||||
adapterAcc.setDropDownViewResource(android.R.layout.simple_list_item_single_choice);
|
adapterAcc.setDropDownViewResource(android.R.layout.simple_list_item_single_choice);
|
||||||
accountSelector = (Spinner) findViewById(R.id.launchermain_spinner_account);
|
|
||||||
accountSelector.setAdapter(adapterAcc);
|
accountSelector.setAdapter(adapterAcc);
|
||||||
|
|
||||||
if (tempProfile != null) {
|
if (tempProfile != null) {
|
||||||
accountSelector.setSelection(0);
|
accountSelector.setSelection(0);
|
||||||
} else {
|
} else {
|
||||||
@ -158,7 +176,8 @@ public class PojavLauncherActivity extends BaseLauncherActivity
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
List<String> versions = new ArrayList<String>();
|
// Setup the minecraft version list
|
||||||
|
List<String> versions = new ArrayList<>();
|
||||||
final File fVers = new File(Tools.DIR_HOME_VERSION);
|
final File fVers = new File(Tools.DIR_HOME_VERSION);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
@ -179,24 +198,15 @@ public class PojavLauncherActivity extends BaseLauncherActivity
|
|||||||
}
|
}
|
||||||
|
|
||||||
//mAvailableVersions;
|
//mAvailableVersions;
|
||||||
ArrayAdapter<String> adapterVer = new ArrayAdapter<String>(this, android.R.layout.simple_spinner_item, mAvailableVersions);
|
ArrayAdapter<String> adapterVer = new ArrayAdapter<>(this, android.R.layout.simple_spinner_item, mAvailableVersions);
|
||||||
adapterVer.setDropDownViewResource(android.R.layout.simple_list_item_single_choice);
|
adapterVer.setDropDownViewResource(android.R.layout.simple_list_item_single_choice);
|
||||||
mVersionSelector = (Spinner) findViewById(R.id.launchermain_spinner_version);
|
|
||||||
mVersionSelector.setAdapter(adapterVer);
|
mVersionSelector.setAdapter(adapterVer);
|
||||||
|
|
||||||
mLaunchProgress = (ProgressBar) findViewById(R.id.progressDownloadBar);
|
|
||||||
mLaunchTextStatus = (TextView) findViewById(R.id.progressDownloadText);
|
|
||||||
logoutBtn = (Button) findViewById(R.id.switchUserBtn);
|
|
||||||
|
|
||||||
mPlayButton = (Button) findViewById(R.id.launchermainPlayButton);
|
|
||||||
|
|
||||||
statusIsLaunching(false);
|
statusIsLaunching(false);
|
||||||
|
|
||||||
|
|
||||||
initTabs(0);
|
//Add the preference changed listener
|
||||||
LauncherPreferences.DEFAULT_PREF.registerOnSharedPreferenceChangeListener(new SharedPreferences.OnSharedPreferenceChangeListener() {
|
LauncherPreferences.DEFAULT_PREF.registerOnSharedPreferenceChangeListener((sharedPreferences, key) -> {
|
||||||
@Override
|
|
||||||
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
|
|
||||||
if(key.equals("hideSidebar")){
|
if(key.equals("hideSidebar")){
|
||||||
changeLookAndFeel(sharedPreferences.getBoolean("hideSidebar",false));
|
changeLookAndFeel(sharedPreferences.getBoolean("hideSidebar",false));
|
||||||
return;
|
return;
|
||||||
@ -206,13 +216,10 @@ public class PojavLauncherActivity extends BaseLauncherActivity
|
|||||||
ignoreNotch(sharedPreferences.getBoolean("ignoreNotch", true), PojavLauncherActivity.this);
|
ignoreNotch(sharedPreferences.getBoolean("ignoreNotch", true), PojavLauncherActivity.this);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
});
|
||||||
changeLookAndFeel(PREF_HIDE_SIDEBAR);
|
changeLookAndFeel(PREF_HIDE_SIDEBAR);
|
||||||
ignoreNotch(PREF_IGNORE_NOTCH, PojavLauncherActivity.this);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private void selectTabPage(int pageIndex){
|
private void selectTabPage(int pageIndex){
|
||||||
viewPager.setCurrentItem(pageIndex);
|
viewPager.setCurrentItem(pageIndex);
|
||||||
setTabActive(pageIndex);
|
setTabActive(pageIndex);
|
||||||
@ -221,8 +228,9 @@ public class PojavLauncherActivity extends BaseLauncherActivity
|
|||||||
private void pickAccount() {
|
private void pickAccount() {
|
||||||
try {
|
try {
|
||||||
mProfile = PojavProfile.getCurrentProfileContent(this);
|
mProfile = PojavProfile.getCurrentProfileContent(this);
|
||||||
|
accountFaceImageView.setImageBitmap(mProfile.getSkinFace());
|
||||||
|
|
||||||
tvUsernameView.setText(getString(R.string.main_welcome, mProfile.username));
|
//TODO FULL BACKGROUND LOGIN
|
||||||
tvConnectStatus.setText(mProfile.accessToken.equals("0") ? R.string.mcl_account_offline : R.string.mcl_account_connected);
|
tvConnectStatus.setText(mProfile.accessToken.equals("0") ? R.string.mcl_account_offline : R.string.mcl_account_connected);
|
||||||
} catch(Exception e) {
|
} catch(Exception e) {
|
||||||
mProfile = new MinecraftAccount();
|
mProfile = new MinecraftAccount();
|
||||||
@ -259,21 +267,18 @@ public class PojavLauncherActivity extends BaseLauncherActivity
|
|||||||
Tabs[index].setTextColor(Color.WHITE);
|
Tabs[index].setTextColor(Color.WHITE);
|
||||||
|
|
||||||
//Animating the white bar on the left
|
//Animating the white bar on the left
|
||||||
ValueAnimator animation = ValueAnimator.ofFloat(selected.getY(), Tabs[index].getY()+(Tabs[index].getHeight()-selected.getHeight())/2f);
|
ValueAnimator animation = ValueAnimator.ofFloat(selectedTab.getY(), Tabs[index].getY()+(Tabs[index].getHeight()- selectedTab.getHeight())/2f);
|
||||||
animation.setDuration(250);
|
animation.setDuration(250);
|
||||||
animation.addUpdateListener(animation1 -> selected.setY((float) animation1.getAnimatedValue()));
|
animation.addUpdateListener(animation1 -> selectedTab.setY((float) animation1.getAnimatedValue()));
|
||||||
animation.start();
|
animation.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void initTabs(int activeTab){
|
protected void initTabs(int activeTab){
|
||||||
final Handler handler = new Handler(Looper.getMainLooper());
|
final Handler handler = new Handler(Looper.getMainLooper());
|
||||||
handler.postDelayed(new Runnable() {
|
handler.post(() -> {
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
//Do something after 100ms
|
//Do something after 100ms
|
||||||
selectTabPage(activeTab);
|
selectTabPage(activeTab);
|
||||||
}
|
});
|
||||||
}, 500);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void changeLookAndFeel(boolean useOldLook){
|
private void changeLookAndFeel(boolean useOldLook){
|
||||||
@ -286,8 +291,9 @@ public class PojavLauncherActivity extends BaseLauncherActivity
|
|||||||
params.guidePercent = 0; // 0%, range: 0 <-> 1
|
params.guidePercent = 0; // 0%, range: 0 <-> 1
|
||||||
guideLine.setLayoutParams(params);
|
guideLine.setLayoutParams(params);
|
||||||
|
|
||||||
//Remove the selected Tab
|
//Remove the selected Tab and the head image
|
||||||
selected.setVisibility(View.GONE);
|
selectedTab.setVisibility(View.GONE);
|
||||||
|
accountFaceImageView.setVisibility(View.GONE);
|
||||||
|
|
||||||
//Enlarge the button, but just a bit.
|
//Enlarge the button, but just a bit.
|
||||||
params = (ConstraintLayout.LayoutParams) mPlayButton.getLayoutParams();
|
params = (ConstraintLayout.LayoutParams) mPlayButton.getLayoutParams();
|
||||||
@ -299,7 +305,8 @@ public class PojavLauncherActivity extends BaseLauncherActivity
|
|||||||
guideLine.setLayoutParams(params);
|
guideLine.setLayoutParams(params);
|
||||||
|
|
||||||
//Show the selected Tab
|
//Show the selected Tab
|
||||||
selected.setVisibility(View.VISIBLE);
|
selectedTab.setVisibility(View.VISIBLE);
|
||||||
|
accountFaceImageView.setVisibility(View.VISIBLE);
|
||||||
|
|
||||||
//Set the default button size
|
//Set the default button size
|
||||||
params = (ConstraintLayout.LayoutParams) mPlayButton.getLayoutParams();
|
params = (ConstraintLayout.LayoutParams) mPlayButton.getLayoutParams();
|
||||||
@ -323,5 +330,22 @@ public class PojavLauncherActivity extends BaseLauncherActivity
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom back stack system. Use the classic backstack when the focus is on the setting screen,
|
||||||
|
* finish the activity and remove the back_preference listener otherwise
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void onBackPressed() {
|
||||||
|
int count = getSupportFragmentManager().getBackStackEntryCount();
|
||||||
|
|
||||||
|
if(count > 0 && viewPager.getCurrentItem() == 3){
|
||||||
|
getSupportFragmentManager().popBackStack();
|
||||||
|
}else{
|
||||||
|
super.onBackPressed();
|
||||||
|
//additional code
|
||||||
|
ExtraCore.removeExtraListenerFromValue("back_preference", backPreferenceListener);
|
||||||
|
finish();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package net.kdt.pojavlaunch;
|
package net.kdt.pojavlaunch;
|
||||||
|
|
||||||
import static net.kdt.pojavlaunch.Architecture.archAsString;
|
import static net.kdt.pojavlaunch.Architecture.archAsString;
|
||||||
|
import static net.kdt.pojavlaunch.Tools.getFileName;
|
||||||
|
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
@ -379,7 +380,7 @@ public class PojavLoginActivity extends BaseActivity
|
|||||||
final Uri uri = data.getData();
|
final Uri uri = data.getData();
|
||||||
Thread t = new Thread(() -> {
|
Thread t = new Thread(() -> {
|
||||||
try {
|
try {
|
||||||
MultiRTUtils.installRuntimeNamed(getContentResolver().openInputStream(uri), BaseLauncherActivity.getFileName(this, uri),
|
MultiRTUtils.installRuntimeNamed(getContentResolver().openInputStream(uri), getFileName(this, uri),
|
||||||
(resid, stuff) -> PojavLoginActivity.this.runOnUiThread(
|
(resid, stuff) -> PojavLoginActivity.this.runOnUiThread(
|
||||||
() -> {
|
() -> {
|
||||||
if (startupTextView != null)
|
if (startupTextView != null)
|
||||||
@ -507,14 +508,8 @@ public class PojavLoginActivity extends BaseActivity
|
|||||||
ImageView imageView = child.findViewById(R.id.account_head);
|
ImageView imageView = child.findViewById(R.id.account_head);
|
||||||
|
|
||||||
String accNameStr = s.substring(0, s.length() - 5);
|
String accNameStr = s.substring(0, s.length() - 5);
|
||||||
String skinFaceBase64 = MinecraftAccount.load(accNameStr).skinFaceBase64;
|
imageView.setImageBitmap(MinecraftAccount.load(accNameStr).getSkinFace());
|
||||||
if (skinFaceBase64 != null) {
|
|
||||||
byte[] faceIconBytes = Base64.decode(skinFaceBase64, Base64.DEFAULT);
|
|
||||||
Bitmap bitmap = BitmapFactory.decodeByteArray(faceIconBytes, 0, faceIconBytes.length);
|
|
||||||
|
|
||||||
imageView.setImageDrawable(new BitmapDrawable(getResources(),
|
|
||||||
bitmap));
|
|
||||||
}
|
|
||||||
accountName.setText(accNameStr);
|
accountName.setText(accNameStr);
|
||||||
|
|
||||||
accountListLayout.addView(child);
|
accountListLayout.addView(child);
|
||||||
@ -635,7 +630,6 @@ public class PojavLoginActivity extends BaseActivity
|
|||||||
builder.clientToken = result[2];
|
builder.clientToken = result[2];
|
||||||
builder.profileId = result[3];
|
builder.profileId = result[3];
|
||||||
builder.username = result[4];
|
builder.username = result[4];
|
||||||
builder.selectedVersion = "1.12.2";
|
|
||||||
builder.updateSkinFace();
|
builder.updateSkinFace();
|
||||||
mProfile = builder;
|
mProfile = builder;
|
||||||
}
|
}
|
||||||
|
@ -25,13 +25,13 @@ public class PojavProfile
|
|||||||
public static MinecraftAccount getCurrentProfileContent(Context ctx) throws JsonSyntaxException {
|
public static MinecraftAccount getCurrentProfileContent(Context ctx) throws JsonSyntaxException {
|
||||||
MinecraftAccount build = MinecraftAccount.load(getCurrentProfileName(ctx));
|
MinecraftAccount build = MinecraftAccount.load(getCurrentProfileName(ctx));
|
||||||
if (build == null) {
|
if (build == null) {
|
||||||
System.out.println("isTempProfile null? " + (getTempProfileContent(ctx) == null));
|
System.out.println("isTempProfile null? " + (getTempProfileContent() == null));
|
||||||
return getTempProfileContent(ctx);
|
return getTempProfileContent();
|
||||||
}
|
}
|
||||||
return build;
|
return build;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MinecraftAccount getTempProfileContent(Context ctx) {
|
public static MinecraftAccount getTempProfileContent() {
|
||||||
try {
|
try {
|
||||||
MinecraftAccount acc = MinecraftAccount.parse(Tools.read(Tools.DIR_DATA+"/cache/tempacc.json"));
|
MinecraftAccount acc = MinecraftAccount.parse(Tools.read(Tools.DIR_DATA+"/cache/tempacc.json"));
|
||||||
if (acc.accessToken == null) {
|
if (acc.accessToken == null) {
|
||||||
|
@ -0,0 +1,122 @@
|
|||||||
|
package net.kdt.pojavlaunch;
|
||||||
|
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
|
||||||
|
import static android.view.MotionEvent.ACTION_DOWN;
|
||||||
|
import static android.view.MotionEvent.ACTION_POINTER_DOWN;
|
||||||
|
import static android.view.MotionEvent.ACTION_POINTER_UP;
|
||||||
|
import static android.view.MotionEvent.ACTION_UP;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class aiming at better detecting X-tap events regardless of the POINTERS
|
||||||
|
* Only uses the least amount of events possible,
|
||||||
|
* since we aren't guaranteed to have all events in order
|
||||||
|
*/
|
||||||
|
public class TapDetector {
|
||||||
|
|
||||||
|
public final static int DETECTION_METHOD_DOWN = 0x1;
|
||||||
|
public final static int DETECTION_METHOD_UP = 0x2;
|
||||||
|
public final static int DETECTION_METHOD_BOTH = 0x3; //Unused for now
|
||||||
|
|
||||||
|
private final static int TAP_MIN_DELTA_MS = 10;
|
||||||
|
private final static int TAP_MAX_DELTA_MS = 300;
|
||||||
|
private final static int TAP_SLOP_SQUARE_PX = (int) Math.pow(Tools.dpToPx(100), 2);
|
||||||
|
|
||||||
|
private final int tapNumberToDetect;
|
||||||
|
private int currentTapNumber = 0;
|
||||||
|
|
||||||
|
private final int detectionMethod;
|
||||||
|
|
||||||
|
private long mLastEventTime = 0;
|
||||||
|
private float mLastX = 9999;
|
||||||
|
private float mLastY = 9999;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param tapNumberToDetect How many taps are needed before onTouchEvent returns True.
|
||||||
|
* @param detectionMethod Method used to detect touches. See DETECTION_METHOD constants above.
|
||||||
|
*/
|
||||||
|
public TapDetector(int tapNumberToDetect, int detectionMethod){
|
||||||
|
this.detectionMethod = detectionMethod;
|
||||||
|
//We expect both ACTION_DOWN and ACTION_UP for the DETECTION_METHOD_BOTH
|
||||||
|
this.tapNumberToDetect = detectBothTouch() ? 2*tapNumberToDetect : tapNumberToDetect;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A function to call when you have a touch event.
|
||||||
|
* @param e The MotionEvent to inspect
|
||||||
|
* @return whether or not a X-tap happened for a pointer
|
||||||
|
*/
|
||||||
|
public boolean onTouchEvent(MotionEvent e){
|
||||||
|
int eventAction = e.getActionMasked();
|
||||||
|
int pointerIndex = -1;
|
||||||
|
|
||||||
|
//Get the event to look forward
|
||||||
|
if(detectDownTouch()){
|
||||||
|
if(eventAction == ACTION_DOWN) pointerIndex = 0;
|
||||||
|
else if(eventAction == ACTION_POINTER_DOWN) pointerIndex = e.getActionIndex();
|
||||||
|
}
|
||||||
|
if(detectUpTouch()){
|
||||||
|
if(eventAction == ACTION_UP) pointerIndex = 0;
|
||||||
|
else if(eventAction == ACTION_POINTER_UP) pointerIndex = e.getActionIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(pointerIndex == -1) return false; // Useless event
|
||||||
|
|
||||||
|
//Store current event info
|
||||||
|
float eventX = e.getX(pointerIndex);
|
||||||
|
float eventY = e.getY(pointerIndex);
|
||||||
|
long eventTime = e.getEventTime();
|
||||||
|
|
||||||
|
//Compute deltas
|
||||||
|
long deltaTime = eventTime - mLastEventTime;
|
||||||
|
int deltaX = (int) mLastX - (int) eventX;
|
||||||
|
int deltaY = (int) mLastY - (int) eventY;
|
||||||
|
|
||||||
|
//Store current event info to persist on next event
|
||||||
|
mLastEventTime = eventTime;
|
||||||
|
mLastX = eventX;
|
||||||
|
mLastY = eventY;
|
||||||
|
|
||||||
|
//Check for high enough speed and precision
|
||||||
|
if(currentTapNumber > 0){
|
||||||
|
if ((deltaTime < TAP_MIN_DELTA_MS || deltaTime > TAP_MAX_DELTA_MS) ||
|
||||||
|
((deltaX*deltaX + deltaY*deltaY) > TAP_SLOP_SQUARE_PX)) {
|
||||||
|
// We invalidate previous taps, not this one though
|
||||||
|
currentTapNumber = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//A worthy tap happened
|
||||||
|
currentTapNumber += 1;
|
||||||
|
if(currentTapNumber >= tapNumberToDetect){
|
||||||
|
resetTapDetectionState();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//If not enough taps are reached
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset the double tap values.
|
||||||
|
*/
|
||||||
|
private void resetTapDetectionState(){
|
||||||
|
currentTapNumber = 0;
|
||||||
|
mLastEventTime = 0;
|
||||||
|
mLastX = 9999;
|
||||||
|
mLastY = 9999;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private boolean detectDownTouch(){
|
||||||
|
return (detectionMethod & DETECTION_METHOD_DOWN) == DETECTION_METHOD_DOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean detectUpTouch(){
|
||||||
|
return (detectionMethod & DETECTION_METHOD_UP) == DETECTION_METHOD_UP;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean detectBothTouch(){
|
||||||
|
return detectionMethod == DETECTION_METHOD_BOTH;
|
||||||
|
}
|
||||||
|
}
|
@ -2,8 +2,10 @@ package net.kdt.pojavlaunch;
|
|||||||
|
|
||||||
import android.app.*;
|
import android.app.*;
|
||||||
import android.content.*;
|
import android.content.*;
|
||||||
|
import android.database.Cursor;
|
||||||
import android.net.*;
|
import android.net.*;
|
||||||
import android.os.*;
|
import android.os.*;
|
||||||
|
import android.provider.OpenableColumns;
|
||||||
import android.system.*;
|
import android.system.*;
|
||||||
import android.util.*;
|
import android.util.*;
|
||||||
import com.google.gson.*;
|
import com.google.gson.*;
|
||||||
@ -861,4 +863,26 @@ public final class Tools {
|
|||||||
if(displaySideRes % 2 != 0) displaySideRes ++;
|
if(displaySideRes % 2 != 0) displaySideRes ++;
|
||||||
return displaySideRes;
|
return displaySideRes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getFileName(Context ctx, Uri uri) {
|
||||||
|
String result = null;
|
||||||
|
if (uri.getScheme().equals("content")) {
|
||||||
|
Cursor cursor = ctx.getContentResolver().query(uri, null, null, null, null);
|
||||||
|
try {
|
||||||
|
if (cursor != null && cursor.moveToFirst()) {
|
||||||
|
result = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
cursor.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (result == null) {
|
||||||
|
result = uri.getPath();
|
||||||
|
int cut = result.lastIndexOf('/');
|
||||||
|
if (cut != -1) {
|
||||||
|
result = result.substring(cut + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -71,7 +71,7 @@ public class MicrosoftAuthTask extends AsyncTask<String, Void, Object> {
|
|||||||
*/
|
*/
|
||||||
Msa msa = new Msa(this, Boolean.parseBoolean(args[0]), args[1]);
|
Msa msa = new Msa(this, Boolean.parseBoolean(args[0]), args[1]);
|
||||||
|
|
||||||
MinecraftAccount acc = new MinecraftAccount();
|
MinecraftAccount acc = MinecraftAccount.load(msa.mcName);
|
||||||
if (msa.doesOwnGame) {
|
if (msa.doesOwnGame) {
|
||||||
acc.clientToken = "0"; /* FIXME */
|
acc.clientToken = "0"; /* FIXME */
|
||||||
acc.accessToken = msa.mcToken;
|
acc.accessToken = msa.mcToken;
|
||||||
|
@ -23,6 +23,10 @@ import org.lwjgl.glfw.*;
|
|||||||
import static net.kdt.pojavlaunch.BaseMainActivity.sendMouseButton;
|
import static net.kdt.pojavlaunch.BaseMainActivity.sendMouseButton;
|
||||||
import static net.kdt.pojavlaunch.LWJGLGLFWKeycode.GLFW_KEY_UNKNOWN;
|
import static net.kdt.pojavlaunch.LWJGLGLFWKeycode.GLFW_KEY_UNKNOWN;
|
||||||
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_BUTTONSIZE;
|
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_BUTTONSIZE;
|
||||||
|
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_CONTROL_BOTTOM_OFFSET;
|
||||||
|
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_CONTROL_LEFT_OFFSET;
|
||||||
|
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_CONTROL_RIGHT_OFFSET;
|
||||||
|
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_CONTROL_TOP_OFFSET;
|
||||||
|
|
||||||
@SuppressLint("ViewConstructor")
|
@SuppressLint("ViewConstructor")
|
||||||
public class ControlButton extends androidx.appcompat.widget.AppCompatButton implements OnLongClickListener
|
public class ControlButton extends androidx.appcompat.widget.AppCompatButton implements OnLongClickListener
|
||||||
@ -152,16 +156,57 @@ public class ControlButton extends androidx.appcompat.widget.AppCompatButton imp
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setX(float x) {
|
public void setX(float x) {
|
||||||
|
// We have to account for control offset preference
|
||||||
|
if(x + (mProperties.getWidth()/2f) > CallbackBridge.physicalWidth/2f){
|
||||||
|
x -= PREF_CONTROL_RIGHT_OFFSET;
|
||||||
|
}else{
|
||||||
|
x += PREF_CONTROL_LEFT_OFFSET;
|
||||||
|
}
|
||||||
|
|
||||||
super.setX(x);
|
super.setX(x);
|
||||||
setModified(true);
|
setModified(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setY(float y) {
|
public void setY(float y) {
|
||||||
|
// We have to account for control offset preference
|
||||||
|
if(y - PREF_CONTROL_TOP_OFFSET + (mProperties.getHeight()/2f) > CallbackBridge.physicalHeight/2f){
|
||||||
|
y -= PREF_CONTROL_BOTTOM_OFFSET;
|
||||||
|
}else{
|
||||||
|
y += PREF_CONTROL_TOP_OFFSET;
|
||||||
|
}
|
||||||
|
|
||||||
super.setY(y);
|
super.setY(y);
|
||||||
setModified(true);
|
setModified(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getX() {
|
||||||
|
float x = super.getX();
|
||||||
|
// We have to account for control offset preference
|
||||||
|
if(x + (mProperties.getWidth()/2f) > (CallbackBridge.physicalWidth)/2f){
|
||||||
|
x += PREF_CONTROL_RIGHT_OFFSET;
|
||||||
|
}else{
|
||||||
|
x -= PREF_CONTROL_LEFT_OFFSET;
|
||||||
|
}
|
||||||
|
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public float getY(){
|
||||||
|
// We have to account for control offset preference
|
||||||
|
float y = super.getY();
|
||||||
|
if(y + (mProperties.getHeight()/2f) > CallbackBridge.physicalHeight/2f){
|
||||||
|
y += PREF_CONTROL_BOTTOM_OFFSET;
|
||||||
|
}else{
|
||||||
|
y -= PREF_CONTROL_TOP_OFFSET;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return y;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply the dynamic equation on the x axis.
|
* Apply the dynamic equation on the x axis.
|
||||||
* @param dynamicX The equation to compute the position from
|
* @param dynamicX The equation to compute the position from
|
||||||
|
@ -3,6 +3,8 @@ package net.kdt.pojavlaunch.customcontrols.gamepad;
|
|||||||
|
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.Choreographer;
|
||||||
import android.view.InputDevice;
|
import android.view.InputDevice;
|
||||||
import android.view.KeyEvent;
|
import android.view.KeyEvent;
|
||||||
import android.view.MotionEvent;
|
import android.view.MotionEvent;
|
||||||
@ -59,10 +61,22 @@ public class Gamepad {
|
|||||||
private final boolean mModifierDigitalTriggers;
|
private final boolean mModifierDigitalTriggers;
|
||||||
private boolean mModifierSwappedAxis = true; //Triggers and right stick axis are swapped.
|
private boolean mModifierSwappedAxis = true; //Triggers and right stick axis are swapped.
|
||||||
|
|
||||||
private final Handler inputHandler = new Handler(Looper.getMainLooper());
|
private final Choreographer screenChoreographer;
|
||||||
private final Runnable switchStateRunnable;
|
private long lastFrameTime;
|
||||||
|
|
||||||
public Gamepad(BaseMainActivity gameActivity, InputDevice inputDevice){
|
public Gamepad(BaseMainActivity gameActivity, InputDevice inputDevice){
|
||||||
|
screenChoreographer = Choreographer.getInstance();
|
||||||
|
Choreographer.FrameCallback frameCallback = new Choreographer.FrameCallback() {
|
||||||
|
@Override
|
||||||
|
public void doFrame(long frameTimeNanos) {
|
||||||
|
updateGrabbingState();
|
||||||
|
tick(frameTimeNanos);
|
||||||
|
screenChoreographer.postFrameCallback(this);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
screenChoreographer.postFrameCallback(frameCallback);
|
||||||
|
lastFrameTime = System.nanoTime();
|
||||||
|
|
||||||
//Toast.makeText(gameActivity.getApplicationContext(),"GAMEPAD CREATED", Toast.LENGTH_LONG).show();
|
//Toast.makeText(gameActivity.getApplicationContext(),"GAMEPAD CREATED", Toast.LENGTH_LONG).show();
|
||||||
for(InputDevice.MotionRange range : inputDevice.getMotionRanges()){
|
for(InputDevice.MotionRange range : inputDevice.getMotionRanges()){
|
||||||
if(range.getAxis() == MotionEvent.AXIS_RTRIGGER
|
if(range.getAxis() == MotionEvent.AXIS_RTRIGGER
|
||||||
@ -88,21 +102,53 @@ public class Gamepad {
|
|||||||
pointerView.getDrawable().setFilterBitmap(false);
|
pointerView.getDrawable().setFilterBitmap(false);
|
||||||
notifyGUISizeChange(gameActivity.getMcScale());
|
notifyGUISizeChange(gameActivity.getMcScale());
|
||||||
|
|
||||||
Runnable handlerRunnable = new Runnable() {
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
updateGrabbingState();
|
|
||||||
tick();
|
|
||||||
|
|
||||||
inputHandler.postDelayed(this, 16);
|
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
|
||||||
inputHandler.postDelayed(handlerRunnable, 16);
|
|
||||||
|
|
||||||
//Initialize runnables to be used by the input system, avoiding generating one each time is better memory.
|
public void tick(long frameTimeNanos){
|
||||||
switchStateRunnable = () -> {
|
//update mouse position
|
||||||
|
if(lastHorizontalValue != 0 || lastVerticalValue != 0){
|
||||||
|
GamepadJoystick currentJoystick = lastGrabbingState ? leftJoystick : rightJoystick;
|
||||||
|
|
||||||
|
double acceleration = (mouseMagnitude - currentJoystick.getDeadzone()) / (1 - currentJoystick.getDeadzone());
|
||||||
|
acceleration = Math.pow(acceleration, mouseMaxAcceleration);
|
||||||
|
if(acceleration > 1) acceleration = 1;
|
||||||
|
|
||||||
|
// Compute delta since last tick time
|
||||||
|
float deltaX = (float) (Math.cos(mouseAngle) * acceleration * mouseSensitivity);
|
||||||
|
float deltaY = (float) (Math.sin(mouseAngle) * acceleration * mouseSensitivity);
|
||||||
|
float deltaTimeScale = ((frameTimeNanos - lastFrameTime) / 16666666f); // Scale of 1 = 60Hz
|
||||||
|
deltaX *= deltaTimeScale;
|
||||||
|
deltaY *= deltaTimeScale;
|
||||||
|
|
||||||
|
CallbackBridge.mouseX += deltaX;
|
||||||
|
CallbackBridge.mouseY -= deltaY;
|
||||||
|
|
||||||
|
if(!lastGrabbingState){
|
||||||
|
CallbackBridge.mouseX = MathUtils.clamp(CallbackBridge.mouseX, 0, CallbackBridge.windowWidth);
|
||||||
|
CallbackBridge.mouseY = MathUtils.clamp(CallbackBridge.mouseY, 0, CallbackBridge.windowHeight);
|
||||||
|
placePointerView((int) (CallbackBridge.mouseX /gameActivity.scaleFactor), (int) (CallbackBridge.mouseY/gameActivity.scaleFactor));
|
||||||
|
}
|
||||||
|
|
||||||
|
gameActivity.mouse_x = CallbackBridge.mouseX;
|
||||||
|
gameActivity.mouse_y = CallbackBridge.mouseY;
|
||||||
|
|
||||||
|
//Send the mouse to the game
|
||||||
|
CallbackBridge.sendCursorPos(CallbackBridge.mouseX, CallbackBridge.mouseY);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update last nano time
|
||||||
|
lastFrameTime = frameTimeNanos;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Update the grabbing state, and change the currentMap, mouse position and sensibility */
|
||||||
|
private void updateGrabbingState() {
|
||||||
|
boolean lastGrabbingValue = lastGrabbingState;
|
||||||
|
lastGrabbingState = CallbackBridge.isGrabbing();
|
||||||
|
if(lastGrabbingValue == lastGrabbingState) return;
|
||||||
|
|
||||||
|
// Switch grabbing state then
|
||||||
currentMap.resetPressedState();
|
currentMap.resetPressedState();
|
||||||
if(lastGrabbingState){
|
if(lastGrabbingState){
|
||||||
currentMap = gameMap;
|
currentMap = gameMap;
|
||||||
@ -119,49 +165,11 @@ public class Gamepad {
|
|||||||
CallbackBridge.sendCursorPos(gameActivity.mouse_x, gameActivity.mouse_y);
|
CallbackBridge.sendCursorPos(gameActivity.mouse_x, gameActivity.mouse_y);
|
||||||
placePointerView(CallbackBridge.physicalWidth/2, CallbackBridge.physicalHeight/2);
|
placePointerView(CallbackBridge.physicalWidth/2, CallbackBridge.physicalHeight/2);
|
||||||
pointerView.setVisibility(View.VISIBLE);
|
pointerView.setVisibility(View.VISIBLE);
|
||||||
//sensitivity in menu is MC and HARDWARE resolution dependent
|
// Sensitivity in menu is MC and HARDWARE resolution dependent
|
||||||
mouseSensitivity = 19 * gameActivity.scaleFactor / gameActivity.sensitivityFactor;
|
mouseSensitivity = 19 * gameActivity.scaleFactor / gameActivity.sensitivityFactor;
|
||||||
};
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private void tick(){
|
|
||||||
//update mouse position
|
|
||||||
if(lastHorizontalValue != 0 || lastVerticalValue != 0){
|
|
||||||
GamepadJoystick currentJoystick = lastGrabbingState ? leftJoystick : rightJoystick;
|
|
||||||
|
|
||||||
double acceleration = (mouseMagnitude - currentJoystick.getDeadzone()) / (1 - currentJoystick.getDeadzone());
|
|
||||||
acceleration = Math.pow(acceleration, mouseMaxAcceleration);
|
|
||||||
if(acceleration > 1) acceleration = 1;
|
|
||||||
|
|
||||||
CallbackBridge.mouseX += Math.cos(mouseAngle) * acceleration * mouseSensitivity;
|
|
||||||
CallbackBridge.mouseY -= Math.sin(mouseAngle) * acceleration * mouseSensitivity;
|
|
||||||
|
|
||||||
if(!lastGrabbingState){
|
|
||||||
CallbackBridge.mouseX = MathUtils.clamp(CallbackBridge.mouseX, 0, CallbackBridge.windowWidth);
|
|
||||||
CallbackBridge.mouseY = MathUtils.clamp(CallbackBridge.mouseY, 0, CallbackBridge.windowHeight);
|
|
||||||
placePointerView((int) (CallbackBridge.mouseX /gameActivity.scaleFactor), (int) (CallbackBridge.mouseY/gameActivity.scaleFactor));
|
|
||||||
}
|
|
||||||
|
|
||||||
gameActivity.mouse_x = CallbackBridge.mouseX;
|
|
||||||
gameActivity.mouse_y = CallbackBridge.mouseY;
|
|
||||||
|
|
||||||
//Send the mouse to the game
|
|
||||||
CallbackBridge.sendCursorPos(CallbackBridge.mouseX, CallbackBridge.mouseY);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateGrabbingState() {
|
|
||||||
boolean lastGrabbingValue = lastGrabbingState;
|
|
||||||
lastGrabbingState = CallbackBridge.isGrabbing();
|
|
||||||
if(lastGrabbingValue != lastGrabbingState){
|
|
||||||
gameActivity.runOnUiThread(switchStateRunnable);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void update(KeyEvent event){
|
public void update(KeyEvent event){
|
||||||
sendButton(event);
|
sendButton(event);
|
||||||
}
|
}
|
||||||
@ -188,11 +196,11 @@ public class Gamepad {
|
|||||||
int lastJoystickDirection = currentJoystickDirection;
|
int lastJoystickDirection = currentJoystickDirection;
|
||||||
currentJoystickDirection = currentJoystick.getHeightDirection(event);
|
currentJoystickDirection = currentJoystick.getHeightDirection(event);
|
||||||
|
|
||||||
if(currentJoystickDirection != lastJoystickDirection){
|
if(currentJoystickDirection == lastJoystickDirection) return;
|
||||||
|
|
||||||
sendDirectionalKeycode(lastJoystickDirection, false, getCurrentMap());
|
sendDirectionalKeycode(lastJoystickDirection, false, getCurrentMap());
|
||||||
sendDirectionalKeycode(currentJoystickDirection, true, getCurrentMap());
|
sendDirectionalKeycode(currentJoystickDirection, true, getCurrentMap());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private void updateAnalogTriggers(MotionEvent event){
|
private void updateAnalogTriggers(MotionEvent event){
|
||||||
if(!mModifierDigitalTriggers){
|
if(!mModifierDigitalTriggers){
|
||||||
|
@ -29,7 +29,7 @@ import static net.kdt.pojavlaunch.customcontrols.handleview.ActionPopupWindow.se
|
|||||||
|
|
||||||
public class EditControlButtonPopup {
|
public class EditControlButtonPopup {
|
||||||
|
|
||||||
protected Dialog dialog;
|
protected AlertDialog dialog;
|
||||||
protected View v;
|
protected View v;
|
||||||
protected AlertDialog.Builder builder;
|
protected AlertDialog.Builder builder;
|
||||||
|
|
||||||
@ -75,7 +75,6 @@ public class EditControlButtonPopup {
|
|||||||
dialog = builder.create();
|
dialog = builder.create();
|
||||||
dialog.setOnShowListener(dialogInterface -> setEditDialogValues());
|
dialog.setOnShowListener(dialogInterface -> setEditDialogValues());
|
||||||
|
|
||||||
|
|
||||||
dialog.show();
|
dialog.show();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ import android.content.DialogInterface;
|
|||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.ArrayAdapter;
|
import android.widget.ArrayAdapter;
|
||||||
import android.widget.Spinner;
|
import android.widget.Spinner;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import net.kdt.pojavlaunch.R;
|
import net.kdt.pojavlaunch.R;
|
||||||
import net.kdt.pojavlaunch.customcontrols.ControlData;
|
import net.kdt.pojavlaunch.customcontrols.ControlData;
|
||||||
@ -32,6 +33,11 @@ public class EditControlDrawerPopup extends EditControlButtonPopup{
|
|||||||
checkPassThrough.setVisibility(View.GONE);
|
checkPassThrough.setVisibility(View.GONE);
|
||||||
checkToggle.setVisibility(View.GONE);
|
checkToggle.setVisibility(View.GONE);
|
||||||
checkBoxSwipeable.setVisibility(View.GONE);
|
checkBoxSwipeable.setVisibility(View.GONE);
|
||||||
|
|
||||||
|
(v.findViewById(R.id.editDynamicPositionX_textView)).setVisibility(View.GONE);
|
||||||
|
(v.findViewById(R.id.editDynamicPositionY_textView)).setVisibility(View.GONE);
|
||||||
|
editDynamicX.setVisibility(View.GONE);
|
||||||
|
editDynamicY.setVisibility(View.GONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -52,18 +58,27 @@ public class EditControlDrawerPopup extends EditControlButtonPopup{
|
|||||||
super.setEditDialogValues();
|
super.setEditDialogValues();
|
||||||
|
|
||||||
spinnerOrientation.setSelection(ControlDrawerData.orientationToInt(drawerData.orientation));
|
spinnerOrientation.setSelection(ControlDrawerData.orientationToInt(drawerData.orientation));
|
||||||
|
|
||||||
|
|
||||||
|
//Using the dialog to replace the button behavior allows us not to dismiss the window
|
||||||
|
dialog.getButton(DialogInterface.BUTTON_NEUTRAL).setOnClickListener(v -> {
|
||||||
|
ControlLayout layout = (ControlLayout) drawer.getParent();
|
||||||
|
ControlData controlData = new ControlData(drawerData.properties);
|
||||||
|
controlData.name = "new";
|
||||||
|
layout.addSubButton(drawer, controlData);
|
||||||
|
|
||||||
|
Context ctx = dialog.getContext();
|
||||||
|
Toast.makeText(ctx, ctx.getString(R.string.customctrl_add_subbutton_message,
|
||||||
|
drawer.getDrawerData().buttonProperties.size()), Toast.LENGTH_SHORT).show();
|
||||||
|
});
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void setupDialogButtons() {
|
protected void setupDialogButtons() {
|
||||||
super.setupDialogButtons();
|
super.setupDialogButtons();
|
||||||
|
|
||||||
builder.setNeutralButton(v.getResources().getString(R.string.customctrl_addsubbutton), (dialogInterface, i) -> {
|
builder.setNeutralButton(v.getResources().getString(R.string.customctrl_addsubbutton), null);
|
||||||
ControlLayout layout = (ControlLayout) drawer.getParent();
|
|
||||||
ControlData controlData = new ControlData(drawerData.properties);
|
|
||||||
controlData.name = "new";
|
|
||||||
layout.addSubButton(drawer, controlData);
|
|
||||||
});
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,129 @@
|
|||||||
|
package net.kdt.pojavlaunch.extra;
|
||||||
|
|
||||||
|
import java.lang.ref.WeakReference;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.concurrent.ConcurrentLinkedQueue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class providing callback across all of a program
|
||||||
|
* to allow easy thread safe implementations of UI update without context leak
|
||||||
|
*
|
||||||
|
* This class uses a singleton pattern to simplify access to it
|
||||||
|
*/
|
||||||
|
public final class ExtraCore {
|
||||||
|
// No unwanted instantiation
|
||||||
|
private ExtraCore(){}
|
||||||
|
|
||||||
|
// Store the key-value pair
|
||||||
|
private final Map<String, String> valueMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
// Store what each ExtraListener listen to
|
||||||
|
private final Map<String, ConcurrentLinkedQueue<WeakReference<ExtraListener>>> listenerMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
// Inner class for singleton implementation
|
||||||
|
private static class ExtraCoreSingleton {
|
||||||
|
private static final ExtraCore extraCore = new ExtraCore();
|
||||||
|
}
|
||||||
|
|
||||||
|
// All public methods will pass through this one
|
||||||
|
private static ExtraCore getInstance(){
|
||||||
|
return ExtraCoreSingleton.extraCore;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the value associated to a key and trigger all listeners
|
||||||
|
* @param key The key
|
||||||
|
* @param value The value
|
||||||
|
*/
|
||||||
|
public static void setValue(String key, String value){
|
||||||
|
getInstance().valueMap.put(key, value);
|
||||||
|
ConcurrentLinkedQueue<WeakReference<ExtraListener>> extraListenerList = getInstance().listenerMap.get(key);
|
||||||
|
for(WeakReference<ExtraListener> listener : extraListenerList){
|
||||||
|
if(listener.get() == null){
|
||||||
|
extraListenerList.remove(listener);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
listener.get().notifyDataChanged(key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @return The value behind the key */
|
||||||
|
public static String getValue(String key){
|
||||||
|
return getInstance().valueMap.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Remove the key and its value from the valueMap */
|
||||||
|
public static void removeValue(String key){
|
||||||
|
getInstance().valueMap.remove(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Remove all values */
|
||||||
|
public static void removeAllValues(){
|
||||||
|
getInstance().valueMap.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Link an ExtraListener to a value
|
||||||
|
* @param key The value key to look for
|
||||||
|
* @param listener The ExtraListener to link
|
||||||
|
*/
|
||||||
|
public static void addExtraListener(String key, ExtraListener listener){
|
||||||
|
ConcurrentLinkedQueue<WeakReference<ExtraListener>> listenerList = getInstance().listenerMap.get(key);
|
||||||
|
// Look for new sets
|
||||||
|
if(listenerList == null){
|
||||||
|
listenerList = new ConcurrentLinkedQueue<>();
|
||||||
|
getInstance().listenerMap.put(key, listenerList);
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is kinda naive, I should look for duplicates
|
||||||
|
listenerList.add(new WeakReference<>(listener));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unlink an ExtraListener from a value.
|
||||||
|
* Unlink null references found along the way
|
||||||
|
* @param key The value key to ignore now
|
||||||
|
* @param listener The ExtraListener to unlink
|
||||||
|
*/
|
||||||
|
public static void removeExtraListenerFromValue(String key, ExtraListener listener){
|
||||||
|
ConcurrentLinkedQueue<WeakReference<ExtraListener>> listenerList = getInstance().listenerMap.get(key);
|
||||||
|
// Look for new sets
|
||||||
|
if(listenerList == null){
|
||||||
|
listenerList = new ConcurrentLinkedQueue<>();
|
||||||
|
getInstance().listenerMap.put(key, listenerList);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Removes all occurrences of ExtraListener and all null references
|
||||||
|
for(WeakReference<ExtraListener> listenerWeakReference : listenerList){
|
||||||
|
ExtraListener actualListener = listenerWeakReference.get();
|
||||||
|
|
||||||
|
if(actualListener == null || actualListener == listener){
|
||||||
|
listenerList.remove(listenerWeakReference);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Unlink all ExtraListeners from a value
|
||||||
|
* @param key The key to which ExtraListener are linked
|
||||||
|
*/
|
||||||
|
public static void removeAllExtraListenersFromValue(String key){
|
||||||
|
ConcurrentLinkedQueue<WeakReference<ExtraListener>> listenerList = getInstance().listenerMap.get(key);
|
||||||
|
// Look for new sets
|
||||||
|
if(listenerList == null){
|
||||||
|
listenerList = new ConcurrentLinkedQueue<>();
|
||||||
|
getInstance().listenerMap.put(key, listenerList);
|
||||||
|
}
|
||||||
|
|
||||||
|
listenerList.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove all ExtraListeners from listening to any value
|
||||||
|
*/
|
||||||
|
public static void removeAllExtraListeners(){
|
||||||
|
getInstance().listenerMap.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,26 @@
|
|||||||
|
package net.kdt.pojavlaunch.extra;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listener class for the ExtraCore
|
||||||
|
* An ExtraListener can listen to a virtually unlimited amount of values
|
||||||
|
*/
|
||||||
|
public abstract class ExtraListener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called by the ExtraCore after a value is set.
|
||||||
|
* Technically, it can be triggered from outside but is seems pointless
|
||||||
|
*/
|
||||||
|
public final void notifyDataChanged(String key, String value){
|
||||||
|
if(onValueSet(key, value)){
|
||||||
|
ExtraCore.removeExtraListenerFromValue(key, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Called upon a new value being set
|
||||||
|
* @param key The name of the value
|
||||||
|
* @param value The new value as a string
|
||||||
|
* @return Whether you consume the Listener (stop listening)
|
||||||
|
*/
|
||||||
|
public abstract boolean onValueSet(String key, String value);
|
||||||
|
}
|
@ -0,0 +1,36 @@
|
|||||||
|
package net.kdt.pojavlaunch.prefs;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
|
||||||
|
import androidx.preference.Preference;
|
||||||
|
|
||||||
|
import net.kdt.pojavlaunch.R;
|
||||||
|
import net.kdt.pojavlaunch.extra.ExtraCore;
|
||||||
|
|
||||||
|
public class BackButtonPreference extends Preference {
|
||||||
|
public BackButtonPreference(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
public BackButtonPreference(Context context) {
|
||||||
|
this(context, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init(){
|
||||||
|
if(getTitle() == null){
|
||||||
|
setTitle(R.string.preference_back_title);
|
||||||
|
}
|
||||||
|
if(getIcon() == null){
|
||||||
|
setIcon(R.drawable.ic_arrow_back_white);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onClick() {
|
||||||
|
// It is caught by an ExtraListener in the LauncherActivity
|
||||||
|
ExtraCore.setValue("back_preference", "true");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,127 @@
|
|||||||
|
package net.kdt.pojavlaunch.prefs;
|
||||||
|
|
||||||
|
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.DEFAULT_PREF;
|
||||||
|
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_CONTROL_BOTTOM_OFFSET;
|
||||||
|
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_CONTROL_LEFT_OFFSET;
|
||||||
|
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_CONTROL_RIGHT_OFFSET;
|
||||||
|
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_CONTROL_TOP_OFFSET;
|
||||||
|
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
import android.widget.SeekBar;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.preference.Preference;
|
||||||
|
|
||||||
|
import net.kdt.pojavlaunch.R;
|
||||||
|
|
||||||
|
/** Custom preference class displaying a dialog */
|
||||||
|
public class ControlOffsetPreference extends Preference {
|
||||||
|
|
||||||
|
private AlertDialog preferenceDialog;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public ControlOffsetPreference(Context context, AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ControlOffsetPreference(Context context) {
|
||||||
|
super(context);
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void init(){
|
||||||
|
// Setup visual values
|
||||||
|
if(getTitle() == null){
|
||||||
|
setTitle(R.string.preference_control_offset_title);
|
||||||
|
setSummary(R.string.preference_control_offset_description);
|
||||||
|
}
|
||||||
|
if(getIcon() == null){
|
||||||
|
setIcon(android.R.drawable.radiobutton_off_background);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Prepare Alert dialog
|
||||||
|
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(getContext());
|
||||||
|
dialogBuilder.setView(R.layout.control_offset_preference_dialog);
|
||||||
|
dialogBuilder.setTitle(getContext().getString(R.string.control_offset_title));
|
||||||
|
|
||||||
|
dialogBuilder.setPositiveButton(android.R.string.ok, null);
|
||||||
|
dialogBuilder.setNegativeButton(android.R.string.cancel, null);
|
||||||
|
|
||||||
|
preferenceDialog = dialogBuilder.create();
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onClick() {
|
||||||
|
preferenceDialog.show();
|
||||||
|
|
||||||
|
SeekBar topOffsetSeekbar = preferenceDialog.findViewById(R.id.control_offset_top_seekbar);
|
||||||
|
SeekBar rightOffsetSeekbar = preferenceDialog.findViewById(R.id.control_offset_right_seekbar);
|
||||||
|
SeekBar bottomOffsetSeekbar = preferenceDialog.findViewById(R.id.control_offset_bottom_seekbar);
|
||||||
|
SeekBar leftOffsetSeekbar = preferenceDialog.findViewById(R.id.control_offset_left_seekbar);
|
||||||
|
|
||||||
|
TextView topOffsetTextView = preferenceDialog.findViewById(R.id.control_offset_top_textview);
|
||||||
|
TextView rightOffsetTextView = preferenceDialog.findViewById(R.id.control_offset_right_textview);
|
||||||
|
TextView bottomOffsetTextView = preferenceDialog.findViewById(R.id.control_offset_bottom_textview);
|
||||||
|
TextView leftOffsetTextView = preferenceDialog.findViewById(R.id.control_offset_left_textview);
|
||||||
|
|
||||||
|
SeekBar.OnSeekBarChangeListener seekBarChangeListener = new SeekBar.OnSeekBarChangeListener() {
|
||||||
|
@Override
|
||||||
|
public void onProgressChanged(SeekBar seekBar, int i, boolean b) {
|
||||||
|
if(seekBar == topOffsetSeekbar){
|
||||||
|
String text = String.format("%s%d", getContext().getString(R.string.control_top_offset), i);
|
||||||
|
topOffsetTextView.setText(text);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(seekBar == rightOffsetSeekbar){
|
||||||
|
String text = String.format("%s%d", getContext().getString(R.string.control_right_offset), i);
|
||||||
|
rightOffsetTextView.setText(text);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(seekBar == bottomOffsetSeekbar){
|
||||||
|
String text = String.format("%s%d", getContext().getString(R.string.control_bottom_offset), i);
|
||||||
|
bottomOffsetTextView.setText(text);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(seekBar == leftOffsetSeekbar){
|
||||||
|
String text = String.format("%s%d", getContext().getString(R.string.control_left_offset), i);
|
||||||
|
leftOffsetTextView.setText(text);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@Override
|
||||||
|
public void onStartTrackingTouch(SeekBar seekBar) {}
|
||||||
|
@Override
|
||||||
|
public void onStopTrackingTouch(SeekBar seekBar) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
topOffsetSeekbar.setOnSeekBarChangeListener(seekBarChangeListener);
|
||||||
|
rightOffsetSeekbar.setOnSeekBarChangeListener(seekBarChangeListener);
|
||||||
|
bottomOffsetSeekbar.setOnSeekBarChangeListener(seekBarChangeListener);
|
||||||
|
leftOffsetSeekbar.setOnSeekBarChangeListener(seekBarChangeListener);
|
||||||
|
|
||||||
|
topOffsetSeekbar.setProgress(PREF_CONTROL_TOP_OFFSET);
|
||||||
|
rightOffsetSeekbar.setProgress(PREF_CONTROL_RIGHT_OFFSET);
|
||||||
|
bottomOffsetSeekbar.setProgress(PREF_CONTROL_BOTTOM_OFFSET);
|
||||||
|
leftOffsetSeekbar.setProgress(PREF_CONTROL_LEFT_OFFSET);
|
||||||
|
|
||||||
|
// Custom writing to preferences
|
||||||
|
preferenceDialog.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener(view -> {
|
||||||
|
DEFAULT_PREF.edit().putInt("controlTopOffset", topOffsetSeekbar.getProgress()).apply();
|
||||||
|
DEFAULT_PREF.edit().putInt("controlRightOffset", rightOffsetSeekbar.getProgress()).apply();
|
||||||
|
DEFAULT_PREF.edit().putInt("controlBottomOffset", bottomOffsetSeekbar.getProgress()).apply();
|
||||||
|
DEFAULT_PREF.edit().putInt("controlLeftOffset", leftOffsetSeekbar.getProgress()).apply();
|
||||||
|
|
||||||
|
|
||||||
|
preferenceDialog.dismiss();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -15,10 +15,14 @@ import net.kdt.pojavlaunch.R;
|
|||||||
|
|
||||||
public class CustomSeekBarPreference extends SeekBarPreference {
|
public class CustomSeekBarPreference extends SeekBarPreference {
|
||||||
|
|
||||||
|
/** The suffix displayed */
|
||||||
private String suffix = "";
|
private String suffix = "";
|
||||||
|
/** Custom minimum value to provide the same behavior as the usual setMin */
|
||||||
private int mMin;
|
private int mMin;
|
||||||
|
/** The textview associated by default to the preference */
|
||||||
private TextView textView;
|
private TextView textView;
|
||||||
|
|
||||||
|
|
||||||
public CustomSeekBarPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
public CustomSeekBarPreference(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
|
||||||
super(context, attrs, defStyleAttr, defStyleRes);
|
super(context, attrs, defStyleAttr, defStyleRes);
|
||||||
TypedArray a = context.obtainStyledAttributes(
|
TypedArray a = context.obtainStyledAttributes(
|
||||||
@ -59,22 +63,26 @@ public class CustomSeekBarPreference extends SeekBarPreference {
|
|||||||
SeekBar seekBar = (SeekBar) view.findViewById(R.id.seekbar);
|
SeekBar seekBar = (SeekBar) view.findViewById(R.id.seekbar);
|
||||||
|
|
||||||
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
|
seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
|
||||||
|
progress = progress / getSeekBarIncrement();
|
||||||
|
progress = progress * getSeekBarIncrement();
|
||||||
|
|
||||||
textView.setText(String.valueOf(progress + mMin));
|
textView.setText(String.valueOf(progress + mMin));
|
||||||
updateTextViewWithSuffix();
|
updateTextViewWithSuffix();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStartTrackingTouch(SeekBar seekBar) {
|
public void onStartTrackingTouch(SeekBar seekBar) {}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onStopTrackingTouch(SeekBar seekBar) {
|
public void onStopTrackingTouch(SeekBar seekBar) {
|
||||||
setValue(seekBar.getProgress() + mMin);
|
int progress = seekBar.getProgress() / getSeekBarIncrement();
|
||||||
updateTextViewWithSuffix();
|
progress *= getSeekBarIncrement();
|
||||||
|
|
||||||
|
setValue(progress + mMin);
|
||||||
|
updateTextViewWithSuffix();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -82,7 +90,6 @@ public class CustomSeekBarPreference extends SeekBarPreference {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
private void updateTextViewWithSuffix(){
|
private void updateTextViewWithSuffix(){
|
||||||
if(!textView.getText().toString().endsWith(suffix)){
|
if(!textView.getText().toString().endsWith(suffix)){
|
||||||
textView.setText(String.format("%s%s", textView.getText(), suffix));
|
textView.setText(String.format("%s%s", textView.getText(), suffix));
|
||||||
|
@ -1,104 +0,0 @@
|
|||||||
package net.kdt.pojavlaunch.prefs;
|
|
||||||
|
|
||||||
|
|
||||||
import android.graphics.Color;
|
|
||||||
import android.os.*;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
import androidx.preference.*;
|
|
||||||
import net.kdt.pojavlaunch.R;
|
|
||||||
import net.kdt.pojavlaunch.fragments.LauncherFragment;
|
|
||||||
|
|
||||||
import android.content.*;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
|
|
||||||
import static net.kdt.pojavlaunch.Architecture.is32BitsDevice;
|
|
||||||
import static net.kdt.pojavlaunch.Tools.getTotalDeviceMemory;
|
|
||||||
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_NOTCH_SIZE;
|
|
||||||
|
|
||||||
public class LauncherPreferenceFragment extends PreferenceFragmentCompat implements SharedPreferences.OnSharedPreferenceChangeListener
|
|
||||||
{
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
|
||||||
view.setBackgroundColor(Color.parseColor("#44000000"));
|
|
||||||
super.onViewCreated(view, savedInstanceState);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreatePreferences(Bundle b, String str) {
|
|
||||||
addPreferencesFromResource(R.xml.pref_main);
|
|
||||||
|
|
||||||
//Disable notch checking behavior on android 8.1 and below.
|
|
||||||
findPreference("ignoreNotch").setVisible(Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && PREF_NOTCH_SIZE != 0);
|
|
||||||
|
|
||||||
CustomSeekBarPreference seek2 = findPreference("timeLongPressTrigger");
|
|
||||||
seek2.setRange(100, 1000);
|
|
||||||
seek2.setValue(LauncherPreferences.PREF_LONGPRESS_TRIGGER);
|
|
||||||
seek2.setSuffix(" ms");
|
|
||||||
|
|
||||||
CustomSeekBarPreference seek3 = findPreference("buttonscale");
|
|
||||||
seek3.setRange(80, 250);
|
|
||||||
seek3.setValue((int) LauncherPreferences.PREF_BUTTONSIZE);
|
|
||||||
seek3.setSuffix(" %");
|
|
||||||
|
|
||||||
CustomSeekBarPreference seek4 = findPreference("mousescale");
|
|
||||||
seek4.setRange(25, 300);
|
|
||||||
seek4.setValue((int) LauncherPreferences.PREF_MOUSESCALE);
|
|
||||||
seek4.setSuffix(" %");
|
|
||||||
|
|
||||||
CustomSeekBarPreference seek5 = findPreference("resolutionRatio");
|
|
||||||
seek5.setMin(25);
|
|
||||||
seek5.setSuffix(" %");
|
|
||||||
|
|
||||||
CustomSeekBarPreference seek6 = findPreference("mousespeed");
|
|
||||||
seek6.setRange(25, 300);
|
|
||||||
seek6.setValue((int)(LauncherPreferences.PREF_MOUSESPEED*100f));
|
|
||||||
seek6.setSuffix(" %");
|
|
||||||
|
|
||||||
|
|
||||||
int maxRAM;
|
|
||||||
int deviceRam = getTotalDeviceMemory(getContext());
|
|
||||||
|
|
||||||
|
|
||||||
CustomSeekBarPreference seek7 = findPreference("allocation");
|
|
||||||
seek7.setMin(256);
|
|
||||||
|
|
||||||
if(is32BitsDevice()) maxRAM = Math.min(1100, deviceRam);
|
|
||||||
else maxRAM = deviceRam - (deviceRam < 3064 ? 800 : 1024); //To have a minimum for the device to breathe
|
|
||||||
|
|
||||||
seek7.setMax(maxRAM);
|
|
||||||
seek7.setValue(LauncherPreferences.PREF_RAM_ALLOCATION);
|
|
||||||
seek7.setSuffix(" MB");
|
|
||||||
|
|
||||||
// #724 bug fix
|
|
||||||
if (seek5.getValue() < 25) {
|
|
||||||
seek5.setValue(100);
|
|
||||||
}
|
|
||||||
|
|
||||||
EditTextPreference editJVMArgs = findPreference("javaArgs");
|
|
||||||
if (editJVMArgs != null) {
|
|
||||||
editJVMArgs.setOnBindEditTextListener((editText) -> editText.setSingleLine());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onResume() {
|
|
||||||
super.onResume();
|
|
||||||
getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onPause() {
|
|
||||||
getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
|
|
||||||
super.onPause();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onSharedPreferenceChanged(SharedPreferences p, String s) {
|
|
||||||
LauncherPreferences.loadPreferences(getContext());
|
|
||||||
}
|
|
||||||
}
|
|
@ -29,6 +29,12 @@ public class LauncherPreferences
|
|||||||
public static float PREF_MOUSESPEED = 1f;
|
public static float PREF_MOUSESPEED = 1f;
|
||||||
public static int PREF_RAM_ALLOCATION;
|
public static int PREF_RAM_ALLOCATION;
|
||||||
public static String PREF_DEFAULT_RUNTIME;
|
public static String PREF_DEFAULT_RUNTIME;
|
||||||
|
public static int PREF_CONTROL_TOP_OFFSET = 0;
|
||||||
|
public static int PREF_CONTROL_RIGHT_OFFSET = 0;
|
||||||
|
public static int PREF_CONTROL_BOTTOM_OFFSET = 0;
|
||||||
|
public static int PREF_CONTROL_LEFT_OFFSET = 0;
|
||||||
|
|
||||||
|
|
||||||
public static void loadPreferences(Context ctx) {
|
public static void loadPreferences(Context ctx) {
|
||||||
//Required for the data folder.
|
//Required for the data folder.
|
||||||
Tools.initContextConstants(ctx);
|
Tools.initContextConstants(ctx);
|
||||||
@ -51,6 +57,11 @@ public class LauncherPreferences
|
|||||||
PREF_DISABLE_GESTURES = DEFAULT_PREF.getBoolean("disableGestures",false);
|
PREF_DISABLE_GESTURES = DEFAULT_PREF.getBoolean("disableGestures",false);
|
||||||
PREF_RAM_ALLOCATION = DEFAULT_PREF.getInt("allocation", findBestRAMAllocation(ctx));
|
PREF_RAM_ALLOCATION = DEFAULT_PREF.getInt("allocation", findBestRAMAllocation(ctx));
|
||||||
PREF_CUSTOM_JAVA_ARGS = DEFAULT_PREF.getString("javaArgs", "");
|
PREF_CUSTOM_JAVA_ARGS = DEFAULT_PREF.getString("javaArgs", "");
|
||||||
|
PREF_CONTROL_TOP_OFFSET = DEFAULT_PREF.getInt("controlTopOffset", 0);
|
||||||
|
PREF_CONTROL_RIGHT_OFFSET = DEFAULT_PREF.getInt("controlRightOffset", 0);
|
||||||
|
PREF_CONTROL_BOTTOM_OFFSET = DEFAULT_PREF.getInt("controlBottomOffset", 0);
|
||||||
|
PREF_CONTROL_LEFT_OFFSET = DEFAULT_PREF.getInt("controlTopOffset", 0);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
if (PREF_CUSTOM_JAVA_ARGS.isEmpty()) {
|
if (PREF_CUSTOM_JAVA_ARGS.isEmpty()) {
|
||||||
String DEFAULT_JAVA_ARGS = "";
|
String DEFAULT_JAVA_ARGS = "";
|
||||||
|
@ -0,0 +1,58 @@
|
|||||||
|
package net.kdt.pojavlaunch.prefs.screens;
|
||||||
|
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import net.kdt.pojavlaunch.R;
|
||||||
|
import net.kdt.pojavlaunch.prefs.CustomSeekBarPreference;
|
||||||
|
import net.kdt.pojavlaunch.prefs.LauncherPreferences;
|
||||||
|
|
||||||
|
public class LauncherPreferenceControlFragment extends LauncherPreferenceFragment {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreatePreferences(Bundle b, String str) {
|
||||||
|
// Get values
|
||||||
|
int longPressTrigger = LauncherPreferences.PREF_LONGPRESS_TRIGGER;
|
||||||
|
int prefButtonSize = (int) LauncherPreferences.PREF_BUTTONSIZE;
|
||||||
|
int mouseScale = (int) LauncherPreferences.PREF_MOUSESCALE;
|
||||||
|
float mouseSpeed = LauncherPreferences.PREF_MOUSESPEED;
|
||||||
|
|
||||||
|
//Triggers a write for some reason which resets the value
|
||||||
|
addPreferencesFromResource(R.xml.pref_control);
|
||||||
|
|
||||||
|
CustomSeekBarPreference seek2 = findPreference("timeLongPressTrigger");
|
||||||
|
seek2.setRange(100, 1000);
|
||||||
|
seek2.setValue(longPressTrigger);
|
||||||
|
seek2.setSuffix(" ms");
|
||||||
|
|
||||||
|
CustomSeekBarPreference seek3 = findPreference("buttonscale");
|
||||||
|
seek3.setRange(80, 250);
|
||||||
|
seek3.setValue(prefButtonSize);
|
||||||
|
seek3.setSuffix(" %");
|
||||||
|
|
||||||
|
CustomSeekBarPreference seek4 = findPreference("mousescale");
|
||||||
|
seek4.setRange(25, 300);
|
||||||
|
seek4.setValue(mouseScale);
|
||||||
|
seek4.setSuffix(" %");
|
||||||
|
|
||||||
|
CustomSeekBarPreference seek6 = findPreference("mousespeed");
|
||||||
|
seek6.setRange(25, 300);
|
||||||
|
seek6.setValue((int)(mouseSpeed *100f));
|
||||||
|
seek6.setSuffix(" %");
|
||||||
|
|
||||||
|
|
||||||
|
computeVisibility();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSharedPreferenceChanged(SharedPreferences p, String s) {
|
||||||
|
super.onSharedPreferenceChanged(p, s);
|
||||||
|
computeVisibility();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void computeVisibility(){
|
||||||
|
CustomSeekBarPreference seek2 = findPreference("timeLongPressTrigger");
|
||||||
|
seek2.setVisible(!LauncherPreferences.PREF_DISABLE_GESTURES);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package net.kdt.pojavlaunch.prefs.screens;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import net.kdt.pojavlaunch.R;
|
||||||
|
|
||||||
|
public class LauncherPreferenceExperimentalFragment extends LauncherPreferenceFragment {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreatePreferences(Bundle b, String str) {
|
||||||
|
addPreferencesFromResource(R.xml.pref_experimental);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
package net.kdt.pojavlaunch.prefs.screens;
|
||||||
|
|
||||||
|
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.os.*;
|
||||||
|
|
||||||
|
import androidx.activity.OnBackPressedCallback;
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.preference.*;
|
||||||
|
import net.kdt.pojavlaunch.R;
|
||||||
|
import net.kdt.pojavlaunch.prefs.LauncherPreferences;
|
||||||
|
|
||||||
|
import android.content.*;
|
||||||
|
import android.view.View;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import static net.kdt.pojavlaunch.Architecture.is32BitsDevice;
|
||||||
|
import static net.kdt.pojavlaunch.Tools.getTotalDeviceMemory;
|
||||||
|
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_NOTCH_SIZE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Preference for the main screen, any sub-screen should inherit this class for consistent behavior,
|
||||||
|
* overriding only onCreatePreferences
|
||||||
|
*/
|
||||||
|
public class LauncherPreferenceFragment extends PreferenceFragmentCompat implements SharedPreferences.OnSharedPreferenceChangeListener {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||||
|
view.setBackgroundColor(Color.parseColor("#232323"));
|
||||||
|
super.onViewCreated(view, savedInstanceState);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreatePreferences(Bundle b, String str) {
|
||||||
|
addPreferencesFromResource(R.xml.pref_main);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onResume() {
|
||||||
|
super.onResume();
|
||||||
|
getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onPause() {
|
||||||
|
getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
|
||||||
|
super.onPause();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onSharedPreferenceChanged(SharedPreferences p, String s) {
|
||||||
|
LauncherPreferences.loadPreferences(getContext());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
package net.kdt.pojavlaunch.prefs.screens;
|
||||||
|
|
||||||
|
import static net.kdt.pojavlaunch.Architecture.is32BitsDevice;
|
||||||
|
import static net.kdt.pojavlaunch.Tools.getTotalDeviceMemory;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.preference.EditTextPreference;
|
||||||
|
|
||||||
|
import net.kdt.pojavlaunch.R;
|
||||||
|
import net.kdt.pojavlaunch.prefs.CustomSeekBarPreference;
|
||||||
|
import net.kdt.pojavlaunch.prefs.LauncherPreferences;
|
||||||
|
|
||||||
|
public class LauncherPreferenceJavaFragment extends LauncherPreferenceFragment {
|
||||||
|
@Override
|
||||||
|
public void onCreatePreferences(Bundle b, String str) {
|
||||||
|
int ramAllocation = LauncherPreferences.PREF_RAM_ALLOCATION;
|
||||||
|
|
||||||
|
// Triggers a write for some reason
|
||||||
|
addPreferencesFromResource(R.xml.pref_java);
|
||||||
|
|
||||||
|
int maxRAM;
|
||||||
|
int deviceRam = getTotalDeviceMemory(getContext());
|
||||||
|
|
||||||
|
CustomSeekBarPreference seek7 = findPreference("allocation");
|
||||||
|
seek7.setMin(256);
|
||||||
|
|
||||||
|
if(is32BitsDevice()) maxRAM = Math.min(1100, deviceRam);
|
||||||
|
else maxRAM = deviceRam - (deviceRam < 3064 ? 800 : 1024); //To have a minimum for the device to breathe
|
||||||
|
|
||||||
|
seek7.setMax(maxRAM);
|
||||||
|
seek7.setValue(ramAllocation);
|
||||||
|
seek7.setSuffix(" MB");
|
||||||
|
|
||||||
|
|
||||||
|
EditTextPreference editJVMArgs = findPreference("javaArgs");
|
||||||
|
if (editJVMArgs != null) {
|
||||||
|
editJVMArgs.setOnBindEditTextListener(TextView::setSingleLine);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
package net.kdt.pojavlaunch.prefs.screens;
|
||||||
|
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import net.kdt.pojavlaunch.R;
|
||||||
|
|
||||||
|
public class LauncherPreferenceMiscellaneousFragment extends LauncherPreferenceFragment {
|
||||||
|
@Override
|
||||||
|
public void onCreatePreferences(Bundle b, String str) {
|
||||||
|
addPreferencesFromResource(R.xml.pref_misc);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
package net.kdt.pojavlaunch.prefs.screens;
|
||||||
|
|
||||||
|
import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_NOTCH_SIZE;
|
||||||
|
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import androidx.preference.PreferenceFragmentCompat;
|
||||||
|
|
||||||
|
import net.kdt.pojavlaunch.R;
|
||||||
|
import net.kdt.pojavlaunch.prefs.CustomSeekBarPreference;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fragment for any settings video related
|
||||||
|
*/
|
||||||
|
public class LauncherPreferenceVideoFragment extends LauncherPreferenceFragment {
|
||||||
|
@Override
|
||||||
|
public void onCreatePreferences(Bundle b, String str) {
|
||||||
|
addPreferencesFromResource(R.xml.pref_video);
|
||||||
|
|
||||||
|
//Disable notch checking behavior on android 8.1 and below.
|
||||||
|
findPreference("ignoreNotch").setVisible(Build.VERSION.SDK_INT >= Build.VERSION_CODES.P && PREF_NOTCH_SIZE != 0);
|
||||||
|
|
||||||
|
CustomSeekBarPreference seek5 = findPreference("resolutionRatio");
|
||||||
|
seek5.setMin(25);
|
||||||
|
seek5.setSuffix(" %");
|
||||||
|
|
||||||
|
// #724 bug fix
|
||||||
|
if (seek5.getValue() < 25) {
|
||||||
|
seek5.setValue(100);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -324,7 +324,7 @@ public class MinecraftDownloaderTask extends AsyncTask<String, String, Throwable
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (p1.length < 3) {
|
if (p1.length < 3) {
|
||||||
mActivity.mConsoleView.putLog(p1[1] + "\n");
|
//mActivity.mConsoleView.putLog(p1[1] + "\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -341,7 +341,7 @@ public class MinecraftDownloaderTask extends AsyncTask<String, String, Throwable
|
|||||||
Tools.showError(mActivity, p1);
|
Tools.showError(mActivity, p1);
|
||||||
}
|
}
|
||||||
if(!launchWithError) {
|
if(!launchWithError) {
|
||||||
mActivity.mCrashView.setLastCrash("");
|
//mActivity.mCrashView.setLastCrash("");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Intent mainIntent = new Intent(mActivity, MainActivity.class /* MainActivity.class */);
|
Intent mainIntent = new Intent(mActivity, MainActivity.class /* MainActivity.class */);
|
||||||
|
@ -77,8 +77,7 @@ public class RefreshVersionListTask extends AsyncTask<Void, Void, ArrayList<Stri
|
|||||||
@Override
|
@Override
|
||||||
public void onItemSelected(AdapterView<?> p1, View p2, int p3, long p4)
|
public void onItemSelected(AdapterView<?> p1, View p2, int p3, long p4)
|
||||||
{
|
{
|
||||||
String version = p1.getItemAtPosition(p3).toString();
|
mActivity.mProfile.selectedVersion = p1.getItemAtPosition(p3).toString();
|
||||||
mActivity.mProfile.selectedVersion = version;
|
|
||||||
|
|
||||||
PojavProfile.setCurrentProfile(mActivity, mActivity.mProfile);
|
PojavProfile.setCurrentProfile(mActivity, mActivity.mProfile);
|
||||||
if (PojavProfile.isFileType(mActivity)) {
|
if (PojavProfile.isFileType(mActivity)) {
|
||||||
@ -89,7 +88,6 @@ public class RefreshVersionListTask extends AsyncTask<Void, Void, ArrayList<Stri
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mActivity.mTextVersion.setText(mActivity.getString(R.string.mcl_version_msg, version));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -109,13 +107,8 @@ public class RefreshVersionListTask extends AsyncTask<Void, Void, ArrayList<Stri
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
*/
|
*/
|
||||||
popup.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
|
popup.setOnMenuItemClickListener(item -> true);
|
||||||
public boolean onMenuItemClick(MenuItem item) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
mActivity.mTextVersion.setText(mActivity.getString(R.string.mcl_version_msg,mActivity.mVersionSelector.getSelectedItem()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ArrayList<String> filter(JMinecraftVersionList.Version[] list1, File[] list2) {
|
private ArrayList<String> filter(JMinecraftVersionList.Version[] list1, File[] list2) {
|
||||||
@ -145,9 +138,8 @@ public class RefreshVersionListTask extends AsyncTask<Void, Void, ArrayList<Stri
|
|||||||
for(String str : strArr){
|
for(String str : strArr){
|
||||||
if (str.equals(select)) {
|
if (str.equals(select)) {
|
||||||
return count;
|
return count;
|
||||||
} else {
|
|
||||||
count++;
|
|
||||||
}
|
}
|
||||||
|
count++;
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,7 @@
|
|||||||
package net.kdt.pojavlaunch.value;
|
package net.kdt.pojavlaunch.value;
|
||||||
|
|
||||||
|
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
|
|
||||||
import net.kdt.pojavlaunch.*;
|
import net.kdt.pojavlaunch.*;
|
||||||
@ -51,6 +54,7 @@ public class MinecraftAccount
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static MinecraftAccount load(String name) throws JsonSyntaxException {
|
public static MinecraftAccount load(String name) throws JsonSyntaxException {
|
||||||
|
if(!accountExists(name)) return new MinecraftAccount();
|
||||||
try {
|
try {
|
||||||
MinecraftAccount acc = parse(Tools.read(Tools.DIR_ACCOUNT_NEW + "/" + name + ".json"));
|
MinecraftAccount acc = parse(Tools.read(Tools.DIR_ACCOUNT_NEW + "/" + name + ".json"));
|
||||||
if (acc.accessToken == null) {
|
if (acc.accessToken == null) {
|
||||||
@ -81,6 +85,18 @@ public class MinecraftAccount
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Bitmap getSkinFace(){
|
||||||
|
if(skinFaceBase64 == null){
|
||||||
|
return Bitmap.createBitmap(1,1, Bitmap.Config.ARGB_8888);
|
||||||
|
}
|
||||||
|
byte[] faceIconBytes = Base64.decode(skinFaceBase64, Base64.DEFAULT);
|
||||||
|
return BitmapFactory.decodeByteArray(faceIconBytes, 0, faceIconBytes.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean accountExists(String username){
|
||||||
|
return new File(Tools.DIR_ACCOUNT_NEW + "/" + username + ".json").exists();
|
||||||
|
}
|
||||||
|
|
||||||
public static void clearTempAccount() {
|
public static void clearTempAccount() {
|
||||||
File tempAccFile = new File(Tools.DIR_DATA, "cache/tempacc.json");
|
File tempAccFile = new File(Tools.DIR_DATA, "cache/tempacc.json");
|
||||||
tempAccFile.delete();
|
tempAccFile.delete();
|
||||||
|
@ -15,7 +15,7 @@ public class CallbackBridge {
|
|||||||
|
|
||||||
public static volatile int windowWidth, windowHeight;
|
public static volatile int windowWidth, windowHeight;
|
||||||
public static volatile int physicalWidth, physicalHeight;
|
public static volatile int physicalWidth, physicalHeight;
|
||||||
public static int mouseX, mouseY;
|
public static float mouseX, mouseY;
|
||||||
public static StringBuilder DEBUG_STRING = new StringBuilder();
|
public static StringBuilder DEBUG_STRING = new StringBuilder();
|
||||||
|
|
||||||
// volatile private static boolean isGrabbing = false;
|
// volatile private static boolean isGrabbing = false;
|
||||||
@ -29,7 +29,7 @@ public class CallbackBridge {
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
putMouseEventWithCoords(button, true, x, y);
|
putMouseEventWithCoords(button, true, x, y);
|
||||||
try { Thread.sleep(40); } catch (InterruptedException e) {}
|
//try { Thread.sleep(1); } catch (InterruptedException e) {}
|
||||||
putMouseEventWithCoords(button, false, x, y);
|
putMouseEventWithCoords(button, false, x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -37,7 +37,7 @@ public class CallbackBridge {
|
|||||||
new Thread(new PusherRunnable(button,x,y)).run();
|
new Thread(new PusherRunnable(button,x,y)).run();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void putMouseEventWithCoords(int button, boolean isDown, int x, int y /* , int dz, long nanos */) {
|
public static void putMouseEventWithCoords(int button, boolean isDown, float x, float y /* , int dz, long nanos */) {
|
||||||
sendCursorPos(x, y);
|
sendCursorPos(x, y);
|
||||||
sendMouseKeycode(button, CallbackBridge.getCurrentMods(), isDown);
|
sendMouseKeycode(button, CallbackBridge.getCurrentMods(), isDown);
|
||||||
}
|
}
|
||||||
@ -49,8 +49,8 @@ public class CallbackBridge {
|
|||||||
}
|
}
|
||||||
|
|
||||||
DEBUG_STRING.append("CursorPos=").append(x).append(", ").append(y).append("\n");
|
DEBUG_STRING.append("CursorPos=").append(x).append(", ").append(y).append("\n");
|
||||||
mouseX = (int) x;
|
mouseX = x;
|
||||||
mouseY = (int) y;
|
mouseY = y;
|
||||||
nativeSendCursorPos(mouseX, mouseY);
|
nativeSendCursorPos(mouseX, mouseY);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,13 +126,6 @@ public class CallbackBridge {
|
|||||||
default: return null;
|
default: return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public static void receiveCallback(int type, String data) {
|
|
||||||
switch (type) {
|
|
||||||
case ANDROID_TYPE_GRAB_STATE:
|
|
||||||
// isGrabbing = Boolean.parseBoolean(data);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*
|
/*
|
||||||
private static String currData;
|
private static String currData;
|
||||||
public static void sendData(int type, Object... dataArr) {
|
public static void sendData(int type, Object... dataArr) {
|
||||||
@ -201,7 +194,7 @@ public class CallbackBridge {
|
|||||||
private static native boolean nativeSendCharMods(char codepoint, int mods);
|
private static native boolean nativeSendCharMods(char codepoint, int mods);
|
||||||
private static native void nativeSendKey(int key, int scancode, int action, int mods);
|
private static native void nativeSendKey(int key, int scancode, int action, int mods);
|
||||||
// private static native void nativeSendCursorEnter(int entered);
|
// private static native void nativeSendCursorEnter(int entered);
|
||||||
private static native void nativeSendCursorPos(int x, int y);
|
private static native void nativeSendCursorPos(float x, float y);
|
||||||
private static native void nativeSendMouseButton(int button, int action, int mods);
|
private static native void nativeSendMouseButton(int button, int action, int mods);
|
||||||
private static native void nativeSendScroll(double xoffset, double yoffset);
|
private static native void nativeSendScroll(double xoffset, double yoffset);
|
||||||
private static native void nativeSendScreenSize(int width, int height);
|
private static native void nativeSendScreenSize(int width, int height);
|
||||||
|
@ -37,7 +37,7 @@ typedef void GLFW_invoke_MouseButton_func(void* window, int button, int action,
|
|||||||
typedef void GLFW_invoke_Scroll_func(void* window, double xoffset, double yoffset);
|
typedef void GLFW_invoke_Scroll_func(void* window, double xoffset, double yoffset);
|
||||||
typedef void GLFW_invoke_WindowSize_func(void* window, int width, int height);
|
typedef void GLFW_invoke_WindowSize_func(void* window, int width, int height);
|
||||||
|
|
||||||
static int grabCursorX, grabCursorY, lastCursorX, lastCursorY;
|
static float grabCursorX, grabCursorY, lastCursorX, lastCursorY;
|
||||||
|
|
||||||
jclass inputBridgeClass_ANDROID, inputBridgeClass_JRE;
|
jclass inputBridgeClass_ANDROID, inputBridgeClass_JRE;
|
||||||
jmethodID inputBridgeMethod_ANDROID, inputBridgeMethod_JRE;
|
jmethodID inputBridgeMethod_ANDROID, inputBridgeMethod_JRE;
|
||||||
@ -255,7 +255,7 @@ JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendCursorEnter(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendCursorPos(JNIEnv* env, jclass clazz, jint x, jint y) {
|
JNIEXPORT void JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeSendCursorPos(JNIEnv* env, jclass clazz, jfloat x, jfloat y) {
|
||||||
if (GLFW_invoke_CursorPos && isInputReady) {
|
if (GLFW_invoke_CursorPos && isInputReady) {
|
||||||
if (!isCursorEntered) {
|
if (!isCursorEntered) {
|
||||||
if (GLFW_invoke_CursorEnter) {
|
if (GLFW_invoke_CursorEnter) {
|
||||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,9 @@
|
|||||||
|
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:width="32dp"
|
||||||
|
android:height="32dp"
|
||||||
|
android:viewportWidth="16"
|
||||||
|
android:viewportHeight="16">
|
||||||
|
<path
|
||||||
|
android:pathData="M16,7L3.8,7l5.6,-5.6L8,0l-8,8 8,8 1.4,-1.4L3.8,9L16,9v-2z"
|
||||||
|
android:fillColor="#FFF"/>
|
||||||
|
</vector>
|
@ -0,0 +1,64 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:layout_marginHorizontal="15dp">
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/control_offset_top_textview"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/control_top_offset"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<SeekBar
|
||||||
|
android:id="@+id/control_offset_top_seekbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="40dp" />
|
||||||
|
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/control_offset_right_textview"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/control_right_offset"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<SeekBar
|
||||||
|
android:id="@+id/control_offset_right_seekbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="40dp" />
|
||||||
|
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/control_offset_bottom_textview"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/control_bottom_offset"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<SeekBar
|
||||||
|
android:id="@+id/control_offset_bottom_seekbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="40dp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/control_offset_left_textview"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/control_left_offset"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<SeekBar
|
||||||
|
android:id="@+id/control_offset_left_seekbar"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="40dp" />
|
||||||
|
|
||||||
|
</LinearLayout>
|
||||||
|
|
||||||
|
</ScrollView>
|
@ -33,17 +33,33 @@
|
|||||||
android:orientation="vertical"
|
android:orientation="vertical"
|
||||||
app:layout_constraintGuide_percent="0.86" />
|
app:layout_constraintGuide_percent="0.86" />
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/launchermain_account_image"
|
||||||
|
android:layout_width="40dp"
|
||||||
|
android:layout_height="40dp"
|
||||||
|
android:layout_marginStart="3dp"
|
||||||
|
android:layout_marginTop="3dp"
|
||||||
|
|
||||||
|
android:src="@mipmap/ic_launcher"
|
||||||
|
|
||||||
|
app:layout_constraintEnd_toEndOf="@id/launchermain_spinner_account"
|
||||||
|
app:layout_constraintHorizontal_bias="0.00"
|
||||||
|
|
||||||
|
app:layout_constraintStart_toStartOf="@id/launchermain_spinner_account"
|
||||||
|
app:layout_constraintTop_toTopOf="parent" />
|
||||||
|
|
||||||
<Spinner
|
<Spinner
|
||||||
android:id="@+id/launchermain_spinner_account"
|
android:id="@+id/launchermain_spinner_account"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="0dp"
|
||||||
android:paddingStart="5dp"
|
android:background="@android:color/transparent"
|
||||||
android:paddingEnd="5dp"
|
|
||||||
android:spinnerMode="dropdown"
|
android:spinnerMode="dropdown"
|
||||||
|
android:paddingLeft="43dp"
|
||||||
|
|
||||||
|
app:layout_constraintBottom_toBottomOf="@+id/launchermain_account_image"
|
||||||
app:layout_constraintEnd_toStartOf="@+id/guidelineLeft"
|
app:layout_constraintEnd_toStartOf="@+id/guidelineLeft"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent" />
|
app:layout_constraintTop_toTopOf="@+id/launchermain_account_image" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/launchermain_text_accountstatus"
|
android:id="@+id/launchermain_text_accountstatus"
|
||||||
@ -89,18 +105,18 @@
|
|||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
|
||||||
android:paddingStart="12dp"
|
|
||||||
android:paddingEnd="0dp"
|
|
||||||
android:paddingTop="10dp"
|
|
||||||
android:paddingBottom="10dp"
|
|
||||||
|
|
||||||
android:background="?attr/selectableItemBackground"
|
android:background="?attr/selectableItemBackground"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
|
|
||||||
android:drawableStart="@drawable/ic_menu_java"
|
android:drawableStart="@drawable/ic_menu_java"
|
||||||
android:focusable="true"
|
android:focusable="true"
|
||||||
|
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:onClick="onTabClicked"
|
android:onClick="onTabClicked"
|
||||||
|
|
||||||
|
android:paddingStart="12dp"
|
||||||
|
android:paddingTop="10dp"
|
||||||
|
android:paddingEnd="0dp"
|
||||||
|
android:paddingBottom="10dp"
|
||||||
android:text="@string/mcl_tab_console"
|
android:text="@string/mcl_tab_console"
|
||||||
android:textAlignment="center"
|
android:textAlignment="center"
|
||||||
android:textAllCaps="true"
|
android:textAllCaps="true"
|
||||||
@ -118,18 +134,18 @@
|
|||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
|
||||||
android:paddingStart="12dp"
|
|
||||||
android:paddingEnd="0dp"
|
|
||||||
android:paddingTop="10dp"
|
|
||||||
android:paddingBottom="10dp"
|
|
||||||
|
|
||||||
android:background="?attr/selectableItemBackground"
|
android:background="?attr/selectableItemBackground"
|
||||||
android:clickable="true"
|
android:clickable="true"
|
||||||
|
|
||||||
android:drawableStart="@drawable/ic_menu_warning"
|
android:drawableStart="@drawable/ic_menu_warning"
|
||||||
android:focusable="true"
|
android:focusable="true"
|
||||||
|
|
||||||
android:gravity="center"
|
android:gravity="center"
|
||||||
android:onClick="onTabClicked"
|
android:onClick="onTabClicked"
|
||||||
|
|
||||||
|
android:paddingStart="12dp"
|
||||||
|
android:paddingTop="10dp"
|
||||||
|
android:paddingEnd="0dp"
|
||||||
|
android:paddingBottom="10dp"
|
||||||
android:text="@string/mcl_tab_crash"
|
android:text="@string/mcl_tab_crash"
|
||||||
android:textAlignment="center"
|
android:textAlignment="center"
|
||||||
android:textAllCaps="true"
|
android:textAllCaps="true"
|
||||||
@ -172,7 +188,7 @@
|
|||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="@+id/guidelineBottom" />
|
app:layout_constraintTop_toTopOf="@+id/guidelineBottom" />
|
||||||
|
|
||||||
<androidx.viewpager.widget.ViewPager
|
<androidx.viewpager2.widget.ViewPager2
|
||||||
android:id="@+id/launchermainTabPager"
|
android:id="@+id/launchermainTabPager"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
@ -217,75 +233,46 @@
|
|||||||
|
|
||||||
<Button
|
<Button
|
||||||
|
|
||||||
|
style="?android:attr/buttonBarButtonStyle"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
android:onClick="launcherMenu"
|
|
||||||
android:text="@string/main_options"
|
|
||||||
|
|
||||||
style="?android:attr/buttonBarButtonStyle"
|
|
||||||
android:background="?attr/selectableItemBackground"
|
android:background="?attr/selectableItemBackground"
|
||||||
|
|
||||||
|
android:onClick="launchCustomControlsActivity"
|
||||||
|
android:text="@string/mcl_option_customcontrol"
|
||||||
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toStartOf="@+id/launchermainPlayButton"
|
app:layout_constraintEnd_toStartOf="@+id/launchermainPlayButton"
|
||||||
app:layout_constraintStart_toStartOf="@+id/guidelineLeft"
|
app:layout_constraintStart_toStartOf="@+id/guidelineLeft"
|
||||||
app:layout_constraintTop_toTopOf="@+id/guidelineBottom2" />
|
app:layout_constraintTop_toTopOf="@+id/guidelineBottom2" />
|
||||||
|
|
||||||
<com.kdt.mcgui.MineButton
|
<com.kdt.mcgui.MineButton
|
||||||
android:background="@drawable/mine_button_background"
|
|
||||||
android:id="@+id/launchermainPlayButton"
|
android:id="@+id/launchermainPlayButton"
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
android:layout_alignParentBottom="true"
|
android:layout_alignParentBottom="true"
|
||||||
|
android:background="@drawable/mine_button_background"
|
||||||
android:onClick="launchGame"
|
android:onClick="launchGame"
|
||||||
android:text="@string/main_play"
|
android:text="@string/main_play"
|
||||||
android:textColor="@android:color/white"
|
android:textColor="@android:color/white"
|
||||||
app:layout_constraintWidth_default="percent"
|
|
||||||
app:layout_constraintWidth_percent="0.25"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="@+id/guidelineLeft"
|
app:layout_constraintStart_toStartOf="@+id/guidelineLeft"
|
||||||
app:layout_constraintTop_toTopOf="@+id/guidelineBottom"
|
app:layout_constraintTop_toTopOf="@+id/guidelineBottom"
|
||||||
/>
|
app:layout_constraintWidth_default="percent"
|
||||||
|
app:layout_constraintWidth_percent="0.25" />
|
||||||
<TextView
|
|
||||||
android:id="@+id/launchermain_text_welcome"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:gravity="center"
|
|
||||||
android:text="@string/main_welcome"
|
|
||||||
android:textSize="12sp"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toEndOf="@+id/launchermainPlayButton"
|
|
||||||
app:layout_constraintTop_toTopOf="@+id/guidelineBottom" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/launcherMainVersionView"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="20dp"
|
|
||||||
android:gravity="center"
|
|
||||||
android:text="@string/global_waiting"
|
|
||||||
android:textSize="12sp"
|
|
||||||
android:singleLine="true"
|
|
||||||
android:scrollHorizontally="true"
|
|
||||||
android:ellipsize="marquee"
|
|
||||||
android:marqueeRepeatLimit="marquee_forever"
|
|
||||||
android:focusable="true"
|
|
||||||
android:focusableInTouchMode="true"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toEndOf="@+id/launchermainPlayButton"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/launchermain_text_welcome" />
|
|
||||||
|
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/switchUserBtn"
|
android:id="@+id/installJarButton"
|
||||||
|
|
||||||
style="?android:attr/buttonBarButtonStyle"
|
style="?android:attr/buttonBarButtonStyle"
|
||||||
android:background="?attr/selectableItemBackground"
|
|
||||||
|
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
|
|
||||||
android:layout_height="0dp"
|
android:layout_height="0dp"
|
||||||
android:onClick="mcaccLogout"
|
android:background="?attr/selectableItemBackground"
|
||||||
android:text="@string/main_switchuser"
|
android:onClick="installJarFile"
|
||||||
|
android:text="@string/main_install_jar_file"
|
||||||
android:textSize="12sp"
|
android:textSize="12sp"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
@ -1,12 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<resources>
|
<resources>
|
||||||
<string-array name="mcl_options">
|
|
||||||
<item>@string/mcl_option_modinstall</item>
|
|
||||||
<item>@string/mcl_option_modinstallwitharg</item>
|
|
||||||
<item>@string/mcl_option_customcontrol</item>
|
|
||||||
<item>@string/mcl_option_about</item>
|
|
||||||
</string-array>
|
|
||||||
|
|
||||||
<string-array name="renderer">
|
<string-array name="renderer">
|
||||||
<item name="2">@string/mcl_setting_renderer_gles2_4</item>
|
<item name="2">@string/mcl_setting_renderer_gles2_4</item>
|
||||||
<item name="3">@string/mcl_setting_renderer_gles2_5</item>
|
<item name="3">@string/mcl_setting_renderer_gles2_5</item>
|
||||||
|
@ -203,9 +203,12 @@
|
|||||||
<string name="customctrl_addbutton">Add button</string>
|
<string name="customctrl_addbutton">Add button</string>
|
||||||
<string name="customctrl_addbutton_drawer">Add button drawer</string>
|
<string name="customctrl_addbutton_drawer">Add button drawer</string>
|
||||||
<string name="customctrl_addsubbutton">Add sub-button</string>
|
<string name="customctrl_addsubbutton">Add sub-button</string>
|
||||||
|
<string name="customctrl_add_subbutton_message">Sub-button n°%d has been added !</string>
|
||||||
|
|
||||||
<string name="customctrl_selectdefault">Select default Control json</string>
|
<string name="customctrl_selectdefault">Select default Control json</string>
|
||||||
|
|
||||||
|
|
||||||
|
<string name="main_install_jar_file">Install .jar</string>
|
||||||
<string name="main_options">Options</string>
|
<string name="main_options">Options</string>
|
||||||
<string name="main_play">Play</string>
|
<string name="main_play">Play</string>
|
||||||
<string name="main_welcome">Welcome, %s</string>
|
<string name="main_welcome">Welcome, %s</string>
|
||||||
@ -253,4 +256,26 @@
|
|||||||
<string name="pvc_title">Per-version settings</string>
|
<string name="pvc_title">Per-version settings</string>
|
||||||
<string name="storage_warning_title">Storage changes</string>
|
<string name="storage_warning_title">Storage changes</string>
|
||||||
<string name="storage_warning_text"> <![CDATA[Due to Google\'s new scoped storage enforcements added in Android 10 and higher, we are required to move the game directory into an app-private folder.<br /> The new folder for Pojav files is <b>Android/data/%s/files/</b> (also accessible using a storage provider in your file explorer).<br /> If you need to copy your game files, please copy everything from the original folder at <b>games/PojavLauncher</b> manually.]]></string>
|
<string name="storage_warning_text"> <![CDATA[Due to Google\'s new scoped storage enforcements added in Android 10 and higher, we are required to move the game directory into an app-private folder.<br /> The new folder for Pojav files is <b>Android/data/%s/files/</b> (also accessible using a storage provider in your file explorer).<br /> If you need to copy your game files, please copy everything from the original folder at <b>games/PojavLauncher</b> manually.]]></string>
|
||||||
|
|
||||||
|
<string name="control_offset_title">Control offset</string>
|
||||||
|
<string name="control_top_offset">Top offset: </string>
|
||||||
|
<string name="control_right_offset">right offset: </string>
|
||||||
|
<string name="control_bottom_offset">bottom offset: </string>
|
||||||
|
<string name="control_left_offset">left offset: </string>
|
||||||
|
|
||||||
|
<string name="preference_control_offset_title">Control side offsets</string>
|
||||||
|
<string name="preference_control_offset_description">Set a custom offset to each side of the screen</string>
|
||||||
|
<string name="preference_video_title">Video and renderer</string>
|
||||||
|
<string name="preference_video_description">Resolution, scaling type, and renderer</string>
|
||||||
|
<string name="preference_control_title">Control customization</string>
|
||||||
|
<string name="preference_control_description">Gestures types, triggers, and scaling</string>
|
||||||
|
<string name="preference_java_title">Java Tweaks</string>
|
||||||
|
<string name="preference_java_description">Java versions, JVM Arguments, and RAM amount</string>
|
||||||
|
<string name="preference_misc_title">Miscellaneous settings</string>
|
||||||
|
<string name="preference_misc_description">Version list, and libs checks</string>
|
||||||
|
<string name="preference_experimental_title">Experimental Stuff</string>
|
||||||
|
<string name="preference_experimental_description">Use things there with consideration, no support.</string>
|
||||||
|
|
||||||
|
<string name="preference_back_title">Back to the last screen</string>
|
||||||
|
|
||||||
</resources>
|
</resources>
|
||||||
|
65
app_pojavlauncher/src/main/res/xml/pref_control.xml
Normal file
65
app_pojavlauncher/src/main/res/xml/pref_control.xml
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app2="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
|
<net.kdt.pojavlaunch.prefs.BackButtonPreference/>
|
||||||
|
|
||||||
|
<PreferenceCategory
|
||||||
|
android:title="Gestures ">
|
||||||
|
|
||||||
|
<androidx.preference.SwitchPreferenceCompat
|
||||||
|
android:defaultValue="false"
|
||||||
|
android:icon="@drawable/ic_disable_gestures"
|
||||||
|
android:key="disableGestures"
|
||||||
|
android:summary="@string/mcl_disable_gestures_subtitle"
|
||||||
|
android:title="@string/mcl_disable_gestures" />
|
||||||
|
|
||||||
|
<net.kdt.pojavlaunch.prefs.CustomSeekBarPreference
|
||||||
|
android:key="timeLongPressTrigger"
|
||||||
|
android:summary="@string/mcl_setting_subtitle_longpresstrigger"
|
||||||
|
android:title="@string/mcl_setting_title_longpresstrigger"
|
||||||
|
app2:showSeekBarValue="true"
|
||||||
|
app2:selectable="false"
|
||||||
|
app2:seekBarIncrement="10"
|
||||||
|
app2:icon="@drawable/tap_len" />
|
||||||
|
|
||||||
|
</PreferenceCategory>
|
||||||
|
|
||||||
|
<PreferenceCategory
|
||||||
|
android:title="Buttons">
|
||||||
|
|
||||||
|
<net.kdt.pojavlaunch.prefs.CustomSeekBarPreference
|
||||||
|
android:key="buttonscale"
|
||||||
|
android:title="@string/mcl_setting_title_buttonscale"
|
||||||
|
android:summary="@string/mcl_setting_subtitle_buttonscale"
|
||||||
|
app2:showSeekBarValue="true"
|
||||||
|
app2:selectable="false"
|
||||||
|
app2:icon="@drawable/btn_scale"/>
|
||||||
|
|
||||||
|
<net.kdt.pojavlaunch.prefs.ControlOffsetPreference/>
|
||||||
|
|
||||||
|
</PreferenceCategory>
|
||||||
|
|
||||||
|
<PreferenceCategory
|
||||||
|
android:title="Virtual mouse">
|
||||||
|
|
||||||
|
<net.kdt.pojavlaunch.prefs.CustomSeekBarPreference
|
||||||
|
android:key="mousescale"
|
||||||
|
android:summary="@string/mcl_setting_subtitle_mousescale"
|
||||||
|
android:title="@string/mcl_setting_title_mousescale"
|
||||||
|
app2:icon="@drawable/mouse_pointer_1"
|
||||||
|
app2:selectable="false"
|
||||||
|
app2:showSeekBarValue="true" />
|
||||||
|
<net.kdt.pojavlaunch.prefs.CustomSeekBarPreference
|
||||||
|
android:key="mousespeed"
|
||||||
|
android:summary="@string/mcl_setting_subtitle_mousespeed"
|
||||||
|
android:title="@string/mcl_setting_title_mousespeed"
|
||||||
|
app2:icon="@drawable/mouse_pointer_spd"
|
||||||
|
app2:selectable="false"
|
||||||
|
app2:showSeekBarValue="true" />
|
||||||
|
</PreferenceCategory>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
</PreferenceScreen>
|
7
app_pojavlauncher/src/main/res/xml/pref_experimental.xml
Normal file
7
app_pojavlauncher/src/main/res/xml/pref_experimental.xml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<net.kdt.pojavlaunch.prefs.BackButtonPreference/>
|
||||||
|
<PreferenceCategory android:title="Experimental fuckury">
|
||||||
|
|
||||||
|
</PreferenceCategory>
|
||||||
|
</PreferenceScreen>
|
31
app_pojavlauncher/src/main/res/xml/pref_java.xml
Normal file
31
app_pojavlauncher/src/main/res/xml/pref_java.xml
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app2="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
|
<net.kdt.pojavlaunch.prefs.BackButtonPreference/>
|
||||||
|
|
||||||
|
<PreferenceCategory android:title="Java Tweaks">
|
||||||
|
<net.kdt.pojavlaunch.prefs.RuntimeManagerPreference
|
||||||
|
android:summary="@string/multirt_subtitle"
|
||||||
|
android:title="@string/multirt_title"/>
|
||||||
|
|
||||||
|
<androidx.preference.EditTextPreference
|
||||||
|
android:dialogTitle="@string/mcl_setting_title_javaargs"
|
||||||
|
android:icon="@drawable/jre_args"
|
||||||
|
android:key="javaArgs"
|
||||||
|
android:singleLine="true"
|
||||||
|
android:summary="@string/mcl_setting_subtitle_javaargs"
|
||||||
|
android:title="@string/mcl_setting_title_javaargs" />
|
||||||
|
|
||||||
|
<net.kdt.pojavlaunch.prefs.CustomSeekBarPreference
|
||||||
|
android:key="allocation"
|
||||||
|
android:icon="@drawable/ic_auto_ram"
|
||||||
|
android:summary="@string/mcl_memory_allocation_subtitle"
|
||||||
|
android:title="@string/mcl_memory_allocation"
|
||||||
|
app2:showSeekBarValue="true"
|
||||||
|
app2:selectable="false"/>
|
||||||
|
|
||||||
|
</PreferenceCategory>
|
||||||
|
|
||||||
|
|
||||||
|
</PreferenceScreen>
|
@ -1,129 +1,39 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<androidx.preference.PreferenceScreen xmlns:app2="http://schemas.android.com/apk/res-auto"
|
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.chom/apk/res-auto">
|
|
||||||
|
|
||||||
<androidx.preference.PreferenceCategory
|
<Preference
|
||||||
android:title="@string/mcl_setting_category_general">
|
android:key="video_screen_setting"
|
||||||
|
android:title="@string/preference_video_title"
|
||||||
|
android:summary="@string/preference_video_description"
|
||||||
|
android:fragment="net.kdt.pojavlaunch.prefs.screens.LauncherPreferenceVideoFragment"
|
||||||
|
/>
|
||||||
|
|
||||||
<net.kdt.pojavlaunch.prefs.RuntimeManagerPreference
|
<Preference
|
||||||
android:summary="@string/multirt_subtitle"
|
android:key="control_screen_setting"
|
||||||
android:title="@string/multirt_title"/>
|
android:title="@string/preference_control_title"
|
||||||
<androidx.preference.ListPreference
|
android:summary="@string/preference_control_description"
|
||||||
android:title="@string/mcl_setting_category_renderer"
|
android:fragment="net.kdt.pojavlaunch.prefs.screens.LauncherPreferenceControlFragment"
|
||||||
android:key="renderer"
|
/>
|
||||||
android:defaultValue="opengles2"
|
|
||||||
android:entries="@array/renderer"
|
|
||||||
android:entryValues="@array/renderer_values"/>
|
|
||||||
|
|
||||||
<net.kdt.pojavlaunch.prefs.CustomSeekBarPreference
|
<Preference
|
||||||
android:key="timeLongPressTrigger"
|
android:key="java_screen_setting"
|
||||||
android:summary="@string/mcl_setting_subtitle_longpresstrigger"
|
android:title="@string/preference_java_title"
|
||||||
android:title="@string/mcl_setting_title_longpresstrigger"
|
android:summary="@string/preference_java_description"
|
||||||
app2:showSeekBarValue="true"
|
android:fragment="net.kdt.pojavlaunch.prefs.screens.LauncherPreferenceJavaFragment"
|
||||||
app2:selectable="false"
|
/>
|
||||||
app2:icon="@drawable/tap_len" />
|
|
||||||
|
|
||||||
|
<Preference
|
||||||
|
android:key="misc_screen_setting"
|
||||||
|
android:title="@string/preference_misc_title"
|
||||||
|
android:summary="@string/preference_misc_description"
|
||||||
|
android:fragment="net.kdt.pojavlaunch.prefs.screens.LauncherPreferenceMiscellaneousFragment"
|
||||||
|
/>
|
||||||
|
|
||||||
<androidx.preference.SwitchPreferenceCompat
|
<Preference
|
||||||
android:defaultValue="false"
|
android:key="experimental_screen_setting"
|
||||||
android:icon="@drawable/ic_disable_gestures"
|
android:title="@string/preference_experimental_title"
|
||||||
android:key="disableGestures"
|
android:summary="@string/preference_experimental_description"
|
||||||
android:summary="@string/mcl_disable_gestures_subtitle"
|
android:fragment="net.kdt.pojavlaunch.prefs.screens.LauncherPreferenceExperimentalFragment"
|
||||||
android:title="@string/mcl_disable_gestures" />
|
/>
|
||||||
|
|
||||||
<androidx.preference.SwitchPreferenceCompat
|
</PreferenceScreen>
|
||||||
android:defaultValue="false"
|
|
||||||
android:key="hideSidebar"
|
|
||||||
android:summary="@string/mcl_setting_subtitle_hide_sidebar"
|
|
||||||
android:title="@string/mcl_setting_title_hide_sidebar"
|
|
||||||
app2:icon="@drawable/hide_sidebar" />
|
|
||||||
<net.kdt.pojavlaunch.prefs.CustomSeekBarPreference
|
|
||||||
android:key="allocation"
|
|
||||||
android:icon="@drawable/ic_auto_ram"
|
|
||||||
android:summary="@string/mcl_memory_allocation_subtitle"
|
|
||||||
android:title="@string/mcl_memory_allocation"
|
|
||||||
app2:showSeekBarValue="true"
|
|
||||||
app2:selectable="false"/>
|
|
||||||
<androidx.preference.SwitchPreferenceCompat
|
|
||||||
android:defaultValue="false"
|
|
||||||
android:key="ignoreNotch"
|
|
||||||
android:summary="@string/mcl_setting_subtitle_ignore_notch"
|
|
||||||
android:title="@string/mcl_setting_title_ignore_notch"
|
|
||||||
app2:icon="@drawable/ignore_notch" />
|
|
||||||
|
|
||||||
<androidx.preference.EditTextPreference
|
|
||||||
android:dialogTitle="@string/mcl_setting_title_javaargs"
|
|
||||||
android:icon="@drawable/jre_args"
|
|
||||||
android:key="javaArgs"
|
|
||||||
android:singleLine="true"
|
|
||||||
android:summary="@string/mcl_setting_subtitle_javaargs"
|
|
||||||
android:title="@string/mcl_setting_title_javaargs" />
|
|
||||||
<androidx.preference.SwitchPreferenceCompat
|
|
||||||
android:defaultValue="true"
|
|
||||||
android:icon="@drawable/ic_lib_check"
|
|
||||||
android:key="checkLibraries"
|
|
||||||
android:summary="@string/mcl_setting_check_libraries_subtitle"
|
|
||||||
android:title="@string/mcl_setting_check_libraries" />
|
|
||||||
</androidx.preference.PreferenceCategory>
|
|
||||||
|
|
||||||
<androidx.preference.PreferenceCategory
|
|
||||||
android:title="@string/mcl_setting_category_scaling">
|
|
||||||
<net.kdt.pojavlaunch.prefs.CustomSeekBarPreference
|
|
||||||
android:key="resolutionRatio"
|
|
||||||
android:summary="@string/mcl_setting_subtitle_resolution_scaler"
|
|
||||||
android:title="@string/mcl_setting_title_resolution_scaler"
|
|
||||||
app2:showSeekBarValue="true"
|
|
||||||
app2:selectable="false"
|
|
||||||
app2:icon="@drawable/resolution_scaler"/>
|
|
||||||
<net.kdt.pojavlaunch.prefs.CustomSeekBarPreference
|
|
||||||
android:key="buttonscale"
|
|
||||||
android:title="@string/mcl_setting_title_buttonscale"
|
|
||||||
android:summary="@string/mcl_setting_subtitle_buttonscale"
|
|
||||||
app2:showSeekBarValue="true"
|
|
||||||
app2:selectable="false"
|
|
||||||
app2:icon="@drawable/btn_scale"/>
|
|
||||||
|
|
||||||
<net.kdt.pojavlaunch.prefs.CustomSeekBarPreference
|
|
||||||
android:key="mousescale"
|
|
||||||
android:summary="@string/mcl_setting_subtitle_mousescale"
|
|
||||||
android:title="@string/mcl_setting_title_mousescale"
|
|
||||||
app2:icon="@drawable/mouse_pointer_1"
|
|
||||||
app2:selectable="false"
|
|
||||||
app2:showSeekBarValue="true" />
|
|
||||||
<net.kdt.pojavlaunch.prefs.CustomSeekBarPreference
|
|
||||||
android:key="mousespeed"
|
|
||||||
android:summary="@string/mcl_setting_subtitle_mousespeed"
|
|
||||||
android:title="@string/mcl_setting_title_mousespeed"
|
|
||||||
app2:icon="@drawable/mouse_pointer_spd"
|
|
||||||
app2:selectable="false"
|
|
||||||
app2:showSeekBarValue="true" />
|
|
||||||
|
|
||||||
</androidx.preference.PreferenceCategory>
|
|
||||||
|
|
||||||
<androidx.preference.PreferenceCategory
|
|
||||||
android:title="@string/mcl_setting_category_veroption">
|
|
||||||
|
|
||||||
<androidx.preference.CheckBoxPreference
|
|
||||||
android:defaultValue="true"
|
|
||||||
android:key="vertype_release"
|
|
||||||
android:title="@string/mcl_setting_veroption_release" />
|
|
||||||
|
|
||||||
<androidx.preference.CheckBoxPreference
|
|
||||||
android:defaultValue="false"
|
|
||||||
android:key="vertype_snapshot"
|
|
||||||
android:title="@string/mcl_setting_veroption_snapshot" />
|
|
||||||
|
|
||||||
<androidx.preference.CheckBoxPreference
|
|
||||||
android:defaultValue="false"
|
|
||||||
android:key="vertype_oldalpha"
|
|
||||||
android:title="@string/mcl_setting_veroption_oldalpha" />
|
|
||||||
|
|
||||||
<androidx.preference.CheckBoxPreference
|
|
||||||
android:defaultValue="false"
|
|
||||||
android:key="vertype_oldbeta"
|
|
||||||
android:title="@string/mcl_setting_veroption_oldbeta" />
|
|
||||||
|
|
||||||
</androidx.preference.PreferenceCategory>
|
|
||||||
|
|
||||||
</androidx.preference.PreferenceScreen>
|
|
50
app_pojavlauncher/src/main/res/xml/pref_misc.xml
Normal file
50
app_pojavlauncher/src/main/res/xml/pref_misc.xml
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app2="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
|
<net.kdt.pojavlaunch.prefs.BackButtonPreference/>
|
||||||
|
|
||||||
|
<PreferenceCategory android:title="Miscellaneous settings">
|
||||||
|
|
||||||
|
<SwitchPreference
|
||||||
|
android:defaultValue="false"
|
||||||
|
android:key="hideSidebar"
|
||||||
|
android:summary="@string/mcl_setting_subtitle_hide_sidebar"
|
||||||
|
android:title="@string/mcl_setting_title_hide_sidebar"
|
||||||
|
app2:icon="@drawable/hide_sidebar" />
|
||||||
|
|
||||||
|
<SwitchPreference
|
||||||
|
android:defaultValue="true"
|
||||||
|
android:icon="@drawable/ic_lib_check"
|
||||||
|
android:key="checkLibraries"
|
||||||
|
android:summary="@string/mcl_setting_check_libraries_subtitle"
|
||||||
|
android:title="@string/mcl_setting_check_libraries" />
|
||||||
|
|
||||||
|
</PreferenceCategory>
|
||||||
|
|
||||||
|
<PreferenceCategory
|
||||||
|
android:title="@string/mcl_setting_category_veroption">
|
||||||
|
|
||||||
|
<CheckBoxPreference
|
||||||
|
android:defaultValue="true"
|
||||||
|
android:key="vertype_release"
|
||||||
|
android:title="@string/mcl_setting_veroption_release" />
|
||||||
|
|
||||||
|
<CheckBoxPreference
|
||||||
|
android:defaultValue="false"
|
||||||
|
android:key="vertype_snapshot"
|
||||||
|
android:title="@string/mcl_setting_veroption_snapshot" />
|
||||||
|
|
||||||
|
<CheckBoxPreference
|
||||||
|
android:defaultValue="false"
|
||||||
|
android:key="vertype_oldalpha"
|
||||||
|
android:title="@string/mcl_setting_veroption_oldalpha" />
|
||||||
|
|
||||||
|
<CheckBoxPreference
|
||||||
|
android:defaultValue="false"
|
||||||
|
android:key="vertype_oldbeta"
|
||||||
|
android:title="@string/mcl_setting_veroption_oldbeta" />
|
||||||
|
|
||||||
|
</PreferenceCategory>
|
||||||
|
|
||||||
|
</PreferenceScreen>
|
31
app_pojavlauncher/src/main/res/xml/pref_video.xml
Normal file
31
app_pojavlauncher/src/main/res/xml/pref_video.xml
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app2="http://schemas.android.com/apk/res-auto">
|
||||||
|
|
||||||
|
<net.kdt.pojavlaunch.prefs.BackButtonPreference/>
|
||||||
|
|
||||||
|
<PreferenceCategory android:title="Video settings" >
|
||||||
|
<androidx.preference.ListPreference
|
||||||
|
android:title="@string/mcl_setting_category_renderer"
|
||||||
|
android:key="renderer"
|
||||||
|
android:defaultValue="opengles2"
|
||||||
|
android:entries="@array/renderer"
|
||||||
|
android:entryValues="@array/renderer_values"
|
||||||
|
app2:useSimpleSummaryProvider="true"/>
|
||||||
|
|
||||||
|
<androidx.preference.SwitchPreferenceCompat
|
||||||
|
android:defaultValue="false"
|
||||||
|
android:key="ignoreNotch"
|
||||||
|
android:summary="@string/mcl_setting_subtitle_ignore_notch"
|
||||||
|
android:title="@string/mcl_setting_title_ignore_notch"
|
||||||
|
app2:icon="@drawable/ignore_notch" />
|
||||||
|
|
||||||
|
<net.kdt.pojavlaunch.prefs.CustomSeekBarPreference
|
||||||
|
android:key="resolutionRatio"
|
||||||
|
android:summary="@string/mcl_setting_subtitle_resolution_scaler"
|
||||||
|
android:title="@string/mcl_setting_title_resolution_scaler"
|
||||||
|
app2:showSeekBarValue="true"
|
||||||
|
app2:selectable="false"
|
||||||
|
app2:icon="@drawable/resolution_scaler"/>
|
||||||
|
</PreferenceCategory>
|
||||||
|
</PreferenceScreen>
|
@ -2,6 +2,3 @@ android.enableJetifier=true
|
|||||||
android.useAndroidX=true
|
android.useAndroidX=true
|
||||||
android.bundle.enableUncompressedNativeLibs=false
|
android.bundle.enableUncompressedNativeLibs=false
|
||||||
android.bundle.language.enableSplit=false
|
android.bundle.language.enableSplit=false
|
||||||
systemProp.http.ssl.insecure=true
|
|
||||||
systemProp.http.ssl.allowall=true
|
|
||||||
systemProp.http.ssl.ignore.validity.dates=true
|
|
||||||
|
@ -53,7 +53,7 @@ public class CallbackBridge {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Called from Android side
|
// Called from Android side
|
||||||
public static void receiveCallback(int type, int i1, int i2, int i3, int i4) {
|
public static void receiveCallback(int type, float i1, float i2, int i3, int i4) {
|
||||||
/*
|
/*
|
||||||
if (INPUT_DEBUG_ENABLED) {
|
if (INPUT_DEBUG_ENABLED) {
|
||||||
System.out.println("LWJGL GLFW Callback received type=" + Integer.toString(type) + ", data=" + i1 + ", " + i2 + ", " + i3 + ", " + i4);
|
System.out.println("LWJGL GLFW Callback received type=" + Integer.toString(type) + ", data=" + i1 + ", " + i2 + ", " + i3 + ", " + i4);
|
||||||
@ -61,10 +61,10 @@ public class CallbackBridge {
|
|||||||
*/
|
*/
|
||||||
if (PENDING_EVENT_READY) {
|
if (PENDING_EVENT_READY) {
|
||||||
if (type == EVENT_TYPE_CURSOR_POS) {
|
if (type == EVENT_TYPE_CURSOR_POS) {
|
||||||
GLFW.mGLFWCursorX = i1;
|
GLFW.mGLFWCursorX = (double) i1;
|
||||||
GLFW.mGLFWCursorY = i2;
|
GLFW.mGLFWCursorY = (double) i2;
|
||||||
} else {
|
} else {
|
||||||
PENDING_EVENT_LIST.add(new Integer[]{type, i1, i2, i3, i4});
|
PENDING_EVENT_LIST.add(new Integer[]{type, (int) i1, (int)i2, i3, i4});
|
||||||
}
|
}
|
||||||
} // else System.out.println("Event input is not ready yet!");
|
} // else System.out.println("Event input is not ready yet!");
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user