diff --git a/android/app/src/main/java/com/github/stenzek/duckstation/EmulationActivity.java b/android/app/src/main/java/com/github/stenzek/duckstation/EmulationActivity.java index 833d6d1b5..3a2b5ae88 100644 --- a/android/app/src/main/java/com/github/stenzek/duckstation/EmulationActivity.java +++ b/android/app/src/main/java/com/github/stenzek/duckstation/EmulationActivity.java @@ -496,26 +496,17 @@ public class EmulationActivity extends AppCompatActivity implements SurfaceHolde return; } - case 3: // Settings - { - Intent intent = new Intent(EmulationActivity.this, SettingsActivity.class); - intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - startActivityForResult(intent, REQUEST_CODE_SETTINGS); - return; - } - - case 4: // Change Touchscreen Controller + case 3: // Change Touchscreen Controller { showTouchscreenControllerMenu(); return; } - case 5: // Edit Touchscreen Controller Layout + case 4: // Settings { - if (mTouchscreenController != null) - mTouchscreenController.startLayoutEditing(); - - onMenuClosed(); + Intent intent = new Intent(EmulationActivity.this, SettingsActivity.class); + intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + startActivityForResult(intent, REQUEST_CODE_SETTINGS); return; } } @@ -526,14 +517,72 @@ public class EmulationActivity extends AppCompatActivity implements SurfaceHolde private void showTouchscreenControllerMenu() { AlertDialog.Builder builder = new AlertDialog.Builder(this); - builder.setItems(R.array.settings_touchscreen_controller_view_entries, (dialogInterface, i) -> { - String[] values = getResources().getStringArray(R.array.settings_touchscreen_controller_view_values); - setStringSetting("Controller1/TouchscreenControllerView", values[i]); - updateControllers(); - onMenuClosed(); + if (mGameTitle != null && !mGameTitle.isEmpty()) + builder.setTitle(mGameTitle); + + builder.setItems(R.array.emulation_touchscreen_menu, (dialogInterface, i) -> { + switch (i) { + case 0: // Change Type + { + final String currentValue = getStringSetting("Controller1/TouchscreenControllerView", ""); + final String[] values = getResources().getStringArray(R.array.settings_touchscreen_controller_view_values); + int currentIndex = -1; + for (int k = 0; k < values.length; k++) { + if (currentValue.equals(values[k])) { + currentIndex = k; + break; + } + } + + final AlertDialog.Builder subBuilder = new AlertDialog.Builder(this); + subBuilder.setTitle(R.string.dialog_touchscreen_controller_type); + subBuilder.setSingleChoiceItems(R.array.settings_touchscreen_controller_view_entries, currentIndex, (dialog, j) -> { + setStringSetting("Controller1/TouchscreenControllerView", values[j]); + updateControllers(); + }); + subBuilder.setNegativeButton(R.string.dialog_done, (dialog, which) -> { + dialog.dismiss(); + }); + subBuilder.setOnDismissListener(dialog -> onMenuClosed()); + subBuilder.create().show(); + } + break; + + case 1: // Change Opacity + { + if (mTouchscreenController != null) { + AlertDialog.Builder subBuilder = mTouchscreenController.createOpacityDialog(this); + subBuilder.setOnDismissListener(dialog -> onMenuClosed()); + subBuilder.create().show(); + } + } + break; + + case 2: // Add/Remove Buttons + { + if (mTouchscreenController != null) { + AlertDialog.Builder subBuilder = mTouchscreenController.createAddRemoveButtonDialog(this); + subBuilder.setOnDismissListener(dialog -> onMenuClosed()); + subBuilder.create().show(); + } + } + break; + + case 3: // Edit Layout + { + if (mTouchscreenController != null) + mTouchscreenController.startLayoutEditing(); + } + break; + } }); - builder.setOnCancelListener(dialogInterface -> onMenuClosed()); + + builder.setOnDismissListener(dialogInterface -> onMenuClosed()); builder.create().show(); + + /* + + */ } private void showPatchesMenu() { diff --git a/android/app/src/main/java/com/github/stenzek/duckstation/TouchscreenControllerAxisView.java b/android/app/src/main/java/com/github/stenzek/duckstation/TouchscreenControllerAxisView.java index 44436dfd3..ec6db05f8 100644 --- a/android/app/src/main/java/com/github/stenzek/duckstation/TouchscreenControllerAxisView.java +++ b/android/app/src/main/java/com/github/stenzek/duckstation/TouchscreenControllerAxisView.java @@ -18,6 +18,8 @@ public final class TouchscreenControllerAxisView extends View { private int mDrawYPos = 0; private String mConfigName; + private boolean mDefaultVisibility = true; + private int mControllerIndex = -1; private int mXAxisCode = -1; private int mYAxisCode = -1; @@ -53,11 +55,13 @@ public final class TouchscreenControllerAxisView extends View { public String getConfigName() { return mConfigName; } - public void setConfigName(String configName) { mConfigName = configName; } + public boolean getDefaultVisibility() { return mDefaultVisibility; } + public void setDefaultVisibility(boolean visibility) { mDefaultVisibility = visibility; } + public void setControllerAxis(int controllerIndex, int xCode, int yCode) { mControllerIndex = controllerIndex; mXAxisCode = xCode; diff --git a/android/app/src/main/java/com/github/stenzek/duckstation/TouchscreenControllerButtonView.java b/android/app/src/main/java/com/github/stenzek/duckstation/TouchscreenControllerButtonView.java index e48f9afeb..cfb5e6305 100644 --- a/android/app/src/main/java/com/github/stenzek/duckstation/TouchscreenControllerButtonView.java +++ b/android/app/src/main/java/com/github/stenzek/duckstation/TouchscreenControllerButtonView.java @@ -26,6 +26,7 @@ public final class TouchscreenControllerButtonView extends View { private int mButtonCode = -1; private Hotkey mHotkey = Hotkey.NONE; private String mConfigName; + private boolean mDefaultVisibility = true; public TouchscreenControllerButtonView(Context context) { super(context); @@ -106,13 +107,15 @@ public final class TouchscreenControllerButtonView extends View { mHotkey = hotkey; } + public String getConfigName() { + return mConfigName; + } public void setConfigName(String name) { mConfigName = name; } - public String getConfigName() { - return mConfigName; - } + public boolean getDefaultVisibility() { return mDefaultVisibility; } + public void setDefaultVisibility(boolean visibility) { mDefaultVisibility = visibility; } public void setHapticFeedback(boolean enabled) { mHapticFeedback = enabled; diff --git a/android/app/src/main/java/com/github/stenzek/duckstation/TouchscreenControllerView.java b/android/app/src/main/java/com/github/stenzek/duckstation/TouchscreenControllerView.java index 7c0b3e23a..8df972aed 100644 --- a/android/app/src/main/java/com/github/stenzek/duckstation/TouchscreenControllerView.java +++ b/android/app/src/main/java/com/github/stenzek/duckstation/TouchscreenControllerView.java @@ -13,8 +13,9 @@ import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.FrameLayout; -import android.widget.RelativeLayout; +import android.widget.SeekBar; +import androidx.appcompat.app.AlertDialog; import androidx.constraintlayout.widget.ConstraintLayout; import androidx.preference.PreferenceManager; @@ -24,6 +25,8 @@ import java.util.ArrayList; * TODO: document your custom view class. */ public class TouchscreenControllerView extends FrameLayout { + public static final int DEFAULT_OPACITY = 100; + private int mControllerIndex; private String mControllerType; private String mViewType; @@ -38,6 +41,7 @@ public class TouchscreenControllerView extends FrameLayout { private float mMovingLastX = 0.0f; private float mMovingLastY = 0.0f; private ConstraintLayout mEditLayout = null; + private int mOpacity = 100; public TouchscreenControllerView(Context context) { super(context); @@ -61,6 +65,10 @@ public class TouchscreenControllerView extends FrameLayout { return String.format("TouchscreenController/%s/%s%sYTranslation", mViewType, name, mLayoutOrientation); } + private String getConfigKeyForVisibility(String name) { + return String.format("TouchscreenController/%s/%s%sVisible", mViewType, name, mLayoutOrientation); + } + private void saveTranslationForButton(String name, float xTranslation, float yTranslation) { final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); final SharedPreferences.Editor editor = prefs.edit(); @@ -69,6 +77,13 @@ public class TouchscreenControllerView extends FrameLayout { editor.commit(); } + private void saveVisibilityForButton(String name, boolean visible) { + final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); + final SharedPreferences.Editor editor = prefs.edit(); + editor.putBoolean(getConfigKeyForVisibility(name), visible); + editor.commit(); + } + private void clearTranslationForAllButtons() { final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); final SharedPreferences.Editor editor = prefs.edit(); @@ -91,7 +106,7 @@ public class TouchscreenControllerView extends FrameLayout { requestLayout(); } - private void reloadButtonTranslation() { + private void reloadButtonSettings() { final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); for (TouchscreenControllerButtonView buttonView : mButtonViews) { @@ -100,6 +115,9 @@ public class TouchscreenControllerView extends FrameLayout { buttonView.setTranslationY(prefs.getFloat(getConfigKeyForYTranslation(buttonView.getConfigName()), 0.0f)); //Log.i("TouchscreenController", String.format("Translation for %s %f %f", buttonView.getConfigName(), // buttonView.getTranslationX(), buttonView.getTranslationY())); + + final boolean visible = prefs.getBoolean(getConfigKeyForVisibility(buttonView.getConfigName()), buttonView.getDefaultVisibility()); + buttonView.setVisibility(visible ? VISIBLE : INVISIBLE); } catch (ClassCastException ex) { } @@ -109,12 +127,38 @@ public class TouchscreenControllerView extends FrameLayout { try { axisView.setTranslationX(prefs.getFloat(getConfigKeyForXTranslation(axisView.getConfigName()), 0.0f)); axisView.setTranslationY(prefs.getFloat(getConfigKeyForYTranslation(axisView.getConfigName()), 0.0f)); + + final boolean visible = prefs.getBoolean(getConfigKeyForVisibility(axisView.getConfigName()), axisView.getDefaultVisibility()); + axisView.setVisibility(visible ? VISIBLE : INVISIBLE); } catch (ClassCastException ex) { } } } + private void setOpacity(int opacity) { + final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); + final SharedPreferences.Editor editor = prefs.edit(); + editor.putInt("TouchscreenController/Opacity", opacity); + editor.commit(); + + updateOpacity(); + } + + private void updateOpacity() { + mOpacity = PreferenceManager.getDefaultSharedPreferences(getContext()).getInt("TouchscreenController/Opacity", DEFAULT_OPACITY); + + float alpha = (float)mOpacity / 100.0f; + alpha = (alpha < 0.0f) ? 0.0f : ((alpha > 1.0f) ? 1.0f : alpha); + + for (TouchscreenControllerButtonView buttonView : mButtonViews) { + buttonView.setAlpha(alpha); + } + for (TouchscreenControllerAxisView axisView : mAxisViews) { + axisView.setAlpha(alpha); + } + } + private String getOrientationString() { switch (getContext().getResources().getConfiguration().orientation) { case Configuration.ORIENTATION_PORTRAIT: @@ -135,7 +179,7 @@ public class TouchscreenControllerView extends FrameLayout { Log.i("TouchscreenController", "New orientation: " + newOrientation); mLayoutOrientation = newOrientation; - reloadButtonTranslation(); + reloadButtonSettings(); requestLayout(); } @@ -185,65 +229,71 @@ public class TouchscreenControllerView extends FrameLayout { SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext()); - linkButton(mMainView, R.id.controller_button_up, "UpButton", "Up"); - linkButton(mMainView, R.id.controller_button_right, "RightButton", "Right"); - linkButton(mMainView, R.id.controller_button_down, "DownButton", "Down"); - linkButton(mMainView, R.id.controller_button_left, "LeftButton", "Left"); - linkButton(mMainView, R.id.controller_button_l1, "L1Button", "L1"); - linkButton(mMainView, R.id.controller_button_l2, "L2Button", "L2"); - linkButton(mMainView, R.id.controller_button_select, "SelectButton", "Select"); - linkButton(mMainView, R.id.controller_button_start, "StartButton", "Start"); - linkButton(mMainView, R.id.controller_button_triangle, "TriangleButton", "Triangle"); - linkButton(mMainView, R.id.controller_button_circle, "CircleButton", "Circle"); - linkButton(mMainView, R.id.controller_button_cross, "CrossButton", "Cross"); - linkButton(mMainView, R.id.controller_button_square, "SquareButton", "Square"); - linkButton(mMainView, R.id.controller_button_r1, "R1Button", "R1"); - linkButton(mMainView, R.id.controller_button_r2, "R2Button", "R2"); + linkButton(mMainView, R.id.controller_button_up, "UpButton", "Up", true); + linkButton(mMainView, R.id.controller_button_right, "RightButton", "Right", true); + linkButton(mMainView, R.id.controller_button_down, "DownButton", "Down", true); + linkButton(mMainView, R.id.controller_button_left, "LeftButton", "Left", true); + linkButton(mMainView, R.id.controller_button_l1, "L1Button", "L1", true); + linkButton(mMainView, R.id.controller_button_l2, "L2Button", "L2", true); + linkButton(mMainView, R.id.controller_button_select, "SelectButton", "Select", true); + linkButton(mMainView, R.id.controller_button_start, "StartButton", "Start", true); + linkButton(mMainView, R.id.controller_button_triangle, "TriangleButton", "Triangle", true); + linkButton(mMainView, R.id.controller_button_circle, "CircleButton", "Circle", true); + linkButton(mMainView, R.id.controller_button_cross, "CrossButton", "Cross", true); + linkButton(mMainView, R.id.controller_button_square, "SquareButton", "Square", true); + linkButton(mMainView, R.id.controller_button_r1, "R1Button", "R1", true); + linkButton(mMainView, R.id.controller_button_r2, "R2Button", "R2", true); - if (!linkAxis(mMainView, R.id.controller_axis_left, "LeftAxis", "Left")) + if (!linkAxis(mMainView, R.id.controller_axis_left, "LeftAxis", "Left", true)) linkAxisToButtons(mMainView, R.id.controller_axis_left, "LeftAxis", ""); - linkAxis(mMainView, R.id.controller_axis_right, "RightAxis", "Right"); + linkAxis(mMainView, R.id.controller_axis_right, "RightAxis", "Right", true); - linkHotkeyButton(mMainView, R.id.controller_button_fast_forward, TouchscreenControllerButtonView.Hotkey.FAST_FORWARD); + linkHotkeyButton(mMainView, R.id.controller_button_fast_forward, "FastForward", + TouchscreenControllerButtonView.Hotkey.FAST_FORWARD, false); - reloadButtonTranslation(); + reloadButtonSettings(); + updateOpacity(); requestLayout(); } - private void linkButton(View view, int id, String configName, String buttonName) { + private void linkButton(View view, int id, String configName, String buttonName, boolean defaultVisibility) { TouchscreenControllerButtonView buttonView = (TouchscreenControllerButtonView) view.findViewById(id); if (buttonView == null) return; + buttonView.setConfigName(configName); + buttonView.setDefaultVisibility(defaultVisibility); + mButtonViews.add(buttonView); + int code = AndroidHostInterface.getControllerButtonCode(mControllerType, buttonName); Log.i("TouchscreenController", String.format("%s -> %d", buttonName, code)); if (code >= 0) { - buttonView.setConfigName(configName); buttonView.setButtonCode(mControllerIndex, code); buttonView.setHapticFeedback(mHapticFeedback); - mButtonViews.add(buttonView); } else { Log.e("TouchscreenController", String.format("Unknown button name '%s' " + "for '%s'", buttonName, mControllerType)); } } - private boolean linkAxis(View view, int id, String configName, String axisName) { + private boolean linkAxis(View view, int id, String configName, String axisName, boolean defaultVisibility) { TouchscreenControllerAxisView axisView = (TouchscreenControllerAxisView) view.findViewById(id); if (axisView == null) return false; + axisView.setConfigName(configName); + axisView.setDefaultVisibility(defaultVisibility); + mAxisViews.add(axisView); + int xCode = AndroidHostInterface.getControllerAxisCode(mControllerType, axisName + "X"); int yCode = AndroidHostInterface.getControllerAxisCode(mControllerType, axisName + "Y"); Log.i("TouchscreenController", String.format("%s -> %d/%d", axisName, xCode, yCode)); if (xCode < 0 && yCode < 0) return false; - axisView.setConfigName(configName); axisView.setControllerAxis(mControllerIndex, xCode, yCode); - mAxisViews.add(axisView); return true; } @@ -261,15 +311,16 @@ public class TouchscreenControllerView extends FrameLayout { return false; axisView.setControllerButtons(mControllerIndex, leftCode, rightCode, upCode, downCode); - mAxisViews.add(axisView); return true; } - private void linkHotkeyButton(View view, int id, TouchscreenControllerButtonView.Hotkey hotkey) { + private void linkHotkeyButton(View view, int id, String configName, TouchscreenControllerButtonView.Hotkey hotkey, boolean defaultVisibility) { TouchscreenControllerButtonView buttonView = (TouchscreenControllerButtonView) view.findViewById(id); if (buttonView == null) return; + buttonView.setConfigName(configName); + buttonView.setDefaultVisibility(defaultVisibility); buttonView.setHotkey(hotkey); mButtonViews.add(buttonView); } @@ -407,6 +458,9 @@ public class TouchscreenControllerView extends FrameLayout { final int pointerCount = event.getPointerCount(); final int liftedPointerIndex = (event.getActionMasked() == MotionEvent.ACTION_POINTER_UP) ? event.getActionIndex() : -1; for (TouchscreenControllerButtonView buttonView : mButtonViews) { + if (buttonView.getVisibility() != VISIBLE) + continue; + buttonView.getHitRect(rect); boolean pressed = false; for (int i = 0; i < pointerCount; i++) { @@ -427,6 +481,9 @@ public class TouchscreenControllerView extends FrameLayout { } for (TouchscreenControllerAxisView axisView : mAxisViews) { + if (axisView.getVisibility() != VISIBLE) + continue; + axisView.getHitRect(rect); boolean pressed = false; for (int i = 0; i < pointerCount; i++) { @@ -454,4 +511,67 @@ public class TouchscreenControllerView extends FrameLayout { return false; } + + public AlertDialog.Builder createAddRemoveButtonDialog(Context context) { + final AlertDialog.Builder builder = new AlertDialog.Builder(context); + final CharSequence[] items = new CharSequence[mButtonViews.size() + mAxisViews.size()]; + final boolean[] itemsChecked = new boolean[mButtonViews.size() + mAxisViews.size()]; + int itemCount = 0; + for (TouchscreenControllerButtonView buttonView : mButtonViews) { + items[itemCount] = buttonView.getConfigName(); + itemsChecked[itemCount] = buttonView.getVisibility() == VISIBLE; + itemCount++; + } + for (TouchscreenControllerAxisView axisView : mAxisViews) { + items[itemCount] = axisView.getConfigName(); + itemsChecked[itemCount] = axisView.getVisibility() == VISIBLE; + itemCount++; + } + + builder.setTitle(R.string.dialog_touchscreen_controller_buttons); + builder.setMultiChoiceItems(items, itemsChecked, (dialog, which, isChecked) -> { + if (which < mButtonViews.size()) { + TouchscreenControllerButtonView buttonView = mButtonViews.get(which); + buttonView.setVisibility(isChecked ? VISIBLE : INVISIBLE); + saveVisibilityForButton(buttonView.getConfigName(), isChecked); + } else { + TouchscreenControllerAxisView axisView = mAxisViews.get(which - mButtonViews.size()); + axisView.setVisibility(isChecked ? VISIBLE : INVISIBLE); + saveVisibilityForButton(axisView.getConfigName(), isChecked); + } + }); + builder.setNegativeButton(R.string.dialog_done, (dialog, which) -> { + dialog.dismiss(); + }); + + return builder; + } + + public AlertDialog.Builder createOpacityDialog(Context context) { + final SeekBar seekBar = new SeekBar(context); + seekBar.setMax(100); + seekBar.setProgress(mOpacity); + seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() { + @Override + public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { + setOpacity(progress); + } + + @Override + public void onStartTrackingTouch(SeekBar seekBar) { + } + + @Override + public void onStopTrackingTouch(SeekBar seekBar) { + } + }); + + final AlertDialog.Builder builder = new AlertDialog.Builder(context); + builder.setTitle(R.string.dialog_touchscreen_controller_opacity); + builder.setView(seekBar); + builder.setNegativeButton(R.string.dialog_done, (dialog, which) -> { + dialog.dismiss(); + }); + return builder; + } } diff --git a/android/app/src/main/res/values-es/arrays.xml b/android/app/src/main/res/values-es/arrays.xml index 1a9f28c8a..66161dfb6 100644 --- a/android/app/src/main/res/values-es/arrays.xml +++ b/android/app/src/main/res/values-es/arrays.xml @@ -91,7 +91,6 @@ Cambiar Disco Configuraciones Cambiar Control de Pantalla Tactil - Editar Diseño del Control de Pantalla Tactil Ninguno (Velocidad Doble) diff --git a/android/app/src/main/res/values-it/arrays.xml b/android/app/src/main/res/values-it/arrays.xml index 7b63ff217..6711f8d7f 100644 --- a/android/app/src/main/res/values-it/arrays.xml +++ b/android/app/src/main/res/values-it/arrays.xml @@ -91,7 +91,6 @@ Cambia Disco Impostazioni Cambia Controller Touchscreen - Edit Touchscreen Controller Layout Nessuna Velocità Doppia) diff --git a/android/app/src/main/res/values-nl/arrays.xml b/android/app/src/main/res/values-nl/arrays.xml index c9743250c..79054a0ce 100644 --- a/android/app/src/main/res/values-nl/arrays.xml +++ b/android/app/src/main/res/values-nl/arrays.xml @@ -91,7 +91,6 @@ Disc Veranderen Instellingen Touchscreen Controller Aanpassen - Edit Touchscreen Controller Layout Geen (Dubbele Snelheid) diff --git a/android/app/src/main/res/values-pt-rBR/arrays.xml b/android/app/src/main/res/values-pt-rBR/arrays.xml index 3beed2aef..5cce064f6 100644 --- a/android/app/src/main/res/values-pt-rBR/arrays.xml +++ b/android/app/src/main/res/values-pt-rBR/arrays.xml @@ -91,7 +91,6 @@ Mudar Disco Configurações Mudar controle em Tela - Editar Posição dos Controles (Tela) Nenhum diff --git a/android/app/src/main/res/values-ru/arrays.xml b/android/app/src/main/res/values-ru/arrays.xml index 6529fadad..6b312aa84 100644 --- a/android/app/src/main/res/values-ru/arrays.xml +++ b/android/app/src/main/res/values-ru/arrays.xml @@ -91,7 +91,6 @@ Сменить диск Настройки Сменить экранный контроллер - Настроить экранный контроллер Нет (двойная скорость) diff --git a/android/app/src/main/res/values/arrays.xml b/android/app/src/main/res/values/arrays.xml index 8bba1c7de..36b118362 100644 --- a/android/app/src/main/res/values/arrays.xml +++ b/android/app/src/main/res/values/arrays.xml @@ -168,9 +168,14 @@ Reset Patch Codes Change Disc - Settings Change Touchscreen Controller - Edit Touchscreen Controller Layout + Settings + + + Change Type + Change Opacity + Add/Remove Buttons + Edit Layout None (Double Speed) diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml index 85af77edd..7e51c20e1 100644 --- a/android/app/src/main/res/values/strings.xml +++ b/android/app/src/main/res/values/strings.xml @@ -221,4 +221,8 @@ CPU Settings GPU Settings Logging Settings + Done + Touchscreen Controller Type + Touchscreen Controller Opacity + Touchscreen Controller Buttons