mirror of
				https://git.tardis.systems/mirrors/yuzu
				synced 2025-10-31 18:54:14 +01:00 
			
		
		
		
	android: Enable overlay scale/opacity dialog
This commit is contained in:
		
							parent
							
								
									1957b7e6cc
								
							
						
					
					
						commit
						ca4b07a2d7
					
				| @ -252,39 +252,6 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener { | ||||
|                 View.SYSTEM_UI_FLAG_IMMERSIVE | ||||
|     } | ||||
| 
 | ||||
|     private fun editControlsPlacement() { | ||||
|         if (emulationFragment!!.isConfiguringControls) { | ||||
|             emulationFragment!!.stopConfiguringControls() | ||||
|         } else { | ||||
|             emulationFragment!!.startConfiguringControls() | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     private fun adjustScale() { | ||||
|         val sliderBinding = DialogSliderBinding.inflate(layoutInflater) | ||||
|         sliderBinding.slider.valueTo = 150F | ||||
|         sliderBinding.slider.value = | ||||
|             PreferenceManager.getDefaultSharedPreferences(applicationContext) | ||||
|                 .getInt(Settings.PREF_CONTROL_SCALE, 50).toFloat() | ||||
|         sliderBinding.slider.addOnChangeListener(OnChangeListener { _, value, _ -> | ||||
|             sliderBinding.textValue.text = value.toString() | ||||
|             setControlScale(value.toInt()) | ||||
|         }) | ||||
|         sliderBinding.textValue.text = sliderBinding.slider.value.toString() | ||||
|         sliderBinding.textUnits.text = "%" | ||||
|         MaterialAlertDialogBuilder(this) | ||||
|             .setTitle(R.string.emulation_control_scale) | ||||
|             .setView(sliderBinding.root) | ||||
|             .setNegativeButton(android.R.string.cancel, null) | ||||
|             .setPositiveButton(android.R.string.ok) { _: DialogInterface?, _: Int -> | ||||
|                 setControlScale(sliderBinding.slider.value.toInt()) | ||||
|             } | ||||
|             .setNeutralButton(R.string.slider_default) { _: DialogInterface?, _: Int -> | ||||
|                 setControlScale(50) | ||||
|             } | ||||
|             .show() | ||||
|     } | ||||
| 
 | ||||
|     private fun startMotionSensorListener() { | ||||
|         val sensorManager = this.getSystemService(Context.SENSOR_SERVICE) as SensorManager | ||||
|         val gyroSensor = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE) | ||||
| @ -302,22 +269,6 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener { | ||||
|         sensorManager.unregisterListener(this, accelSensor) | ||||
|     } | ||||
| 
 | ||||
|     private fun setControlScale(scale: Int) { | ||||
|         PreferenceManager.getDefaultSharedPreferences(applicationContext).edit() | ||||
|             .putInt(Settings.PREF_CONTROL_SCALE, scale) | ||||
|             .apply() | ||||
|         emulationFragment!!.refreshInputOverlay() | ||||
|     } | ||||
| 
 | ||||
|     private fun resetOverlay() { | ||||
|         MaterialAlertDialogBuilder(this) | ||||
|             .setTitle(getString(R.string.emulation_touch_overlay_reset)) | ||||
|             .setPositiveButton(android.R.string.ok) { _: DialogInterface?, _: Int -> emulationFragment!!.resetInputOverlay() } | ||||
|             .setNegativeButton(android.R.string.cancel, null) | ||||
|             .create() | ||||
|             .show() | ||||
|     } | ||||
| 
 | ||||
|     companion object { | ||||
|         const val EXTRA_SELECTED_GAME = "SelectedGame" | ||||
| 
 | ||||
|  | ||||
| @ -111,6 +111,7 @@ class Settings { | ||||
| 
 | ||||
|         const val PREF_OVERLAY_INIT = "OverlayInit" | ||||
|         const val PREF_CONTROL_SCALE = "controlScale" | ||||
|         const val PREF_CONTROL_OPACITY = "controlOpacity" | ||||
|         const val PREF_TOUCH_ENABLED = "isTouchEnabled" | ||||
|         const val PREF_BUTTON_TOGGLE_0 = "buttonToggle0" | ||||
|         const val PREF_BUTTON_TOGGLE_1 = "buttonToggle1" | ||||
|  | ||||
| @ -3,8 +3,10 @@ | ||||
| 
 | ||||
| package org.yuzu.yuzu_emu.fragments | ||||
| 
 | ||||
| import android.annotation.SuppressLint | ||||
| import android.app.AlertDialog | ||||
| import android.content.Context | ||||
| import android.content.DialogInterface | ||||
| import android.content.SharedPreferences | ||||
| import android.graphics.Color | ||||
| import android.os.Bundle | ||||
| @ -21,10 +23,12 @@ import androidx.core.view.WindowInsetsCompat | ||||
| import androidx.fragment.app.Fragment | ||||
| import androidx.preference.PreferenceManager | ||||
| import com.google.android.material.dialog.MaterialAlertDialogBuilder | ||||
| import com.google.android.material.slider.Slider | ||||
| import org.yuzu.yuzu_emu.NativeLibrary | ||||
| import org.yuzu.yuzu_emu.R | ||||
| import org.yuzu.yuzu_emu.YuzuApplication | ||||
| import org.yuzu.yuzu_emu.activities.EmulationActivity | ||||
| import org.yuzu.yuzu_emu.databinding.DialogOverlayAdjustBinding | ||||
| import org.yuzu.yuzu_emu.databinding.FragmentEmulationBinding | ||||
| import org.yuzu.yuzu_emu.features.settings.model.Settings | ||||
| import org.yuzu.yuzu_emu.features.settings.ui.SettingsActivity | ||||
| @ -168,14 +172,14 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { | ||||
|         super.onDetach() | ||||
|     } | ||||
| 
 | ||||
|     fun refreshInputOverlay() { | ||||
|     private fun refreshInputOverlay() { | ||||
|         binding.surfaceInputOverlay.refreshControls() | ||||
|     } | ||||
| 
 | ||||
|     fun resetInputOverlay() { | ||||
|         // Reset button scale | ||||
|     private fun resetInputOverlay() { | ||||
|         preferences.edit() | ||||
|             .putInt(Settings.PREF_CONTROL_SCALE, 50) | ||||
|             .remove(Settings.PREF_CONTROL_SCALE) | ||||
|             .remove(Settings.PREF_CONTROL_OPACITY) | ||||
|             .apply() | ||||
|         binding.surfaceInputOverlay.post { binding.surfaceInputOverlay.resetButtonPlacement() } | ||||
|     } | ||||
| @ -251,6 +255,11 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { | ||||
|                     true | ||||
|                 } | ||||
| 
 | ||||
|                 R.id.menu_adjust_overlay -> { | ||||
|                     adjustOverlay() | ||||
|                     true | ||||
|                 } | ||||
| 
 | ||||
|                 R.id.menu_toggle_controls -> { | ||||
|                     val preferences = | ||||
|                         PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext) | ||||
| @ -278,9 +287,9 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { | ||||
|                     // Override normal behaviour so the dialog doesn't close | ||||
|                     dialog.getButton(AlertDialog.BUTTON_NEUTRAL) | ||||
|                         .setOnClickListener { | ||||
|                             val isChecked = !optionsArray[0]; | ||||
|                             val isChecked = !optionsArray[0] | ||||
|                             for (i in 0..14) { | ||||
|                                 optionsArray[i] = isChecked; | ||||
|                                 optionsArray[i] = isChecked | ||||
|                                 dialog.listView.setItemChecked(i, isChecked) | ||||
|                                 preferences.edit() | ||||
|                                     .putBoolean("buttonToggle$i", isChecked) | ||||
| @ -328,18 +337,64 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback { | ||||
|         popup.show() | ||||
|     } | ||||
| 
 | ||||
|     fun startConfiguringControls() { | ||||
|     private fun startConfiguringControls() { | ||||
|         binding.doneControlConfig.visibility = View.VISIBLE | ||||
|         binding.surfaceInputOverlay.setIsInEditMode(true) | ||||
|     } | ||||
| 
 | ||||
|     fun stopConfiguringControls() { | ||||
|     private fun stopConfiguringControls() { | ||||
|         binding.doneControlConfig.visibility = View.GONE | ||||
|         binding.surfaceInputOverlay.setIsInEditMode(false) | ||||
|     } | ||||
| 
 | ||||
|     val isConfiguringControls: Boolean | ||||
|         get() = binding.surfaceInputOverlay.isInEditMode | ||||
|     @SuppressLint("SetTextI18n") | ||||
|     private fun adjustOverlay() { | ||||
|         val adjustBinding = DialogOverlayAdjustBinding.inflate(layoutInflater) | ||||
|         adjustBinding.apply { | ||||
|             inputScaleSlider.apply { | ||||
|                 valueTo = 150F | ||||
|                 value = preferences.getInt(Settings.PREF_CONTROL_SCALE, 50).toFloat() | ||||
|                 addOnChangeListener(Slider.OnChangeListener { _, value, _ -> | ||||
|                     inputScaleValue.text = "${value.toInt()}%" | ||||
|                     setControlScale(value.toInt()) | ||||
|                 }) | ||||
|             } | ||||
|             inputOpacitySlider.apply { | ||||
|                 valueTo = 100F | ||||
|                 value = preferences.getInt(Settings.PREF_CONTROL_OPACITY, 100).toFloat() | ||||
|                 addOnChangeListener(Slider.OnChangeListener { _, value, _ -> | ||||
|                     inputOpacityValue.text = "${value.toInt()}%" | ||||
|                     setControlOpacity(value.toInt()) | ||||
|                 }) | ||||
|             } | ||||
|             inputScaleValue.text = "${inputScaleSlider.value.toInt()}%" | ||||
|             inputOpacityValue.text = "${inputOpacitySlider.value.toInt()}%" | ||||
|         } | ||||
| 
 | ||||
|         MaterialAlertDialogBuilder(requireContext()) | ||||
|             .setTitle(R.string.emulation_control_adjust) | ||||
|             .setView(adjustBinding.root) | ||||
|             .setPositiveButton(android.R.string.ok, null) | ||||
|             .setNeutralButton(R.string.slider_default) { _: DialogInterface?, _: Int -> | ||||
|                 setControlScale(50) | ||||
|                 setControlOpacity(100) | ||||
|             } | ||||
|             .show() | ||||
|     } | ||||
| 
 | ||||
|     private fun setControlScale(scale: Int) { | ||||
|         preferences.edit() | ||||
|             .putInt(Settings.PREF_CONTROL_SCALE, scale) | ||||
|             .apply() | ||||
|         refreshInputOverlay() | ||||
|     } | ||||
| 
 | ||||
|     private fun setControlOpacity(opacity: Int) { | ||||
|         preferences.edit() | ||||
|             .putInt(Settings.PREF_CONTROL_OPACITY, opacity) | ||||
|             .apply() | ||||
|         refreshInputOverlay() | ||||
|     } | ||||
| 
 | ||||
|     private fun setInsets() { | ||||
|         ViewCompat.setOnApplyWindowInsetsListener(binding.inGameMenu) { v: View, windowInsets: WindowInsetsCompat -> | ||||
|  | ||||
| @ -49,9 +49,6 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context | ||||
|     private var dpadBeingConfigured: InputOverlayDrawableDpad? = null | ||||
|     private var joystickBeingConfigured: InputOverlayDrawableJoystick? = null | ||||
| 
 | ||||
|     private val preferences: SharedPreferences = | ||||
|         PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext) | ||||
| 
 | ||||
|     private lateinit var windowInsets: WindowInsets | ||||
| 
 | ||||
|     override fun onLayout(changed: Boolean, left: Int, top: Int, right: Int, bottom: Int) { | ||||
| @ -709,6 +706,9 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context | ||||
|     } | ||||
| 
 | ||||
|     companion object { | ||||
|         private val preferences: SharedPreferences = | ||||
|             PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext) | ||||
| 
 | ||||
|         /** | ||||
|          * Resizes a [Bitmap] by a given scale factor | ||||
|          * | ||||
| @ -899,6 +899,8 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context | ||||
|                 drawableX - (width / 2), | ||||
|                 drawableY - (height / 2) | ||||
|             ) | ||||
|             val savedOpacity = preferences.getInt(Settings.PREF_CONTROL_OPACITY, 100) | ||||
|             overlayDrawable.setOpacity(savedOpacity * 255 / 100) | ||||
|             return overlayDrawable | ||||
|         } | ||||
| 
 | ||||
| @ -973,6 +975,8 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context | ||||
| 
 | ||||
|             // Need to set the image's position | ||||
|             overlayDrawable.setPosition(drawableX - (width / 2), drawableY - (height / 2)) | ||||
|             val savedOpacity = preferences.getInt(Settings.PREF_CONTROL_OPACITY, 100) | ||||
|             overlayDrawable.setOpacity(savedOpacity * 255 / 100) | ||||
|             return overlayDrawable | ||||
|         } | ||||
| 
 | ||||
| @ -1052,6 +1056,8 @@ class InputOverlay(context: Context, attrs: AttributeSet?) : SurfaceView(context | ||||
| 
 | ||||
|             // Need to set the image's position | ||||
|             overlayDrawable.setPosition(drawableX, drawableY) | ||||
|             val savedOpacity = preferences.getInt(Settings.PREF_CONTROL_OPACITY, 100) | ||||
|             overlayDrawable.setOpacity(savedOpacity * 255 / 100) | ||||
|             return overlayDrawable | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -114,6 +114,7 @@ class InputOverlayDrawableButton( | ||||
|                 controlPositionX = fingerPositionX - (width / 2) | ||||
|                 controlPositionY = fingerPositionY - (height / 2) | ||||
|             } | ||||
| 
 | ||||
|             MotionEvent.ACTION_MOVE -> { | ||||
|                 controlPositionX += fingerPositionX - previousTouchX | ||||
|                 controlPositionY += fingerPositionY - previousTouchY | ||||
| @ -135,6 +136,11 @@ class InputOverlayDrawableButton( | ||||
|         pressedStateBitmap.setBounds(left, top, right, bottom) | ||||
|     } | ||||
| 
 | ||||
|     fun setOpacity(value: Int) { | ||||
|         defaultStateBitmap.alpha = value | ||||
|         pressedStateBitmap.alpha = value | ||||
|     } | ||||
| 
 | ||||
|     val status: Int | ||||
|         get() = if (pressedState) ButtonState.PRESSED else ButtonState.RELEASED | ||||
|     val bounds: Rect | ||||
|  | ||||
| @ -231,6 +231,7 @@ class InputOverlayDrawableDpad( | ||||
|                 previousTouchX = fingerPositionX | ||||
|                 previousTouchY = fingerPositionY | ||||
|             } | ||||
| 
 | ||||
|             MotionEvent.ACTION_MOVE -> { | ||||
|                 controlPositionX += fingerPositionX - previousTouchX | ||||
|                 controlPositionY += fingerPositionY - previousTouchY | ||||
| @ -258,6 +259,12 @@ class InputOverlayDrawableDpad( | ||||
|         pressedTwoDirectionsStateBitmap.setBounds(left, top, right, bottom) | ||||
|     } | ||||
| 
 | ||||
|     fun setOpacity(value: Int) { | ||||
|         defaultStateBitmap.alpha = value | ||||
|         pressedOneDirectionStateBitmap.alpha = value | ||||
|         pressedTwoDirectionsStateBitmap.alpha = value | ||||
|     } | ||||
| 
 | ||||
|     val bounds: Rect | ||||
|         get() = defaultStateBitmap.bounds | ||||
| 
 | ||||
|  | ||||
| @ -48,6 +48,8 @@ class InputOverlayDrawableJoystick( | ||||
|     val width: Int | ||||
|     val height: Int | ||||
| 
 | ||||
|     private var opacity: Int = 0 | ||||
| 
 | ||||
|     private var virtBounds: Rect | ||||
|     private var origBounds: Rect | ||||
| 
 | ||||
| @ -121,7 +123,7 @@ class InputOverlayDrawableJoystick( | ||||
|             } | ||||
|             pressedState = true | ||||
|             outerBitmap.alpha = 0 | ||||
|             boundsBoxBitmap.alpha = 255 | ||||
|             boundsBoxBitmap.alpha = opacity | ||||
|             if (EmulationMenuSettings.joystickRelCenter) { | ||||
|                 virtBounds.offset( | ||||
|                     xPosition - virtBounds.centerX(), | ||||
| @ -139,7 +141,7 @@ class InputOverlayDrawableJoystick( | ||||
|             pressedState = false | ||||
|             xAxis = 0.0f | ||||
|             yAxis = 0.0f | ||||
|             outerBitmap.alpha = 255 | ||||
|             outerBitmap.alpha = opacity | ||||
|             boundsBoxBitmap.alpha = 0 | ||||
|             virtBounds = Rect( | ||||
|                 origBounds.left, | ||||
| @ -203,6 +205,7 @@ class InputOverlayDrawableJoystick( | ||||
|                 controlPositionX = fingerPositionX - (width / 2) | ||||
|                 controlPositionY = fingerPositionY - (height / 2) | ||||
|             } | ||||
| 
 | ||||
|             MotionEvent.ACTION_MOVE -> { | ||||
|                 controlPositionX += fingerPositionX - previousTouchX | ||||
|                 controlPositionY += fingerPositionY - previousTouchY | ||||
| @ -261,4 +264,19 @@ class InputOverlayDrawableJoystick( | ||||
|         controlPositionX = x | ||||
|         controlPositionY = y | ||||
|     } | ||||
| 
 | ||||
|     fun setOpacity(value: Int) { | ||||
|         opacity = value | ||||
| 
 | ||||
|         defaultStateInnerBitmap.alpha = value | ||||
|         pressedStateInnerBitmap.alpha = value | ||||
| 
 | ||||
|         if (trackId == -1) { | ||||
|             outerBitmap.alpha = value | ||||
|             boundsBoxBitmap.alpha = 0 | ||||
|         } else { | ||||
|             outerBitmap.alpha = 0 | ||||
|             boundsBoxBitmap.alpha = value | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -0,0 +1,67 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <androidx.constraintlayout.widget.ConstraintLayout | ||||
|     xmlns:android="http://schemas.android.com/apk/res/android" | ||||
|     xmlns:tools="http://schemas.android.com/tools" | ||||
|     xmlns:app="http://schemas.android.com/apk/res-auto" | ||||
|     android:layout_width="match_parent" | ||||
|     android:layout_height="match_parent"> | ||||
| 
 | ||||
|     <TextView | ||||
|         android:id="@+id/input_scale_name" | ||||
|         android:layout_width="wrap_content" | ||||
|         android:layout_height="wrap_content" | ||||
|         android:layout_marginTop="16dp" | ||||
|         android:text="@string/emulation_control_scale" | ||||
|         android:textAlignment="viewStart" | ||||
|         android:textSize="16sp" | ||||
|         app:layout_constraintStart_toStartOf="@+id/input_scale_slider" | ||||
|         app:layout_constraintTop_toTopOf="parent" /> | ||||
| 
 | ||||
|     <com.google.android.material.slider.Slider | ||||
|         android:id="@+id/input_scale_slider" | ||||
|         android:layout_width="0dp" | ||||
|         android:layout_height="wrap_content" | ||||
|         android:layout_marginHorizontal="24dp" | ||||
|         app:layout_constraintEnd_toEndOf="parent" | ||||
|         app:layout_constraintStart_toStartOf="parent" | ||||
|         app:layout_constraintTop_toBottomOf="@+id/input_scale_name" /> | ||||
| 
 | ||||
|     <TextView | ||||
|         android:id="@+id/input_scale_value" | ||||
|         android:layout_width="wrap_content" | ||||
|         android:layout_height="wrap_content" | ||||
|         android:gravity="end" | ||||
|         app:layout_constraintBottom_toTopOf="@+id/input_scale_slider" | ||||
|         app:layout_constraintEnd_toEndOf="@+id/input_scale_slider" | ||||
|         tools:text="100%" /> | ||||
| 
 | ||||
|     <TextView | ||||
|         android:id="@+id/input_opacity_name" | ||||
|         android:layout_width="wrap_content" | ||||
|         android:layout_height="wrap_content" | ||||
|         android:layout_marginTop="16dp" | ||||
|         android:text="@string/emulation_control_opacity" | ||||
|         android:textAlignment="viewStart" | ||||
|         android:textSize="16sp" | ||||
|         app:layout_constraintStart_toStartOf="@+id/input_opacity_slider" | ||||
|         app:layout_constraintTop_toBottomOf="@+id/input_scale_slider" /> | ||||
| 
 | ||||
|     <com.google.android.material.slider.Slider | ||||
|         android:id="@+id/input_opacity_slider" | ||||
|         android:layout_width="0dp" | ||||
|         android:layout_height="wrap_content" | ||||
|         android:layout_marginHorizontal="24dp" | ||||
|         app:layout_constraintEnd_toEndOf="parent" | ||||
|         app:layout_constraintStart_toStartOf="parent" | ||||
|         app:layout_constraintTop_toBottomOf="@+id/input_opacity_name" /> | ||||
| 
 | ||||
|     <TextView | ||||
|         android:id="@+id/input_opacity_value" | ||||
|         android:layout_width="wrap_content" | ||||
|         android:layout_height="wrap_content" | ||||
|         android:gravity="end" | ||||
|         app:layout_constraintBottom_toTopOf="@+id/input_opacity_slider" | ||||
|         app:layout_constraintEnd_toEndOf="@+id/input_opacity_slider" | ||||
|         tools:text="100%" /> | ||||
| 
 | ||||
| </androidx.constraintlayout.widget.ConstraintLayout> | ||||
| @ -10,6 +10,10 @@ | ||||
|         android:id="@+id/menu_edit_overlay" | ||||
|         android:title="@string/emulation_touch_overlay_edit" /> | ||||
| 
 | ||||
|     <item | ||||
|         android:id="@+id/menu_adjust_overlay" | ||||
|         android:title="@string/emulation_control_adjust" /> | ||||
| 
 | ||||
|     <item | ||||
|         android:id="@+id/menu_toggle_controls" | ||||
|         android:title="@string/emulation_toggle_controls" /> | ||||
|  | ||||
| @ -204,7 +204,9 @@ | ||||
|     <string name="emulation_haptics">Haptics</string> | ||||
|     <string name="emulation_show_overlay">Show Overlay</string> | ||||
|     <string name="emulation_toggle_all">Toggle All</string> | ||||
|     <string name="emulation_control_scale">Adjust Scale</string> | ||||
|     <string name="emulation_control_adjust">Adjust Overlay</string> | ||||
|     <string name="emulation_control_scale">Scale</string> | ||||
|     <string name="emulation_control_opacity">Opacity</string> | ||||
|     <string name="emulation_touch_overlay_reset">Reset Overlay</string> | ||||
|     <string name="emulation_touch_overlay_edit">Edit Overlay</string> | ||||
|     <string name="emulation_pause">Pause Emulation</string> | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user