mirror of
https://github.com/yairm210/Unciv.git
synced 2025-02-23 21:22:39 +07:00
158 lines
5.8 KiB
Kotlin
158 lines
5.8 KiB
Kotlin
package com.unciv.app
|
|
|
|
import android.content.pm.ActivityInfo
|
|
import android.os.Build
|
|
import android.view.Display
|
|
import android.view.Display.Mode
|
|
import android.view.View
|
|
import android.view.WindowManager
|
|
import androidx.annotation.RequiresApi
|
|
import com.badlogic.gdx.backends.android.AndroidApplication
|
|
import com.unciv.models.metadata.GameSettings
|
|
import com.unciv.models.translations.tr
|
|
import com.unciv.utils.PlatformDisplay
|
|
import com.unciv.utils.ScreenMode
|
|
import com.unciv.utils.ScreenOrientation
|
|
|
|
|
|
class AndroidDisplay(private val activity: AndroidApplication) : PlatformDisplay {
|
|
|
|
private var display: Display? = null
|
|
private var displayModes: HashMap<Int, ScreenMode> = hashMapOf()
|
|
|
|
init {
|
|
|
|
// Fetch current display
|
|
@Suppress("DEPRECATION") // M..P should use the deprecated API
|
|
display = when {
|
|
Build.VERSION.SDK_INT >= Build.VERSION_CODES.R -> activity.display
|
|
Build.VERSION.SDK_INT >= Build.VERSION_CODES.M -> activity.windowManager.defaultDisplay
|
|
else -> null
|
|
}
|
|
|
|
// Add default mode
|
|
displayModes[AndroidScreenMode.defaultId] = AndroidScreenMode.default
|
|
|
|
// Add other supported modes
|
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
|
|
fetchScreenModes()
|
|
}
|
|
|
|
@RequiresApi(Build.VERSION_CODES.M)
|
|
private fun fetchScreenModes() {
|
|
val display = display ?: return
|
|
for (mode in display.supportedModes)
|
|
displayModes[mode.modeId] = AndroidScreenMode(mode)
|
|
}
|
|
|
|
override fun getScreenModes(): Map<Int, ScreenMode> {
|
|
return displayModes
|
|
}
|
|
|
|
override fun setScreenMode(id: Int, settings: GameSettings) {
|
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) return
|
|
activity.runOnUiThread {
|
|
val params = activity.window.attributes
|
|
params.preferredDisplayModeId = id
|
|
activity.window.attributes = params
|
|
}
|
|
}
|
|
|
|
override fun hasSystemUiVisibility() = true
|
|
|
|
override fun setSystemUiVisibility(hide: Boolean) {
|
|
activity.runOnUiThread {
|
|
setSystemUiVisibilityFromUiThread(hide)
|
|
}
|
|
}
|
|
internal fun setSystemUiVisibilityFromUiThread(hide: Boolean) {
|
|
@Suppress("DEPRECATION") // Avoids @RequiresApi(Build.VERSION_CODES.R)
|
|
activity.window.decorView.systemUiVisibility =
|
|
if (hide)
|
|
View.SYSTEM_UI_FLAG_LAYOUT_STABLE or
|
|
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or
|
|
View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or View.SYSTEM_UI_FLAG_FULLSCREEN or
|
|
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
|
|
else
|
|
View.SYSTEM_UI_FLAG_LAYOUT_STABLE
|
|
}
|
|
|
|
override fun hasCutout(): Boolean {
|
|
return when {
|
|
Build.VERSION.SDK_INT >= Build.VERSION_CODES.R ->
|
|
activity.display?.cutout != null
|
|
Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q ->
|
|
@Suppress("DEPRECATION")
|
|
activity.windowManager.defaultDisplay.cutout != null
|
|
Build.VERSION.SDK_INT >= Build.VERSION_CODES.P ->
|
|
activity.window.decorView.rootWindowInsets.displayCutout != null
|
|
else -> false
|
|
}
|
|
}
|
|
|
|
override fun setCutout(enabled: Boolean) {
|
|
activity.runOnUiThread {
|
|
setCutoutFromUiThread(enabled)
|
|
}
|
|
}
|
|
internal fun setCutoutFromUiThread(enabled: Boolean) {
|
|
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.P) return
|
|
val params = activity.window.attributes
|
|
params.layoutInDisplayCutoutMode = when {
|
|
enabled -> WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES
|
|
else -> WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_NEVER
|
|
}
|
|
activity.window.attributes = params // This is the only line to actually need to be running on the Ui Thread
|
|
}
|
|
|
|
|
|
/*
|
|
Sources for Info about current orientation in case need:
|
|
val windowManager = (activity.getSystemService(Context.WINDOW_SERVICE) as WindowManager)
|
|
val displayRotation = windowManager.defaultDisplay.rotation
|
|
val currentOrientation = activity.resources.configuration.orientation
|
|
const val ORIENTATION_UNDEFINED = 0
|
|
const val ORIENTATION_PORTRAIT = 1
|
|
const val ORIENTATION_LANDSCAPE = 2
|
|
*/
|
|
|
|
override fun hasOrientation(): Boolean {
|
|
return true
|
|
}
|
|
|
|
override fun setOrientation(orientation: ScreenOrientation) {
|
|
val mode = when (orientation) {
|
|
// Automatically adjust landscape based on sensors.
|
|
ScreenOrientation.Landscape -> ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
|
|
// Automatically adjust the portrait based on the sensor.
|
|
ScreenOrientation.Portrait -> ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT
|
|
ScreenOrientation.Auto -> ActivityInfo.SCREEN_ORIENTATION_SENSOR
|
|
}
|
|
// Ensure ActivityTaskManager.getService().setRequestedOrientation isn't called unless necessary!
|
|
if (activity.requestedOrientation != mode)
|
|
activity.requestedOrientation = mode
|
|
}
|
|
|
|
class AndroidScreenMode private constructor(
|
|
private val modeId: Int,
|
|
private val name: String
|
|
) : ScreenMode {
|
|
@RequiresApi(Build.VERSION_CODES.M)
|
|
constructor(mode: Mode) : this(mode.modeId, "${mode.physicalWidth}x${mode.physicalHeight} (${mode.refreshRate.toInt()}Hz)")
|
|
|
|
override fun getId(): Int {
|
|
return modeId
|
|
}
|
|
|
|
override fun toString(): String {
|
|
return name.tr()
|
|
}
|
|
|
|
companion object {
|
|
const val defaultId = 0
|
|
val default: AndroidScreenMode
|
|
get() = AndroidScreenMode(defaultId, "Default")
|
|
}
|
|
}
|
|
}
|