diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MainActivity.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MainActivity.java index b2e49c652..a284bcbc6 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MainActivity.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/MainActivity.java @@ -1,6 +1,7 @@ package net.kdt.pojavlaunch; import static net.kdt.pojavlaunch.Tools.currentDisplayMetrics; +import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_ENABLE_GYRO; import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_SUSTAINED_PERFORMANCE; import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_USE_ALTERNATE_SURFACE; import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_VIRTUAL_MOUSE_START; @@ -55,6 +56,7 @@ import net.kdt.pojavlaunch.customcontrols.mouse.GyroControl; import net.kdt.pojavlaunch.customcontrols.mouse.Touchpad; import net.kdt.pojavlaunch.lifecycle.ContextExecutor; import net.kdt.pojavlaunch.prefs.LauncherPreferences; +import net.kdt.pojavlaunch.prefs.QuickSettingSideDialog; import net.kdt.pojavlaunch.services.GameService; import net.kdt.pojavlaunch.utils.JREUtils; import net.kdt.pojavlaunch.utils.MCOptionUtils; @@ -91,6 +93,8 @@ public class MainActivity extends BaseActivity implements ControlButtonMenuListe public AdapterView.OnItemClickListener ingameControlsEditorListener; private GameService.LocalBinder mServiceBinder; + private QuickSettingSideDialog mQuickSettingSideDialog; + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -103,7 +107,8 @@ public class MainActivity extends BaseActivity implements ControlButtonMenuListe initLayout(R.layout.activity_basemain); CallbackBridge.addGrabListener(touchpad); CallbackBridge.addGrabListener(minecraftGLView); - if(LauncherPreferences.PREF_ENABLE_GYRO) mGyroControl = new GyroControl(this); + + mGyroControl = new GyroControl(this); // Enabling this on TextureView results in a broken white result if(PREF_USE_ALTERNATE_SURFACE) getWindow().setBackgroundDrawable(null); @@ -185,9 +190,8 @@ public class MainActivity extends BaseActivity implements ControlButtonMenuListe case 0: dialogForceClose(MainActivity.this); break; case 1: openLogOutput(); break; case 2: dialogSendCustomKey(); break; - case 3: adjustMouseSpeedLive(); break; - case 4: adjustGyroSensitivityLive(); break; - case 5: openCustomControls(); break; + case 3: mQuickSettingSideDialog.appear(true); break; + case 4: openCustomControls(); break; } drawerLayout.closeDrawers(); }; @@ -208,6 +212,23 @@ public class MainActivity extends BaseActivity implements ControlButtonMenuListe Tools.showErrorRemote(e); } }); + + mQuickSettingSideDialog = new QuickSettingSideDialog(this, mControlLayout) { + @Override + public void onResolutionChanged() { + //TODO: reflect the change in event positions sent down to the game + minecraftGLView.refreshSize(); + } + + @Override + public void onGyroStateChanged() { + if (PREF_ENABLE_GYRO) { + mGyroControl.enable(); + } else { + mGyroControl.disable(); + } + } + }; } catch (Throwable e) { Tools.showError(this, e, true); } @@ -260,16 +281,17 @@ public class MainActivity extends BaseActivity implements ControlButtonMenuListe @Override public void onResume() { super.onResume(); - if(mGyroControl != null) mGyroControl.enable(); + if(PREF_ENABLE_GYRO) mGyroControl.enable(); CallbackBridge.nativeSetWindowAttrib(LwjglGlfwKeycode.GLFW_HOVERED, 1); } @Override protected void onPause() { - if(mGyroControl != null) mGyroControl.disable(); + mGyroControl.disable(); if (CallbackBridge.isGrabbing()){ sendKeyPress(LwjglGlfwKeycode.GLFW_KEY_ESCAPE); } + mQuickSettingSideDialog.cancel(); CallbackBridge.nativeSetWindowAttrib(LwjglGlfwKeycode.GLFW_HOVERED, 0); super.onPause(); } @@ -423,83 +445,6 @@ public class MainActivity extends BaseActivity implements ControlButtonMenuListe if(touchCharInput != null) touchCharInput.switchKeyboardState(); } - - int tmpMouseSpeed; - public void adjustMouseSpeedLive() { - AlertDialog.Builder b = new AlertDialog.Builder(this); - b.setTitle(R.string.mcl_setting_title_mousespeed); - View v = LayoutInflater.from(this).inflate(R.layout.dialog_live_mouse_speed_editor,null); - final SeekBar sb = v.findViewById(R.id.mouseSpeed); - final TextView tv = v.findViewById(R.id.mouseSpeedTV); - sb.setMax(275); - tmpMouseSpeed = (int) ((LauncherPreferences.PREF_MOUSESPEED*100)); - sb.setProgress(tmpMouseSpeed-25); - tv.setText(getString(R.string.percent_format, tmpMouseSpeed)); - sb.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { - @Override - public void onProgressChanged(SeekBar seekBar, int i, boolean b) { - tmpMouseSpeed = i+25; - tv.setText(getString(R.string.percent_format, tmpMouseSpeed)); - } - @Override - public void onStartTrackingTouch(SeekBar seekBar) {} - @Override - public void onStopTrackingTouch(SeekBar seekBar) {} - }); - b.setView(v); - b.setPositiveButton(android.R.string.ok, (dialogInterface, i) -> { - LauncherPreferences.PREF_MOUSESPEED = ((float)tmpMouseSpeed)/100f; - LauncherPreferences.DEFAULT_PREF.edit().putInt("mousespeed",tmpMouseSpeed).apply(); - dialogInterface.dismiss(); - System.gc(); - }); - b.setNegativeButton(android.R.string.cancel, (dialogInterface, i) -> { - dialogInterface.dismiss(); - System.gc(); - }); - b.show(); - } - - int tmpGyroSensitivity; - public void adjustGyroSensitivityLive() { - if(!LauncherPreferences.PREF_ENABLE_GYRO) { - Toast.makeText(this, R.string.toast_turn_on_gyro, Toast.LENGTH_LONG).show(); - return; - } - AlertDialog.Builder b = new AlertDialog.Builder(this); - b.setTitle(R.string.preference_gyro_sensitivity_title); - View v = LayoutInflater.from(this).inflate(R.layout.dialog_live_mouse_speed_editor,null); - final SeekBar sb = v.findViewById(R.id.mouseSpeed); - final TextView tv = v.findViewById(R.id.mouseSpeedTV); - sb.setMax(275); - tmpGyroSensitivity = (int) ((LauncherPreferences.PREF_GYRO_SENSITIVITY*100)); - sb.setProgress(tmpGyroSensitivity -25); - tv.setText(getString(R.string.percent_format, tmpGyroSensitivity)); - sb.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { - @Override - public void onProgressChanged(SeekBar seekBar, int i, boolean b) { - tmpGyroSensitivity = i+25; - tv.setText(getString(R.string.percent_format, tmpGyroSensitivity)); - } - @Override - public void onStartTrackingTouch(SeekBar seekBar) {} - @Override - public void onStopTrackingTouch(SeekBar seekBar) {} - }); - b.setView(v); - b.setPositiveButton(android.R.string.ok, (dialogInterface, i) -> { - LauncherPreferences.PREF_GYRO_SENSITIVITY = ((float) tmpGyroSensitivity)/100f; - LauncherPreferences.DEFAULT_PREF.edit().putInt("gyroSensitivity", tmpGyroSensitivity).apply(); - dialogInterface.dismiss(); - System.gc(); - }); - b.setNegativeButton(android.R.string.cancel, (dialogInterface, i) -> { - dialogInterface.dismiss(); - System.gc(); - }); - b.show(); - } - private static void setUri(Context context, String input, Intent intent) { if(input.startsWith("file:")) { int truncLength = 5; diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/mouse/GyroControl.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/mouse/GyroControl.java index 4ead091c1..55851824b 100644 --- a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/mouse/GyroControl.java +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/customcontrols/mouse/GyroControl.java @@ -87,6 +87,11 @@ public class GyroControl implements SensorEventListener, GrabListener { SensorManager.getRotationMatrixFromVector(mCurrentRotation, sensorEvent.values); + float xLocalFactor = xFactor; + float yLocalFactor = yFactor; + if(LauncherPreferences.PREF_GYRO_INVERT_X) xLocalFactor *= -1; + if(LauncherPreferences.PREF_GYRO_INVERT_Y) yLocalFactor *= -1; + if(mFirstPass){ // Setup initial position mFirstPass = false; return; @@ -101,20 +106,20 @@ public class GyroControl implements SensorEventListener, GrabListener { float absY = Math.abs(mStoredY); if(absX + absY > MULTI_AXIS_LOW_PASS_THRESHOLD) { - CallbackBridge.mouseX -= ((mSwapXY ? mStoredY : mStoredX) * xFactor); - CallbackBridge.mouseY += ((mSwapXY ? mStoredX : mStoredY) * yFactor); + CallbackBridge.mouseX -= ((mSwapXY ? mStoredY : mStoredX) * xLocalFactor); + CallbackBridge.mouseY += ((mSwapXY ? mStoredX : mStoredY) * yLocalFactor); mStoredX = 0; mStoredY = 0; updatePosition = true; } else { if(Math.abs(mStoredX) > SINGLE_AXIS_LOW_PASS_THRESHOLD){ - CallbackBridge.mouseX -= ((mSwapXY ? mStoredY : mStoredX) * xFactor); + CallbackBridge.mouseX -= ((mSwapXY ? mStoredY : mStoredX) * xLocalFactor); mStoredX = 0; updatePosition = true; } if(Math.abs(mStoredY) > SINGLE_AXIS_LOW_PASS_THRESHOLD) { - CallbackBridge.mouseY += ((mSwapXY ? mStoredX : mStoredY) * yFactor); + CallbackBridge.mouseY += ((mSwapXY ? mStoredX : mStoredY) * yLocalFactor); mStoredY = 0; updatePosition = true; } @@ -151,9 +156,6 @@ public class GyroControl implements SensorEventListener, GrabListener { yFactor = -1; break; } - - if(LauncherPreferences.PREF_GYRO_INVERT_X) xFactor *= -1; - if(LauncherPreferences.PREF_GYRO_INVERT_Y) yFactor *= -1; } @Override @@ -242,9 +244,6 @@ public class GyroControl implements SensorEventListener, GrabListener { } break; } - - if(LauncherPreferences.PREF_GYRO_INVERT_X) xFactor *= -1; - if(LauncherPreferences.PREF_GYRO_INVERT_Y) yFactor *= -1; } } } diff --git a/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/prefs/QuickSettingSideDialog.java b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/prefs/QuickSettingSideDialog.java new file mode 100644 index 000000000..cc927d1b6 --- /dev/null +++ b/app_pojavlauncher/src/main/java/net/kdt/pojavlaunch/prefs/QuickSettingSideDialog.java @@ -0,0 +1,220 @@ +package net.kdt.pojavlaunch.prefs; + +import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_DISABLE_GESTURES; +import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_ENABLE_GYRO; +import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_GYRO_INVERT_X; +import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_GYRO_INVERT_Y; +import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_GYRO_SENSITIVITY; +import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_LONGPRESS_TRIGGER; +import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_MOUSESPEED; +import static net.kdt.pojavlaunch.prefs.LauncherPreferences.PREF_SCALE_FACTOR; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Switch; +import android.widget.TextView; + +import androidx.constraintlayout.widget.ConstraintLayout; + +import com.kdt.CustomSeekbar; + +import net.kdt.pojavlaunch.R; +import net.kdt.pojavlaunch.utils.SimpleSeekBarListener; + +/** + * Side dialog for quick settings that you can change in game + * The implementation has to take action on some preference changes + */ +public abstract class QuickSettingSideDialog extends com.kdt.SideDialogView { + + @SuppressLint("UseSwitchCompatOrMaterialCode") + private Switch mGyroSwitch, mGyroXSwitch, mGyroYSwitch, mGestureSwitch; + private CustomSeekbar mGyroSensitivityBar, mMouseSpeedBar, mGestureDelayBar, mResolutionBar; + private TextView mGyroSensitivityText, mGyroSensitivityDisplayText, mMouseSpeedText, mGestureDelayText, mGestureDelayDisplayText, mResolutionText; + + private boolean mOriginalGyroEnabled, mOriginalGyroXEnabled, mOriginalGyroYEnabled, mOriginalGestureDisabled; + private float mOriginalGyroSensitivity, mOriginalMouseSpeed; + private int mOriginalGestureDelay, mOriginalResolution; + + public QuickSettingSideDialog(Context context, ViewGroup parent) { + super(context, parent, R.layout.dialog_quick_setting); + setTitle(R.string.quick_setting_title); + bindLayout(); + setupCancelButton(); + } + + @Override + public boolean appear(boolean fromRight) { + boolean hasChanged = super.appear(fromRight); + if (hasChanged) setupListeners(); + return hasChanged; + } + + @Override + public void disappear() { + super.disappear(); + removeListeners(); + } + + private void bindLayout() { + // Bind layout elements + mGyroSwitch = mDialogContent.findViewById(R.id.checkboxGyro); + mGyroXSwitch = mDialogContent.findViewById(R.id.checkboxGyroX); + mGyroYSwitch = mDialogContent.findViewById(R.id.checkboxGyroY); + mGestureSwitch = mDialogContent.findViewById(R.id.checkboxGesture); + + mGyroSensitivityBar = mDialogContent.findViewById(R.id.editGyro_seekbar); + mMouseSpeedBar = mDialogContent.findViewById(R.id.editMouseSpeed_seekbar); + mGestureDelayBar = mDialogContent.findViewById(R.id.editGestureDelay_seekbar); + mResolutionBar = mDialogContent.findViewById(R.id.editResolution_seekbar); + + mGyroSensitivityText = mDialogContent.findViewById(R.id.editGyro_textView_percent); + mGyroSensitivityDisplayText = mDialogContent.findViewById(R.id.editGyro_textView); + mMouseSpeedText = mDialogContent.findViewById(R.id.editMouseSpeed_textView_percent); + mGestureDelayText = mDialogContent.findViewById(R.id.editGestureDelay_textView_percent); + mGestureDelayDisplayText = mDialogContent.findViewById(R.id.editGestureDelay_textView); + mResolutionText = mDialogContent.findViewById(R.id.editResolution_textView_percent); + } + + private void setupListeners() { + mOriginalGyroEnabled = PREF_ENABLE_GYRO; + mOriginalGyroXEnabled = PREF_GYRO_INVERT_X; + mOriginalGyroYEnabled = PREF_GYRO_INVERT_Y; + mOriginalGestureDisabled = PREF_DISABLE_GESTURES; + + mOriginalGyroSensitivity = PREF_GYRO_SENSITIVITY; + mOriginalMouseSpeed = PREF_MOUSESPEED; + mOriginalGestureDelay = PREF_LONGPRESS_TRIGGER; + mOriginalResolution = PREF_SCALE_FACTOR; + + mGyroSwitch.setChecked(mOriginalGyroEnabled); + mGyroXSwitch.setChecked(mOriginalGyroXEnabled); + mGyroYSwitch.setChecked(mOriginalGyroYEnabled); + mGestureSwitch.setChecked(mOriginalGestureDisabled); + + mGyroSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { + PREF_ENABLE_GYRO = isChecked; + onGyroStateChanged(); + updateGyroVisibility(isChecked); + LauncherPreferences.DEFAULT_PREF.edit().putBoolean("enableGyro", isChecked).apply(); + }); + + mGyroXSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { + PREF_GYRO_INVERT_X = isChecked; + LauncherPreferences.DEFAULT_PREF.edit().putBoolean("gyroInvertX", isChecked).apply(); + }); + + mGyroYSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { + PREF_GYRO_INVERT_Y = isChecked; + LauncherPreferences.DEFAULT_PREF.edit().putBoolean("gyroInvertY", isChecked).apply(); + }); + + mGestureSwitch.setOnCheckedChangeListener((buttonView, isChecked) -> { + PREF_DISABLE_GESTURES = isChecked; + updateGestureVisibility(isChecked); + LauncherPreferences.DEFAULT_PREF.edit().putBoolean("disableGestures", isChecked).apply(); + }); + + mGyroSensitivityBar.setRange(25, 300); + mGyroSensitivityBar.setIncrement(5); + mGyroSensitivityBar.setOnSeekBarChangeListener((SimpleSeekBarListener) (seekBar, progress, fromUser) -> { + PREF_GYRO_SENSITIVITY = progress / 100f; + LauncherPreferences.DEFAULT_PREF.edit().putInt("gyroSensitivity", progress).apply(); + mGyroSensitivityText.setText(progress + "%"); + }); + mGyroSensitivityBar.setProgress((int) (mOriginalGyroSensitivity * 100f)); + + mMouseSpeedBar.setRange(25, 300); + mMouseSpeedBar.setIncrement(5); + mMouseSpeedBar.setOnSeekBarChangeListener((SimpleSeekBarListener) (seekBar, progress, fromUser) -> { + PREF_MOUSESPEED = progress / 100f; + LauncherPreferences.DEFAULT_PREF.edit().putInt("mousespeed", progress).apply(); + mMouseSpeedText.setText(progress + "%"); + }); + mMouseSpeedBar.setProgress((int) (mOriginalMouseSpeed * 100f)); + + mGestureDelayBar.setRange(100, 1000); + mGestureDelayBar.setIncrement(10); + mGestureDelayBar.setOnSeekBarChangeListener((SimpleSeekBarListener) (seekBar, progress, fromUser) -> { + PREF_LONGPRESS_TRIGGER = progress; + LauncherPreferences.DEFAULT_PREF.edit().putInt("timeLongPressTrigger", progress).apply(); + mGestureDelayText.setText(progress + "ms"); + }); + mGestureDelayBar.setProgress(mOriginalGestureDelay); + + mResolutionBar.setRange(25, 100); + mResolutionBar.setIncrement(5); + mResolutionBar.setOnSeekBarChangeListener((SimpleSeekBarListener) (seekBar, progress, fromUser) -> { + onResolutionChanged(); + PREF_SCALE_FACTOR = progress; + LauncherPreferences.DEFAULT_PREF.edit().putInt("resolutionRatio", progress).apply(); + mResolutionText.setText(progress + "%"); + }); + mResolutionBar.setProgress(mOriginalResolution); + + + updateGyroVisibility(mOriginalGyroEnabled); + updateGestureVisibility(mOriginalGestureDisabled); + } + + private void updateGyroVisibility(boolean isEnabled) { + int visibility = isEnabled ? View.VISIBLE : View.GONE; + mGyroXSwitch.setVisibility(visibility); + mGyroYSwitch.setVisibility(visibility); + + mGyroSensitivityBar.setVisibility(visibility); + mGyroSensitivityText.setVisibility(visibility); + mGyroSensitivityDisplayText.setVisibility(visibility); + } + + private void updateGestureVisibility(boolean isDisabled) { + int visibility = isDisabled ? View.GONE : View.VISIBLE; + mGestureDelayBar.setVisibility(visibility); + mGestureDelayText.setVisibility(visibility); + mGestureDelayDisplayText.setVisibility(visibility); + } + + private void removeListeners() { + mGyroSwitch.setOnCheckedChangeListener(null); + mGyroXSwitch.setOnCheckedChangeListener(null); + mGyroYSwitch.setOnCheckedChangeListener(null); + mGestureSwitch.setOnCheckedChangeListener(null); + + mGyroSensitivityBar.setOnSeekBarChangeListener(null); + mMouseSpeedBar.setOnSeekBarChangeListener(null); + mGestureDelayBar.setOnSeekBarChangeListener(null); + mResolutionBar.setOnSeekBarChangeListener(null); + } + + private void setupCancelButton() { + setStartButtonListener(android.R.string.cancel, v -> cancel()); + setEndButtonListener(android.R.string.ok, v -> disappear()); + } + + /** Resets all settings to their original values */ + public void cancel() { + PREF_ENABLE_GYRO = mOriginalGyroEnabled; + PREF_GYRO_INVERT_X = mOriginalGyroXEnabled; + PREF_GYRO_INVERT_Y = mOriginalGyroYEnabled; + PREF_DISABLE_GESTURES = mOriginalGestureDisabled; + + PREF_GYRO_SENSITIVITY = mOriginalGyroSensitivity; + PREF_MOUSESPEED = mOriginalMouseSpeed; + PREF_LONGPRESS_TRIGGER = mOriginalGestureDelay; + PREF_SCALE_FACTOR = mOriginalResolution; + + onGyroStateChanged(); + onResolutionChanged(); + + disappear(); + } + + /** Called when the resolution is changed. Use {@link LauncherPreferences#PREF_SCALE_FACTOR} */ + public abstract void onResolutionChanged(); + + /** Called when the gyro state is changed. Use {@link LauncherPreferences#PREF_ENABLE_GYRO} */ + public abstract void onGyroStateChanged(); + +} diff --git a/app_pojavlauncher/src/main/res/layout/dialog_quick_setting.xml b/app_pojavlauncher/src/main/res/layout/dialog_quick_setting.xml new file mode 100644 index 000000000..435781a04 --- /dev/null +++ b/app_pojavlauncher/src/main/res/layout/dialog_quick_setting.xml @@ -0,0 +1,191 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app_pojavlauncher/src/main/res/values/headings_array.xml b/app_pojavlauncher/src/main/res/values/headings_array.xml index b5a3256bb..f32663a0d 100644 --- a/app_pojavlauncher/src/main/res/values/headings_array.xml +++ b/app_pojavlauncher/src/main/res/values/headings_array.xml @@ -30,8 +30,7 @@ @string/control_forceclose @string/control_viewout @string/control_customkey - @string/mcl_setting_title_mousespeed - @string/preference_gyro_sensitivity_title + @string/quick_setting_title @string/mcl_option_customcontrol diff --git a/app_pojavlauncher/src/main/res/values/strings.xml b/app_pojavlauncher/src/main/res/values/strings.xml index 9e977c1aa..580899b17 100644 --- a/app_pojavlauncher/src/main/res/values/strings.xml +++ b/app_pojavlauncher/src/main/res/values/strings.xml @@ -418,4 +418,5 @@ https://discord.gg/pojavlauncher-724163890803638273 Unsuitable username The username must be between 3–16 characters long, and must only contain latin letters, arabic numerals and underscores. + Quick settings