android: Properly adjust emulation surface aspect ratio
Previously the emulation surface wouldn't respond properly to orientation changes. This would result in the screen appearing stretched when starting in one orientation and switching to another. The code for calculating the bounds of the view have been changed to match the expected behavior now. Before the view would just match parent in height and width. Now instead of using setLeftTopRightBottom (which is intended to be used for animations) we pass newly calculated bounds for the view into super. Now the view bounds match the emulation output. This also means that we don't need the overload for the SettingsActivity to launch it using an ActivityResultLauncher. We can just update the view in onResume.
This commit is contained in:
parent
6c4abd23be
commit
338d6f29b1
|
@ -11,7 +11,6 @@ import android.view.View
|
||||||
import android.view.ViewGroup.MarginLayoutParams
|
import android.view.ViewGroup.MarginLayoutParams
|
||||||
import android.widget.Toast
|
import android.widget.Toast
|
||||||
import androidx.activity.OnBackPressedCallback
|
import androidx.activity.OnBackPressedCallback
|
||||||
import androidx.activity.result.ActivityResultLauncher
|
|
||||||
import androidx.activity.viewModels
|
import androidx.activity.viewModels
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import androidx.core.view.ViewCompat
|
import androidx.core.view.ViewCompat
|
||||||
|
@ -246,17 +245,5 @@ class SettingsActivity : AppCompatActivity(), SettingsActivityView {
|
||||||
settings.putExtra(ARG_GAME_ID, gameId)
|
settings.putExtra(ARG_GAME_ID, gameId)
|
||||||
context.startActivity(settings)
|
context.startActivity(settings)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun launch(
|
|
||||||
context: Context,
|
|
||||||
launcher: ActivityResultLauncher<Intent>,
|
|
||||||
menuTag: String?,
|
|
||||||
gameId: String?
|
|
||||||
) {
|
|
||||||
val settings = Intent(context, SettingsActivity::class.java)
|
|
||||||
settings.putExtra(ARG_MENU_TAG, menuTag)
|
|
||||||
settings.putExtra(ARG_GAME_ID, gameId)
|
|
||||||
launcher.launch(settings)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ import android.annotation.SuppressLint
|
||||||
import android.app.AlertDialog
|
import android.app.AlertDialog
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.DialogInterface
|
import android.content.DialogInterface
|
||||||
import android.content.Intent
|
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import android.content.pm.ActivityInfo
|
import android.content.pm.ActivityInfo
|
||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
|
@ -19,8 +18,6 @@ import android.util.Rational
|
||||||
import android.view.*
|
import android.view.*
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import androidx.activity.OnBackPressedCallback
|
import androidx.activity.OnBackPressedCallback
|
||||||
import androidx.activity.result.ActivityResultLauncher
|
|
||||||
import androidx.activity.result.contract.ActivityResultContracts
|
|
||||||
import androidx.appcompat.widget.PopupMenu
|
import androidx.appcompat.widget.PopupMenu
|
||||||
import androidx.core.content.res.ResourcesCompat
|
import androidx.core.content.res.ResourcesCompat
|
||||||
import androidx.core.graphics.Insets
|
import androidx.core.graphics.Insets
|
||||||
|
@ -66,8 +63,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||||
|
|
||||||
private var isInFoldableLayout = false
|
private var isInFoldableLayout = false
|
||||||
|
|
||||||
private lateinit var onReturnFromSettings: ActivityResultLauncher<Intent>
|
|
||||||
|
|
||||||
override fun onAttach(context: Context) {
|
override fun onAttach(context: Context) {
|
||||||
super.onAttach(context)
|
super.onAttach(context)
|
||||||
if (context is EmulationActivity) {
|
if (context is EmulationActivity) {
|
||||||
|
@ -81,11 +76,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||||
.collect { updateFoldableLayout(context, it) }
|
.collect { updateFoldableLayout(context, it) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onReturnFromSettings = context.activityResultRegistry.register(
|
|
||||||
"SettingsResult",
|
|
||||||
ActivityResultContracts.StartActivityForResult()
|
|
||||||
) { updateScreenLayout() }
|
|
||||||
} else {
|
} else {
|
||||||
throw IllegalStateException("EmulationFragment must have EmulationActivity parent")
|
throw IllegalStateException("EmulationFragment must have EmulationActivity parent")
|
||||||
}
|
}
|
||||||
|
@ -149,12 +139,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
|
||||||
}
|
}
|
||||||
|
|
||||||
R.id.menu_settings -> {
|
R.id.menu_settings -> {
|
||||||
SettingsActivity.launch(
|
SettingsActivity.launch(requireContext(), SettingsFile.FILE_NAME_CONFIG, "")
|
||||||
requireContext(),
|
|
||||||
onReturnFromSettings,
|
|
||||||
SettingsFile.FILE_NAME_CONFIG,
|
|
||||||
""
|
|
||||||
)
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,6 @@ import android.content.Context
|
||||||
import android.util.AttributeSet
|
import android.util.AttributeSet
|
||||||
import android.util.Rational
|
import android.util.Rational
|
||||||
import android.view.SurfaceView
|
import android.view.SurfaceView
|
||||||
import kotlin.math.roundToInt
|
|
||||||
|
|
||||||
class FixedRatioSurfaceView @JvmOverloads constructor(
|
class FixedRatioSurfaceView @JvmOverloads constructor(
|
||||||
context: Context,
|
context: Context,
|
||||||
|
@ -22,27 +21,44 @@ class FixedRatioSurfaceView @JvmOverloads constructor(
|
||||||
*/
|
*/
|
||||||
fun setAspectRatio(ratio: Rational?) {
|
fun setAspectRatio(ratio: Rational?) {
|
||||||
aspectRatio = ratio?.toFloat() ?: 0f
|
aspectRatio = ratio?.toFloat() ?: 0f
|
||||||
|
requestLayout()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
|
override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
|
||||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
|
val displayWidth: Float = MeasureSpec.getSize(widthMeasureSpec).toFloat()
|
||||||
val width = MeasureSpec.getSize(widthMeasureSpec)
|
val displayHeight: Float = MeasureSpec.getSize(heightMeasureSpec).toFloat()
|
||||||
val height = MeasureSpec.getSize(heightMeasureSpec)
|
|
||||||
if (aspectRatio != 0f) {
|
if (aspectRatio != 0f) {
|
||||||
val newWidth: Int
|
val displayAspect = displayWidth / displayHeight
|
||||||
val newHeight: Int
|
if (displayAspect < aspectRatio) {
|
||||||
if (height * aspectRatio < width) {
|
// Max out width
|
||||||
newWidth = (height * aspectRatio).roundToInt()
|
val halfHeight = displayHeight / 2
|
||||||
newHeight = height
|
val surfaceHeight = displayWidth / aspectRatio
|
||||||
|
val newTop: Float = halfHeight - (surfaceHeight / 2)
|
||||||
|
val newBottom: Float = halfHeight + (surfaceHeight / 2)
|
||||||
|
super.onMeasure(
|
||||||
|
widthMeasureSpec,
|
||||||
|
MeasureSpec.makeMeasureSpec(
|
||||||
|
newBottom.toInt() - newTop.toInt(),
|
||||||
|
MeasureSpec.EXACTLY
|
||||||
|
)
|
||||||
|
)
|
||||||
|
return
|
||||||
} else {
|
} else {
|
||||||
newWidth = width
|
// Max out height
|
||||||
newHeight = (width / aspectRatio).roundToInt()
|
val halfWidth = displayWidth / 2
|
||||||
}
|
val surfaceWidth = displayHeight * aspectRatio
|
||||||
val left = (width - newWidth) / 2
|
val newLeft: Float = halfWidth - (surfaceWidth / 2)
|
||||||
val top = (height - newHeight) / 2
|
val newRight: Float = halfWidth + (surfaceWidth / 2)
|
||||||
setLeftTopRightBottom(left, top, left + newWidth, top + newHeight)
|
super.onMeasure(
|
||||||
} else {
|
MeasureSpec.makeMeasureSpec(
|
||||||
setLeftTopRightBottom(0, 0, width, height)
|
newRight.toInt() - newLeft.toInt(),
|
||||||
|
MeasureSpec.EXACTLY
|
||||||
|
),
|
||||||
|
heightMeasureSpec
|
||||||
|
)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
super.onMeasure(widthMeasureSpec, heightMeasureSpec)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Reference in New Issue