Android: Add drawerlayout with the option to exit emulation (#298)
This commit is contained in:
parent
1a6c52216d
commit
00b15a301e
|
|
@ -58,6 +58,7 @@ android {
|
|||
dependencies {
|
||||
implementation("androidx.activity:activity-ktx:1.9.3")
|
||||
implementation("androidx.core:core-ktx:1.15.0")
|
||||
implementation("androidx.drawerlayout:drawerlayout:1.2.0")
|
||||
implementation("androidx.core:core-splashscreen:1.0.1")
|
||||
implementation("androidx.documentfile:documentfile:1.0.1")
|
||||
implementation("androidx.window:window:1.3.0")
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ object NativeLibrary {
|
|||
external fun getSettingString(setting: String): String
|
||||
external fun getSettingBool(setting: String): Boolean
|
||||
external fun setSettingString(setting: String, value: String)
|
||||
external fun setSettingBool(setting: String, value: Boolean)
|
||||
external fun getSettingInt(setting: String): Int
|
||||
external fun setSettingInt(setting: String, value: Int)
|
||||
external fun saveSettings()
|
||||
|
|
|
|||
|
|
@ -2,7 +2,16 @@ package org.nxemu
|
|||
|
||||
object NXUISetting {
|
||||
const val GameDirectories = "nxui:GameDirectories"
|
||||
const val ShowInputOverlay = "nxui:ShowInputOverlay"
|
||||
const val JoystickRelCenter = "nxui:JoystickRelCenter"
|
||||
const val DpadSlide = "nxui:DpadSlide"
|
||||
const val HapticFeedback = "nxui:HapticFeedback"
|
||||
const val Touchscreen = "nxui:Touchscreen"
|
||||
const val OverlayScale = "nxui:OverlayScale"
|
||||
const val OverlayOpacity = "nxui:OverlayOpacity"
|
||||
const val OverlayControlData = "nxui:OverlayControlData"
|
||||
const val ThemeMode = "nxui:ThemeMode"
|
||||
const val LockDrawer = "nxui:LockDrawer"
|
||||
}
|
||||
|
||||
object NXCoreSetting {
|
||||
|
|
|
|||
|
|
@ -1,11 +0,0 @@
|
|||
package org.nxemu.features.settings.model
|
||||
|
||||
enum class BooleanSetting {
|
||||
JOYSTICK_REL_CENTER,
|
||||
DPAD_SLIDE,
|
||||
HAPTIC_FEEDBACK,
|
||||
SHOW_INPUT_OVERLAY,
|
||||
TOUCHSCREEN;
|
||||
|
||||
fun getBoolean(needsGlobal: Boolean = false): Boolean = true
|
||||
}
|
||||
|
|
@ -1,8 +0,0 @@
|
|||
package org.nxemu.features.settings.model
|
||||
|
||||
enum class IntSetting(private val default: Int) {
|
||||
OVERLAY_SCALE(50),
|
||||
OVERLAY_OPACITY(100);
|
||||
|
||||
fun getInt(needsGlobal: Boolean = false): Int = default
|
||||
}
|
||||
|
|
@ -24,13 +24,13 @@ import androidx.core.content.ContextCompat
|
|||
import androidx.window.layout.WindowMetricsCalculator
|
||||
import kotlin.math.max
|
||||
import kotlin.math.min
|
||||
import org.nxemu.NXUISetting
|
||||
import org.nxemu.NativeLibrary
|
||||
import org.nxemu.features.input.NativeInput
|
||||
import org.nxemu.R
|
||||
import org.nxemu.features.input.model.NativeAnalog
|
||||
import org.nxemu.features.input.model.NativeButton
|
||||
import org.nxemu.features.input.model.NpadStyleIndex
|
||||
import org.nxemu.features.settings.model.BooleanSetting
|
||||
import org.nxemu.features.settings.model.IntSetting
|
||||
import org.nxemu.overlay.model.OverlayControl
|
||||
import org.nxemu.overlay.model.OverlayControlData
|
||||
import org.nxemu.overlay.model.OverlayLayout
|
||||
|
|
@ -119,7 +119,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) :
|
|||
}
|
||||
|
||||
for (dpad in overlayDpads) {
|
||||
if (!dpad.updateStatus(event, BooleanSetting.DPAD_SLIDE.getBoolean())) {
|
||||
if (!dpad.updateStatus(event, NativeLibrary.getSettingBool(NXUISetting.DpadSlide))) {
|
||||
continue
|
||||
}
|
||||
NativeInput.onOverlayButtonEvent(
|
||||
|
|
@ -169,7 +169,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) :
|
|||
invalidate()
|
||||
}
|
||||
|
||||
if (!BooleanSetting.TOUCHSCREEN.getBoolean()) {
|
||||
if (!NativeLibrary.getSettingBool(NXUISetting.Touchscreen)) {
|
||||
return true
|
||||
}
|
||||
|
||||
|
|
@ -206,7 +206,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) :
|
|||
}
|
||||
|
||||
private fun playHaptics(event: MotionEvent) {
|
||||
if (BooleanSetting.HAPTIC_FEEDBACK.getBoolean()) {
|
||||
if (NativeLibrary.getSettingBool(NXUISetting.HapticFeedback)) {
|
||||
when (event.actionMasked) {
|
||||
MotionEvent.ACTION_DOWN,
|
||||
MotionEvent.ACTION_POINTER_DOWN ->
|
||||
|
|
@ -601,7 +601,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) :
|
|||
overlayJoysticks.clear()
|
||||
|
||||
// Add all the enabled overlay items back to the HashSet.
|
||||
if (BooleanSetting.SHOW_INPUT_OVERLAY.getBoolean()) {
|
||||
if (NativeLibrary.getSettingBool(NXUISetting.ShowInputOverlay)) {
|
||||
addOverlayControls(layout)
|
||||
}
|
||||
invalidate()
|
||||
|
|
@ -857,7 +857,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) :
|
|||
|
||||
else -> 0.11f
|
||||
}
|
||||
scale *= (IntSetting.OVERLAY_SCALE.getInt() + 50).toFloat()
|
||||
scale *= (NativeLibrary.getSettingInt(NXUISetting.OverlayScale) + 50).toFloat()
|
||||
scale /= 100f
|
||||
|
||||
// Initialize the InputOverlayDrawableButton.
|
||||
|
|
@ -896,7 +896,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) :
|
|||
drawableX - (width / 2),
|
||||
drawableY - (height / 2)
|
||||
)
|
||||
overlayDrawable.setOpacity(IntSetting.OVERLAY_OPACITY.getInt() * 255 / 100)
|
||||
overlayDrawable.setOpacity(NativeLibrary.getSettingInt(NXUISetting.OverlayOpacity) * 255 / 100)
|
||||
return overlayDrawable
|
||||
}
|
||||
|
||||
|
|
@ -924,7 +924,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) :
|
|||
|
||||
// Decide scale based on button ID and user preference
|
||||
var scale = 0.25f
|
||||
scale *= (IntSetting.OVERLAY_SCALE.getInt() + 50).toFloat()
|
||||
scale *= (NativeLibrary.getSettingInt(NXUISetting.OverlayScale) + 50).toFloat()
|
||||
scale /= 100f
|
||||
|
||||
// Initialize the InputOverlayDrawableDpad.
|
||||
|
|
@ -963,7 +963,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) :
|
|||
|
||||
// Need to set the image's position
|
||||
overlayDrawable.setPosition(drawableX - (width / 2), drawableY - (height / 2))
|
||||
overlayDrawable.setOpacity(IntSetting.OVERLAY_OPACITY.getInt() * 255 / 100)
|
||||
overlayDrawable.setOpacity(NativeLibrary.getSettingInt(NXUISetting.OverlayOpacity) * 255 / 100)
|
||||
return overlayDrawable
|
||||
}
|
||||
|
||||
|
|
@ -997,7 +997,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) :
|
|||
|
||||
// Decide scale based on user preference
|
||||
var scale = 0.3f
|
||||
scale *= (IntSetting.OVERLAY_SCALE.getInt() + 50).toFloat()
|
||||
scale *= (NativeLibrary.getSettingInt(NXUISetting.OverlayScale) + 50).toFloat()
|
||||
scale /= 100f
|
||||
|
||||
// Initialize the InputOverlayDrawableJoystick.
|
||||
|
|
@ -1042,7 +1042,7 @@ class InputOverlay(context: Context, attrs: AttributeSet?) :
|
|||
|
||||
// Need to set the image's position
|
||||
overlayDrawable.setPosition(drawableX, drawableY)
|
||||
overlayDrawable.setOpacity(IntSetting.OVERLAY_OPACITY.getInt() * 255 / 100)
|
||||
overlayDrawable.setOpacity(NativeLibrary.getSettingInt(NXUISetting.OverlayOpacity) * 255 / 100)
|
||||
return overlayDrawable
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -13,10 +13,11 @@ import kotlin.math.atan2
|
|||
import kotlin.math.cos
|
||||
import kotlin.math.sin
|
||||
import kotlin.math.sqrt
|
||||
import org.nxemu.NXUISetting
|
||||
import org.nxemu.NativeLibrary
|
||||
import org.nxemu.features.input.NativeInput.ButtonState
|
||||
import org.nxemu.features.input.model.NativeAnalog
|
||||
import org.nxemu.features.input.model.NativeButton
|
||||
import org.nxemu.features.settings.model.BooleanSetting
|
||||
|
||||
/**
|
||||
* Custom [BitmapDrawable] that is capable
|
||||
|
|
@ -126,7 +127,7 @@ class InputOverlayDrawableJoystick(
|
|||
pressedState = true
|
||||
outerBitmap.alpha = 0
|
||||
boundsBoxBitmap.alpha = opacity
|
||||
if (BooleanSetting.JOYSTICK_REL_CENTER.getBoolean()) {
|
||||
if (NativeLibrary.getSettingBool(NXUISetting.JoystickRelCenter)) {
|
||||
virtBounds.offset(
|
||||
xPosition - virtBounds.centerX(),
|
||||
yPosition - virtBounds.centerY()
|
||||
|
|
|
|||
|
|
@ -11,8 +11,11 @@ import android.os.Build
|
|||
import android.os.Bundle
|
||||
import android.os.Handler
|
||||
import android.os.Looper
|
||||
import android.os.SystemClock
|
||||
import android.util.Base64
|
||||
import android.util.Log
|
||||
import android.view.Gravity
|
||||
import android.view.MotionEvent
|
||||
import android.view.SurfaceHolder
|
||||
import android.view.SurfaceView
|
||||
import android.view.View
|
||||
|
|
@ -20,14 +23,18 @@ import android.view.WindowManager
|
|||
import android.widget.ImageView
|
||||
import android.widget.TextView
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.activity.OnBackPressedCallback
|
||||
import androidx.core.view.WindowCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import androidx.core.view.WindowInsetsControllerCompat
|
||||
import androidx.drawerlayout.widget.DrawerLayout
|
||||
import org.nxemu.NXCoreSetting
|
||||
import org.nxemu.NXUISetting
|
||||
import org.nxemu.NativeLibrary
|
||||
import org.nxemu.R
|
||||
import org.nxemu.overlay.InputOverlay
|
||||
import org.nxemu.overlay.model.OverlayLayout
|
||||
import org.nxemu.utils.NativeConfig
|
||||
import org.json.JSONObject
|
||||
import java.nio.ByteBuffer
|
||||
import java.util.Locale
|
||||
|
|
@ -50,6 +57,8 @@ class EmulationActivity : ComponentActivity(), SurfaceHolder.Callback {
|
|||
private lateinit var showFpsText: TextView
|
||||
private lateinit var showDeviceText: TextView
|
||||
private lateinit var surfaceInputOverlay: InputOverlay
|
||||
private lateinit var drawerLayout: DrawerLayout
|
||||
private lateinit var lockDrawerItem: TextView
|
||||
private lateinit var overlayAppVersion: String
|
||||
private lateinit var overlayPhoneModel: String
|
||||
private lateinit var overlaySoc: String
|
||||
|
|
@ -79,12 +88,28 @@ class EmulationActivity : ComponentActivity(), SurfaceHolder.Callback {
|
|||
surfaceInputOverlay = findViewById(R.id.surface_input_overlay)
|
||||
surfaceInputOverlay.setZOrderMediaOverlay(true)
|
||||
surfaceInputOverlay.holder.setFormat(PixelFormat.TRANSLUCENT)
|
||||
drawerLayout = findViewById(R.id.drawer_layout)
|
||||
lockDrawerItem = findViewById(R.id.menu_lock_drawer)
|
||||
setupInGameDrawer()
|
||||
updateInputOverlayLayout()
|
||||
cacheDeviceOverlayInfo()
|
||||
|
||||
NativeLibrary.addSettingChangedListener(settingChangedListener)
|
||||
hideLoadingIfFirstFrame()
|
||||
|
||||
onBackPressedDispatcher.addCallback(
|
||||
this,
|
||||
object : OnBackPressedCallback(true) {
|
||||
override fun handleOnBackPressed() {
|
||||
if (drawerLayout.isDrawerOpen(Gravity.START)) {
|
||||
drawerLayout.closeDrawer(Gravity.START)
|
||||
} else {
|
||||
drawerLayout.openDrawer(Gravity.START)
|
||||
}
|
||||
}
|
||||
},
|
||||
)
|
||||
|
||||
val path = intent.getStringExtra(EXTRA_GAME_PATH)
|
||||
if (path.isNullOrEmpty()) {
|
||||
Log.e(TAG, "Missing EXTRA_GAME_PATH")
|
||||
|
|
@ -103,6 +128,78 @@ class EmulationActivity : ComponentActivity(), SurfaceHolder.Callback {
|
|||
}
|
||||
}
|
||||
|
||||
private fun setupInGameDrawer() {
|
||||
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_LOCKED_CLOSED)
|
||||
drawerLayout.addDrawerListener(object : DrawerLayout.SimpleDrawerListener() {
|
||||
override fun onDrawerSlide(drawerView: View, slideOffset: Float) {
|
||||
releaseOverlayTouches()
|
||||
if (slideOffset > 0f) {
|
||||
surfaceInputOverlay.visibility = View.INVISIBLE
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDrawerOpened(drawerView: View) {
|
||||
drawerLayout.setDrawerLockMode(DrawerLayout.LOCK_MODE_UNLOCKED)
|
||||
findViewById<View>(R.id.in_game_menu).requestFocus()
|
||||
}
|
||||
|
||||
override fun onDrawerClosed(drawerView: View) {
|
||||
drawerLayout.setDrawerLockMode(savedDrawerLockMode())
|
||||
if (loadingIndicator.visibility != View.VISIBLE) {
|
||||
surfaceInputOverlay.visibility = View.VISIBLE
|
||||
}
|
||||
}
|
||||
})
|
||||
lockDrawerItem.setOnClickListener { toggleDrawerLock() }
|
||||
findViewById<View>(R.id.menu_exit).setOnClickListener {
|
||||
drawerLayout.closeDrawers()
|
||||
finish()
|
||||
}
|
||||
updateLockDrawerLabel()
|
||||
}
|
||||
|
||||
private fun releaseOverlayTouches() {
|
||||
val event = MotionEvent.obtain(
|
||||
SystemClock.uptimeMillis(),
|
||||
SystemClock.uptimeMillis(),
|
||||
MotionEvent.ACTION_UP,
|
||||
0f,
|
||||
0f,
|
||||
0,
|
||||
)
|
||||
surfaceInputOverlay.dispatchTouchEvent(event)
|
||||
event.recycle()
|
||||
}
|
||||
|
||||
private fun savedDrawerLockMode(): Int {
|
||||
val mode = NativeLibrary.getSettingInt(NXUISetting.LockDrawer)
|
||||
return if (mode == DrawerLayout.LOCK_MODE_LOCKED_CLOSED) {
|
||||
DrawerLayout.LOCK_MODE_LOCKED_CLOSED
|
||||
} else {
|
||||
DrawerLayout.LOCK_MODE_UNLOCKED
|
||||
}
|
||||
}
|
||||
|
||||
private fun toggleDrawerLock() {
|
||||
val mode = if (savedDrawerLockMode() == DrawerLayout.LOCK_MODE_UNLOCKED) {
|
||||
DrawerLayout.LOCK_MODE_LOCKED_CLOSED
|
||||
} else {
|
||||
DrawerLayout.LOCK_MODE_UNLOCKED
|
||||
}
|
||||
NativeLibrary.setSettingInt(NXUISetting.LockDrawer, mode)
|
||||
updateLockDrawerLabel()
|
||||
NativeConfig.saveGlobalConfig()
|
||||
}
|
||||
|
||||
private fun updateLockDrawerLabel() {
|
||||
lockDrawerItem.text = getString(
|
||||
if (savedDrawerLockMode() == DrawerLayout.LOCK_MODE_LOCKED_CLOSED) {
|
||||
R.string.unlock_drawer
|
||||
} else {
|
||||
R.string.lock_drawer
|
||||
},
|
||||
)
|
||||
}
|
||||
private fun hideSystemBars() {
|
||||
WindowCompat.getInsetsController(window, window.decorView).apply {
|
||||
hide(WindowInsetsCompat.Type.systemBars())
|
||||
|
|
@ -115,7 +212,10 @@ class EmulationActivity : ComponentActivity(), SurfaceHolder.Callback {
|
|||
stopAnimatedDrawables()
|
||||
loadingIndicator.visibility = View.GONE
|
||||
startPerfOverlay()
|
||||
surfaceInputOverlay.visibility = View.VISIBLE
|
||||
if (!drawerLayout.isDrawerOpen(Gravity.START)) {
|
||||
surfaceInputOverlay.visibility = View.VISIBLE
|
||||
}
|
||||
drawerLayout.setDrawerLockMode(savedDrawerLockMode())
|
||||
updateInputOverlayLayout()
|
||||
surfaceInputOverlay.refreshControls()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,16 @@ class NxEmuBridge(private val activity: MainActivity) {
|
|||
NativeLibrary.saveSettings()
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
fun getSettingBool(setting: String): Boolean {
|
||||
return NativeLibrary.getSettingBool(setting)
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
fun setSettingBool(setting: String, value: Boolean) {
|
||||
NativeLibrary.setSettingBool(setting, value)
|
||||
}
|
||||
|
||||
@JavascriptInterface
|
||||
fun getSettingInt(setting: String): Int {
|
||||
return NativeLibrary.getSettingInt(setting)
|
||||
|
|
|
|||
|
|
@ -1,140 +1,185 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
<androidx.drawerlayout.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/drawer_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@android:color/black">
|
||||
|
||||
<SurfaceView
|
||||
android:id="@+id/emulation_surface"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:keepScreenOn="true" />
|
||||
|
||||
<org.nxemu.overlay.InputOverlay
|
||||
android:id="@+id/surface_input_overlay"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center"
|
||||
android:defaultFocusHighlightEnabled="false"
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true"
|
||||
android:visibility="invisible" />
|
||||
android:keepScreenOn="true">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/loading_indicator"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
android:layout_height="match_parent"
|
||||
android:background="@android:color/black">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/loading_corner_logo"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="48dp"
|
||||
android:layout_gravity="top|start"
|
||||
android:adjustViewBounds="true"
|
||||
android:contentDescription="@null"
|
||||
android:padding="8dp"
|
||||
android:scaleType="fitStart"
|
||||
android:visibility="gone" />
|
||||
<SurfaceView
|
||||
android:id="@+id/emulation_surface"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:keepScreenOn="true" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
<org.nxemu.overlay.InputOverlay
|
||||
android:id="@+id/surface_input_overlay"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="center"
|
||||
android:background="@drawable/emulation_loading_card"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingHorizontal="24dp"
|
||||
android:paddingVertical="20dp">
|
||||
android:defaultFocusHighlightEnabled="false"
|
||||
android:focusable="true"
|
||||
android:focusableInTouchMode="true"
|
||||
android:visibility="invisible" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/loading_indicator"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/loading_image"
|
||||
android:layout_width="64dp"
|
||||
android:layout_height="64dp"
|
||||
android:contentDescription="@string/app_name"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@mipmap/ic_launcher" />
|
||||
android:id="@+id/loading_corner_logo"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="48dp"
|
||||
android:layout_gravity="top|start"
|
||||
android:adjustViewBounds="true"
|
||||
android:contentDescription="@null"
|
||||
android:padding="8dp"
|
||||
android:scaleType="fitStart"
|
||||
android:visibility="gone" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="16dp"
|
||||
android:orientation="vertical">
|
||||
android:layout_gravity="center"
|
||||
android:background="@drawable/emulation_loading_card"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:paddingHorizontal="24dp"
|
||||
android:paddingVertical="20dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/loading_title"
|
||||
<ImageView
|
||||
android:id="@+id/loading_image"
|
||||
android:layout_width="64dp"
|
||||
android:layout_height="64dp"
|
||||
android:contentDescription="@string/app_name"
|
||||
android:scaleType="fitCenter"
|
||||
android:src="@mipmap/ic_launcher" />
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="marquee"
|
||||
android:maxWidth="280dp"
|
||||
android:singleLine="true"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold" />
|
||||
android:layout_marginStart="16dp"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/loading_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:text="@string/loading"
|
||||
android:textColor="#B3FFFFFF"
|
||||
android:textSize="14sp" />
|
||||
<TextView
|
||||
android:id="@+id/loading_title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="marquee"
|
||||
android:maxWidth="280dp"
|
||||
android:singleLine="true"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/loading_progress"
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
android:layout_width="200dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
android:indeterminate="true" />
|
||||
<TextView
|
||||
android:id="@+id/loading_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="4dp"
|
||||
android:text="@string/loading"
|
||||
android:textColor="#B3FFFFFF"
|
||||
android:textSize="14sp" />
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/loading_progress"
|
||||
style="?android:attr/progressBarStyleHorizontal"
|
||||
android:layout_width="200dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
android:indeterminate="true" />
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/loading_corner_banner"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="64dp"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:adjustViewBounds="true"
|
||||
android:contentDescription="@null"
|
||||
android:maxWidth="186dp"
|
||||
android:padding="6dp"
|
||||
android:scaleType="fitEnd"
|
||||
android:visibility="gone" />
|
||||
<ImageView
|
||||
android:id="@+id/loading_corner_banner"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="64dp"
|
||||
android:layout_gravity="bottom|end"
|
||||
android:adjustViewBounds="true"
|
||||
android:contentDescription="@null"
|
||||
android:maxWidth="186dp"
|
||||
android:padding="6dp"
|
||||
android:scaleType="fitEnd"
|
||||
android:visibility="gone" />
|
||||
</FrameLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/overlay_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginHorizontal="20dp"
|
||||
android:paddingTop="4dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/show_fps_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="top|start"
|
||||
android:clickable="false"
|
||||
android:focusable="false"
|
||||
android:shadowColor="@android:color/black"
|
||||
android:shadowRadius="3"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="12sp"
|
||||
android:visibility="gone" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/show_device_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="top|end"
|
||||
android:clickable="false"
|
||||
android:focusable="false"
|
||||
android:gravity="end"
|
||||
android:shadowColor="@android:color/black"
|
||||
android:shadowRadius="3"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="12sp"
|
||||
android:visibility="gone" />
|
||||
</FrameLayout>
|
||||
</FrameLayout>
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/overlay_container"
|
||||
android:layout_width="match_parent"
|
||||
<LinearLayout
|
||||
android:id="@+id/in_game_menu"
|
||||
android:layout_width="280dp"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginHorizontal="20dp"
|
||||
android:paddingTop="4dp">
|
||||
android:layout_gravity="start"
|
||||
android:background="#F0121212"
|
||||
android:clickable="true"
|
||||
android:elevation="16dp"
|
||||
android:focusable="true"
|
||||
android:orientation="vertical"
|
||||
android:paddingTop="24dp">
|
||||
<TextView
|
||||
android:id="@+id/menu_lock_drawer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingHorizontal="20dp"
|
||||
android:text="@string/lock_drawer"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="16sp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/show_fps_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="top|start"
|
||||
android:clickable="false"
|
||||
android:focusable="false"
|
||||
android:shadowColor="@android:color/black"
|
||||
android:shadowRadius="3"
|
||||
android:id="@+id/menu_exit"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="48dp"
|
||||
android:background="?android:attr/selectableItemBackground"
|
||||
android:clickable="true"
|
||||
android:focusable="true"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingHorizontal="20dp"
|
||||
android:text="@string/emulation_exit"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="12sp"
|
||||
android:visibility="gone" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/show_device_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="top|end"
|
||||
android:clickable="false"
|
||||
android:focusable="false"
|
||||
android:gravity="end"
|
||||
android:shadowColor="@android:color/black"
|
||||
android:shadowRadius="3"
|
||||
android:textColor="@android:color/white"
|
||||
android:textSize="12sp"
|
||||
android:visibility="gone" />
|
||||
</FrameLayout>
|
||||
</FrameLayout>
|
||||
android:textSize="16sp" />
|
||||
</LinearLayout>
|
||||
</androidx.drawerlayout.widget.DrawerLayout>
|
||||
|
|
|
|||
|
|
@ -2,4 +2,7 @@
|
|||
<resources>
|
||||
<string name="app_name">NxEmu</string>
|
||||
<string name="loading">Loading...</string>
|
||||
<string name="emulation_exit">Exit emulation</string>
|
||||
<string name="lock_drawer">Lock drawer</string>
|
||||
<string name="unlock_drawer">Unlock drawer</string>
|
||||
</resources>
|
||||
|
|
|
|||
Loading…
Reference in New Issue